vendor/doctrine/lib/Doctrine/ORM/EntityRepository.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     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 LGPL. 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 /**
       
    26  * An EntityRepository serves as a repository for entities with generic as well as
       
    27  * business specific methods for retrieving entities.
       
    28  *
       
    29  * This class is designed for inheritance and users can subclass this class to
       
    30  * write their own repositories with business-specific methods to locate entities.
       
    31  *
       
    32  * @since   2.0
       
    33  * @author  Benjamin Eberlei <kontakt@beberlei.de>
       
    34  * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
       
    35  * @author  Jonathan Wage <jonwage@gmail.com>
       
    36  * @author  Roman Borschel <roman@code-factory.org>
       
    37  */
       
    38 class EntityRepository implements ObjectRepository
       
    39 {
       
    40     /**
       
    41      * @var string
       
    42      */
       
    43     protected $_entityName;
       
    44 
       
    45     /**
       
    46      * @var EntityManager
       
    47      */
       
    48     protected $_em;
       
    49 
       
    50     /**
       
    51      * @var Doctrine\ORM\Mapping\ClassMetadata
       
    52      */
       
    53     protected $_class;
       
    54 
       
    55     /**
       
    56      * Initializes a new <tt>EntityRepository</tt>.
       
    57      *
       
    58      * @param EntityManager $em The EntityManager to use.
       
    59      * @param ClassMetadata $classMetadata The class descriptor.
       
    60      */
       
    61     public function __construct($em, Mapping\ClassMetadata $class)
       
    62     {
       
    63         $this->_entityName = $class->name;
       
    64         $this->_em = $em;
       
    65         $this->_class = $class;
       
    66     }
       
    67 
       
    68     /**
       
    69      * Create a new QueryBuilder instance that is prepopulated for this entity name
       
    70      *
       
    71      * @param string $alias
       
    72      * @return QueryBuilder $qb
       
    73      */
       
    74     public function createQueryBuilder($alias)
       
    75     {
       
    76         return $this->_em->createQueryBuilder()
       
    77             ->select($alias)
       
    78             ->from($this->_entityName, $alias);
       
    79     }
       
    80 
       
    81     /**
       
    82      * Create a new Query instance based on a predefined metadata named query.
       
    83      *
       
    84      * @param string $queryName
       
    85      * @return Query
       
    86      */
       
    87     public function createNamedQuery($queryName)
       
    88     {
       
    89         return $this->_em->createQuery($this->_class->getNamedQuery($queryName));
       
    90     }
       
    91 
       
    92     /**
       
    93      * Clears the repository, causing all managed entities to become detached.
       
    94      */
       
    95     public function clear()
       
    96     {
       
    97         $this->_em->clear($this->_class->rootEntityName);
       
    98     }
       
    99 
       
   100     /**
       
   101      * Finds an entity by its primary key / identifier.
       
   102      *
       
   103      * @param $id The identifier.
       
   104      * @param int $lockMode
       
   105      * @param int $lockVersion
       
   106      * @return object The entity.
       
   107      */
       
   108     public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
       
   109     {
       
   110         // Check identity map first
       
   111         if ($entity = $this->_em->getUnitOfWork()->tryGetById($id, $this->_class->rootEntityName)) {
       
   112             if (!($entity instanceof $this->_class->name)) {
       
   113                 return null;
       
   114             }
       
   115             
       
   116             if ($lockMode != LockMode::NONE) {
       
   117                 $this->_em->lock($entity, $lockMode, $lockVersion);
       
   118             }
       
   119 
       
   120             return $entity; // Hit!
       
   121         }
       
   122 
       
   123         if ( ! is_array($id) || count($id) <= 1) {
       
   124             // @todo FIXME: Not correct. Relies on specific order.
       
   125             $value = is_array($id) ? array_values($id) : array($id);
       
   126             $id = array_combine($this->_class->identifier, $value);
       
   127         }
       
   128 
       
   129         if ($lockMode == LockMode::NONE) {
       
   130             return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);
       
   131         } else if ($lockMode == LockMode::OPTIMISTIC) {
       
   132             if (!$this->_class->isVersioned) {
       
   133                 throw OptimisticLockException::notVersioned($this->_entityName);
       
   134             }
       
   135             $entity = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id);
       
   136 
       
   137             $this->_em->getUnitOfWork()->lock($entity, $lockMode, $lockVersion);
       
   138 
       
   139             return $entity;
       
   140         } else {
       
   141             if (!$this->_em->getConnection()->isTransactionActive()) {
       
   142                 throw TransactionRequiredException::transactionRequired();
       
   143             }
       
   144             
       
   145             return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($id, null, null, array(), $lockMode);
       
   146         }
       
   147     }
       
   148 
       
   149     /**
       
   150      * Finds all entities in the repository.
       
   151      *
       
   152      * @return array The entities.
       
   153      */
       
   154     public function findAll()
       
   155     {
       
   156         return $this->findBy(array());
       
   157     }
       
   158 
       
   159     /**
       
   160      * Finds entities by a set of criteria.
       
   161      *
       
   162      * @param array $criteria
       
   163      * @param array|null $orderBy
       
   164      * @param int|null $limit
       
   165      * @param int|null $offset
       
   166      * @return array The objects.
       
   167      */
       
   168     public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
       
   169     {
       
   170         return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->loadAll($criteria, $orderBy, $limit, $offset);
       
   171     }
       
   172 
       
   173     /**
       
   174      * Finds a single entity by a set of criteria.
       
   175      *
       
   176      * @param array $criteria
       
   177      * @return object
       
   178      */
       
   179     public function findOneBy(array $criteria)
       
   180     {
       
   181         return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->load($criteria);
       
   182     }
       
   183 
       
   184     /**
       
   185      * Adds support for magic finders.
       
   186      *
       
   187      * @return array|object The found entity/entities.
       
   188      * @throws BadMethodCallException  If the method called is an invalid find* method
       
   189      *                                 or no find* method at all and therefore an invalid
       
   190      *                                 method call.
       
   191      */
       
   192     public function __call($method, $arguments)
       
   193     {
       
   194         if (substr($method, 0, 6) == 'findBy') {
       
   195             $by = substr($method, 6, strlen($method));
       
   196             $method = 'findBy';
       
   197         } else if (substr($method, 0, 9) == 'findOneBy') {
       
   198             $by = substr($method, 9, strlen($method));
       
   199             $method = 'findOneBy';
       
   200         } else {
       
   201             throw new \BadMethodCallException(
       
   202                 "Undefined method '$method'. The method name must start with ".
       
   203                 "either findBy or findOneBy!"
       
   204             );
       
   205         }
       
   206 
       
   207         if ( !isset($arguments[0])) {
       
   208             // we dont even want to allow null at this point, because we cannot (yet) transform it into IS NULL.
       
   209             throw ORMException::findByRequiresParameter($method.$by);
       
   210         }
       
   211 
       
   212         $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
       
   213 
       
   214         if ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName)) {
       
   215             return $this->$method(array($fieldName => $arguments[0]));
       
   216         } else {
       
   217             throw ORMException::invalidFindByCall($this->_entityName, $fieldName, $method.$by);
       
   218         }
       
   219     }
       
   220 
       
   221     /**
       
   222      * @return string
       
   223      */
       
   224     protected function getEntityName()
       
   225     {
       
   226         return $this->_entityName;
       
   227     }
       
   228 
       
   229     /**
       
   230      * @return EntityManager
       
   231      */
       
   232     protected function getEntityManager()
       
   233     {
       
   234         return $this->_em;
       
   235     }
       
   236 
       
   237     /**
       
   238      * @return Mapping\ClassMetadata
       
   239      */
       
   240     protected function getClassMetadata()
       
   241     {
       
   242         return $this->_class;
       
   243     }
       
   244 }