Completed
Push — master ( 9cf27e...6b6682 )
by Julián
01:55
created

getQueryBuilderFromCriteria()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 8.439
c 0
b 0
f 0
cc 6
eloc 17
nc 9
nop 2
1
<?php
2
3
/*
4
 * doctrine-orm-repositories (https://github.com/juliangut/doctrine-orm-repositories).
5
 * Doctrine2 ORM utility entity repositories.
6
 *
7
 * @license MIT
8
 * @link https://github.com/juliangut/doctrine-orm-repositories
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
declare(strict_types=1);
13
14
namespace Jgut\Doctrine\Repository\ORM;
15
16
use Doctrine\Common\Util\ClassUtils;
17
use Doctrine\ORM\EntityManager;
18
use Doctrine\ORM\EntityRepository;
19
use Doctrine\ORM\Query;
20
use Doctrine\ORM\QueryBuilder;
21
use Doctrine\ORM\Tools\Pagination\Paginator as RelationalPaginator;
22
use Jgut\Doctrine\Repository\EventsTrait;
23
use Jgut\Doctrine\Repository\PaginatorTrait;
24
use Jgut\Doctrine\Repository\Repository;
25
use Jgut\Doctrine\Repository\RepositoryTrait;
26
use Rb\Specification\Doctrine\SpecificationAwareInterface;
27
use Rb\Specification\Doctrine\SpecificationRepositoryTrait;
28
use Zend\Paginator\Paginator;
29
30
/**
31
 * Relational entity repository.
32
 */
33
class RelationalRepository extends EntityRepository implements Repository, SpecificationAwareInterface
34
{
35
    use SpecificationRepositoryTrait;
36
    use RepositoryTrait;
37
    use EventsTrait;
38
    use PaginatorTrait;
39
40
    /**
41
     * Class alias.
42
     *
43
     * @var string
44
     */
45
    protected $classAlias;
46
47
    /**
48
     * Get class alias.
49
     *
50
     * @return string
51
     */
52
    protected function getClassAlias(): string
53
    {
54
        if ($this->classAlias === null) {
55
            $this->classAlias = strtoupper($this->getEntityName()[0]);
56
        }
57
58
        return $this->classAlias;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function getClassName(): string
65
    {
66
        return ClassUtils::getRealClass(parent::getClassName());
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    protected function getManager(): EntityManager
73
    {
74
        return $this->getEntityManager();
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     *
80
     * @param array      $criteria
81
     * @param array|null $orderBy
82
     * @param int        $itemsPerPage
83
     *
84
     * @return \Zend\Paginator\Paginator
85
     */
86
    public function findPaginatedBy($criteria, array $orderBy = [], int $itemsPerPage = 10): Paginator
87
    {
88
        $queryBuilder = $this->getQueryBuilderFromCriteria($criteria, $orderBy);
89
90
        return $this->paginate($queryBuilder->getQuery(), $itemsPerPage);
91
    }
92
93
    /**
94
     * Get query builder from criteria array.
95
     *
96
     * @param array $criteria
97
     * @param array $orderBy
98
     *
99
     * @return QueryBuilder
100
     */
101
    protected function getQueryBuilderFromCriteria(array $criteria, array $orderBy = []): QueryBuilder
102
    {
103
        $entityAlias = $this->getClassAlias();
104
        $queryBuilder = $this->createQueryBuilder($entityAlias);
105
106
        foreach ($criteria as $field => $value) {
107
            if (is_null($value)) {
108
                $queryBuilder->andWhere(sprintf('%s.%s IS NULL', $entityAlias, $field));
109
            } else {
110
                $parameter = sprintf('%s_%s', $field, substr(sha1($field), 0, 4));
111
112
                $queryBuilder->andWhere(sprintf('%s.%s = :%s', $entityAlias, $field, $parameter));
113
                $queryBuilder->setParameter($parameter, $value);
114
            }
115
        }
116
117
        if (is_array($orderBy)) {
118
            $entityAlias = count($queryBuilder->getRootAliases())
119
                ? $queryBuilder->getRootAliases()[0]
120
                : $this->getClassAlias();
121
122
            foreach ($orderBy as $field => $order) {
123
                $queryBuilder->addOrderBy($entityAlias . '.' . $field, $order);
124
            }
125
        }
126
127
        return $queryBuilder;
128
    }
129
130
    /**
131
     * Paginate query.
132
     *
133
     * @param Query $query
134
     * @param int   $itemsPerPage
135
     *
136
     * @return Paginator
137
     */
138
    protected function paginate(Query $query, int $itemsPerPage = 10): Paginator
139
    {
140
        return $this->getPaginator(new RelationalPaginatorAdapter(new RelationalPaginator($query)), $itemsPerPage);
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     *
146
     * @param array|QueryBuilder $criteria
147
     *
148
     * @return int
149
     */
150
    public function countBy($criteria): int
151
    {
152
        return $this->getEntityManager()->getUnitOfWork()->getEntityPersister($this->getEntityName())->count($criteria);
153
    }
154
}
155