GridFactoryBuilder   C
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 35

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 35
dl 0
loc 147
rs 5
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 12 3
A createWithDefaults() 0 18 1
A addArrayDriver() 0 6 1
A addAnnotationDriver() 0 6 1
A addAction() 0 6 1
A addFilter() 0 6 1
A addColumn() 0 6 1
A addSubscriber() 0 6 1
B createGridFactory() 0 61 5
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')
0 ignored issues
show
Unused Code introduced by
The call to SelectColumn::__construct() has too many arguments starting with $agentFinder.

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.

Loading history...
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