Completed
Pull Request — master (#19)
by Daniel
03:21 queued 01:29
created

GridFactory::getNumberOfRecords()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Psi\Component\Grid;
6
7
use Metadata\MetadataFactory;
8
use Psi\Component\Grid\Metadata\GridMetadata;
9
use Psi\Component\ObjectAgent\AgentFinder;
10
use Psi\Component\ObjectAgent\AgentInterface;
11
use Psi\Component\ObjectAgent\Query\Query;
12
13
class GridFactory
14
{
15
    private $agentFinder;
16
    private $metadataFactory;
17
    private $cellFactory;
18
    private $filterFactory;
19
20
    public function __construct(
21
        AgentFinder $agentFinder,
22
        MetadataFactory $metadataFactory,
23
        CellFactory $cellFactory,
24
        FilterFormFactory $filterFactory
25
    ) {
26
        $this->agentFinder = $agentFinder;
27
        $this->metadataFactory = $metadataFactory;
28
        $this->cellFactory = $cellFactory;
29
        $this->filterFactory = $filterFactory;
30
    }
31
32
    public function loadGrid(string $classFqn, array $options): Grid
33
    {
34
        $options = new GridContext($classFqn, $options);
35
36
        try {
37
            return $this->doLoadGrid($classFqn, $options);
38
        } catch (\Exception $exception) {
39
            throw new \InvalidArgumentException(sprintf(
40
                'Could not load grid for class "%s"', $classFqn
41
            ), 0, $exception);
42
        }
43
    }
44
45
    private function doLoadGrid(string $classFqn, GridContext $options): Grid
46
    {
47
        if (null === $metadata = $this->metadataFactory->getMetadataForClass($classFqn)) {
48
            throw new \InvalidArgumentException('Could not locate grid metadata');
49
        }
50
51
        $gridMetadata = $this->resolveGridMetadata($metadata->getGrids(), $options->getVariant());
52
        $agent = $this->agentFinder->findFor($classFqn);
53
54
        $form = $this->filterFactory->createForm($gridMetadata, $agent->getCapabilities());
55
        $form->submit($options->getFilter());
56
        $expression = $this->getExpression($gridMetadata, $form->getData());
57
58
        $query = Query::create(
59
            $classFqn,
60
            $expression,
61
            $options->getOrderings(),
62
            $options->getPageOffset(),
63
            $options->getPageSize()
64
        );
65
        $collection = $agent->query($query);
66
67
        return new Grid(
68
            $classFqn,
69
            $gridMetadata->getName(),
70
            new Table($this->cellFactory, $gridMetadata, $collection, $options),
71
            new Paginator($options, count($collection), $this->getNumberOfRecords($agent, $query)),
72
            new FilterForm($form->createView(), $options)
73
        );
74
    }
75
76
    private function getExpression(GridMetadata $gridMetadata, array $filterData)
77
    {
78
        return $this->filterFactory->createExpression($gridMetadata, $filterData);
79
    }
80
81
    private function getNumberOfRecords(AgentInterface $agent, Query $query)
82
    {
83
        if (false === $agent->getCapabilities()->canQueryCount()) {
0 ignored issues
show
Bug introduced by
The method canQueryCount() does not seem to exist on object<Psi\Component\ObjectAgent\Capabilities>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
84
            return;
85
        }
86
87
        return $agent->queryCount($query);
0 ignored issues
show
Bug introduced by
The method queryCount() does not seem to exist on object<Psi\Component\ObjectAgent\AgentInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
88
    }
89
90
    private function resolveGridMetadata(array $grids, string $variant = null)
91
    {
92
        if (empty($grids)) {
93
            throw new \InvalidArgumentException('No grid variants are available');
94
        }
95
96
        // if no explicit grid variant is requested, return the first one that
97
        // was defined.
98
        if (null === $variant) {
99
            return reset($grids);
100
        }
101
102
        if (!isset($grids[$variant])) {
103
            throw new \InvalidArgumentException(sprintf(
104
                'Unknown grid variant "%s", available variants: "%s"',
105
                implode('", "', array_keys($grids))
106
            ));
107
        }
108
109
        return $grids[$variant];
110
    }
111
}
112