AttributesType   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 46
c 2
b 0
f 0
dl 0
loc 82
ccs 0
cts 43
cp 0
rs 10
wmc 18

4 Methods

Rating   Name   Duplication   Size   Complexity  
C buildForm() 0 59 15
A configureOptions() 0 8 1
A __construct() 0 2 1
A getBlockPrefix() 0 2 1
1
<?php
2
3
namespace App\Form;
4
5
use App\Entity\ServiceAttributeType;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, App\Form\ServiceAttributeType. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use App\Repository\ServiceAttributeRepositoryInterface;
7
use SchulIT\CommonBundle\Form\FieldsetType;
8
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
9
use Symfony\Component\Form\Extension\Core\Type\TextType;
10
use Symfony\Component\Form\FormBuilderInterface;
11
use Symfony\Component\OptionsResolver\OptionsResolver;
12
13
class AttributesType extends FieldsetType {
14
15
    public const EXPANDED_THRESHOLD = 7;
16
17
    public function __construct(private ServiceAttributeRepositoryInterface $serviceAttributeRepository)
18
    {
19
    }
20
21
    public function configureOptions(OptionsResolver $resolver) {
22
        parent::configureOptions($resolver);
23
24
        $resolver
25
            ->setDefault('attribute_values', [ ])
26
            ->setDefault('mapped', false)
27
            ->setDefault('only_user_editable', false)
28
            ->remove('fields');
29
    }
30
31
    public function buildForm(FormBuilderInterface $builder, array $options) {
32
        $attributeValues = $options['attribute_values'];
33
        $onlyUserEditable = $options['only_user_editable'];
34
35
        foreach($this->serviceAttributeRepository->findAll() as $attribute) {
36
            $type = $attribute->getType() === ServiceAttributeType::Text ? TextType::class : ChoiceType::class;
37
38
            $options = [
39
                'label' => $attribute->getLabel(),
40
                'attr' => [
41
                    'help' => $attribute->getDescription()
42
                ],
43
                'required' => false,
44
                'mapped' => false,
45
                'disabled' => $attribute->isUserEditEnabled() !== true && $onlyUserEditable === true,
46
                'data' => $attributeValues[$attribute->getName()] ?? null
47
            ];
48
49
            if($type === ChoiceType::class) {
50
                $choices = [];
51
                $values = $attributeValues[$attribute->getName()] ?? [ ];
52
53
                if(!is_array($values)) {
54
                    $values = [ $values ];
55
                }
56
57
                foreach ($attribute->getOptions() as $key => $value) {
58
                    if($onlyUserEditable === false || in_array($key, $values)) {
59
                        $choices[$value] = $key;
60
                    }
61
                }
62
63
                if(count($choices) === 0) {
64
                    continue;
65
                }
66
67
                if ($attribute->isMultipleChoice()) {
68
                    $options['multiple'] = true;
69
                } else {
70
                    array_unshift($choices, [
71
                        'label.not_specified' => null
72
                    ]);
73
                    $options['placeholder'] = false;
74
                }
75
76
                $options['choices'] = $choices;
77
78
                if (count($choices) < static::EXPANDED_THRESHOLD) {
79
                    $options['expanded'] = true;
80
                    $options['label_attr'] = [
81
                        'class' => $attribute->isMultipleChoice() ? 'checkbox-custom' : 'radio-custom'
82
                    ];
83
                }
84
            } else if($type === TextType::class && $options['disabled']) {
85
                $type = ReadonlyTextType::class;
86
            }
87
88
            $builder
89
                ->add($attribute->getName(), $type, $options);
90
        }
91
    }
92
93
    public function getBlockPrefix(): string {
94
        return $this->getName();
95
    }
96
}