SspAssetForm::addNameField()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 17
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 SprykerFeature\Zed\SelfServicePortal\Communication\Asset\Form;
9
10
use Generated\Shared\Transfer\CompanyBusinessUnitCriteriaFilterTransfer;
11
use Generated\Shared\Transfer\CompanyBusinessUnitTransfer;
12
use Generated\Shared\Transfer\CompanyCriteriaFilterTransfer;
13
use Generated\Shared\Transfer\SspAssetTransfer;
14
use Spryker\Zed\Gui\Communication\Form\Type\Select2ComboBoxType;
15
use Spryker\Zed\Kernel\Communication\Form\AbstractType;
16
use Symfony\Component\Form\CallbackTransformer;
17
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
18
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
19
use Symfony\Component\Form\Extension\Core\Type\TextType;
20
use Symfony\Component\Form\Extension\Core\Type\UrlType;
21
use Symfony\Component\Form\FormBuilderInterface;
22
use Symfony\Component\Form\FormError;
23
use Symfony\Component\Form\FormEvent;
24
use Symfony\Component\Form\FormEvents;
25
use Symfony\Component\OptionsResolver\OptionsResolver;
26
use Symfony\Component\Validator\Constraints\Length;
27
use Symfony\Component\Validator\Constraints\NotBlank;
28
use Symfony\Component\Validator\Constraints\Url;
29
30
/**
31
 * @method \SprykerFeature\Zed\SelfServicePortal\Communication\SelfServicePortalCommunicationFactory getFactory()
32
 * @method \SprykerFeature\Zed\SelfServicePortal\SelfServicePortalConfig getConfig()
33
 * @method \SprykerFeature\Zed\SelfServicePortal\Business\SelfServicePortalFacadeInterface getFacade()
34
 * @method \SprykerFeature\Zed\SelfServicePortal\Persistence\SelfServicePortalRepositoryInterface getRepository()
35
 */
36
class SspAssetForm extends AbstractType
37
{
38
    /**
39
     * @var string
40
     */
41
    protected const FIELD_NAME = 'name';
42
43
    /**
44
     * @var string
45
     */
46
    public const FIELD_BUSINESS_UNIT_OWNER = 'companyBusinessUnit';
47
48
    /**
49
     * @var string
50
     */
51
    protected const FIELD_SERIAL_NUMBER = 'serialNumber';
52
53
    /**
54
     * @var string
55
     */
56
    protected const FIELD_STATUS = 'status';
57
58
    /**
59
     * @var string
60
     */
61
    protected const FIELD_NOTE = 'note';
62
63
    /**
64
     * @var string
65
     */
66
    protected const FIELD_EXTERNAL_IMAGE_URL = 'externalImageUrl';
67
68
    /**
69
     * @var string
70
     */
71
    public const FIELD_ASSIGNED_COMPANIES = 'assignedCompanies';
72
73
    /**
74
     * @var string
75
     */
76
    protected const LABEL_COMPANY = 'Company';
77
78
    /**
79
     * @var string
80
     */
81
    protected const LABEL_BUSINESS_UNIT_OWNER = 'Business unit owner';
82
83
    /**
84
     * @var string
85
     */
86
    public const FIELD_IMAGE = 'asset_image';
87
88
    /**
89
     * @var string
90
     */
91
    public const OPTION_ORIGINAL_IMAGE_URL = 'imageUrl';
92
93
    /**
94
     * @var string
95
     */
96
    public const FIELD_ASSIGNED_BUSINESS_UNITS = 'assignedBusinessUnits';
97
98
    /**
99
     * @var string
100
     */
101
    protected const LABEL_BUSINESS_UNIT = 'Business Units';
102
103
    /**
104
     * @uses \Spryker\Zed\CompanyGui\Communication\Controller\SuggestController::indexAction()
105
     *
106
     * @var string
107
     */
108
    protected const ROUTE_COMPANY_SUGGEST = '/company-gui/suggest';
109
110
    /**
111
     * @uses \Spryker\Zed\CompanyBusinessUnitGui\Communication\Controller\SuggestController::indexAction()
112
     *
113
     * @var string
114
     */
115
    protected const ROUTE_BUSINESS_UNIT_SUGGEST = '/company-business-unit-gui/suggest?';
116
117
    /**
118
     * @var string
119
     */
120
    protected const PLACEHOLDER_SEARCH = 'Start typing to search...';
121
122
    /**
123
     * @var string
124
     */
125
    public const OPTION_COMPANY_ASSIGMENT_OPTIONS = 'companyAssignments';
126
127
    /**
128
     * @var string
129
     */
130
    public const OPTION_BUSINESS_UNIT_ASSIGMENT_OPTIONS = 'businessUnitAssignments';
131
132
    /**
133
     * @var string
134
     */
135
    public const OPTION_BUSINESS_UNIT_OWNER = 'businessUnitOwner';
136
137
    /**
138
     * @var string
139
     */
140
    public const OPTION_STATUS_OPTIONS = 'statuses';
141
142
    /**
143
     * @var string
144
     */
145
    public const FORM_NAME = 'assetForm';
146
147
    public function getBlockPrefix(): string
148
    {
149
        return static::FORM_NAME;
150
    }
151
152
    public function configureOptions(OptionsResolver $resolver): void
153
    {
154
        $resolver->setRequired([
155
            static::OPTION_BUSINESS_UNIT_ASSIGMENT_OPTIONS,
156
            static::OPTION_BUSINESS_UNIT_OWNER,
157
            static::OPTION_STATUS_OPTIONS,
158
            static::OPTION_COMPANY_ASSIGMENT_OPTIONS,
159
            ]);
160
161
        $resolver->setDefaults([
162
            'data_class' => SspAssetTransfer::class,
163
            static::OPTION_ORIGINAL_IMAGE_URL => null,
164
            static::OPTION_BUSINESS_UNIT_ASSIGMENT_OPTIONS => [],
165
            static::OPTION_COMPANY_ASSIGMENT_OPTIONS => [],
166
            static::OPTION_STATUS_OPTIONS => [],
167
            static::OPTION_BUSINESS_UNIT_OWNER => [],
168
        ]);
169
    }
170
171
    /**
172
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
173
     * @param array<string, mixed> $options
174
     *
175
     * @return void
176
     */
177
    public function buildForm(FormBuilderInterface $builder, array $options): void
178
    {
179
        $this
180
            ->addImageField($builder, $options)
181
            ->addNameField($builder)
182
            ->addSerialNumberField($builder)
183
            ->addStatusField($builder, $options)
184
            ->addExternalImageUrlField($builder)
185
            ->addNoteField($builder)
186
            ->addCompanyField($builder, $options)
187
            ->addAssignedBusinessUnitField($builder, $options)
188
            ->addBusinessUnitOwnerField($builder, $options);
189
190
        $this->addAssignedBusinessUnitDataListener($builder);
191
        $this->addBusinessUnitOwnerValidationListener($builder);
192
        $this->addCompanyAssignmentValidationListener($builder);
193
        $this->addBusinessUnitAssignmentValidationListener($builder);
194
    }
195
196
    /**
197
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
198
     * @param array<string, mixed> $options
199
     *
200
     * @return $this
201
     */
202
    protected function addBusinessUnitOwnerField(FormBuilderInterface $builder, array $options = [])
203
    {
204
        $builder->add(static::FIELD_BUSINESS_UNIT_OWNER, Select2ComboBoxType::class, [
205
            'label' => static::LABEL_BUSINESS_UNIT_OWNER,
206
            'choices' => $options[static::OPTION_BUSINESS_UNIT_OWNER],
207
            'multiple' => false,
208
            'mapped' => true,
209
            'required' => true,
210
            'attr' => [
211
                'data-autocomplete-url' => static::ROUTE_BUSINESS_UNIT_SUGGEST,
212
                'data-clear-initial' => false,
213
                'dependent-autocomplete-key' => 'idsCompany',
214
                'data-depends-on-field' => '.js-select-dependable--assigned-companies',
215
                'class' => 'js-select-dependable js-select-dependable--business-unit spryker-form-select2combobox',
216
                'data-minimum-input-length' => 4,
217
                'placeholder' => static::PLACEHOLDER_SEARCH,
218
                'data-clearable' => true,
219
            ],
220
        ]);
221
222
        $builder->get(static::FIELD_BUSINESS_UNIT_OWNER)->addModelTransformer(
223
            new CallbackTransformer(
224
                function ($companyBusinessUnitTransfer) {
225
                    if (!$companyBusinessUnitTransfer instanceof CompanyBusinessUnitTransfer) {
226
                        return null;
227
                    }
228
229
                    return $companyBusinessUnitTransfer->getIdCompanyBusinessUnit();
230
                },
231
                function ($idCompanyBusinessUnitSubmitted) {
232
                    if (!$idCompanyBusinessUnitSubmitted) {
233
                        return null;
234
                    }
235
236
                    return (new CompanyBusinessUnitTransfer())->setIdCompanyBusinessUnit($idCompanyBusinessUnitSubmitted);
237
                },
238
            ),
239
        );
240
241
        return $this;
242
    }
243
244
    /**
245
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
246
     *
247
     * @return $this
248
     */
249
    protected function addNameField(FormBuilderInterface $builder)
250
    {
251
        $builder->add(static::FIELD_NAME, TextType::class, [
252
            'label' => 'Name',
253
            'required' => true,
254
            'sanitize_xss' => true,
255
            'constraints' => [
256
                new NotBlank(),
257
                new Length([
258
                    'min' => 3,
259
                    'max' => 255,
260
                    'minMessage' => 'self_service_portal.asset.form.name.validation.min',
261
                ]),
262
            ],
263
        ]);
264
265
        return $this;
266
    }
267
268
    /**
269
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
270
     *
271
     * @return $this
272
     */
273
    protected function addSerialNumberField(FormBuilderInterface $builder)
274
    {
275
        $builder->add(static::FIELD_SERIAL_NUMBER, TextType::class, [
276
            'label' => 'Serial number',
277
            'required' => false,
278
            'sanitize_xss' => true,
279
            'constraints' => [
280
                new Length([
281
                    'max' => 255,
282
                    'minMessage' => 'self_service_portal.asset.form.serial_number.validation.min',
283
                ]),
284
            ],
285
        ]);
286
287
        return $this;
288
    }
289
290
    /**
291
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
292
     * @param array<string, mixed> $options
293
     *
294
     * @return $this
295
     */
296
    protected function addStatusField(FormBuilderInterface $builder, array $options = [])
297
    {
298
        $builder->add(static::FIELD_STATUS, ChoiceType::class, [
299
            'label' => 'Status',
300
            'required' => true,
301
            'choices' => $options[static::OPTION_STATUS_OPTIONS],
302
            'multiple' => false,
303
        ]);
304
305
        return $this;
306
    }
307
308
    /**
309
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
310
     *
311
     * @return $this
312
     */
313
    protected function addNoteField(FormBuilderInterface $builder)
314
    {
315
        $builder->add(static::FIELD_NOTE, TextareaType::class, [
316
            'label' => 'Note',
317
            'required' => false,
318
            'sanitize_xss' => true,
319
            'constraints' => [
320
                new Length([
321
                    'max' => 1000,
322
                    'minMessage' => 'self_service_portal.asset.form.note.validation.min',
323
                ]),
324
            ],
325
            'attr' => ['rows' => 5],
326
        ]);
327
328
        return $this;
329
    }
330
331
    /**
332
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
333
     * @param array<string, mixed> $options
334
     *
335
     * @return $this
336
     */
337
    protected function addImageField(FormBuilderInterface $builder, array $options = [])
338
    {
339
        $builder->add(static::FIELD_IMAGE, SspAssetImageForm::class, [
340
            'mapped' => false,
341
            SspAssetImageForm::OPTION_ORIGINAL_IMAGE_URL => $options[static::OPTION_ORIGINAL_IMAGE_URL] ?? null,
342
        ]);
343
344
        return $this;
345
    }
346
347
    /**
348
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
349
     * @param array<string, mixed> $options
350
     *
351
     * @return $this
352
     */
353
    protected function addCompanyField(FormBuilderInterface $builder, array $options = [])
354
    {
355
        $builder->add(static::FIELD_ASSIGNED_COMPANIES, Select2ComboBoxType::class, [
356
            'label' => static::LABEL_COMPANY,
357
            'choices' => $options[static::OPTION_COMPANY_ASSIGMENT_OPTIONS],
358
            'multiple' => true,
359
            'mapped' => false,
360
            'required' => false,
361
            'attr' => [
362
                'data-autocomplete-url' => static::ROUTE_COMPANY_SUGGEST,
363
                'data-minimum-input-length' => 4,
364
                'dependent-autocomplete-key' => 'idsCompany',
365
                'data-dependent-name' => 'idsCompany',
366
                'placeholder' => static::PLACEHOLDER_SEARCH,
367
                'data-qa' => 'ssp-asset-assigned-companies-field',
368
                'class' => 'js-select-dependable--assigned-companies',
369
            ],
370
        ]);
371
372
        return $this;
373
    }
374
375
    /**
376
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
377
     * @param array<string, mixed> $options
378
     *
379
     * @return $this
380
     */
381
    protected function addAssignedBusinessUnitField(FormBuilderInterface $builder, array $options = [])
382
    {
383
        $builder->add(static::FIELD_ASSIGNED_BUSINESS_UNITS, Select2ComboBoxType::class, [
384
            'label' => static::LABEL_BUSINESS_UNIT,
385
            'choices' => $options[static::OPTION_BUSINESS_UNIT_ASSIGMENT_OPTIONS],
386
            'multiple' => true,
387
            'required' => true,
388
            'mapped' => false,
389
            'attr' => [
390
                'data-autocomplete-url' => static::ROUTE_BUSINESS_UNIT_SUGGEST,
391
                'data-clear-initial' => false,
392
                'dependent-autocomplete-key' => 'idsCompany',
393
                'data-depends-on-field' => '.js-select-dependable--assigned-companies',
394
                'class' => 'js-select-dependable js-select-dependable--business-unit spryker-form-select2combobox',
395
                'data-qa' => 'ssp-asset-business-unit-field',
396
            ],
397
        ]);
398
399
        return $this;
400
    }
401
402
    protected function addAssignedBusinessUnitDataListener(FormBuilderInterface $builder): void
403
    {
404
        $builder->addEventListener(
405
            FormEvents::POST_SET_DATA,
406
            function (FormEvent $event): void {
407
                $sspAssetTransfer = $event->getData();
408
409
                if (!$sspAssetTransfer instanceof SspAssetTransfer) {
410
                    return;
411
                }
412
413
                if ($event->getForm()->has(static::FIELD_ASSIGNED_BUSINESS_UNITS)) {
414
                    $event->getForm()->get(static::FIELD_ASSIGNED_BUSINESS_UNITS)->setData($this->extractBusinessUnitsFromTransfer($sspAssetTransfer));
415
                }
416
                if ($event->getForm()->has(static::FIELD_ASSIGNED_COMPANIES)) {
417
                    $event->getForm()->get(static::FIELD_ASSIGNED_COMPANIES)->setData($this->extractCompaniesFromTransfer($sspAssetTransfer));
418
                }
419
            },
420
        );
421
    }
422
423
    /**
424
     * Adds a validation listener to ensure business unit owner is one of the assigned business units
425
     *
426
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
427
     *
428
     * @return void
429
     */
430
    protected function addBusinessUnitOwnerValidationListener(FormBuilderInterface $builder): void
431
    {
432
        $builder->addEventListener(
433
            FormEvents::PRE_SUBMIT,
434
            function (FormEvent $event): void {
435
                $data = $event->getData();
436
                $form = $event->getForm();
437
438
                $businessUnitOwnerId = $data[static::FIELD_BUSINESS_UNIT_OWNER] ?? null;
439
                $assignedBusinessUnitIds = $data[static::FIELD_ASSIGNED_BUSINESS_UNITS] ?? [];
440
441
                if (!$businessUnitOwnerId && $assignedBusinessUnitIds === []) {
442
                    return;
443
                }
444
445
                if (!$businessUnitOwnerId && $assignedBusinessUnitIds !== []) {
446
                    $form->addError(new FormError('Business unit owner is required when business units are assigned.'));
447
448
                    return;
449
                }
450
451
                if (!in_array($businessUnitOwnerId, $assignedBusinessUnitIds)) {
452
                    $form->addError(new FormError('Business unit owner must be one of the assigned business units.'));
453
                }
454
            },
455
        );
456
    }
457
458
    /**
459
     * Adds a validation listener to ensure assigned companies contain all companies from assigned business units
460
     *
461
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
462
     *
463
     * @return void
464
     */
465
    protected function addCompanyAssignmentValidationListener(FormBuilderInterface $builder): void
466
    {
467
        $builder->addEventListener(
468
            FormEvents::PRE_SUBMIT,
469
            function (FormEvent $event): void {
470
                $data = $event->getData();
471
                $form = $event->getForm();
472
473
                if (!isset($data[static::FIELD_ASSIGNED_BUSINESS_UNITS]) || !$data[static::FIELD_ASSIGNED_BUSINESS_UNITS]) {
474
                    return;
475
                }
476
477
                if (!isset($data[static::FIELD_ASSIGNED_COMPANIES]) || !$data[static::FIELD_ASSIGNED_COMPANIES]) {
478
                    $form->addError(new FormError('Companies must be assigned when business units are assigned.'));
479
480
                    return;
481
                }
482
483
                $assignedBusinessUnitIds = array_map('intval', $data[static::FIELD_ASSIGNED_BUSINESS_UNITS]);
484
                $assignedCompanyIds = array_map('intval', $data[static::FIELD_ASSIGNED_COMPANIES]);
485
486
                $businessUnitOptions = $form->getConfig()->getOption(static::OPTION_BUSINESS_UNIT_ASSIGMENT_OPTIONS);
487
                $companyOptions = $form->getConfig()->getOption(static::OPTION_COMPANY_ASSIGMENT_OPTIONS);
488
489
                if (!$businessUnitOptions || !$companyOptions) {
490
                    return;
491
                }
492
493
                $companyBusinessUnitFacade = $this->getFactory()->getCompanyBusinessUnitFacade();
494
                $businessUnitCollection = $companyBusinessUnitFacade->getCompanyBusinessUnitCollection(
495
                    (new CompanyBusinessUnitCriteriaFilterTransfer())->setCompanyBusinessUnitIds($assignedBusinessUnitIds),
496
                );
497
498
                $requiredCompanyIds = [];
499
                foreach ($businessUnitCollection->getCompanyBusinessUnits() as $businessUnit) {
500
                    if ($businessUnit->getCompany() && $businessUnit->getCompany()->getIdCompany()) {
501
                        $requiredCompanyIds[] = $businessUnit->getCompany()->getIdCompany();
502
                    }
503
                }
504
505
                $requiredCompanyIds = array_unique($requiredCompanyIds);
506
                $missingCompanyIds = array_diff($requiredCompanyIds, $assignedCompanyIds);
507
508
                if ($missingCompanyIds) {
509
                    $companyFacade = $this->getFactory()->getCompanyFacade();
510
                    $missingCompanyCollection = $companyFacade->getCompanyCollection(
511
                        (new CompanyCriteriaFilterTransfer())->setCompanyIds($missingCompanyIds),
512
                    );
513
514
                    $missingCompanyNames = [];
515
                    foreach ($missingCompanyCollection->getCompanies() as $company) {
516
                        $missingCompanyNames[] = $company->getName();
517
                    }
518
519
                    $errorMessage = sprintf(
520
                        'All companies that own the assigned business units must be included in assigned companies. Missing companies: %s.',
521
                        implode(', ', $missingCompanyNames),
522
                    );
523
524
                    $form->addError(new FormError($errorMessage));
525
                }
526
            },
527
        );
528
    }
529
530
    /**
531
     * Adds a validation listener to ensure that if a company is selected, at least one business unit of that company is selected too
532
     *
533
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
534
     *
535
     * @return void
536
     */
537
    protected function addBusinessUnitAssignmentValidationListener(FormBuilderInterface $builder): void
538
    {
539
        $builder->addEventListener(
540
            FormEvents::PRE_SUBMIT,
541
            function (FormEvent $event): void {
542
                $data = $event->getData();
543
                $form = $event->getForm();
544
545
                if (!isset($data[static::FIELD_ASSIGNED_COMPANIES]) || !$data[static::FIELD_ASSIGNED_COMPANIES]) {
546
                    return;
547
                }
548
549
                if (!isset($data[static::FIELD_ASSIGNED_BUSINESS_UNITS]) || !$data[static::FIELD_ASSIGNED_BUSINESS_UNITS]) {
550
                    return;
551
                }
552
553
                $assignedCompanyIds = array_map('intval', $data[static::FIELD_ASSIGNED_COMPANIES]);
554
                $assignedBusinessUnitIds = array_map('intval', $data[static::FIELD_ASSIGNED_BUSINESS_UNITS]);
555
556
                $companyBusinessUnitFacade = $this->getFactory()->getCompanyBusinessUnitFacade();
557
                $businessUnitCollection = $companyBusinessUnitFacade->getCompanyBusinessUnitCollection(
558
                    (new CompanyBusinessUnitCriteriaFilterTransfer())->setCompanyIds($assignedCompanyIds),
559
                );
560
561
                $companyBusinessUnits = [];
562
                foreach ($businessUnitCollection->getCompanyBusinessUnits() as $businessUnit) {
563
                    if ($businessUnit->getFkCompany() && $businessUnit->getIdCompanyBusinessUnit()) {
564
                        $companyId = $businessUnit->getFkCompany();
565
                        $businessUnitId = $businessUnit->getIdCompanyBusinessUnit();
566
567
                        if (!isset($companyBusinessUnits[$companyId])) {
568
                            $companyBusinessUnits[$companyId] = [];
569
                        }
570
571
                        $companyBusinessUnits[$companyId][] = $businessUnitId;
572
                    }
573
                }
574
575
                $companyFacade = $this->getFactory()->getCompanyFacade();
576
                $companiesWithoutBusinessUnits = [];
577
578
                foreach ($assignedCompanyIds as $companyId) {
579
                    $hasSelectedBusinessUnit = false;
580
581
                    if (isset($companyBusinessUnits[$companyId])) {
582
                        foreach ($companyBusinessUnits[$companyId] as $businessUnitId) {
583
                            if (in_array($businessUnitId, $assignedBusinessUnitIds)) {
584
                                $hasSelectedBusinessUnit = true;
585
586
                                break;
587
                            }
588
                        }
589
                    }
590
591
                    if (!$hasSelectedBusinessUnit) {
592
                        $companyCollection = $companyFacade->getCompanyCollection(
593
                            (new CompanyCriteriaFilterTransfer())->setCompanyIds([$companyId]),
594
                        );
595
596
                        if ($companyCollection->getCompanies()->count() > 0) {
597
                            $company = $companyCollection->getCompanies()->getIterator()->current();
598
                            $companiesWithoutBusinessUnits[] = $company->getNameOrFail();
599
                        }
600
                    }
601
                }
602
603
                if ((bool)$companiesWithoutBusinessUnits) {
604
                    $errorMessage = sprintf(
605
                        'For each selected company, at least one of its business units must be selected. Missing business units for companies: %s.',
606
                        implode(', ', $companiesWithoutBusinessUnits),
607
                    );
608
609
                    $form->addError(new FormError($errorMessage));
610
                }
611
            },
612
        );
613
    }
614
615
    /**
616
     * @param \Generated\Shared\Transfer\SspAssetTransfer $sspAssetTransfer
617
     *
618
     * @return array<int>
619
     */
620
    protected function extractBusinessUnitsFromTransfer(SspAssetTransfer $sspAssetTransfer): array
621
    {
622
        $sspAssetAssignmentTransfers = $sspAssetTransfer->getBusinessUnitAssignments();
623
        if ($sspAssetAssignmentTransfers->count() === 0) {
624
            return [];
625
        }
626
627
        $businessUnitIds = [];
628
        foreach ($sspAssetAssignmentTransfers as $sspAssetAssignmentTransfer) {
629
            $companyBusinessUnitTransfer = $sspAssetAssignmentTransfer->getCompanyBusinessUnit();
630
            if ($companyBusinessUnitTransfer) {
631
                $businessUnitIds[sprintf(
632
                    '%s (ID: %s)',
633
                    $companyBusinessUnitTransfer->getNameOrFail(),
634
                    $companyBusinessUnitTransfer->getIdCompanyBusinessUnitOrFail(),
635
                )] = $companyBusinessUnitTransfer->getIdCompanyBusinessUnitOrFail();
636
            }
637
        }
638
639
        return $businessUnitIds;
640
    }
641
642
    /**
643
     * @param \Generated\Shared\Transfer\SspAssetTransfer $sspAssetTransfer
644
     *
645
     * @return array<int>
646
     */
647
    protected function extractCompaniesFromTransfer(SspAssetTransfer $sspAssetTransfer): array
648
    {
649
        $sspAssetAssignmentTransfers = $sspAssetTransfer->getBusinessUnitAssignments();
650
        if ($sspAssetAssignmentTransfers->count() === 0) {
651
            return [];
652
        }
653
654
        $companyIds = [];
655
        foreach ($sspAssetAssignmentTransfers as $sspAssetAssignmentTransfer) {
656
            $companyBusinessUnitTransfer = $sspAssetAssignmentTransfer->getCompanyBusinessUnit();
657
            if ($companyBusinessUnitTransfer) {
658
                $companyTransfer = $companyBusinessUnitTransfer->getCompanyOrFail();
659
                $companyIds[sprintf(
660
                    '%s (ID: %s)',
661
                    $companyTransfer->getNameOrFail(),
662
                    $companyTransfer->getIdCompanyOrFail(),
663
                )] = $companyTransfer->getIdCompanyOrFail();
664
            }
665
        }
666
667
        return $companyIds;
668
    }
669
670
    /**
671
     * @param \Symfony\Component\Form\FormBuilderInterface $builder
672
     *
673
     * @return $this
674
     */
675
    protected function addExternalImageUrlField(FormBuilderInterface $builder)
676
    {
677
        $builder->add(static::FIELD_EXTERNAL_IMAGE_URL, UrlType::class, [
678
            'label' => 'External image URL',
679
            'required' => false,
680
            'sanitize_xss' => true,
681
            'constraints' => [
682
                new Length([
683
                    'max' => 2048,
684
                    'maxMessage' => 'External image URL cannot be longer than {{ limit }} characters.',
685
                ]),
686
                new Url([
687
                    'message' => 'Please enter a valid URL.',
688
                ]),
689
            ],
690
            'attr' => [
691
                'placeholder' => 'https://example.com/image.jpg',
692
                'data-qa' => 'ssp-asset-external-image-url-field',
693
            ],
694
        ]);
695
696
        return $this;
697
    }
698
}
699