Completed
Push — master ( 8d3dbf...7592af )
by Paweł
62:36
created

EntityRepository::getPaginatedByCriteria()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 4
cts 5
cp 0.8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 3
crap 2.032
1
<?php
2
3
/*
4
 * This file is part of the Superdesk Web Publisher Storage Bundle.
5
 *
6
 * Copyright 2016 Sourcefabric z.ú. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2016 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\StorageBundle\Doctrine\ORM;
16
17
use Doctrine\ORM\EntityRepository as BaseEntityRepository;
18
use Doctrine\ORM\QueryBuilder;
19
use Knp\Component\Pager\Paginator;
20
use Knp\Component\Pager\Pagination\PaginationInterface;
21
use SWP\Component\Common\Criteria\Criteria;
22
use SWP\Component\Common\Pagination\PaginationData;
23
use SWP\Component\Storage\Model\PersistableInterface;
24
use SWP\Component\Storage\Repository\RepositoryInterface;
25
26
/**
27
 * @author Paweł Jędrzejewski <[email protected]>
28
 */
29
class EntityRepository extends BaseEntityRepository implements RepositoryInterface
30
{
31
    /**
32
     * Default value for number of results.
33
     */
34
    const MAX_RESULTS = 10;
35
36
    /**
37
     * {@inheritdoc}
38
     */
39
    public function persist(PersistableInterface $object)
40
    {
41
        $this->_em->persist($object);
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 100
    public function add(PersistableInterface $object)
48
    {
49 100
        $this->_em->persist($object);
50 100
        $this->_em->flush();
51 100
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 76
    public function flush()
57
    {
58 76
        $this->_em->flush();
59 76
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64 6 View Code Duplication
    public function remove(PersistableInterface $object)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65
    {
66 6
        if (null !== $this->find($object->getId())) {
67 6
            $this->_em->remove($object);
68 6
            $this->_em->flush();
69
        }
70 6
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 11
    public function getPaginatedByCriteria(Criteria $criteria, array $sorting = [], PaginationData $paginationData = null)
76
    {
77 11
        $queryBuilder = $this->getQueryByCriteria($criteria, $sorting, 's');
78
79 11
        if (null === $paginationData) {
80
            $paginationData = new PaginationData();
81
        }
82
83 11
        return $this->getPaginator($queryBuilder, $paginationData);
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89 87
    public function getQueryByCriteria(Criteria $criteria, array $sorting, string $alias): QueryBuilder
90
    {
91 87
        $queryBuilder = $this->createQueryBuilder($alias);
92 87
        $this->applyCriteria($queryBuilder, $criteria, $alias);
93 87
        $this->applySorting($queryBuilder, $sorting, $alias);
94 87
        $this->applyLimiting($queryBuilder, $criteria);
95
96 87
        return $queryBuilder;
97
    }
98
99
    /**
100
     * @param $queryBuilder
101
     * @param PaginationData $paginationData
102
     *
103
     * @return PaginationInterface
104
     */
105 16
    protected function getPaginator($queryBuilder, PaginationData $paginationData)
106
    {
107 16
        $paginator = new Paginator();
108
109 16
        return $paginator->paginate($queryBuilder, $paginationData->getPageNumber(), $paginationData->getLimit());
110
    }
111
112
    /**
113
     * @param QueryBuilder $queryBuilder
114
     * @param Criteria     $criteria
115
     * @param string       $alias
116
     */
117 87
    protected function applyCriteria(QueryBuilder $queryBuilder, Criteria $criteria, string $alias)
118
    {
119 87
        $properties = array_merge($this->getClassMetadata()->getFieldNames(), $this->getClassMetadata()->getAssociationNames());
120 87
        foreach ($criteria->all() as $property => $value) {
121 87
            if (!in_array($property, $properties)) {
122 18
                continue;
123
            }
124
125 87
            $name = $this->getPropertyName($property, $alias);
126 87
            if (null === $value) {
127
                $queryBuilder->andWhere($queryBuilder->expr()->isNull($name));
128 87
            } elseif (is_array($value)) {
129 3
                $queryBuilder->andWhere($queryBuilder->expr()->in($name, $value));
130 87
            } elseif ('' !== $value) {
131 87
                $parameter = str_replace('.', '_', $property);
132
                $queryBuilder
133 87
                    ->andWhere($queryBuilder->expr()->eq($name, ':'.$parameter))
134 87
                    ->setParameter($parameter, $value)
135
                ;
136
            }
137
        }
138 87
    }
139
140
    /**
141
     * @param QueryBuilder $queryBuilder
142
     * @param array        $sorting
143
     * @param string       $alias
144
     */
145 87
    protected function applySorting(QueryBuilder $queryBuilder, array $sorting, string $alias)
146
    {
147 87
        foreach ($sorting as $property => $order) {
148 10
            if (!empty($order)) {
149 10
                $queryBuilder->addOrderBy($this->getPropertyName($property, $alias), $order);
150
            }
151
        }
152 87
    }
153
154
    /**
155
     * @param QueryBuilder $queryBuilder
156
     * @param Criteria     $criteria
157
     */
158 87
    public function applyLimiting(QueryBuilder $queryBuilder, Criteria $criteria)
159
    {
160 87
        $queryBuilder->setFirstResult($criteria->get('firstResult', 0));
161 87
        if ($criteria->has('maxResults')) {
162 17
            $queryBuilder->setMaxResults($criteria->get('maxResults'));
163
        } else {
164 78
            $queryBuilder->setMaxResults(self::MAX_RESULTS);
165
        }
166 87
    }
167
168
    /**
169
     * @param string $name
170
     * @param string $alias
171
     *
172
     * @return string
173
     */
174 87
    protected function getPropertyName(string $name, string $alias)
175
    {
176 87
        if (false === strpos($name, '.')) {
177 87
            return $alias.'.'.$name;
178
        }
179
180
        return $name;
181
    }
182
}
183