Passed
Push — master ( 1d30f9...202808 )
by Peter
04:48
created

ApiClient::getUserResources()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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\Factory\Base;
20
use AbterPhp\Framework\Form\Factory\IFormFactory;
21
use AbterPhp\Framework\Form\IForm;
22
use AbterPhp\Framework\Form\Label\Label;
23
use AbterPhp\Framework\Html\Component;
24
use AbterPhp\Framework\Html\Component\ButtonFactory;
25
use AbterPhp\Framework\Html\Component\ButtonWithIcon;
26
use AbterPhp\Framework\I18n\ITranslator;
27
use Opulence\Orm\IEntity;
28
use Opulence\Sessions\ISession;
29
30
class ApiClient extends Base
31
{
32
    /** @var AdminResourceRepo */
33
    protected $adminResourceRepo;
34
35
    /** @var ButtonFactory */
36
    protected $buttonFactory;
37
38
    /**
39
     * ApiClient constructor.
40
     *
41
     * @param ISession          $session
42
     * @param ITranslator       $translator
43
     * @param AdminResourceRepo $adminResourceRepo
44
     * @param ButtonFactory     $buttonFactory
45
     */
46
    public function __construct(
47
        ISession $session,
48
        ITranslator $translator,
49
        AdminResourceRepo $adminResourceRepo,
50
        ButtonFactory $buttonFactory
51
    ) {
52
        parent::__construct($session, $translator);
53
54
        $this->adminResourceRepo = $adminResourceRepo;
55
        $this->buttonFactory     = $buttonFactory;
56
    }
57
58
    /**
59
     * @param string       $action
60
     * @param string       $method
61
     * @param string       $showUrl
62
     * @param IEntity|null $entity
63
     *
64
     * @return IForm
65
     */
66
    public function create(string $action, string $method, string $showUrl, ?IEntity $entity = null): IForm
67
    {
68
        if (!($entity instanceof Entity)) {
69
            throw new \InvalidArgumentException(IFormFactory::ERR_MSG_ENTITY_MISSING);
70
        }
71
72
        $this->createForm($action, $method)
73
            ->addJsOnly()
74
            ->addDefaultElements()
75
            ->addId($entity)
76
            ->addDescription($entity)
77
            ->addAdminResources($entity)
78
            ->addSecret($entity)
0 ignored issues
show
Unused Code introduced by
The call to AbterPhp\Admin\Form\Factory\ApiClient::addSecret() has too many arguments starting with $entity. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

78
            ->/** @scrutinizer ignore-call */ addSecret($entity)

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
79
            ->addDefaultButtons($showUrl);
80
81
        $form = $this->form;
82
83
        $this->form = null;
84
85
        return $form;
86
    }
87
88
    /**
89
     * @return $this
90
     */
91
    protected function addJsOnly(): ApiClient
92
    {
93
        $content    = sprintf(
94
            '<i class="material-icons">warning</i>&nbsp;%s',
95
            $this->translator->translate('admin:jsOnly')
96
        );
97
        $attributes = [Html5::ATTR_CLASS => 'only-js-form-warning'];
98
99
        $this->form[] = new Component($content, [], $attributes, Html5::TAG_P);
100
101
        return $this;
102
    }
103
104
    /**
105
     * @param Entity $entity
106
     *
107
     * @return $this
108
     */
109
    protected function addId(Entity $entity): ApiClient
110
    {
111
        $this->form[] = new Input('id', 'id', $entity->getId(), [], [Html5::ATTR_TYPE => Input::TYPE_HIDDEN]);
112
113
        return $this;
114
    }
115
116
    /**
117
     * @param Entity $entity
118
     *
119
     * @return $this
120
     */
121
    protected function addDescription(Entity $entity): ApiClient
122
    {
123
        $input = new Textarea(
124
            'description',
125
            'description',
126
            $entity->getDescription()
127
        );
128
        $label = new Label('description', 'admin:apiClientDescription');
129
130
        $this->form[] = new FormGroup($input, $label);
131
132
        return $this;
133
    }
134
135
    /**
136
     * @param Entity $entity
137
     *
138
     * @return $this
139
     */
140
    protected function addAdminResources(Entity $entity): ApiClient
141
    {
142
        $allUserResources = $this->getUserResources();
143
144
        $existingData = [];
145
        foreach ($entity->getAdminResources() as $adminResource) {
146
            $existingData[$adminResource->getId()] = $adminResource->getIdentifier();
147
        }
148
149
        $options = $this->createAdminResourceOptions($allUserResources, $existingData);
150
151
        $this->form[] = new FormGroup(
152
            $this->createAdminResourceSelect($options),
153
            $this->createAdminResourceLabel()
154
        );
155
156
        return $this;
157
    }
158
159
    /**
160
     * @return UserGroup[]
161
     */
162
    protected function getUserResources(): array
163
    {
164
        $userId = $this->session->get(Session::USER_ID);
165
166
        return $this->adminResourceRepo->getByUserId($userId);
0 ignored issues
show
Bug introduced by
It seems like $userId can also be of type null; however, parameter $userId of AbterPhp\Admin\Orm\Admin...urceRepo::getByUserId() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

166
        return $this->adminResourceRepo->getByUserId(/** @scrutinizer ignore-type */ $userId);
Loading history...
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
        $attributes = [
196
            Html5::ATTR_SIZE => $this->getMultiSelectSize(
197
                count($options),
198
                static::MULTISELECT_MIN_SIZE,
199
                static::MULTISELECT_MAX_SIZE
200
            ),
201
        ];
202
203
        $select = new MultiSelect('admin_resource_ids', 'admin_resource_ids[]', [], $attributes);
204
205
        foreach ($options as $option) {
206
            $select[] = $option;
207
        }
208
209
        return $select;
210
    }
211
212
    /**
213
     * @return $this
214
     */
215
    protected function addSecret(): ApiClient
216
    {
217
        $input = new Input('secret', 'secret', '', [], [Html5::ATTR_READONLY => null]);
218
        $label = new Label('secret', 'admin:apiClientSecret');
219
220
        $container   = new Component(null, [], [], Html5::TAG_DIV);
221
        $container[] = new Component(
222
            $this->buttonFactory->createWithIcon(
223
                'admin:generateSecret',
224
                'autorenew',
225
                [],
226
                [],
227
                [ButtonWithIcon::INTENT_DANGER, ButtonWithIcon::INTENT_SMALL],
228
                [
229
                    Html5::ATTR_ID    => 'generateSecret',
230
                    'data-positionX'  => 'center',
231
                    'data-positionY'  => 'top',
232
                    'data-effect'     => 'fadeInUp',
233
                    'data-duration'   => '2000',
234
                    Html5::ATTR_CLASS => 'pmd-alert-toggle',
235
236
                ],
237
                HTML5::TAG_A
238
            ),
239
            [],
240
            [Html5::ATTR_CLASS => 'button-container'],
241
            Html5::TAG_DIV
242
        );
243
        $container[] = new Help(
244
            'admin:apiClientSecretHelp',
245
            [Help::INTENT_HIDDEN],
246
            [Html5::ATTR_ID => 'secretHelp']
247
        );
248
249
        $this->form[] = new FormGroup($input, $label, $container);
250
251
        return $this;
252
    }
253
254
    /**
255
     * @return Label
256
     */
257
    protected function createAdminResourceLabel(): Label
258
    {
259
        return new Label('admin_resource_ids', 'admin:adminResources');
260
    }
261
}
262