Completed
Push — master ( c05768...f75231 )
by Julián
01:49
created

RelationalRepository::commit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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