User::addEmail()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 11
c 1
b 0
f 0
dl 0
loc 20
rs 9.9
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Form\Factory;
6
7
use AbterPhp\Admin\Domain\Entities\User as Entity;
8
use AbterPhp\Admin\Domain\Entities\UserGroup;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, AbterPhp\Admin\Form\Factory\UserGroup. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
use AbterPhp\Admin\Domain\Entities\UserLanguage;
10
use AbterPhp\Admin\Orm\UserGroupRepo;
11
use AbterPhp\Admin\Orm\UserLanguageRepo;
12
use AbterPhp\Framework\Constant\Html5;
13
use AbterPhp\Framework\Form\Component\Option;
14
use AbterPhp\Framework\Form\Container\CheckboxGroup;
15
use AbterPhp\Framework\Form\Container\FormGroup;
16
use AbterPhp\Framework\Form\Element\Input;
17
use AbterPhp\Framework\Form\Element\MultiSelect;
18
use AbterPhp\Framework\Form\Element\Select;
19
use AbterPhp\Framework\Form\Extra\Help;
20
use AbterPhp\Framework\Form\IForm;
21
use AbterPhp\Framework\Form\Label\Label;
22
use AbterPhp\Framework\Html\Helper\Attributes;
23
use AbterPhp\Framework\Html\Tag;
24
use AbterPhp\Framework\I18n\ITranslator;
25
use Opulence\Orm\IEntity;
26
use Opulence\Orm\OrmException;
27
use Opulence\Sessions\ISession;
28
29
class User extends Base
30
{
31
    protected UserGroupRepo $userGroupRepo;
32
33
    protected UserLanguageRepo $userLanguageRepo;
34
35
    /**
36
     * User constructor.
37
     *
38
     * @param ISession         $session
39
     * @param ITranslator      $translator
40
     * @param UserGroupRepo    $userGroupRepo
41
     * @param UserLanguageRepo $userLanguageRepo
42
     */
43
    public function __construct(
44
        ISession $session,
45
        ITranslator $translator,
46
        UserGroupRepo $userGroupRepo,
47
        UserLanguageRepo $userLanguageRepo
48
    ) {
49
        parent::__construct($session, $translator);
50
51
        $this->userGroupRepo    = $userGroupRepo;
52
        $this->userLanguageRepo = $userLanguageRepo;
53
    }
54
55
    /**
56
     * @param string       $action
57
     * @param string       $method
58
     * @param string       $showUrl
59
     * @param IEntity|null $entity
60
     *
61
     * @return IForm
62
     * @throws OrmException
63
     */
64
    public function create(string $action, string $method, string $showUrl, ?IEntity $entity = null): IForm
65
    {
66
        assert($entity instanceof Entity, new \InvalidArgumentException());
67
68
        $this->createForm($action, $method)
69
            ->addDefaultElements()
70
            ->addJsOnly()
71
            ->addUsername($entity)
72
            ->addEmail($entity)
73
            ->addPassword()
74
            ->addPasswordConfirmed()
75
            ->addRawPassword($entity)
76
            ->addRawPasswordConfirmed($entity)
77
            ->addCanLogin($entity)
78
            ->addIsGravatarAllowed($entity)
79
            ->addUserGroups($entity)
80
            ->addUserLanguages($entity)
81
            ->addDefaultButtons($showUrl);
82
83
        $form = $this->form;
84
85
        $this->form = null;
86
87
        return $form;
88
    }
89
90
    /**
91
     * @return $this
92
     */
93
    protected function addJsOnly(): User
94
    {
95
        $content    = sprintf(
96
            '<i class="material-icons">warning</i>&nbsp;%s',
97
            $this->translator->translate('admin:jsOnly')
98
        );
99
        $attributes = Attributes::fromArray([Html5::ATTR_CLASS => 'only-js-form-warning']);
100
101
        $this->form[] = new Tag($content, [], $attributes, Html5::TAG_P);
102
103
        return $this;
104
    }
105
106
    /**
107
     * @param Entity $entity
108
     *
109
     * @return $this
110
     */
111
    protected function addUsername(Entity $entity): User
112
    {
113
        $attributes = Attributes::fromArray([Html5::ATTR_NAME => [Input::AUTOCOMPLETE_OFF]]);
114
        $input      = new Input('username', 'username', $entity->getUsername(), [], $attributes);
115
        $label      = new Label('username', 'admin:userUsername');
116
117
        $attributes   = Attributes::fromArray([Html5::ATTR_CLASS => FormGroup::CLASS_REQUIRED]);
118
        $this->form[] = new FormGroup($input, $label, null, [], $attributes);
119
120
        return $this;
121
    }
122
123
    /**
124
     * @param Entity $entity
125
     *
126
     * @return $this
127
     */
128
    protected function addEmail(Entity $entity): User
129
    {
130
        $input = new Input(
131
            'email',
132
            'email',
133
            $entity->getEmail(),
134
            [],
135
            Attributes::fromArray(
136
                [
137
                    Html5::ATTR_AUTOCOMPLETE => [Input::AUTOCOMPLETE_OFF],
138
                    Html5::ATTR_TYPE         => Input::TYPE_EMAIL,
139
                ]
140
            )
141
        );
142
        $label = new Label('email', 'admin:userEmail');
143
144
        $attributes   = Attributes::fromArray([Html5::ATTR_CLASS => FormGroup::CLASS_REQUIRED]);
145
        $this->form[] = new FormGroup($input, $label, null, [], $attributes);
146
147
        return $this;
148
    }
149
150
    /**
151
     * @return $this
152
     */
153
    protected function addPassword(): User
154
    {
155
        $this->form[] = new Input(
156
            'password',
157
            'password',
158
            '',
159
            [],
160
            Attributes::fromArray([Html5::ATTR_TYPE => [Input::TYPE_HIDDEN]])
161
        );
162
163
        return $this;
164
    }
165
166
    /**
167
     * @return $this
168
     */
169
    protected function addPasswordConfirmed(): User
170
    {
171
        $this->form[] = new Input(
172
            'password_confirmed',
173
            'password_confirmed',
174
            '',
175
            [],
176
            Attributes::fromArray([Html5::ATTR_TYPE => [Input::TYPE_HIDDEN]])
177
        );
178
179
        return $this;
180
    }
181
182
    /**
183
     * @param Entity $entity
184
     *
185
     * @return $this
186
     */
187
    protected function addRawPassword(Entity $entity): User
188
    {
189
        $input = new Input(
190
            'raw_password',
191
            'raw_password',
192
            '',
193
            [],
194
            Attributes::fromArray(
195
                [
196
                    Html5::ATTR_NAME => [Input::AUTOCOMPLETE_OFF],
197
                    Html5::ATTR_TYPE => [Input::TYPE_PASSWORD],
198
                ]
199
            )
200
        );
201
        $label = new Label('raw_password', 'admin:userPassword');
202
203
        $class = $entity->getId() ? '' : FormGroup::CLASS_REQUIRED;
204
205
        $attributes   = Attributes::fromArray([Html5::ATTR_CLASS => $class]);
206
        $this->form[] = new FormGroup($input, $label, null, [], $attributes);
207
208
        return $this;
209
    }
210
211
    /**
212
     * @param Entity $entity
213
     *
214
     * @return $this
215
     */
216
    protected function addRawPasswordConfirmed(Entity $entity): User
217
    {
218
        $input = new Input(
219
            'raw_password_confirmed',
220
            'raw_password_confirmed',
221
            '',
222
            [],
223
            Attributes::fromArray(
224
                [
225
                    Html5::ATTR_NAME => [Input::AUTOCOMPLETE_OFF],
226
                    Html5::ATTR_TYPE => [Input::TYPE_PASSWORD],
227
                ]
228
            )
229
        );
230
        $label = new Label('raw_password_confirmed', 'admin:userConfirmPassword');
231
232
        $class = $entity->getId() ? '' : FormGroup::CLASS_REQUIRED;
233
234
        $attributes   = Attributes::fromArray([Html5::ATTR_CLASS => $class]);
235
        $this->form[] = new FormGroup($input, $label, null, [], $attributes);
236
237
        return $this;
238
    }
239
240
    /**
241
     * @param Entity $entity
242
     *
243
     * @return $this
244
     */
245
    protected function addCanLogin(Entity $entity): User
246
    {
247
        $attributes = Attributes::fromArray([Html5::ATTR_TYPE => [Input::TYPE_CHECKBOX]]);
248
        if ($entity->canLogin()) {
249
            $attributes = Attributes::addItem($attributes, Html5::ATTR_CHECKED);
250
        }
251
        $input = new Input(
252
            'can_login',
253
            'can_login',
254
            '1',
255
            [],
256
            $attributes
257
        );
258
        $label = new Label('can_login', 'admin:userCanLogin');
259
        $help  = new Help('admin:userCanLoginHelp');
260
261
        $this->form[] = new CheckboxGroup($input, $label, $help);
262
263
        return $this;
264
    }
265
266
    /**
267
     * @param Entity $entity
268
     *
269
     * @return $this
270
     */
271
    protected function addIsGravatarAllowed(Entity $entity): User
272
    {
273
        $attributes = Attributes::fromArray([Html5::ATTR_TYPE => [Input::TYPE_CHECKBOX]]);
274
        if ($entity->isGravatarAllowed()) {
275
            $attributes = Attributes::addItem($attributes, Html5::ATTR_CHECKED);
276
        }
277
        $input = new Input(
278
            'is_gravatar_allowed',
279
            'is_gravatar_allowed',
280
            '1',
281
            [],
282
            $attributes
283
        );
284
        $label = new Label(
285
            'is_gravatar_allowed',
286
            'admin:userIsGravatarAllowed'
287
        );
288
        $help  = new Help('admin:userIsGravatarAllowedHelp');
289
290
        $this->form[] = new CheckboxGroup($input, $label, $help);
291
292
        return $this;
293
    }
294
295
    /**
296
     * @param Entity $entity
297
     *
298
     * @return $this
299
     * @throws OrmException
300
     */
301
    protected function addUserGroups(Entity $entity): User
302
    {
303
        $allUserGroups = $this->getAllUserGroups();
304
305
        $userGroupIds = [];
306
        foreach ($entity->getUserGroups() as $userGroup) {
307
            $userGroupIds[] = $userGroup->getId();
308
        }
309
310
        $options = $this->createUserGroupOptions($allUserGroups, $userGroupIds);
311
312
        $this->form[] = new FormGroup(
313
            $this->createUserGroupSelect($options),
314
            $this->createUserGroupLabel()
315
        );
316
317
        return $this;
318
    }
319
320
    /**
321
     * @return UserGroup[]
322
     * @throws OrmException
323
     */
324
    protected function getAllUserGroups(): array
325
    {
326
        return $this->userGroupRepo->getAll();
327
    }
328
329
    /**
330
     * @param UserGroup[] $allUserGroups
331
     * @param UserGroup[] $userGroupIds
332
     *
333
     * @return array
334
     */
335
    protected function createUserGroupOptions(array $allUserGroups, array $userGroupIds): array
336
    {
337
        $options = [];
338
        foreach ($allUserGroups as $userGroup) {
339
            $isSelected = in_array($userGroup->getId(), $userGroupIds, true);
340
            $options[]  = new Option($userGroup->getId(), $userGroup->getName(), $isSelected);
341
        }
342
343
        return $options;
344
    }
345
346
    /**
347
     * @param Option[] $options
348
     *
349
     * @return Select
350
     */
351
    protected function createUserGroupSelect(array $options): Select
352
    {
353
        $size       = $this->getMultiSelectSize(
354
            count($options),
355
            static::MULTISELECT_MIN_SIZE,
356
            static::MULTISELECT_MAX_SIZE
357
        );
358
        $attributes = Attributes::fromArray([Html5::ATTR_SIZE => [(string)$size]]);
359
360
        $select = new MultiSelect('user_group_ids', 'user_group_ids[]', [], $attributes);
361
362
        foreach ($options as $option) {
363
            $select[] = $option;
364
        }
365
366
        return $select;
367
    }
368
369
    /**
370
     * @return Label
371
     */
372
    protected function createUserGroupLabel(): Label
373
    {
374
        return new Label('user_group_ids', 'admin:userGroups');
375
    }
376
377
    /**
378
     * @param Entity $entity
379
     *
380
     * @return $this
381
     * @throws OrmException
382
     */
383
    protected function addUserLanguages(Entity $entity): User
384
    {
385
        $allUserGroups = $this->getAllUserLanguages();
386
        $userGroupId   = $entity->getUserLanguage()->getId();
387
388
        $options = $this->createUserLanguageOptions($allUserGroups, $userGroupId);
389
390
        $attributes = Attributes::fromArray([Html5::ATTR_CLASS => FormGroup::CLASS_REQUIRED]);
391
        $this->form[] = new FormGroup(
392
            $this->createUserLanguageSelect($options),
393
            $this->createUserLanguageLabel(),
394
            null,
395
            [],
396
            $attributes
397
        );
398
399
        return $this;
400
    }
401
402
    /**
403
     * @return UserLanguage[]
404
     * @throws OrmException
405
     */
406
    protected function getAllUserLanguages(): array
407
    {
408
        return $this->userLanguageRepo->getAll();
409
    }
410
411
    /**
412
     * @param UserLanguage[] $allUserLanguages
413
     * @param string         $userLanguageId
414
     *
415
     * @return array
416
     */
417
    protected function createUserLanguageOptions(array $allUserLanguages, string $userLanguageId): array
418
    {
419
        $options = [];
420
        foreach ($allUserLanguages as $userLanguage) {
421
            $isSelected = $userLanguageId === $userLanguage->getId();
422
            $options[]  = new Option($userLanguage->getId(), $userLanguage->getName(), $isSelected);
423
        }
424
425
        return $options;
426
    }
427
428
    /**
429
     * @param Option[] $options
430
     *
431
     * @return Select
432
     */
433
    protected function createUserLanguageSelect(array $options): Select
434
    {
435
        $size       = $this->getMultiSelectSize(
436
            count($options),
437
            static::MULTISELECT_MIN_SIZE,
438
            static::MULTISELECT_MAX_SIZE
439
        );
440
        $attributes = Attributes::fromArray([Html5::ATTR_SIZE => [(string)$size]]);
441
442
        $select = new MultiSelect('user_language_id', 'user_language_id', [], $attributes);
443
444
        foreach ($options as $option) {
445
            $select[] = $option;
446
        }
447
448
        return $select;
449
    }
450
451
    /**
452
     * @return Label
453
     */
454
    protected function createUserLanguageLabel(): Label
455
    {
456
        return new Label('user_language_id', 'admin:userLanguages');
457
    }
458
}
459