Passed
Push — master ( 5047e3...b9f250 )
by Peter
02:23
created

PageCategory::createUserGroupSelect()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 9
nc 2
nop 1
dl 0
loc 17
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Website\Form\Factory;
6
7
use AbterPhp\Admin\Orm\UserGroupRepo;
8
use AbterPhp\Framework\Constant\Html5;
9
use AbterPhp\Framework\Form\Component\Option;
10
use AbterPhp\Framework\Form\Container\FormGroup;
11
use AbterPhp\Framework\Form\Container\Hideable;
12
use AbterPhp\Framework\Form\Element\Input;
13
use AbterPhp\Framework\Form\Element\MultiSelect;
14
use AbterPhp\Framework\Form\Element\Select;
15
use AbterPhp\Framework\Form\Element\Textarea;
16
use AbterPhp\Framework\Form\Factory\Base;
17
use AbterPhp\Framework\Form\Factory\IFormFactory;
18
use AbterPhp\Framework\Form\IForm;
19
use AbterPhp\Framework\Form\Label\Label;
20
use AbterPhp\Framework\I18n\ITranslator;
21
use AbterPhp\Website\Domain\Entities\PageCategory as Entity;
22
use Opulence\Orm\IEntity;
23
use Opulence\Sessions\ISession;
24
25
class PageCategory extends Base
26
{
27
    /** @var UserGroupRepo */
28
    protected $userGroupRepo;
29
30
    /**
31
     * PageCategory constructor.
32
     *
33
     * @param ISession      $session
34
     * @param ITranslator   $translator
35
     * @param UserGroupRepo $userGroupRepo
36
     */
37
    public function __construct(ISession $session, ITranslator $translator, UserGroupRepo $userGroupRepo)
38
    {
39
        parent::__construct($session, $translator);
40
41
        $this->userGroupRepo = $userGroupRepo;
42
    }
43
44
    /**
45
     * @param string       $action
46
     * @param string       $method
47
     * @param string       $showUrl
48
     * @param IEntity|null $entity
49
     *
50
     * @return IForm
51
     */
52
    public function create(string $action, string $method, string $showUrl, ?IEntity $entity = null): IForm
53
    {
54
        if (!($entity instanceof Entity)) {
55
            throw new \InvalidArgumentException(IFormFactory::ERR_MSG_ENTITY_MISSING);
56
        }
57
58
        $this->createForm($action, $method)
59
            ->addDefaultElements()
60
            ->addIdentifier($entity)
61
            ->addName($entity)
62
            ->addUserGroups($entity)
63
            ->addDefaultButtons($showUrl);
64
65
        $form = $this->form;
66
67
        $this->form = null;
68
69
        return $form;
70
    }
71
72
    /**
73
     * @param Entity $entity
74
     *
75
     * @return $this
76
     */
77
    protected function addIdentifier(Entity $entity): PageCategory
78
    {
79
        $input = new Input('identifier', 'identifier', $entity->getIdentifier());
80
        $label = new Label('identifier', 'website:pageCategoryIdentifier');
81
82
        $this->form[] = new FormGroup($input, $label, null);
83
84
        return $this;
85
    }
86
87
    /**
88
     * @param Entity $entity
89
     *
90
     * @return $this
91
     */
92
    protected function addName(Entity $entity): PageCategory
93
    {
94
        $input = new Input('name', 'name', $entity->getIdentifier());
95
        $label = new Label('name', 'website:pageCategoryName');
96
97
        $this->form[] = new FormGroup($input, $label);
98
99
        return $this;
100
    }
101
102
    /**
103
     * @param Entity $entity
104
     *
105
     * @return $this
106
     */
107
    protected function addUserGroups(Entity $entity): PageCategory
108
    {
109
        $allUserGroups = $this->getAllUserGroups();
110
        $userGroupIds  = $this->getUserGroupIds($entity);
111
112
        $options = $this->createUserGroupOptions($allUserGroups, $userGroupIds);
113
114
        $this->form[] = new FormGroup(
115
            $this->createUserGroupSelect($options),
116
            $this->createUserGroupLabel()
117
        );
118
119
        return $this;
120
    }
121
122
    /**
123
     * @return UserGroup[]
124
     */
125
    protected function getAllUserGroups(): array
126
    {
127
        return $this->userGroupRepo->getAll();
128
    }
129
130
    /**
131
     * @param Entity $entity
132
     *
133
     * @return int[]
134
     */
135
    protected function getUserGroupIds(Entity $entity): array
136
    {
137
        $userGroupIds = [];
138
        foreach ($entity->getUserGroups() as $userGroup) {
139
            $userGroupIds[] = $userGroup->getId();
140
        }
141
142
        return $userGroupIds;
143
    }
144
145
    /**
146
     * @param UserGroup[] $allUserGroups
147
     * @param int[]       $userGroupIds
148
     *
149
     * @return array
150
     */
151
    protected function createUserGroupOptions(array $allUserGroups, array $userGroupIds): array
152
    {
153
        $options = [];
154
        foreach ($allUserGroups as $userGroup) {
155
            $isSelected = in_array($userGroup->getId(), $userGroupIds, true);
156
            $options[]  = new Option((string)$userGroup->getId(), $userGroup->getName(), $isSelected);
157
        }
158
159
        return $options;
160
    }
161
162
    /**
163
     * @param Option[] $options
164
     *
165
     * @return Select
166
     */
167
    protected function createUserGroupSelect(array $options): Select
168
    {
169
        $attributes = [
170
            Html5::ATTR_SIZE => $this->getMultiSelectSize(
171
                count($options),
172
                static::MULTISELECT_MIN_SIZE,
173
                static::MULTISELECT_MAX_SIZE
174
            ),
175
        ];
176
177
        $select = new MultiSelect('user_group_ids', 'user_group_ids[]', [], $attributes);
178
179
        foreach ($options as $option) {
180
            $select[] = $option;
181
        }
182
183
        return $select;
184
    }
185
186
    /**
187
     * @return Label
188
     */
189
    protected function createUserGroupLabel(): Label
190
    {
191
        return new Label('user_group_ids', 'website:pageCategoryUserGroups');
192
    }
193
194
    /**
195
     * @param int $optionCount
196
     * @param int $minSize
197
     * @param int $maxSize
198
     *
199
     * @return int
200
     */
201
    protected function getMultiSelectSize(int $optionCount, int $minSize, int $maxSize): int
202
    {
203
        return (int)max(min($optionCount, $maxSize), $minSize);
204
    }
205
}
206