Completed
Pull Request — master (#719)
by
unknown
02:18
created

RepositoryTrait::matching()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Doctrine Bundle
5
 *
6
 * The code was originally distributed inside the Symfony framework.
7
 *
8
 * (c) Fabien Potencier <[email protected]>
9
 * (c) Doctrine Project, Benjamin Eberlei <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Doctrine\Bundle\DoctrineBundle\Repository;
16
17
use Doctrine\Common\Collections\Criteria;
18
use Doctrine\ORM\EntityManager;
19
use Doctrine\ORM\LazyCriteriaCollection;
20
use Doctrine\ORM\NativeQuery;
21
use Doctrine\ORM\ORMException;
22
use Doctrine\ORM\Query;
23
use Doctrine\ORM\Query\ResultSetMappingBuilder;
24
use Doctrine\ORM\QueryBuilder;
25
26
/**
27
 * A helpful trait when creating your own repository.
28
 *
29
 * @author Ryan Weaver <[email protected]>
30
 */
31
trait RepositoryTrait
32
{
33
    /**
34
     * @return EntityManager
35
     */
36
    abstract protected function getEntityManager();
37
38
    /**
39
     * Returns the class name for this entity.
40
     *
41
     * This method is public to more naturally match ObjectRepository.
42
     *
43
     * @return string
44
     */
45
    abstract public function getClassName();
46
47
    /**
48
     * Creates a new QueryBuilder instance that is prepopulated for this entity name.
49
     *
50
     * @param string $alias
51
     * @param string $indexBy The index for the from.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $indexBy not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
52
     *
53
     * @return QueryBuilder
54
     */
55
    public function createQueryBuilder($alias, $indexBy = null)
56
    {
57
        return $this->getEntityManager()->createQueryBuilder()
58
            ->select($alias)
59
            ->from($this->getClassName(), $alias, $indexBy);
60
    }
61
62
    /**
63
     * Creates a new result set mapping builder for this entity.
64
     *
65
     * The column naming strategy is "INCREMENT".
66
     *
67
     * @param string $alias
68
     *
69
     * @return ResultSetMappingBuilder
70
     */
71
    public function createResultSetMappingBuilder($alias)
72
    {
73
        $rsm = new ResultSetMappingBuilder($this->getEntityManager(), ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);
74
        $rsm->addRootEntityFromClassMetadata($this->getClassName(), $alias);
75
76
        return $rsm;
77
    }
78
79
    /**
80
     * Creates a new Query instance based on a predefined metadata named query.
81
     *
82
     * @param string $queryName
83
     *
84
     * @return Query
85
     */
86
    public function createNamedQuery($queryName)
87
    {
88
        return $this->getEntityManager()->createQuery($this->getClassMetadata()->getNamedQuery($queryName));
89
    }
90
91
    /**
92
     * Creates a native SQL query.
93
     *
94
     * @param string $queryName
95
     *
96
     * @return NativeQuery
97
     */
98
    public function createNativeNamedQuery($queryName)
99
    {
100
        $queryMapping = $this->getClassMetadata()->getNamedNativeQuery($queryName);
101
        $rsm = new Query\ResultSetMappingBuilder($this->getEntityManager());
102
        $rsm->addNamedNativeQueryMapping($this->getClassMetadata(), $queryMapping);
103
104
        return $this->getEntityManager()->createNativeQuery($queryMapping['query'], $rsm);
105
    }
106
107
    /**
108
     * Clears the repository, causing all managed entities to become detached.
109
     *
110
     * @return void
111
     */
112
    public function clear()
113
    {
114
        $this->getEntityManager()->clear($this->getClassMetadata()->rootEntityName);
115
    }
116
117
    /**
118
     * Finds an entity by its primary key / identifier.
119
     *
120
     * @param mixed $id The identifier.
121
     * @param int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants
122
     *                              or NULL if no specific lock mode should be used
123
     *                              during the search.
124
     * @param int|null $lockVersion The lock version.
125
     *
126
     * @return object|null The entity instance or NULL if the entity can not be found.
127
     */
128
    public function find($id, $lockMode = null, $lockVersion = null)
129
    {
130
        return $this->getEntityManager()->find($this->getClassName(), $id, $lockMode, $lockVersion);
131
    }
132
133
    /**
134
     * Finds all entities in the repository.
135
     *
136
     * @return array The entities.
137
     */
138
    public function findAll()
139
    {
140
        return $this->findBy(array());
141
    }
142
143
    /**
144
     * Finds entities by a set of criteria.
145
     *
146
     * @param array $criteria
147
     * @param array|null $orderBy
148
     * @param int|null $limit
149
     * @param int|null $offset
150
     *
151
     * @return array The objects.
152
     */
153
    public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
154
    {
155
        $persister = $this->getEntityManager()->getUnitOfWork()->getEntityPersister($this->getClassName());
156
157
        return $persister->loadAll($criteria, $orderBy, $limit, $offset);
158
    }
159
160
    /**
161
     * Finds a single entity by a set of criteria.
162
     *
163
     * @param array $criteria
164
     * @param array|null $orderBy
165
     *
166
     * @return object|null The entity instance or NULL if the entity can not be found.
167
     */
168
    public function findOneBy(array $criteria, array $orderBy = null)
169
    {
170
        $persister = $this->getEntityManager()->getUnitOfWork()->getEntityPersister($this->getClassName());
171
172
        return $persister->load($criteria, null, null, array(), null, 1, $orderBy);
173
    }
174
175
    /**
176
     * Adds support for magic finders.
177
     *
178
     * @param string $method
179
     * @param array $arguments
180
     *
181
     * @return array|object The found entity/entities.
182
     *
183
     * @throws ORMException
184
     * @throws \BadMethodCallException If the method called is an invalid find* method
185
     *                                 or no find* method at all and therefore an invalid
186
     *                                 method call.
187
     */
188
    public function __call($method, $arguments)
189
    {
190
        switch (true) {
191
            case (0 === strpos($method, 'findBy')):
192
                $by = substr($method, 6);
193
                $method = 'findBy';
194
                break;
195
196
            case (0 === strpos($method, 'findOneBy')):
197
                $by = substr($method, 9);
198
                $method = 'findOneBy';
199
                break;
200
201
            default:
202
                throw new \BadMethodCallException(
203
                    "Undefined method '$method'. The method name must start with " .
204
                    "either findBy or findOneBy!"
205
                );
206
        }
207
208
        if (empty($arguments)) {
209
            throw ORMException::findByRequiresParameter($method . $by);
210
        }
211
212
        $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
213
214
        if ($this->getClassMetadata()->hasField($fieldName) || $this->getClassMetadata()->hasAssociation($fieldName)) {
215
            switch (count($arguments)) {
216
                case 1:
217
                    return $this->$method(array($fieldName => $arguments[0]));
218
219
                case 2:
220
                    return $this->$method(array($fieldName => $arguments[0]), $arguments[1]);
221
222 View Code Duplication
                case 3:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
223
                    return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
224
225 View Code Duplication
                case 4:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
226
                    return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
227
228
                default:
229
                    // Do nothing
230
            }
231
        }
232
233
        throw ORMException::invalidFindByCall($this->getClassName(), $fieldName, $method . $by);
234
    }
235
236
    /**
237
     * Select all elements from a selectable that match the expression and
238
     * return a new collection containing these elements.
239
     *
240
     * @param \Doctrine\Common\Collections\Criteria $criteria
241
     *
242
     * @return \Doctrine\Common\Collections\Collection
243
     */
244
    public function matching(Criteria $criteria)
245
    {
246
        $persister = $this->getEntityManager()->getUnitOfWork()->getEntityPersister($this->getClassName());
247
248
        return new LazyCriteriaCollection($persister, $criteria);
249
    }
250
251
    /**
252
     * @return \Doctrine\ORM\Mapping\ClassMetadata
253
     */
254
    private function getClassMetadata()
255
    {
256
        return $this->getEntityManager()->getClassMetadata($this->getClassName());
257
    }
258
}
259