ListReader::getListActions()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace KunicMarko\SonataAnnotationBundle\Reader;
6
7
use KunicMarko\SonataAnnotationBundle\Annotation\ListAction;
8
use KunicMarko\SonataAnnotationBundle\Annotation\ListAssociationField;
9
use KunicMarko\SonataAnnotationBundle\Annotation\ListField;
10
use Sonata\AdminBundle\Datagrid\ListMapper;
11
12
/**
13
 * @author Marko Kunic <[email protected]>
14
 */
15
final class ListReader
16
{
17
    use AnnotationReaderTrait;
18
19
    public function configureFields(\ReflectionClass $class, ListMapper $listMapper): void
20
    {
21
        $propertiesAndMethodsWithPosition = [];
22
        $propertiesAndMethodsWithoutPosition = [];
23
24
        //
25
        // Properties
26
        //
27
28
        foreach ($class->getProperties() as $property) {
29
            foreach ($this->getPropertyAnnotations($property) as $annotation) {
30
                if (!$annotation instanceof ListField && !$annotation instanceof ListAssociationField) {
31
                    continue;
32
                }
33
34
                // the name property changes for ListAssociationField
35
                $name = $property->getName();
36
                if ($annotation instanceof ListAssociationField) {
37
                    $name .= '.'.$annotation->getField();
38
                }
39
40
                if (!$annotation->hasPosition()) {
41
                    $propertiesAndMethodsWithoutPosition[] = [
42
                        'name' => $name,
43
                        'annotation' => $annotation,
44
                    ];
45
46
                    continue;
47
                }
48
49
                if (\array_key_exists($annotation->position, $propertiesAndMethodsWithPosition)) {
50
                    throw new \InvalidArgumentException(sprintf(
51
                        'Position "%s" is already in use by "%s", try setting a different position for "%s".',
52
                        $annotation->position,
53
                        $propertiesAndMethodsWithPosition[$annotation->position]['name'],
54
                        $property->getName()
55
                    ));
56
                }
57
58
                $propertiesAndMethodsWithPosition[$annotation->position] = [
59
                    'name' => $name,
60
                    'annotation' => $annotation,
61
                ];
62
            }
63
        }
64
65
        //
66
        // Methods
67
        //
68
69
        foreach ($class->getMethods() as $method) {
70
            if ($annotation = $this->getMethodAnnotation($method, ListField::class)) {
71
                $name = $method->getName();
72
73
                if (!$annotation->hasPosition()) {
74
                    $propertiesAndMethodsWithoutPosition[] = [
75
                        'name' => $name,
76
                        'annotation' => $annotation,
77
                    ];
78
79
                    continue;
80
                }
81
82
                if (\array_key_exists($annotation->position, $propertiesAndMethodsWithPosition)) {
83
                    throw new \InvalidArgumentException(sprintf(
84
                        'Position "%s" is already in use by "%s", try setting a different position for "%s".',
85
                        $annotation->position,
86
                        $propertiesAndMethodsWithPosition[$annotation->position]['name'],
87
                        $name
88
                    ));
89
                }
90
91
                $propertiesAndMethodsWithPosition[$annotation->position] = [
92
                    'name' => $name,
93
                    'annotation' => $annotation,
94
                ];
95
            }
96
        }
97
98
        //
99
        // Sorting
100
        //
101
102
        \ksort($propertiesAndMethodsWithPosition);
103
104
        $propertiesAndMethods = \array_merge($propertiesAndMethodsWithPosition, $propertiesAndMethodsWithoutPosition);
105
106
        foreach ($propertiesAndMethods as $propertyAndMethod) {
107
            $this->addField($propertyAndMethod['name'], $propertyAndMethod['annotation'], $listMapper);
108
        }
109
110
        //
111
        // Actions
112
        //
113
114
        if ($actions = $this->getListActions($this->getClassAnnotations($class))) {
115
            $listMapper->add('_action', null, [
116
                'actions' => $actions,
117
            ]);
118
        }
119
    }
120
121
    private function addField(string $name, ListField $annotation, ListMapper $listMapper): void
122
    {
123
        if ($annotation->identifier) {
124
            $listMapper->addIdentifier($name, ...$annotation->getSettings());
0 ignored issues
show
Bug introduced by
It seems like $annotation->getSettings() can also be of type array; however, parameter $type of Sonata\AdminBundle\Datag...Mapper::addIdentifier() does only seem to accept null|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

124
            $listMapper->addIdentifier($name, /** @scrutinizer ignore-type */ ...$annotation->getSettings());
Loading history...
125
126
            return;
127
        }
128
129
        $listMapper->add($name, ...$annotation->getSettings());
0 ignored issues
show
Bug introduced by
It seems like $annotation->getSettings() can also be of type array; however, parameter $type of Sonata\AdminBundle\Datagrid\ListMapper::add() does only seem to accept null|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

129
        $listMapper->add($name, /** @scrutinizer ignore-type */ ...$annotation->getSettings());
Loading history...
130
    }
131
132
    private function getListActions(array $annotations): array
133
    {
134
        $actions = [];
135
136
        foreach ($annotations as $annotation) {
137
            if ($annotation instanceof ListAction) {
138
                $actions[$annotation->getName()] = $annotation->options;
139
            }
140
        }
141
142
        return $actions;
143
    }
144
}
145