Completed
Push — master ( a682ba...4851b3 )
by Paweł
40:50
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 2
    public function persist(PersistableInterface $object)
40
    {
41 2
        $this->_em->persist($object);
42 2
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 38
    public function add(PersistableInterface $object)
48
    {
49 38
        $this->_em->persist($object);
50 38
        $this->_em->flush();
51 38
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 9 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...
57
    {
58 9
        if (null !== $this->find($object->getId())) {
59 9
            $this->_em->remove($object);
60 9
            $this->_em->flush();
61
        }
62 9
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 4
    public function getPaginatedByCriteria(Criteria $criteria, array $sorting = [], PaginationData $paginationData = null)
68
    {
69 4
        $queryBuilder = $this->getQueryByCriteria($criteria, $sorting, 's');
70
71 4
        if (null === $paginationData) {
72
            $paginationData = new PaginationData();
73
        }
74
75 4
        return $this->getPaginator($queryBuilder, $paginationData);
76
    }
77
78 26
    public function getQueryByCriteria(Criteria $criteria, array $sorting, string $alias): QueryBuilder
79
    {
80 26
        $queryBuilder = $this->createQueryBuilder($alias);
81 26
        $this->applyCriteria($queryBuilder, $criteria, $alias);
82 26
        $this->applySorting($queryBuilder, $sorting, $alias);
83 26
        $this->applyLimiting($queryBuilder, $criteria);
84
85 26
        return $queryBuilder;
86
    }
87
88
    /**
89
     * @param $queryBuilder
90
     * @param PaginationData $paginationData
91
     *
92
     * @return PaginationInterface
93
     */
94 4
    protected function getPaginator($queryBuilder, PaginationData $paginationData)
95
    {
96 4
        $paginator = new Paginator();
97
98 4
        return $paginator->paginate($queryBuilder, $paginationData->getPageNumber(), $paginationData->getLimit());
99
    }
100
101
    /**
102
     * @param QueryBuilder $queryBuilder
103
     * @param Criteria     $criteria
104
     * @param string       $alias
105
     */
106 26
    protected function applyCriteria(QueryBuilder $queryBuilder, Criteria $criteria, string $alias)
107
    {
108 26
        $properties = array_merge($this->getClassMetadata()->getFieldNames(), $this->getClassMetadata()->getAssociationNames());
109 26
        foreach ($criteria->all() as $property => $value) {
110 22
            if (!in_array($property, $properties)) {
111 20
                continue;
112
            }
113
114 22
            $name = $this->getPropertyName($property, $alias);
115 22
            if (null === $value) {
116
                $queryBuilder->andWhere($queryBuilder->expr()->isNull($name));
117 22
            } elseif (is_array($value)) {
118
                $queryBuilder->andWhere($queryBuilder->expr()->in($name, $value));
119 22
            } elseif ('' !== $value) {
120 22
                $parameter = str_replace('.', '_', $property);
121
                $queryBuilder
122 22
                    ->andWhere($queryBuilder->expr()->eq($name, ':'.$parameter))
123 22
                    ->setParameter($parameter, $value)
124
                ;
125
            }
126
        }
127 26
    }
128
129
    /**
130
     * @param QueryBuilder $queryBuilder
131
     * @param array        $sorting
132
     * @param string       $alias
133
     */
134 26
    protected function applySorting(QueryBuilder $queryBuilder, array $sorting, string $alias)
135
    {
136 26
        foreach ($sorting as $property => $order) {
137 3
            if (!empty($order)) {
138 3
                $queryBuilder->addOrderBy($this->getPropertyName($property, $alias), $order);
139
            }
140
        }
141 26
    }
142
143
    /**
144
     * @param QueryBuilder $queryBuilder
145
     * @param Criteria     $criteria
146
     */
147 26
    public function applyLimiting(QueryBuilder $queryBuilder, Criteria $criteria)
148
    {
149 26
        $queryBuilder->setFirstResult($criteria->get('firstResult', 0));
150 26
        if ($criteria->has('maxResults')) {
151 18
            $queryBuilder->setMaxResults($criteria->get('maxResults'));
152
        } else {
153 19
            $queryBuilder->setMaxResults(self::MAX_RESULTS);
154
        }
155 26
    }
156
157
    /**
158
     * @param string $name
159
     * @param string $alias
160
     *
161
     * @return string
162
     */
163 22
    protected function getPropertyName(string $name, string $alias)
164
    {
165 22
        if (false === strpos($name, '.')) {
166 22
            return $alias.'.'.$name;
167
        }
168
169
        return $name;
170
    }
171
}
172