1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Psi\Component\Grid; |
6
|
|
|
|
7
|
|
|
use Metadata\MetadataFactory; |
8
|
|
|
use Psi\Component\ObjectAgent\AgentFinder; |
9
|
|
|
use Psi\Component\ObjectAgent\Query\Query; |
10
|
|
|
use Psi\Component\View\ViewFactory; |
11
|
|
|
|
12
|
|
|
class GridFactory |
13
|
|
|
{ |
14
|
|
|
private $agentFinder; |
15
|
|
|
private $metadataFactory; |
16
|
|
|
private $viewFactory; |
17
|
|
|
private $filterFactory; |
18
|
|
|
|
19
|
|
|
public function __construct( |
20
|
|
|
AgentFinder $agentFinder, |
21
|
|
|
MetadataFactory $metadataFactory, |
22
|
|
|
ViewFactory $viewFactory, |
23
|
|
|
FilterFormFactory $filterFactory |
24
|
|
|
) { |
25
|
|
|
$this->agentFinder = $agentFinder; |
26
|
|
|
$this->metadataFactory = $metadataFactory; |
27
|
|
|
$this->viewFactory = $viewFactory; |
28
|
|
|
$this->filterFactory = $filterFactory; |
29
|
|
|
} |
30
|
|
|
|
31
|
|
|
public function loadGrid(string $classFqn, array $options, array $filterData = []): Grid |
32
|
|
|
{ |
33
|
|
|
$options = new GridOptions($options); |
34
|
|
|
|
35
|
|
|
try { |
36
|
|
|
return $this->doLoadGrid($classFqn, $options, $filterData); |
37
|
|
|
} catch (\Exception $exception) { |
38
|
|
|
throw new \InvalidArgumentException(sprintf( |
39
|
|
|
'Could not load grid for class "%s"', $classFqn |
40
|
|
|
), null, $exception); |
41
|
|
|
} |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
private function doLoadGrid(string $classFqn, GridOptions $options, array $filterData): Grid |
45
|
|
|
{ |
46
|
|
|
if (null === $metadata = $this->metadataFactory->getMetadataForClass($classFqn)) { |
47
|
|
|
throw new \InvalidArgumentException('Could not locate grid metadata'); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
$gridMetadata = $this->resolveGridMetadata($metadata->getGrids(), $options->getVariant()); |
51
|
|
|
$agent = $this->agentFinder->findAgentFor($classFqn); |
52
|
|
|
$expression = null; |
53
|
|
|
|
54
|
|
|
$form = $this->filterFactory->createForm($gridMetadata, $agent->getCapabilities(), $filterData); |
|
|
|
|
55
|
|
|
$form->submit($filterData); |
56
|
|
|
|
57
|
|
|
if ($filterData && $form->isValid()) { |
|
|
|
|
58
|
|
|
$expression = $this->filterFactory->createExpression($gridMetadata, $form->getData()); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
$query = Query::create( |
62
|
|
|
$classFqn, |
63
|
|
|
$expression, |
64
|
|
|
$options->getOrderings(), |
65
|
|
|
$options->getPageOffset(), |
66
|
|
|
$options->getPageSize() |
67
|
|
|
); |
68
|
|
|
$collection = $agent->query($query); |
69
|
|
|
|
70
|
|
|
return new Grid( |
71
|
|
|
new Table($this->viewFactory, $gridMetadata, $collection), |
72
|
|
|
new Paginator( |
73
|
|
|
$options->getPageSize(), |
74
|
|
|
$options->getCurrentPage() |
75
|
|
|
), |
76
|
|
|
new FilterForm($form->createView()) |
77
|
|
|
); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
private function resolveGridMetadata(array $grids, string $variant = null) |
81
|
|
|
{ |
82
|
|
|
if (empty($grids)) { |
83
|
|
|
throw new \InvalidArgumentException('No grid variants are available'); |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
if (null === $variant) { |
87
|
|
|
return reset($grids); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
if (!isset($grids[$variant])) { |
91
|
|
|
throw new \InvalidArgumentException(sprintf( |
92
|
|
|
'Unknown grid variant "%s", available variants: "%s"', |
93
|
|
|
implode('", "', array_keys($grids)) |
94
|
|
|
)); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
return $grids[$variant]; |
98
|
|
|
} |
99
|
|
|
} |
100
|
|
|
|
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.