vendor/doctrine/orm/lib/Doctrine/ORM/EntityRepository.php line 189

Open in your IDE?
  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. namespace Doctrine\ORM;
  20. use Doctrine\Common\Collections\Criteria;
  21. use Doctrine\Common\Collections\Selectable;
  22. use Doctrine\Common\Inflector\Inflector;
  23. use Doctrine\ORM\Query\ResultSetMappingBuilder;
  24. use Doctrine\Persistence\ObjectRepository;
  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 ObjectRepositorySelectable
  39. {
  40.     /**
  41.      * @var string
  42.      */
  43.     protected $_entityName;
  44.     /**
  45.      * @var EntityManager
  46.      */
  47.     protected $_em;
  48.     /**
  49.      * @var \Doctrine\ORM\Mapping\ClassMetadata
  50.      */
  51.     protected $_class;
  52.     /**
  53.      * Initializes a new <tt>EntityRepository</tt>.
  54.      */
  55.     public function __construct(EntityManagerInterface $emMapping\ClassMetadata $class)
  56.     {
  57.         $this->_entityName $class->name;
  58.         $this->_em         $em;
  59.         $this->_class      $class;
  60.     }
  61.     /**
  62.      * Creates a new QueryBuilder instance that is prepopulated for this entity name.
  63.      *
  64.      * @param string $alias
  65.      * @param string $indexBy The index for the from.
  66.      *
  67.      * @return QueryBuilder
  68.      */
  69.     public function createQueryBuilder($alias$indexBy null)
  70.     {
  71.         return $this->_em->createQueryBuilder()
  72.             ->select($alias)
  73.             ->from($this->_entityName$alias$indexBy);
  74.     }
  75.     /**
  76.      * Creates a new result set mapping builder for this entity.
  77.      *
  78.      * The column naming strategy is "INCREMENT".
  79.      *
  80.      * @param string $alias
  81.      *
  82.      * @return ResultSetMappingBuilder
  83.      */
  84.     public function createResultSetMappingBuilder($alias)
  85.     {
  86.         $rsm = new ResultSetMappingBuilder($this->_emResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);
  87.         $rsm->addRootEntityFromClassMetadata($this->_entityName$alias);
  88.         return $rsm;
  89.     }
  90.     /**
  91.      * Creates a new Query instance based on a predefined metadata named query.
  92.      *
  93.      * @param string $queryName
  94.      *
  95.      * @return Query
  96.      */
  97.     public function createNamedQuery($queryName)
  98.     {
  99.         return $this->_em->createQuery($this->_class->getNamedQuery($queryName));
  100.     }
  101.     /**
  102.      * Creates a native SQL query.
  103.      *
  104.      * @param string $queryName
  105.      *
  106.      * @return NativeQuery
  107.      */
  108.     public function createNativeNamedQuery($queryName)
  109.     {
  110.         $queryMapping   $this->_class->getNamedNativeQuery($queryName);
  111.         $rsm            = new Query\ResultSetMappingBuilder($this->_em);
  112.         $rsm->addNamedNativeQueryMapping($this->_class$queryMapping);
  113.         return $this->_em->createNativeQuery($queryMapping['query'], $rsm);
  114.     }
  115.     /**
  116.      * Clears the repository, causing all managed entities to become detached.
  117.      *
  118.      * @return void
  119.      */
  120.     public function clear()
  121.     {
  122.         $this->_em->clear($this->_class->rootEntityName);
  123.     }
  124.     /**
  125.      * Finds an entity by its primary key / identifier.
  126.      *
  127.      * @param mixed    $id          The identifier.
  128.      * @param int|null $lockMode    One of the \Doctrine\DBAL\LockMode::* constants
  129.      *                              or NULL if no specific lock mode should be used
  130.      *                              during the search.
  131.      * @param int|null $lockVersion The lock version.
  132.      *
  133.      * @return object|null The entity instance or NULL if the entity can not be found.
  134.      */
  135.     public function find($id$lockMode null$lockVersion null)
  136.     {
  137.         return $this->_em->find($this->_entityName$id$lockMode$lockVersion);
  138.     }
  139.     /**
  140.      * Finds all entities in the repository.
  141.      *
  142.      * @return array The entities.
  143.      */
  144.     public function findAll()
  145.     {
  146.         return $this->findBy([]);
  147.     }
  148.     /**
  149.      * Finds entities by a set of criteria.
  150.      *
  151.      * @param array      $criteria
  152.      * @param array|null $orderBy
  153.      * @param int|null   $limit
  154.      * @param int|null   $offset
  155.      *
  156.      * @return array The objects.
  157.      */
  158.     public function findBy(array $criteria, array $orderBy null$limit null$offset null)
  159.     {
  160.         $persister $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
  161.         return $persister->loadAll($criteria$orderBy$limit$offset);
  162.     }
  163.     /**
  164.      * Finds a single entity by a set of criteria.
  165.      *
  166.      * @param array      $criteria
  167.      * @param array|null $orderBy
  168.      *
  169.      * @return object|null The entity instance or NULL if the entity can not be found.
  170.      */
  171.     public function findOneBy(array $criteria, array $orderBy null)
  172.     {
  173.         $persister $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
  174.         return $persister->load($criterianullnull, [], null1$orderBy);
  175.     }
  176.     /**
  177.      * Counts entities by a set of criteria.
  178.      *
  179.      * @todo Add this method to `ObjectRepository` interface in the next major release
  180.      *
  181.      * @param array $criteria
  182.      *
  183.      * @return int The cardinality of the objects that match the given criteria.
  184.      */
  185.     public function count(array $criteria)
  186.     {
  187.         return $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName)->count($criteria);
  188.     }
  189.     /**
  190.      * Adds support for magic method calls.
  191.      *
  192.      * @param string $method
  193.      * @param array  $arguments
  194.      *
  195.      * @return mixed The returned value from the resolved method.
  196.      *
  197.      * @throws ORMException
  198.      * @throws \BadMethodCallException If the method called is invalid
  199.      */
  200.     public function __call($method$arguments)
  201.     {
  202.         if (=== strpos($method'findBy')) {
  203.             return $this->resolveMagicCall('findBy'substr($method6), $arguments);
  204.         }
  205.         if (=== strpos($method'findOneBy')) {
  206.             return $this->resolveMagicCall('findOneBy'substr($method9), $arguments);
  207.         }
  208.         if (=== strpos($method'countBy')) {
  209.             return $this->resolveMagicCall('count'substr($method7), $arguments);
  210.         }
  211.         throw new \BadMethodCallException(
  212.             "Undefined method '$method'. The method name must start with ".
  213.             "either findBy, findOneBy or countBy!"
  214.         );
  215.     }
  216.     /**
  217.      * @return string
  218.      */
  219.     protected function getEntityName()
  220.     {
  221.         return $this->_entityName;
  222.     }
  223.     /**
  224.      * @return string
  225.      */
  226.     public function getClassName()
  227.     {
  228.         return $this->getEntityName();
  229.     }
  230.     /**
  231.      * @return EntityManager
  232.      */
  233.     protected function getEntityManager()
  234.     {
  235.         return $this->_em;
  236.     }
  237.     /**
  238.      * @return Mapping\ClassMetadata
  239.      */
  240.     protected function getClassMetadata()
  241.     {
  242.         return $this->_class;
  243.     }
  244.     /**
  245.      * Select all elements from a selectable that match the expression and
  246.      * return a new collection containing these elements.
  247.      *
  248.      * @param \Doctrine\Common\Collections\Criteria $criteria
  249.      *
  250.      * @return \Doctrine\Common\Collections\Collection
  251.      */
  252.     public function matching(Criteria $criteria)
  253.     {
  254.         $persister $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
  255.         return new LazyCriteriaCollection($persister$criteria);
  256.     }
  257.     /**
  258.      * Resolves a magic method call to the proper existent method at `EntityRepository`.
  259.      *
  260.      * @param string $method    The method to call
  261.      * @param string $by        The property name used as condition
  262.      * @param array  $arguments The arguments to pass at method call
  263.      *
  264.      * @throws ORMException If the method called is invalid or the requested field/association does not exist
  265.      *
  266.      * @return mixed
  267.      */
  268.     private function resolveMagicCall($method$by, array $arguments)
  269.     {
  270.         if (! $arguments) {
  271.             throw ORMException::findByRequiresParameter($method $by);
  272.         }
  273.         $fieldName lcfirst(Inflector::classify($by));
  274.         if (! ($this->_class->hasField($fieldName) || $this->_class->hasAssociation($fieldName))) {
  275.             throw ORMException::invalidMagicCall($this->_entityName$fieldName$method $by);
  276.         }
  277.         return $this->$method([$fieldName => $arguments[0]], ...array_slice($arguments1));
  278.     }
  279. }