Passed
Push — bugfix/ps-9925-punchout-connec... ( 3e09d6 )
by
unknown
09:56 queued 33s
created

createGlobalTotalsModeValidationConstraint()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 15
rs 9.9
1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace SprykerEco\Zed\PunchoutCatalogs\Communication\Form;
9
10
use Generated\Shared\Transfer\PunchoutCatalogConnectionTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfe...talogConnectionTransfer 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...
11
use Spryker\Zed\Gui\Communication\Form\Type\SelectType;
12
use Spryker\Zed\Kernel\Communication\Form\AbstractType;
13
use SprykerEco\Zed\PunchoutCatalogs\Communication\Form\ConnectionSetupSubForms\PunchoutCatalogConnectionCartForm;
14
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
15
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
16
use Symfony\Component\Form\Extension\Core\Type\TextType;
17
use Symfony\Component\Form\FormBuilderInterface;
18
use Symfony\Component\Form\FormEvent;
19
use Symfony\Component\Form\FormEvents;
20
use Symfony\Component\Form\FormInterface;
21
use Symfony\Component\OptionsResolver\OptionsResolver;
22
use Symfony\Component\Validator\Constraint;
23
use Symfony\Component\Validator\Constraints\Callback;
24
use Symfony\Component\Validator\Constraints\Length;
25
use Symfony\Component\Validator\Constraints\NotBlank;
26
use Symfony\Component\Validator\Constraints\Valid;
27
use Symfony\Component\Validator\Context\ExecutionContextInterface;
28
29
/**
30
 * @method \SprykerEco\Zed\PunchoutCatalogs\PunchoutCatalogsConfig getConfig()
31
 * @method \SprykerEco\Zed\PunchoutCatalogs\Persistence\PunchoutCatalogsRepositoryInterface getRepository()
32
 * @method \SprykerEco\Zed\PunchoutCatalogs\Business\PunchoutCatalogsFacadeInterface getFacade()
33
 * @method \SprykerEco\Zed\PunchoutCatalogs\Communication\PunchoutCatalogsCommunicationFactory getFactory()
34
 */
35
class PunchoutCatalogConnectionForm extends AbstractType
36
{
37
    public const OPTION_BUSINESS_UNIT_CHOICES = 'OPTION_BUSINESS_UNIT_CHOICES';
38
    public const OPTION_CONNECTION_FORMAT_SUB_FORM_TYPES = 'OPTION_CONNECTION_FORMAT_FORMS';
39
    public const OPTION_CONNECTION_TYPE_SUB_FORM_TYPES = 'OPTION_CONNECTION_TYPE_SUB_FORM_TYPES';
40
41
    protected const VALIDATION_GROUP_DISABLED = 'disabled';
42
43
    protected const TOGGLE_GROUP_CONNECTION_TYPE = 'type';
44
    protected const TOGGLE_GROUP_CONNECTION_FORMAT = 'format';
45
46
    /**
47
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
48
     * @param array $options
49
     *
50
     * @return void
51
     */
52
    public function buildForm(FormBuilderInterface $builder, array $options): void
53
    {
54
        $this->addNameField($builder)
55
            ->addBusinessUnitField($builder, $options)
56
            ->addAddMappingField($builder)
57
            ->addConnectionFormatField($builder, $options)
58
            ->addConnectionTypeField($builder, $options)
59
            ->addConnectionFormatSubForms($builder, $options)
60
            ->addConnectionTypeSubForms($builder, $options);
61
    }
62
63
    /**
64
     * @param \Symfony\Component\OptionsResolver\OptionsResolver $resolver
65
     *
66
     * @return void
67
     */
68
    public function configureOptions(OptionsResolver $resolver): void
69
    {
70
        $resolver->setRequired([
71
            static::OPTION_BUSINESS_UNIT_CHOICES,
72
            static::OPTION_CONNECTION_FORMAT_SUB_FORM_TYPES,
73
            static::OPTION_CONNECTION_TYPE_SUB_FORM_TYPES,
74
        ]);
75
76
        $resolver->setDefaults(
77
            [
78
                'constraints' => [$this->createGlobalTotalsModeValidationConstraint()]
79
            ]
80
        );
81
    }
82
83
    /**
84
     * @return string
85
     */
86
    public function getBlockPrefix(): string
87
    {
88
        return 'punchoutCatalogConnection';
89
    }
90
91
    /**
92
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
93
     *
94
     * @return $this
95
     */
96
    protected function addNameField(FormBuilderInterface $builder)
97
    {
98
        $builder->add(PunchoutCatalogConnectionTransfer::NAME, TextType::class, [
99
            'label' => 'Name',
100
            'constraints' => [
101
                new NotBlank(),
102
                new Length(['max' => 255]),
103
            ],
104
        ]);
105
106
        return $this;
107
    }
108
109
    /**
110
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
111
     * @param array $options
112
     *
113
     * @return $this
114
     */
115
    protected function addConnectionFormatField(FormBuilderInterface $builder, array $options)
116
    {
117
        $formats = array_keys($options[static::OPTION_CONNECTION_FORMAT_SUB_FORM_TYPES]);
118
119
        $builder->add(PunchoutCatalogConnectionTransfer::FORMAT, ChoiceType::class, [
120
            'label' => 'Format',
121
            'choices' => array_combine($formats, $formats),
122
            'constraints' => [
123
                new NotBlank(),
124
            ],
125
            'attr' => [
126
                'class' => 'toggle-trigger',
127
                'data-toggle-group' => static::TOGGLE_GROUP_CONNECTION_FORMAT,
128
            ],
129
        ]);
130
131
        return $this;
132
    }
133
134
    /**
135
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
136
     * @param array $options
137
     *
138
     * @return $this
139
     */
140
    protected function addConnectionTypeField(FormBuilderInterface $builder, array $options)
141
    {
142
        $types = array_keys($options[static::OPTION_CONNECTION_TYPE_SUB_FORM_TYPES]);
143
144
        $builder->add(PunchoutCatalogConnectionTransfer::TYPE, ChoiceType::class, [
145
            'label' => 'Type',
146
            'choices' => array_combine($types, $types),
147
            'constraints' => [
148
                new NotBlank(),
149
            ],
150
            'attr' => [
151
                'class' => 'toggle-trigger',
152
                'data-toggle-group' => static::TOGGLE_GROUP_CONNECTION_TYPE,
153
            ],
154
        ]);
155
156
        return $this;
157
    }
158
159
    /**
160
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
161
     * @param array $options
162
     *
163
     * @return $this
164
     */
165
    protected function addConnectionFormatSubForms(FormBuilderInterface $builder, array $options)
166
    {
167
        foreach ($options[static::OPTION_CONNECTION_FORMAT_SUB_FORM_TYPES] as $connectionFormat => $connectionFormatSubFormType) {
168
            $builder->add($connectionFormat, $connectionFormatSubFormType, [
169
                'mapped' => false,
170
                'validation_groups' => static::VALIDATION_GROUP_DISABLED,
171
                'label' => false,
172
                'attr' => [
173
                    'class' => 'toggle-inner-item',
174
                    'data-toggle-type' => $connectionFormat,
175
                    'data-toggle-group' => static::TOGGLE_GROUP_CONNECTION_FORMAT,
176
                ],
177
            ]);
178
        }
179
180
        $this->addConnectionFormatDynamicSubFormListener($builder);
181
182
        return $this;
183
    }
184
185
    /**
186
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
187
     * @param array $options
188
     *
189
     * @return $this
190
     */
191
    protected function addConnectionTypeSubForms(FormBuilderInterface $builder, array $options)
192
    {
193
        foreach ($options[static::OPTION_CONNECTION_TYPE_SUB_FORM_TYPES] as $connectionType => $connectionTypeSubFormType) {
194
            $builder->add($connectionType, $connectionTypeSubFormType, [
195
                'mapped' => false,
196
                'validation_groups' => static::VALIDATION_GROUP_DISABLED,
197
                'label' => false,
198
                'constraints' => [
199
                    new Valid(),
200
                ],
201
                'attr' => [
202
                    'class' => 'toggle-inner-item',
203
                    'data-toggle-type' => $connectionType,
204
                    'data-toggle-group' => static::TOGGLE_GROUP_CONNECTION_TYPE,
205
                ],
206
            ]);
207
        }
208
209
        $this->addConnectionTypeDynamicSubFormListener($builder);
210
211
        return $this;
212
    }
213
214
    /**
215
     * @return \Symfony\Component\Validator\Constraints\Callback
216
     */
217
    protected function createGlobalTotalsModeValidationConstraint(): Callback
218
    {
219
        return new Callback([
220
            'callback' => function ($dataToValidate, ExecutionContextInterface $context) {
221
                $connectionFormat = $context->getRoot()
222
                    ->get(PunchoutCatalogConnectionTransfer::FORMAT)
223
                    ->getData();
224
225
                $totalsMode = $dataToValidate->getCart()->getTotalsMode();
226
                $allowedConnectionFormats =
227
                    PunchoutCatalogConnectionCartForm::ALLOWED_CONNECTION_FORMATS_FOR_TOTALS_MODES[$totalsMode] ?? [];
228
229
                if (!in_array($connectionFormat, $allowedConnectionFormats)) {
230
                    $context->addViolation(
231
                        'Saving of connection was not successful. Please re-check the input and try again.'
232
                    );
233
                }
234
            },
235
        ]);
236
    }
237
238
    /**
239
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
240
     *
241
     * @return void
242
     */
243
    protected function addConnectionFormatDynamicSubFormListener(FormBuilderInterface $builder): void
244
    {
245
        $connectionFormatSubFormTypes = static::OPTION_CONNECTION_FORMAT_SUB_FORM_TYPES;
246
        $formModificationCallback = function (FormEvent $event) use ($connectionFormatSubFormTypes) {
247
            $format = $event->getData()[PunchoutCatalogConnectionTransfer::FORMAT] ?? null;
248
249
            if (!$format) {
250
                return;
251
            }
252
253
            $this->addActiveDependentFieldSubFormToConnectionForm(
254
                $event,
255
                $connectionFormatSubFormTypes,
256
                $format
257
            );
258
        };
259
260
        $builder->addEventListener(FormEvents::PRE_SET_DATA, $formModificationCallback);
261
        $builder->addEventListener(FormEvents::PRE_SUBMIT, $formModificationCallback);
262
    }
263
264
    /**
265
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
266
     *
267
     * @return void
268
     */
269
    protected function addConnectionTypeDynamicSubFormListener(FormBuilderInterface $builder): void
270
    {
271
        $connectionTypeSubFormTypes = static::OPTION_CONNECTION_TYPE_SUB_FORM_TYPES;
272
        $formModificationCallback = function (FormEvent $event) use ($connectionTypeSubFormTypes) {
273
            $type = $event->getData()[PunchoutCatalogConnectionTransfer::TYPE] ?? null;
274
275
            if (!$type) {
276
                return;
277
            }
278
279
            $this->addActiveDependentFieldSubFormToConnectionForm(
280
                $event,
281
                $connectionTypeSubFormTypes,
282
                $type
283
            );
284
        };
285
286
        $builder->addEventListener(FormEvents::PRE_SET_DATA, $formModificationCallback)
287
            ->addEventListener(FormEvents::PRE_SUBMIT, $formModificationCallback);
288
    }
289
290
    /**
291
     * @param \Symfony\Component\Form\FormEvent $event
292
     * @param string $subFormsOptionName
293
     * @param string $selectedSubFormName
294
     *
295
     * @return void
296
     */
297
    protected function addActiveDependentFieldSubFormToConnectionForm(FormEvent $event, string $subFormsOptionName, string $selectedSubFormName): void
298
    {
299
        $form = $event->getForm();
300
        $formOptions = $form->getConfig()->getOptions();
301
        $subForms = $formOptions[$subFormsOptionName];
302
303
        foreach ($subForms as $subFormName => $subFormType) {
304
            $existingFieldOptions = $form->get($subFormName)
305
                ->getConfig()
306
                ->getOptions();
307
308
            $isActiveSubForm = $subFormName === $selectedSubFormName;
309
310
            $form->add($subFormName, $subFormType, array_merge(
311
                $existingFieldOptions,
312
                [
313
                    'inherit_data' => $isActiveSubForm,
314
                    'validation_groups' => $isActiveSubForm ? null : static::VALIDATION_GROUP_DISABLED,
315
                ]
316
            ));
317
        }
318
    }
319
320
    /**
321
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
322
     *
323
     * @return $this
324
     */
325
    protected function addAddMappingField(FormBuilderInterface $builder)
326
    {
327
        $builder->add(PunchoutCatalogConnectionTransfer::MAPPING, TextareaType::class, [
328
            'label' => 'Request Mapping',
329
            'required' => false,
330
        ]);
331
332
        return $this;
333
    }
334
335
    /**
336
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
337
     * @param array $options
338
     *
339
     * @return $this
340
     */
341
    protected function addBusinessUnitField(FormBuilderInterface $builder, array $options)
342
    {
343
        $builder->add(
344
            PunchoutCatalogConnectionTransfer::FK_COMPANY_BUSINESS_UNIT,
345
            SelectType::class,
346
            [
347
                'choices' => $options[static::OPTION_BUSINESS_UNIT_CHOICES],
348
                'placeholder' => 'Choose business unit',
349
                'label' => 'Business Unit',
350
                'constraints' => [
351
                    new NotBlank(),
352
                ],
353
            ]
354
        );
355
356
        return $this;
357
    }
358
}
359