Completed
Pull Request — master (#5713)
by Ondřej
14:07
created

EntityRepository::getEntityManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ORM;
21
22
use Doctrine\ORM\EntityManagerInterface;
23
use Doctrine\ORM\Query\ResultSetMappingBuilder;
24
use Doctrine\Common\Persistence\ObjectRepository;
25
use Doctrine\Common\Collections\Selectable;
26
use Doctrine\Common\Collections\Criteria;
27
28
/**
29
 * An EntityRepository serves as a repository for entities with generic as well as
30
 * business specific methods for retrieving entities.
31
 *
32
 * This class is designed for inheritance and users can subclass this class to
33
 * write their own repositories with business-specific methods to locate entities.
34
 *
35
 * @since   2.0
36
 * @author  Benjamin Eberlei <[email protected]>
37
 * @author  Guilherme Blanco <[email protected]>
38
 * @author  Jonathan Wage <[email protected]>
39
 * @author  Roman Borschel <[email protected]>
40
 */
41
class EntityRepository implements ObjectRepository, Selectable
42
{
43
    /**
44
     * @var string
45
     */
46
    protected $_entityName;
47
48
    /**
49
     * @var EntityManager
50
     */
51
    protected $_em;
52
53
    /**
54
     * @var \Doctrine\ORM\Mapping\ClassMetadata
55
     */
56
    protected $_class;
57
58
    /**
59
     * Initializes a new <tt>EntityRepository</tt>.
60
     *
61
     * @param EntityManager         $em    The EntityManager to use.
62
     * @param Mapping\ClassMetadata $class The class descriptor.
63
     */
64 144
    public function __construct(EntityManagerInterface $em, Mapping\ClassMetadata $class)
65
    {
66 144
        $this->_entityName = $class->name;
67 144
        $this->_em         = $em;
0 ignored issues
show
Documentation Bug introduced by
$em is of type object<Doctrine\ORM\EntityManagerInterface>, but the property $_em was declared to be of type object<Doctrine\ORM\EntityManager>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
68 144
        $this->_class      = $class;
69 144
    }
70
71
    /**
72
     * Creates a new QueryBuilder instance that is prepopulated for this entity name.
73
     *
74
     * @param string $alias
75
     * @param string $indexBy The index for the from.
76
     *
77
     * @return QueryBuilder
78
     */
79 6
    public function createQueryBuilder($alias, $indexBy = null)
80
    {
81 6
        return $this->_em->createQueryBuilder()
82 6
            ->select($alias)
83 6
            ->from($this->_entityName, $alias, $indexBy);
84
    }
85
86
    /**
87
     * Creates a new result set mapping builder for this entity.
88
     *
89
     * The column naming strategy is "INCREMENT".
90
     *
91
     * @param string $alias
92
     *
93
     * @return ResultSetMappingBuilder
94
     */
95 1
    public function createResultSetMappingBuilder($alias)
96
    {
97 1
        $rsm = new ResultSetMappingBuilder($this->_em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);
98 1
        $rsm->addRootEntityFromClassMetadata($this->_entityName, $alias);
99
100 1
        return $rsm;
101
    }
102
103
    /**
104
     * Creates a new Query instance based on a predefined metadata named query.
105
     *
106
     * @param string $queryName
107
     *
108
     * @return Query
109
     */
110 3
    public function createNamedQuery($queryName)
111
    {
112 3
        return $this->_em->createQuery($this->_class->getNamedQuery($queryName));
113
    }
114
115
    /**
116
     * Creates a native SQL query.
117
     *
118
     * @param string $queryName
119
     *
120
     * @return NativeQuery
121
     */
122 7
    public function createNativeNamedQuery($queryName)
123
    {
124 7
        $queryMapping   = $this->_class->getNamedNativeQuery($queryName);
125 7
        $rsm            = new Query\ResultSetMappingBuilder($this->_em);
126 7
        $rsm->addNamedNativeQueryMapping($this->_class, $queryMapping);
127
128 7
        return $this->_em->createNativeQuery($queryMapping['query'], $rsm);
129
    }
130
131
    /**
132
     * Clears the repository, causing all managed entities to become detached.
133
     *
134
     * @return void
135
     */
136
    public function clear()
137
    {
138
        $this->_em->clear($this->_class->rootEntityName);
139
    }
140
141
    /**
142
     * Finds an entity by its primary key / identifier.
143
     *
144
     * @param mixed    $id          The identifier.
145
     * @param int|null $lockMode    One of the \Doctrine\DBAL\LockMode::* constants
146
     *                              or NULL if no specific lock mode should be used
147
     *                              during the search.
148
     * @param int|null $lockVersion The lock version.
149
     *
150
     * @return object|null The entity instance or NULL if the entity can not be found.
151
     */
152 14
    public function find($id, $lockMode = null, $lockVersion = null)
153
    {
154 14
        return $this->_em->find($this->_entityName, $id, $lockMode, $lockVersion);
155
    }
156
157
    /**
158
     * Finds all entities in the repository.
159
     *
160
     * @return array The entities.
161
     */
162 30
    public function findAll()
163
    {
164 30
        return $this->findBy(array());
165
    }
166
167
    /**
168
     * Finds entities by a set of criteria.
169
     *
170
     * @param array      $criteria
171
     * @param array|null $orderBy
172
     * @param int|null   $limit
173
     * @param int|null   $offset
174
     *
175
     * @return array The objects.
176
     */
177 60
    public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
178
    {
179 60
        $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
180
181 60
        return $persister->loadAll($criteria, $orderBy, $limit, $offset);
182
    }
183
184
    /**
185
     * Finds a single entity by a set of criteria.
186
     *
187
     * @param array      $criteria
188
     * @param array|null $orderBy
189
     *
190
     * @return object|null The entity instance or NULL if the entity can not be found.
191
     */
192 21
    public function findOneBy(array $criteria, array $orderBy = null)
193
    {
194 21
        $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
195
196 21
        return $persister->load($criteria, null, null, array(), null, 1, $orderBy);
197
    }
198
199
    /**
200
     * Adds support for magic finders.
201
     *
202
     * @param string $method
203
     * @param array  $arguments
204
     *
205
     * @return array|object The found entity/entities.
206
     *
207
     * @throws ORMException
208
     * @throws \BadMethodCallException If the method called is an invalid find* method
209
     *                                 or no find* method at all and therefore an invalid
210
     *                                 method call.
211
     */
212 12
    public function __call($method, $arguments)
213
    {
214
        switch (true) {
215 12
            case (0 === strpos($method, 'findBy')):
216 8
                $by = substr($method, 6);
217 8
                $method = 'findBy';
218 8
                break;
219
220 4
            case (0 === strpos($method, 'findOneBy')):
221 3
                $by = substr($method, 9);
222 3
                $method = 'findOneBy';
223 3
                break;
224
225
            default:
226 1
                throw new \BadMethodCallException(
227 1
                    "Undefined method '$method'. The method name must start with ".
228 1
                    "either findBy or findOneBy!"
229
                );
230
        }
231
232 11
        if (empty($arguments)) {
233 1
            throw ORMException::findByRequiresParameter($method . $by);
234
        }
235
236 10
        $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
237
238 10
        if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) {
239 9
            switch (count($arguments)) {
240 9
                case 1:
241 7
                    return $this->$method(array($fieldName => $arguments[0]));
242
243 2
                case 2:
244 1
                    return $this->$method(array($fieldName => $arguments[0]), $arguments[1]);
245
246 1
                case 3:
247
                    return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
248
249 1
                case 4:
250 1
                    return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
251
252
                default:
253
                    // Do nothing
254
            }
255
        }
256
257 1
        throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
258
    }
259
260
    /**
261
     * @return string
262
     */
263
    protected function getEntityName()
264
    {
265
        return $this->_entityName;
266
    }
267
268
    /**
269
     * @return string
270
     */
271
    public function getClassName()
272
    {
273
        return $this->getEntityName();
274
    }
275
276
    /**
277
     * @return EntityManager
278
     */
279
    protected function getEntityManager()
280
    {
281
        return $this->_em;
282
    }
283
284
    /**
285
     * @return Mapping\ClassMetadata
286
     */
287
    protected function getClassMetadata()
288
    {
289
        return $this->_class;
290
    }
291
292
    /**
293
     * Select all elements from a selectable that match the expression and
294
     * return a new collection containing these elements.
295
     *
296
     * @param \Doctrine\Common\Collections\Criteria $criteria
297
     *
298
     * @return \Doctrine\Common\Collections\Collection
299
     */
300 24
    public function matching(Criteria $criteria)
301
    {
302 24
        $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
303
304 24
        return new LazyCriteriaCollection($persister, $criteria);
305
    }
306
}
307