Passed
Push — develop ( 3d1775...ebd477 )
by Mathieu
02:47
created

AbstractFieldConfigurationReader::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 6
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
namespace KunicMarko\SonataAnnotationBundle\Reader;
4
5
use Doctrine\Common\Annotations\Reader;
6
use InvalidArgumentException;
7
use KunicMarko\SonataAnnotationBundle\Annotation\ActionAnnotationInterface;
8
use KunicMarko\SonataAnnotationBundle\Annotation\AssociationFieldInterface;
9
use KunicMarko\SonataAnnotationBundle\Annotation\PositionAnnotationInterface;
10
use ReflectionClass;
11
use Sonata\AdminBundle\Datagrid\DatagridMapper;
12
use Sonata\AdminBundle\Datagrid\ListMapper;
13
use Sonata\AdminBundle\Form\FormMapper;
14
use Sonata\AdminBundle\Mapper\MapperInterface;
15
use Sonata\AdminBundle\Show\ShowMapper;
16
17
/**
18
 * Field configuration reader.
19
 */
20
class AbstractFieldConfigurationReader extends AbstractReader
21
{
22
23
    /**
24
     * Associated annotation class.
25
     *
26
     * @var string|null
27
     */
28
    protected ?string $annotationClass;
29
30
    /**
31
     * @param Reader  $annotationReader Doctrine annotation reader.
32
     * @param ?string $annotationClass  Associated annotation class.
33
     */
34
    public function __construct(
35
        Reader $annotationReader,
36
        ?string $annotationClass = null
37
    ) {
38
        parent::__construct($annotationReader);
39
        $this->annotationClass = $annotationClass;
40
    }
41
42
    /**
43
     * Build list field configurations.
44
     *
45
     * @param ReflectionClass $class  Entity class.
46
     * @param MapperInterface $mapper Admin mapper.
47
     *
48
     * @return void
49
     */
50
    public function configureFields(
51
        ReflectionClass $class,
52
        MapperInterface $mapper
53
    ): void {
54
        $this->configureReaderFields(
55
            $class,
56
            $mapper,
57
            $this->annotationClass
58
        );
59
    }
60
61
    /**
62
     * Configure fields with positions.
63
     *
64
     * @param ReflectionClass $class           Read entity class.
65
     * @param MapperInterface $mapper          Admin mapper.
66
     * @param string|null     $annotationClass Filtered annotation class.
67
     * @param string|null     $action          Current action.
68
     *
69
     * @return void
70
     */
71
    protected function configureReaderFields(
72
        ReflectionClass $class,
73
        MapperInterface $mapper,
74
        ?string $annotationClass = null,
75
        ?string $action = null
76
    ): void {
77
        $propertiesAndMethods = array_merge(
78
            $this->getClassPropertiesAnnotations($class, $annotationClass),
79
            $this->getClassMethodsAnnotations($class, $annotationClass)
80
        );
81
82
        $fields = [];
83
        $propertiesWithPosition = [];
84
        $propertiesWithoutPosition = [];
85
86
        foreach ($propertiesAndMethods as $name => $annotations) {
87
            foreach ($annotations as $annotation) {
88
                if ($annotation instanceof ActionAnnotationInterface
89
                    && $action !== null
90
                    && isset($annotation->action)
91
                    && $annotation->action !== $action
92
                ) {
93
                    continue;
94
                }
95
96
                if ($annotation instanceof AssociationFieldInterface) {
97
                    $name = sprintf('%s.%s', $name, $annotation->field);
98
                }
99
100
                if ($annotation instanceof PositionAnnotationInterface) {
101
                    if (!isset($annotation->position)) {
102
                        $propertiesWithoutPosition[] = [
103
                            'name' => $name,
104
                            'annotation' => $annotation,
105
                        ];
106
                        continue;
107
                    }
108
109
                    if (array_key_exists(
110
                        $annotation->position,
111
                        $propertiesWithPosition
112
                    )) {
113
                        throw new InvalidArgumentException(
114
                            sprintf(
115
                                'Position "%s" is already in use by "%s", try setting a different position for "%s".',
116
                                $annotation->position,
117
                                $propertiesWithPosition[$annotation->position]['name'],
118
                                $name
119
                            )
120
                        );
121
                    }
122
123
                    $propertiesWithPosition[$annotation->position] = [
124
                        'name' => $name,
125
                        'annotation' => $annotation,
126
                    ];
127
                }
128
            }
129
        }
130
131
        if (!empty($propertiesWithPosition)
132
            || !empty($propertiesWithoutPosition)
133
        ) {
134
            ksort($propertiesWithPosition);
135
136
            $fields = array_merge(
137
                $propertiesWithPosition,
138
                $propertiesWithoutPosition
139
            );
140
        }
141
142
143
        array_walk(
144
            $fields,
145
            fn(array $field) => $this->addMapperProperty($mapper, $field)
146
        );
147
    }
148
149
150
    /**
151
     * Add a property to the given mapper.
152
     *
153
     * @param MapperInterface $mapper   Admin mapper.
154
     * @param array           $property Property information.
155
     *
156
     * @return void
157
     */
158
    private function addMapperProperty(
159
        MapperInterface $mapper,
160
        array $property
161
    ): void {
162
        if ($mapper instanceof DatagridMapper
163
            || $mapper instanceof FormMapper
164
            || $mapper instanceof ListMapper
165
            || $mapper instanceof ShowMapper
166
        ) {
167
            $mapper->add(
168
                $property['name'],
169
                ...$property['annotation']->getSettings()
0 ignored issues
show
Bug introduced by
$property['annotation']->getSettings() is expanded, but the parameter $type of Sonata\AdminBundle\Show\ShowMapper::add() does not expect variable arguments. ( Ignorable by Annotation )

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

169
                /** @scrutinizer ignore-type */ ...$property['annotation']->getSettings()
Loading history...
Bug introduced by
$property['annotation']->getSettings() is expanded, but the parameter $type of Sonata\AdminBundle\Datagrid\DatagridMapper::add() does not expect variable arguments. ( Ignorable by Annotation )

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

169
                /** @scrutinizer ignore-type */ ...$property['annotation']->getSettings()
Loading history...
Bug introduced by
$property['annotation']->getSettings() is expanded, but the parameter $type of Sonata\AdminBundle\Form\FormMapper::add() does not expect variable arguments. ( Ignorable by Annotation )

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

169
                /** @scrutinizer ignore-type */ ...$property['annotation']->getSettings()
Loading history...
Bug introduced by
$property['annotation']->getSettings() is expanded, but the parameter $type of Sonata\AdminBundle\Datagrid\ListMapper::add() does not expect variable arguments. ( Ignorable by Annotation )

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

169
                /** @scrutinizer ignore-type */ ...$property['annotation']->getSettings()
Loading history...
170
            );
171
        }
172
    }
173
174
}