RelationalRepository::getClassAlias()   A
last analyzed

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 0
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\Collections\ArrayCollection;
17
use Doctrine\Common\Util\ClassUtils;
18
use Doctrine\ORM\EntityManager;
19
use Doctrine\ORM\EntityRepository;
20
use Doctrine\ORM\Query;
21
use Doctrine\ORM\QueryBuilder;
22
use Doctrine\ORM\Tools\Pagination\Paginator as RelationalPaginator;
23
use Happyr\DoctrineSpecification\EntitySpecificationRepositoryInterface;
24
use Happyr\DoctrineSpecification\EntitySpecificationRepositoryTrait;
25
use Jgut\Doctrine\Repository\EventsTrait;
26
use Jgut\Doctrine\Repository\FiltersTrait;
27
use Jgut\Doctrine\Repository\PaginatorTrait;
28
use Jgut\Doctrine\Repository\Repository;
29
use Jgut\Doctrine\Repository\RepositoryTrait;
30
use Zend\Paginator\Paginator;
31
32
/**
33
 * Relational entity repository.
34
 */
35
class RelationalRepository extends EntityRepository implements Repository, EntitySpecificationRepositoryInterface
36
{
37
    use RepositoryTrait;
38
    use EventsTrait;
39
    use FiltersTrait;
40
    use PaginatorTrait;
41
    use EntitySpecificationRepositoryTrait;
42
43
    /**
44
     * Class name.
45
     *
46
     * @var string
47
     */
48
    protected $className;
49
50
    /**
51
     * Class alias.
52
     *
53
     * @var string
54
     */
55
    protected $classAlias;
56
57
    /**
58
     * Get class alias.
59
     *
60
     * @return string
61
     */
62
    protected function getClassAlias(): string
63
    {
64
        if ($this->classAlias === null) {
65
            $this->classAlias = strtoupper($this->getEntityName()[0]);
66
        }
67
68
        return $this->classAlias;
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74
    public function getClassName(): string
75
    {
76
        if ($this->className === null) {
77
            $this->className = ClassUtils::getRealClass($this->getEntityName());
78
        }
79
80
        return $this->className;
81
    }
82
83
    /**
84
     * Finds entities by a set of criteria.
85
     *
86
     * @param array      $criteria
87
     * @param array|null $orderBy
88
     * @param int|null   $limit
89
     * @param int|null   $offset
90
     *
91
     * @return ArrayCollection
92
     *
93
     * @codeCoverageIgnore
94
     */
95
    public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
96
    {
97
        return new ArrayCollection(parent::findBy($criteria, $orderBy, $limit, $offset));
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    protected function getFilterCollection()
104
    {
105
        return $this->getManager()->getFilters();
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111
    protected function getManager(): EntityManager
112
    {
113
        return $this->getEntityManager();
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     *
119
     * @param array      $criteria
120
     * @param array|null $orderBy
121
     * @param int        $itemsPerPage
122
     *
123
     * @return \Zend\Paginator\Paginator
124
     */
125
    public function findPaginatedBy($criteria, array $orderBy = null, int $itemsPerPage = 10): Paginator
126
    {
127
        $queryBuilder = $this->getQueryBuilderFromCriteria($criteria, $orderBy);
128
129
        return $this->paginate($queryBuilder->getQuery(), $itemsPerPage);
130
    }
131
132
    /**
133
     * Get query builder from criteria array.
134
     *
135
     * @param array      $criteria
136
     * @param array|null $orderBy
137
     *
138
     * @return QueryBuilder
139
     */
140
    protected function getQueryBuilderFromCriteria(array $criteria, array $orderBy = null): QueryBuilder
141
    {
142
        $entityAlias = $this->getClassAlias();
143
        $queryBuilder = $this->createQueryBuilder($entityAlias);
144
        $entityAlias = !empty($queryBuilder->getRootAliases()) ? $queryBuilder->getRootAliases()[0] : $entityAlias;
145
146
        foreach ($criteria as $field => $value) {
147
            $this->addQueryCriteria($queryBuilder, $field, $value, $entityAlias);
148
        }
149
150
        if (is_array($orderBy)) {
151
            foreach ($orderBy as $field => $order) {
152
                $queryBuilder->addOrderBy($entityAlias . '.' . $field, $order);
153
            }
154
        }
155
156
        return $queryBuilder;
157
    }
158
159
    /**
160
     * Add query builder criteria.
161
     *
162
     * @param QueryBuilder $queryBuilder
163
     * @param string       $field
164
     * @param mixed        $value
165
     * @param string       $entityAlias
166
     */
167
    protected function addQueryCriteria(QueryBuilder $queryBuilder, string $field, $value, string $entityAlias)
168
    {
169
        if ($value === null) {
170
            $queryBuilder->andWhere(sprintf('%s.%s IS NULL', $entityAlias, $field));
171
        } else {
172
            $placeholder = sprintf('%s_%s', $field, substr(sha1($field), 0, 5));
173
174
            if (is_array($value)) {
175
                $queryBuilder->andWhere(sprintf('%s.%s IN (:%s)', $entityAlias, $field, $placeholder));
176
            } else {
177
                $queryBuilder->andWhere(sprintf('%s.%s = :%s', $entityAlias, $field, $placeholder));
178
            }
179
180
            $queryBuilder->setParameter($placeholder, $value);
181
        }
182
    }
183
184
    /**
185
     * Paginate query.
186
     *
187
     * @param Query $query
188
     * @param int   $itemsPerPage
189
     *
190
     * @return Paginator
191
     */
192
    protected function paginate(Query $query, int $itemsPerPage = 10): Paginator
193
    {
194
        return $this->getPaginator(new RelationalPaginatorAdapter(new RelationalPaginator($query)), $itemsPerPage);
195
    }
196
197
    /**
198
     * {@inheritdoc}
199
     *
200
     * @param array|QueryBuilder $criteria
201
     *
202
     * @return int
203
     */
204
    public function countBy($criteria): int
205
    {
206
        return $this->getEntityManager()->getUnitOfWork()->getEntityPersister($this->getEntityName())->count($criteria);
207
    }
208
209
    /**
210
     * Begin transaction.
211
     */
212
    public function beginTransaction()
213
    {
214
        $this->getManager()->getConnection()->beginTransaction();
215
    }
216
217
    /**
218
     * Commit transaction.
219
     *
220
     * @throws \Doctrine\DBAL\ConnectionException
221
     */
222
    public function commit()
223
    {
224
        $this->getManager()->getConnection()->commit();
225
    }
226
227
    /**
228
     * Rollback transaction.
229
     *
230
     * @throws \Doctrine\DBAL\ConnectionException
231
     */
232
    public function rollBack()
233
    {
234
        $this->getManager()->getConnection()->rollBack();
235
    }
236
}
237