Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / orm / lib / Doctrine / ORM / EntityRepository.php
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\DBAL\LockMode;
23 use Doctrine\Common\Persistence\ObjectRepository;
24
25 use Doctrine\Common\Collections\Selectable;
26 use Doctrine\Common\Collections\Criteria;
27 use Doctrine\Common\Collections\ArrayCollection;
28 use Doctrine\Common\Collections\ExpressionBuilder;
29
30 /**
31  * An EntityRepository serves as a repository for entities with generic as well as
32  * business specific methods for retrieving entities.
33  *
34  * This class is designed for inheritance and users can subclass this class to
35  * write their own repositories with business-specific methods to locate entities.
36  *
37  * @since   2.0
38  * @author  Benjamin Eberlei <kontakt@beberlei.de>
39  * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
40  * @author  Jonathan Wage <jonwage@gmail.com>
41  * @author  Roman Borschel <roman@code-factory.org>
42  */
43 class EntityRepository implements ObjectRepository, Selectable
44 {
45     /**
46      * @var string
47      */
48     protected $_entityName;
49
50     /**
51      * @var EntityManager
52      */
53     protected $_em;
54
55     /**
56      * @var \Doctrine\ORM\Mapping\ClassMetadata
57      */
58     protected $_class;
59
60     /**
61      * Initializes a new <tt>EntityRepository</tt>.
62      *
63      * @param EntityManager $em The EntityManager to use.
64      * @param ClassMetadata $classMetadata The class descriptor.
65      */
66     public function __construct($em, Mapping\ClassMetadata $class)
67     {
68         $this->_entityName = $class->name;
69         $this->_em         = $em;
70         $this->_class      = $class;
71     }
72
73     /**
74      * Create a new QueryBuilder instance that is prepopulated for this entity name
75      *
76      * @param string $alias
77      * @return QueryBuilder $qb
78      */
79     public function createQueryBuilder($alias)
80     {
81         return $this->_em->createQueryBuilder()
82             ->select($alias)
83             ->from($this->_entityName, $alias);
84     }
85
86     /**
87      * Create a new Query instance based on a predefined metadata named query.
88      *
89      * @param string $queryName
90      * @return Query
91      */
92     public function createNamedQuery($queryName)
93     {
94         return $this->_em->createQuery($this->_class->getNamedQuery($queryName));
95     }
96
97     /**
98      * Creates a native SQL query.
99      *
100      * @param string $queryName
101      * @return NativeQuery
102      */
103     public function createNativeNamedQuery($queryName)
104     {
105         $queryMapping   = $this->_class->getNamedNativeQuery($queryName);
106         $rsm            = new Query\ResultSetMappingBuilder($this->_em);
107         $rsm->addNamedNativeQueryMapping($this->_class, $queryMapping);
108
109         return $this->_em->createNativeQuery($queryMapping['query'], $rsm);
110     }
111
112     /**
113      * Clears the repository, causing all managed entities to become detached.
114      */
115     public function clear()
116     {
117         $this->_em->clear($this->_class->rootEntityName);
118     }
119
120     /**
121      * Finds an entity by its primary key / identifier.
122      *
123      * @param mixed $id The identifier.
124      * @param integer $lockMode
125      * @param integer $lockVersion
126      *
127      * @return object The entity.
128      */
129     public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
130     {
131         return $this->_em->find($this->_entityName, $id, $lockMode, $lockVersion);
132     }
133
134     /**
135      * Finds all entities in the repository.
136      *
137      * @return array The entities.
138      */
139     public function findAll()
140     {
141         return $this->findBy(array());
142     }
143
144     /**
145      * Finds entities by a set of criteria.
146      *
147      * @param array $criteria
148      * @param array|null $orderBy
149      * @param int|null $limit
150      * @param int|null $offset
151      * @return array The objects.
152      */
153     public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
154     {
155         $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
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      * @return object
165      */
166     public function findOneBy(array $criteria)
167     {
168         $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
169
170         return $persister->load($criteria, null, null, array(), 0, 1);
171     }
172
173     /**
174      * Adds support for magic finders.
175      *
176      * @return array|object The found entity/entities.
177      * @throws BadMethodCallException  If the method called is an invalid find* method
178      *                                 or no find* method at all and therefore an invalid
179      *                                 method call.
180      */
181     public function __call($method, $arguments)
182     {
183         switch (true) {
184             case (0 === strpos($method, 'findBy')):
185                 $by = substr($method, 6);
186                 $method = 'findBy';
187                 break;
188
189             case (0 === strpos($method, 'findOneBy')):
190                 $by = substr($method, 9);
191                 $method = 'findOneBy';
192                 break;
193
194             default:
195                 throw new \BadMethodCallException(
196                     "Undefined method '$method'. The method name must start with ".
197                     "either findBy or findOneBy!"
198                 );
199         }
200
201         if (empty($arguments)) {
202             throw ORMException::findByRequiresParameter($method . $by);
203         }
204
205         $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
206
207         if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) {
208             switch (count($arguments)) {
209                 case 1:
210                     return $this->$method(array($fieldName => $arguments[0]));
211
212                 case 2:
213                     return $this->$method(array($fieldName => $arguments[0]), $arguments[1]);
214
215                 case 3:
216                     return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
217
218                 case 4;
219                     return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
220
221                 default:
222                     // Do nothing
223             }
224         }
225
226         throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
227     }
228
229     /**
230      * @return string
231      */
232     protected function getEntityName()
233     {
234         return $this->_entityName;
235     }
236
237     /**
238      * @return string
239      */
240     public function getClassName()
241     {
242         return $this->getEntityName();
243     }
244
245     /**
246      * @return EntityManager
247      */
248     protected function getEntityManager()
249     {
250         return $this->_em;
251     }
252
253     /**
254      * @return Mapping\ClassMetadata
255      */
256     protected function getClassMetadata()
257     {
258         return $this->_class;
259     }
260
261     /**
262      * Select all elements from a selectable that match the expression and
263      * return a new collection containing these elements.
264      *
265      * @param \Doctrine\Common\Collections\Criteria $criteria
266      *
267      * @return \Doctrine\Common\Collections\Collection
268      */
269     public function matching(Criteria $criteria)
270     {
271         $persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
272
273         return new ArrayCollection($persister->loadCriteria($criteria));
274     }
275 }
276