Completed
Pull Request — master (#154)
by Arnaud
09:08
created

ORMDataProvider::getCollection()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 34
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 3.0105

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 19
c 2
b 0
f 0
nc 3
nop 2
dl 0
loc 34
ccs 17
cts 19
cp 0.8947
crap 3.0105
rs 9.6333
1
<?php
2
3
namespace LAG\AdminBundle\Bridge\Doctrine\ORM\DataProvider;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Doctrine\ORM\EntityRepository;
7
use Doctrine\Persistence\ObjectRepository;
8
use LAG\AdminBundle\Admin\AdminInterface;
9
use LAG\AdminBundle\Bridge\Doctrine\ORM\Event\ORMFilterEvent;
10
use LAG\AdminBundle\Bridge\Doctrine\ORM\Results\ResultsHandlerInterface;
11
use LAG\AdminBundle\DataProvider\DataProviderInterface;
12
use LAG\AdminBundle\Event\Events;
13
use LAG\AdminBundle\Exception\Exception;
14
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
15
16
class ORMDataProvider implements DataProviderInterface
17
{
18
    /**
19
     * @var EntityManagerInterface
20
     */
21
    private $entityManager;
22
23
    /**
24
     * @var EventDispatcherInterface
25
     */
26
    private $eventDispatcher;
27
28
    /**
29
     * @var ResultsHandlerInterface
30
     */
31
    private $resultsHandler;
32
33
    /**
34
     * DoctrineORMDataProvider constructor.
35
     */
36 16
    public function __construct(
37
        EntityManagerInterface $entityManager,
38
        EventDispatcherInterface $eventDispatcher,
39
        ResultsHandlerInterface $handler
40
    ) {
41 16
        $this->entityManager = $entityManager;
42 16
        $this->eventDispatcher = $eventDispatcher;
43 16
        $this->resultsHandler = $handler;
44 16
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 4
    public function getCollection(AdminInterface $admin, array $filters = [])
50
    {
51 4
        $adminConfiguration = $admin->getConfiguration();
52 4
        $actionConfiguration = $admin->getAction()->getConfiguration();
53 4
        $repository = $this->getRepository($adminConfiguration->get('entity'));
54
55
        // Allow to change the default method in configuration
56 4
        $alias = strtolower($admin->getName());
57 4
        $method = $actionConfiguration->get('repository_method');
58 4
        $pagination = ('pagerfanta' === $actionConfiguration->get('pager'));
59
60
        // The repository could return an object, an array, a collection, a pager or a query builder. The results
61
        // handler will act according to result type
62 4
        if ($method) {
63 2
            $data = $repository->$method($alias);
64
        } else {
65 2
            if (!$repository instanceof EntityRepository) {
66
                throw new Exception(
67
                    sprintf('The repository of admin "%s" should be an instance of "%s" to use the default method createQueryBuilder()', $admin->getName(), EntityRepository::class)
68
                );
69
            }
70 2
            $data = $repository->createQueryBuilder($alias);
71
        }
72
73
        // Dispatch an event to allow filter alteration on the query builder
74 4
        $event = new ORMFilterEvent($data, $admin, $filters);
75 4
        $this->eventDispatcher->dispatch($event, Events::DOCTRINE_ORM_FILTER);
0 ignored issues
show
Unused Code introduced by
The call to Symfony\Contracts\EventD...erInterface::dispatch() has too many arguments starting with LAG\AdminBundle\Event\Events::DOCTRINE_ORM_FILTER. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

75
        $this->eventDispatcher->/** @scrutinizer ignore-call */ 
76
                                dispatch($event, Events::DOCTRINE_ORM_FILTER);

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. Please note the @ignore annotation hint above.

Loading history...
76
77
        // Fetch pagination parameters
78 4
        $pageParameter = $actionConfiguration->get('page_parameter');
79 4
        $page = (int) $admin->getRequest()->get($pageParameter, 1);
80 4
        $maxPerPage = $actionConfiguration->get('max_per_page');
81
82 4
        return $this->resultsHandler->handle($data, $pagination, $page, $maxPerPage);
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 4
    public function get(AdminInterface $admin, string $identifier)
89
    {
90 4
        $class = $admin->getConfiguration()->get('entity');
91
        $item = $this
92 4
            ->getRepository($class)
93 4
            ->find($identifier)
94
        ;
95
96 4
        if (null === $item) {
97 2
            throw new Exception(sprintf('Item of class "%s" with identifier "%s" not found.', $class, $identifier));
98
        }
99
100 2
        return $item;
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106 2
    public function save(AdminInterface $admin): void
107
    {
108 2
        $this->entityManager->persist($admin->getEntities()->first());
109 2
        $this->entityManager->flush();
110 2
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115 2
    public function create(AdminInterface $admin)
116
    {
117 2
        $class = $admin->getConfiguration()->get('entity');
118
119 2
        return new $class();
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125 4
    public function delete(AdminInterface $admin): void
126
    {
127 4
        if ($admin->getEntities()->isEmpty()) {
128 2
            throw new Exception('The admin "'.$admin->getName().'" has no loaded entity');
129
        }
130 2
        $this->entityManager->remove($admin->getEntities()->first());
131 2
        $this->entityManager->flush();
132 2
    }
133
134
    /**
135
     * @return ObjectRepository|EntityRepository
136
     */
137 8
    private function getRepository(string $class)
138
    {
139 8
        return $this->entityManager->getRepository($class);
140
    }
141
}
142