ApiClient   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 237
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 14
eloc 90
c 0
b 0
f 0
dl 0
loc 237
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A createAdminResourceOptions() 0 11 2
A getUserResources() 0 5 1
A addDescription() 0 12 1
A __construct() 0 10 1
A createAdminResourceSelect() 0 16 2
A addId() 0 6 1
A addAdminResources() 0 17 2
A addJsOnly() 0 11 1
A create() 0 18 1
A addSecret() 0 45 1
A createAdminResourceLabel() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Form\Factory;
6
7
use AbterPhp\Admin\Domain\Entities\AdminResource;
8
use AbterPhp\Admin\Domain\Entities\ApiClient as Entity;
9
use AbterPhp\Admin\Orm\AdminResourceRepo;
10
use AbterPhp\Framework\Constant\Html5;
11
use AbterPhp\Framework\Constant\Session;
12
use AbterPhp\Framework\Form\Component\Option;
13
use AbterPhp\Framework\Form\Container\FormGroup;
14
use AbterPhp\Framework\Form\Element\Input;
15
use AbterPhp\Framework\Form\Element\MultiSelect;
16
use AbterPhp\Framework\Form\Element\Select;
17
use AbterPhp\Framework\Form\Element\Textarea;
18
use AbterPhp\Framework\Form\Extra\Help;
19
use AbterPhp\Framework\Form\IForm;
20
use AbterPhp\Framework\Form\Label\Label;
21
use AbterPhp\Framework\Html\Component\ButtonWithIcon;
22
use AbterPhp\Framework\Html\Factory\Button as ButtonFactory;
23
use AbterPhp\Framework\Html\Helper\Attributes;
24
use AbterPhp\Framework\Html\Tag;
25
use AbterPhp\Framework\I18n\ITranslator;
26
use Opulence\Orm\IEntity;
27
use Opulence\Orm\OrmException;
28
use Opulence\Sessions\ISession;
29
30
class ApiClient extends Base
31
{
32
    protected AdminResourceRepo $adminResourceRepo;
33
34
    protected ButtonFactory $buttonFactory;
35
36
    /**
37
     * ApiClient constructor.
38
     *
39
     * @param ISession          $session
40
     * @param ITranslator       $translator
41
     * @param AdminResourceRepo $adminResourceRepo
42
     * @param ButtonFactory     $buttonFactory
43
     */
44
    public function __construct(
45
        ISession $session,
46
        ITranslator $translator,
47
        AdminResourceRepo $adminResourceRepo,
48
        ButtonFactory $buttonFactory
49
    ) {
50
        parent::__construct($session, $translator);
51
52
        $this->adminResourceRepo = $adminResourceRepo;
53
        $this->buttonFactory     = $buttonFactory;
54
    }
55
56
    /**
57
     * @param string       $action
58
     * @param string       $method
59
     * @param string       $showUrl
60
     * @param IEntity|null $entity
61
     *
62
     * @return IForm
63
     * @throws OrmException
64
     */
65
    public function create(string $action, string $method, string $showUrl, ?IEntity $entity = null): IForm
66
    {
67
        assert($entity instanceof Entity, new \InvalidArgumentException());
68
69
        $this->createForm($action, $method)
70
            ->addJsOnly()
71
            ->addDefaultElements()
72
            ->addId($entity)
73
            ->addDescription($entity)
74
            ->addAdminResources($entity)
75
            ->addSecret()
76
            ->addDefaultButtons($showUrl);
77
78
        $form = $this->form;
79
80
        $this->form = null;
81
82
        return $form;
83
    }
84
85
    /**
86
     * @return $this
87
     */
88
    protected function addJsOnly(): ApiClient
89
    {
90
        $content    = sprintf(
91
            '<i class="material-icons">warning</i>&nbsp;%s',
92
            $this->translator->translate('admin:jsOnly')
93
        );
94
        $attributes = Attributes::fromArray([Html5::ATTR_CLASS => 'only-js-form-warning']);
95
96
        $this->form[] = new Tag($content, [], $attributes, Html5::TAG_P);
97
98
        return $this;
99
    }
100
101
    /**
102
     * @param Entity $entity
103
     *
104
     * @return $this
105
     */
106
    protected function addId(Entity $entity): ApiClient
107
    {
108
        $formAttributes = Attributes::fromArray([Html5::ATTR_TYPE => Input::TYPE_HIDDEN]);
109
        $this->form[]   = new Input('id', 'id', $entity->getId(), [], $formAttributes);
110
111
        return $this;
112
    }
113
114
    /**
115
     * @param Entity $entity
116
     *
117
     * @return $this
118
     */
119
    protected function addDescription(Entity $entity): ApiClient
120
    {
121
        $input = new Textarea(
122
            'description',
123
            'description',
124
            $entity->getDescription()
125
        );
126
        $label = new Label('description', 'admin:apiClientDescription');
127
128
        $this->form[] = new FormGroup($input, $label);
129
130
        return $this;
131
    }
132
133
    /**
134
     * @param Entity $entity
135
     *
136
     * @return $this
137
     * @throws OrmException
138
     */
139
    protected function addAdminResources(Entity $entity): ApiClient
140
    {
141
        $allUserResources = $this->getUserResources();
142
143
        $existingData = [];
144
        foreach ($entity->getAdminResources() as $adminResource) {
145
            $existingData[$adminResource->getId()] = $adminResource->getIdentifier();
146
        }
147
148
        $options = $this->createAdminResourceOptions($allUserResources, $existingData);
149
150
        $this->form[] = new FormGroup(
151
            $this->createAdminResourceSelect($options),
152
            $this->createAdminResourceLabel()
153
        );
154
155
        return $this;
156
    }
157
158
    /**
159
     * @return AdminResource[]
160
     * @throws OrmException
161
     */
162
    protected function getUserResources(): array
163
    {
164
        $userId = (string)$this->session->get(Session::USER_ID);
165
166
        return $this->adminResourceRepo->getByUserId($userId);
167
    }
168
169
    /**
170
     * @param AdminResource[] $allUserResources
171
     * @param string[]        $existingData
172
     *
173
     * @return array
174
     */
175
    protected function createAdminResourceOptions(array $allUserResources, array $existingData): array
176
    {
177
        $existingIds = array_keys($existingData);
178
179
        $options = [];
180
        foreach ($allUserResources as $userResources) {
181
            $isSelected = in_array($userResources->getId(), $existingIds, true);
182
            $options[]  = new Option($userResources->getId(), $userResources->getIdentifier(), $isSelected);
183
        }
184
185
        return $options;
186
    }
187
188
    /**
189
     * @param Option[] $options
190
     *
191
     * @return Select
192
     */
193
    protected function createAdminResourceSelect(array $options): Select
194
    {
195
        $size       = $this->getMultiSelectSize(
196
            count($options),
197
            static::MULTISELECT_MIN_SIZE,
198
            static::MULTISELECT_MAX_SIZE
199
        );
200
        $attributes = Attributes::fromArray([Html5::ATTR_SIZE => [(string)$size]]);
201
202
        $select = new MultiSelect('admin_resource_ids', 'admin_resource_ids[]', [], $attributes);
203
204
        foreach ($options as $option) {
205
            $select[] = $option;
206
        }
207
208
        return $select;
209
    }
210
211
    /**
212
     * @return $this
213
     */
214
    protected function addSecret(): ApiClient
215
    {
216
        $attributes = Attributes::fromArray([Html5::ATTR_READONLY => null]);
217
        $input      = new Input('secret', 'secret', '', [], $attributes);
218
        $label      = new Label('secret', 'admin:apiClientSecret');
219
220
        $btnAttributes = Attributes::fromArray(
221
            [
222
                Html5::ATTR_ID    => ['generateSecret'],
223
                'data-positionX'  => ['center'],
224
                'data-positionY'  => ['top'],
225
                'data-effect'     => ['fadeInUp'],
226
                'data-duration'   => ['2000'],
227
                Html5::ATTR_CLASS => ['pmd-alert-toggle'],
228
            ]
229
        );
230
        $btn           = $this->buttonFactory->createWithIcon(
231
            'admin:generateSecret',
232
            'autorenew',
233
            [],
234
            [],
235
            [ButtonWithIcon::INTENT_DANGER, ButtonWithIcon::INTENT_SMALL],
236
            $btnAttributes,
237
            HTML5::TAG_A
238
        );
239
240
        $btnContainerAttributes = Attributes::fromArray([Html5::ATTR_CLASS => 'button-container']);
241
        $helpAttributes         = Attributes::fromArray([Html5::ATTR_ID => ['secretHelp']]);
242
243
        $container   = new Tag(null, [], [], Html5::TAG_DIV);
244
        $container[] = new Tag(
245
            $btn,
246
            [],
247
            $btnContainerAttributes,
248
            Html5::TAG_DIV
249
        );
250
        $container[] = new Help(
251
            'admin:apiClientSecretHelp',
252
            [Tag::INTENT_HIDDEN],
253
            $helpAttributes
254
        );
255
256
        $this->form[] = new FormGroup($input, $label, $container);
257
258
        return $this;
259
    }
260
261
    /**
262
     * @return Label
263
     */
264
    protected function createAdminResourceLabel(): Label
265
    {
266
        return new Label('admin_resource_ids', 'admin:adminResources');
267
    }
268
}
269