1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Psi\Component\Grid; |
6
|
|
|
|
7
|
|
|
use Metadata\Driver\DriverChain; |
8
|
|
|
use Metadata\MetadataFactory; |
9
|
|
|
use Psi\Component\Grid\Action\DeleteAction; |
10
|
|
|
use Psi\Component\Grid\Column\BooleanColumn; |
11
|
|
|
use Psi\Component\Grid\Column\DateTimeColumn; |
12
|
|
|
use Psi\Component\Grid\Column\MoneyColumn; |
13
|
|
|
use Psi\Component\Grid\Column\PropertyColumn; |
14
|
|
|
use Psi\Component\Grid\Column\SelectColumn; |
15
|
|
|
use Psi\Component\Grid\Column\TextColumn; |
16
|
|
|
use Psi\Component\Grid\Filter\BooleanFilter; |
17
|
|
|
use Psi\Component\Grid\Filter\ChoiceFilter; |
18
|
|
|
use Psi\Component\Grid\Filter\DateFilter; |
19
|
|
|
use Psi\Component\Grid\Filter\NumberFilter; |
20
|
|
|
use Psi\Component\Grid\Filter\StringFilter; |
21
|
|
|
use Psi\Component\Grid\Form\GridExtension; |
22
|
|
|
use Psi\Component\Grid\Metadata\Driver\AnnotationDriver; |
23
|
|
|
use Psi\Component\Grid\Metadata\Driver\ArrayDriver; |
24
|
|
|
use Psi\Component\ObjectAgent\AgentFinder; |
25
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcher; |
26
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
27
|
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
28
|
|
|
use Symfony\Component\Form\Extension\Validator\ValidatorExtension; |
29
|
|
|
use Symfony\Component\Form\FormFactoryBuilderInterface; |
30
|
|
|
use Symfony\Component\Form\Forms; |
31
|
|
|
use Symfony\Component\Validator\Validation; |
32
|
|
|
|
33
|
|
|
final class GridFactoryBuilder |
34
|
|
|
{ |
35
|
|
|
private $agentFinder; |
36
|
|
|
private $eventDispatcher; |
37
|
|
|
private $formFactoryBuilder; |
38
|
|
|
|
39
|
|
|
private $actions = []; |
40
|
|
|
private $columns = []; |
41
|
|
|
private $filters = []; |
42
|
|
|
private $metadataDrivers = []; |
43
|
|
|
|
44
|
|
|
public static function create( |
45
|
|
|
AgentFinder $agentFinder, |
46
|
|
|
FormFactoryBuilderInterface $formFactoryBuilder = null, |
47
|
|
|
EventDispatcherInterface $eventDispatcher = null |
48
|
|
|
) { |
49
|
|
|
$instance = new self(); |
50
|
|
|
$instance->agentFinder = $agentFinder; |
51
|
|
|
$instance->formFactoryBuilder = $formFactoryBuilder ?: Forms::createFormFactoryBuilder(); |
52
|
|
|
$instance->eventDispatcher = $eventDispatcher ?: new EventDispatcher(); |
53
|
|
|
|
54
|
|
|
return $instance; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
public static function createWithDefaults(AgentFinder $agentFinder, FormFactoryBuilderInterface $formFactoryBuilder = null) |
58
|
|
|
{ |
59
|
|
|
return self::create($agentFinder, $formFactoryBuilder) |
60
|
|
|
->addAction(new DeleteAction(), 'delete') |
61
|
|
|
|
62
|
|
|
->addColumn(new PropertyColumn(), 'property') |
63
|
|
|
->addColumn(new SelectColumn($agentFinder), 'select') |
|
|
|
|
64
|
|
|
->addColumn(new MoneyColumn(), 'money') |
65
|
|
|
->addColumn(new BooleanColumn(), 'boolean') |
66
|
|
|
->addColumn(new DateTimeColumn(), 'datetime') |
67
|
|
|
->addColumn(new TextColumn(), 'text') |
68
|
|
|
|
69
|
|
|
->addFilter(new StringFilter(), 'string') |
70
|
|
|
->addFilter(new BooleanFilter(), 'boolean') |
71
|
|
|
->addFilter(new NumberFilter(), 'number') |
72
|
|
|
->addFilter(new DateFilter(), 'date') |
73
|
|
|
->addFilter(new ChoiceFilter(), 'choice'); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
public function addArrayDriver(array $mapping) |
77
|
|
|
{ |
78
|
|
|
$this->metadataDrivers[] = new ArrayDriver($mapping); |
79
|
|
|
|
80
|
|
|
return $this; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
public function addAnnotationDriver() |
84
|
|
|
{ |
85
|
|
|
$this->metadataDrivers[] = new AnnotationDriver(); |
86
|
|
|
|
87
|
|
|
return $this; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
public function addAction(ActionInterface $action, $alias = null): self |
91
|
|
|
{ |
92
|
|
|
$this->actions[$alias] = $action; |
93
|
|
|
|
94
|
|
|
return $this; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
public function addFilter(FilterInterface $filter, $alias = null) |
98
|
|
|
{ |
99
|
|
|
$this->filters[$alias] = $filter; |
100
|
|
|
|
101
|
|
|
return $this; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
public function addColumn(ColumnInterface $column, $alias = null) |
105
|
|
|
{ |
106
|
|
|
$this->columns[$alias] = $column; |
107
|
|
|
|
108
|
|
|
return $this; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
public function addSubscriber(EventSubscriberInterface $subscriber) |
112
|
|
|
{ |
113
|
|
|
$this->eventDispatcher->addSubscriber($subscriber); |
114
|
|
|
|
115
|
|
|
return $this; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
public function createGridFactory() |
119
|
|
|
{ |
120
|
|
|
if (empty($this->metadataDrivers)) { |
121
|
|
|
throw new \InvalidArgumentException( |
122
|
|
|
'You must add at least one metadata driver (e.g. ->addArrayDriver, ->addAnnotationDriver, ->addXmlDriver)' |
123
|
|
|
); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
$actionRegistry = new ActionRegistry(); |
127
|
|
|
foreach ($this->actions as $alias => $action) { |
128
|
|
|
$actionRegistry->register($action, $alias); |
129
|
|
|
} |
130
|
|
|
$columnRegistry = new ColumnRegistry(); |
131
|
|
|
foreach ($this->columns as $alias => $column) { |
132
|
|
|
$columnRegistry->register($column, $alias); |
133
|
|
|
} |
134
|
|
|
$filterRegistry = new FilterRegistry(); |
135
|
|
|
foreach ($this->filters as $alias => $filter) { |
136
|
|
|
$filterRegistry->register($filter, $alias); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
$metadataDriver = new DriverChain($this->metadataDrivers); |
140
|
|
|
$columnFactory = new ColumnFactory($columnRegistry); |
141
|
|
|
$metadataFactory = new MetadataFactory($metadataDriver); |
142
|
|
|
$gridMetadataFactory = new EventDispatchingGridMetadataFactory( |
143
|
|
|
new GridMetadataFactory($metadataFactory), |
144
|
|
|
$this->eventDispatcher |
145
|
|
|
); |
146
|
|
|
|
147
|
|
|
$validator = Validation::createValidator(); |
148
|
|
|
|
149
|
|
|
$formFactory = $this->formFactoryBuilder |
150
|
|
|
->addExtension(new ValidatorExtension($validator)) |
151
|
|
|
->addExtension(new GridExtension( |
152
|
|
|
$columnRegistry, |
153
|
|
|
$filterRegistry |
154
|
|
|
)) |
155
|
|
|
->getFormFactory(); |
156
|
|
|
|
157
|
|
|
$filterFactory = new EventDispatchingFilterBarFactory( |
158
|
|
|
new FilterBarFactory($formFactory, $filterRegistry), |
159
|
|
|
$this->eventDispatcher |
160
|
|
|
); |
161
|
|
|
|
162
|
|
|
$queryFactory = new QueryFactory($metadataFactory); |
163
|
|
|
|
164
|
|
|
$gridViewFactory = new GridViewFactory( |
165
|
|
|
$columnFactory, |
166
|
|
|
$filterFactory, |
167
|
|
|
$queryFactory |
168
|
|
|
); |
169
|
|
|
|
170
|
|
|
$actionPerformer = new ActionPerformer($actionRegistry); |
171
|
|
|
|
172
|
|
|
return new GridFactory( |
173
|
|
|
$this->agentFinder, |
174
|
|
|
$gridMetadataFactory, |
175
|
|
|
$gridViewFactory, |
176
|
|
|
$actionPerformer |
177
|
|
|
); |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.