Passed
Push — main ( b15a24...935ae5 )
by Axel
04:15
created

UsersUiSubscriber::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 0
nc 1
nop 9
dl 0
loc 12
rs 10
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\ProfileBundle\EventSubscriber;
15
16
use Symfony\Component\DependencyInjection\Attribute\Autowire;
17
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
18
use Symfony\Component\HttpFoundation\File\UploadedFile;
19
use Symfony\Contracts\Translation\TranslatorInterface;
20
use Twig\Environment;
21
use Zikula\Bundle\FormExtensionBundle\Event\FormTypeChoiceEvent;
22
use Zikula\ProfileBundle\Form\ProfileTypeFactory;
23
use Zikula\ProfileBundle\Form\Type\AvatarType;
24
use Zikula\ProfileBundle\Helper\UploadHelper;
25
use Zikula\ProfileBundle\ProfileConstant;
26
use Zikula\ProfileBundle\Repository\PropertyRepositoryInterface;
27
use Zikula\UsersBundle\Event\EditUserFormPostCreatedEvent;
0 ignored issues
show
Bug introduced by
The type Zikula\UsersBundle\Event...serFormPostCreatedEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use Zikula\UsersBundle\Event\EditUserFormPostValidatedEvent;
0 ignored issues
show
Bug introduced by
The type Zikula\UsersBundle\Event...rFormPostValidatedEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
use Zikula\UsersBundle\Event\UserAccountDisplayEvent;
30
use Zikula\UsersBundle\Repository\UserRepositoryInterface;
31
use Zikula\UsersBundle\UsersConstant;
32
33
/**
34
 * Hook-like event handlers for basic profile data.
35
 */
36
class UsersUiSubscriber implements EventSubscriberInterface
37
{
38
    /**
39
     * The area name that this handler processes.
40
     */
41
    public const EVENT_KEY = 'module.profile.users_ui_handler';
42
43
    public function __construct(
44
        private readonly TranslatorInterface $translator,
45
        private readonly UserRepositoryInterface $userRepository,
46
        private readonly PropertyRepositoryInterface $propertyRepository,
47
        private readonly ProfileTypeFactory $factory,
48
        private readonly Environment $twig,
49
        private readonly UploadHelper $uploadHelper,
50
        #[Autowire('%zikula_profile_module.property_prefix%')]
51
        private readonly string $prefix,
52
        private readonly bool $displayRegistrationDate,
53
        private readonly string $avatarImagePath
54
    ) {
55
    }
56
57
    public static function getSubscribedEvents(): array
58
    {
59
        return [
60
            UserAccountDisplayEvent::class => ['uiView'],
61
            EditUserFormPostCreatedEvent::class => ['amendForm'],
62
            EditUserFormPostValidatedEvent::class => ['editFormHandler'],
63
            FormTypeChoiceEvent::class => ['formTypeChoices'],
64
        ];
65
    }
66
67
    /**
68
     * Render and return profile information for display as part of a hook-like UI event issued from the Users bundle.
69
     */
70
    public function uiView(UserAccountDisplayEvent $event): void
71
    {
72
        $event->addContent(self::EVENT_KEY, $this->twig->render('@ZikulaProfile/Hook/display.html.twig', [
73
            'prefix' => $this->prefix,
74
            'user' => $event->getUser(),
75
            'activeProperties' => $this->propertyRepository->getDynamicFieldsSpecification(),
76
            'displayRegistrationDate' => $this->displayRegistrationDate,
77
        ]));
78
    }
79
80
    public function amendForm(EditUserFormPostCreatedEvent $event): void
81
    {
82
        $user = $event->getFormData();
83
        $uid = !empty($user['uid']) ? $user['uid'] : UsersConstant::USER_ID_ANONYMOUS;
84
        $userEntity = $this->userRepository->find($uid);
85
        $attributes = $userEntity->getAttributes() ?? [];
86
87
        // unpack json values (e.g. array for multi-valued options)
88
        foreach ($attributes as $key => $attribute) {
89
            $value = $attribute->getValue();
90
            if (is_string($value) && is_array(json_decode($value, true)) && JSON_ERROR_NONE === json_last_error()) {
91
                $attribute->setValue(json_decode($value, true));
92
            }
93
        }
94
95
        $profileForm = $this->formFactory->createForm($attributes, false);
0 ignored issues
show
Bug Best Practice introduced by
The property formFactory does not exist on Zikula\ProfileBundle\Eve...riber\UsersUiSubscriber. Did you maybe forget to declare it?
Loading history...
96
        $event
97
            ->formAdd($profileForm)
98
            ->addTemplate('@ZikulaProfile/Hook/edit.html.twig', [
99
                'imagePath' => $this->avatarImagePath,
100
            ])
101
        ;
102
    }
103
104
    public function editFormHandler(EditUserFormPostValidatedEvent $event): void
105
    {
106
        $userEntity = $event->getUser();
107
        $formData = $event->getFormData(ProfileConstant::FORM_BLOCK_PREFIX);
108
        foreach ($formData as $key => $value) {
109
            if (!empty($value)) {
110
                if ($value instanceof UploadedFile) {
111
                    $value = $this->uploadHelper->handleUpload($value, $userEntity->getUid());
112
                } elseif (is_array($value)) {
113
                    // pack multi-valued options into json
114
                    $value = json_encode($value);
115
                }
116
                $userEntity->setAttribute($key, $value);
117
            } elseif (false === mb_strpos($key, 'avatar')) {
118
                $userEntity->delAttribute($key);
119
            }
120
        }
121
122
        // we do not call flush here on purpose because maybe
123
        // other modules need to care for certain things before
124
        // the Users module calls flush after all listeners finished
125
    }
126
127
    public function formTypeChoices(FormTypeChoiceEvent $event): void
128
    {
129
        $choices = $event->getChoices();
130
131
        $groupName = $this->translator->trans('Other Fields', [], 'zikula');
132
        if (!isset($choices[$groupName])) {
133
            $choices[$groupName] = [];
134
        }
135
136
        $groupChoices = $choices[$groupName];
137
        $groupChoices[$this->translator->trans('Avatar')] = AvatarType::class;
138
        $choices[$groupName] = $groupChoices;
139
140
        $event->setChoices($choices);
141
    }
142
}
143