vendor/gedmo/doctrine-extensions/src/Tree/Entity/Repository/AbstractTreeRepository.php line 44

  1. <?php
  2. /*
  3.  * This file is part of the Doctrine Behavioral Extensions package.
  4.  * (c) Gediminas Morkevicius <gediminas.morkevicius@gmail.com> http://www.gediminasm.org
  5.  * For the full copyright and license information, please view the LICENSE
  6.  * file that was distributed with this source code.
  7.  */
  8. namespace Gedmo\Tree\Entity\Repository;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use Doctrine\ORM\EntityRepository;
  11. use Doctrine\ORM\Mapping\ClassMetadata;
  12. use Doctrine\ORM\Query;
  13. use Doctrine\ORM\QueryBuilder;
  14. use Gedmo\Exception\InvalidArgumentException;
  15. use Gedmo\Tool\Wrapper\EntityWrapper;
  16. use Gedmo\Tree\RepositoryInterface;
  17. use Gedmo\Tree\RepositoryUtils;
  18. use Gedmo\Tree\RepositoryUtilsInterface;
  19. use Gedmo\Tree\TreeListener;
  20. abstract class AbstractTreeRepository extends EntityRepository implements RepositoryInterface
  21. {
  22.     /**
  23.      * Tree listener on event manager
  24.      *
  25.      * @var TreeListener
  26.      */
  27.     protected $listener;
  28.     /**
  29.      * Repository utils
  30.      *
  31.      * @var RepositoryUtilsInterface
  32.      */
  33.     protected $repoUtils;
  34.     public function __construct(EntityManagerInterface $emClassMetadata $class)
  35.     {
  36.         parent::__construct($em$class);
  37.         $treeListener null;
  38.         foreach ($em->getEventManager()->getAllListeners() as $listeners) {
  39.             foreach ($listeners as $listener) {
  40.                 if ($listener instanceof TreeListener) {
  41.                     $treeListener $listener;
  42.                     break 2;
  43.                 }
  44.             }
  45.         }
  46.         if (null === $treeListener) {
  47.             throw new \Gedmo\Exception\InvalidMappingException('Tree listener was not found on your entity manager, it must be hooked into the event manager');
  48.         }
  49.         $this->listener $treeListener;
  50.         if (!$this->validate()) {
  51.             throw new \Gedmo\Exception\InvalidMappingException('This repository cannot be used for tree type: '.$treeListener->getStrategy($em$class->getName())->getName());
  52.         }
  53.         $this->repoUtils = new RepositoryUtils($this->_em$this->getClassMetadata(), $this->listener$this);
  54.     }
  55.     /**
  56.      * Sets the RepositoryUtilsInterface instance
  57.      *
  58.      * @return static
  59.      */
  60.     public function setRepoUtils(RepositoryUtilsInterface $repoUtils)
  61.     {
  62.         $this->repoUtils $repoUtils;
  63.         return $this;
  64.     }
  65.     /**
  66.      * Returns the RepositoryUtilsInterface instance
  67.      *
  68.      * @return \Gedmo\Tree\RepositoryUtilsInterface|null
  69.      */
  70.     public function getRepoUtils()
  71.     {
  72.         return $this->repoUtils;
  73.     }
  74.     public function childCount($node null$direct false)
  75.     {
  76.         $meta $this->getClassMetadata();
  77.         if (is_object($node)) {
  78.             if (!is_a($node$meta->getName())) {
  79.                 throw new InvalidArgumentException('Node is not related to this repository');
  80.             }
  81.             $wrapped = new EntityWrapper($node$this->_em);
  82.             if (!$wrapped->hasValidIdentifier()) {
  83.                 throw new InvalidArgumentException('Node is not managed by UnitOfWork');
  84.             }
  85.         }
  86.         $qb $this->getChildrenQueryBuilder($node$direct);
  87.         // We need to remove the ORDER BY DQL part since some vendors could throw an error
  88.         // in count queries
  89.         $dqlParts $qb->getDQLParts();
  90.         // We need to check first if there's an ORDER BY DQL part, because resetDQLPart doesn't
  91.         // check if its internal array has an "orderby" index
  92.         if (isset($dqlParts['orderBy'])) {
  93.             $qb->resetDQLPart('orderBy');
  94.         }
  95.         $aliases $qb->getRootAliases();
  96.         $alias $aliases[0];
  97.         $qb->select('COUNT('.$alias.')');
  98.         return (int) $qb->getQuery()->getSingleScalarResult();
  99.     }
  100.     /**
  101.      * @see \Gedmo\Tree\RepositoryUtilsInterface::childrenHierarchy
  102.      */
  103.     public function childrenHierarchy($node null$direct false, array $options = [], $includeNode false)
  104.     {
  105.         return $this->repoUtils->childrenHierarchy($node$direct$options$includeNode);
  106.     }
  107.     /**
  108.      * @see \Gedmo\Tree\RepositoryUtilsInterface::buildTree
  109.      */
  110.     public function buildTree(array $nodes, array $options = [])
  111.     {
  112.         return $this->repoUtils->buildTree($nodes$options);
  113.     }
  114.     /**
  115.      * @see \Gedmo\Tree\RepositoryUtilsInterface::buildTreeArray
  116.      */
  117.     public function buildTreeArray(array $nodes)
  118.     {
  119.         return $this->repoUtils->buildTreeArray($nodes);
  120.     }
  121.     /**
  122.      * @see \Gedmo\Tree\RepositoryUtilsInterface::setChildrenIndex
  123.      */
  124.     public function setChildrenIndex($childrenIndex)
  125.     {
  126.         $this->repoUtils->setChildrenIndex($childrenIndex);
  127.     }
  128.     /**
  129.      * @see \Gedmo\Tree\RepositoryUtilsInterface::getChildrenIndex
  130.      */
  131.     public function getChildrenIndex()
  132.     {
  133.         return $this->repoUtils->getChildrenIndex();
  134.     }
  135.     /**
  136.      * Get all root nodes query builder
  137.      *
  138.      * @param string|null $sortByField Sort by field
  139.      * @param string      $direction   Sort direction ("asc" or "desc")
  140.      *
  141.      * @return QueryBuilder QueryBuilder object
  142.      */
  143.     abstract public function getRootNodesQueryBuilder($sortByField null$direction 'asc');
  144.     /**
  145.      * Get all root nodes query
  146.      *
  147.      * @param string|null $sortByField Sort by field
  148.      * @param string      $direction   Sort direction ("asc" or "desc")
  149.      *
  150.      * @return Query Query object
  151.      */
  152.     abstract public function getRootNodesQuery($sortByField null$direction 'asc');
  153.     /**
  154.      * Returns a QueryBuilder configured to return an array of nodes suitable for buildTree method
  155.      *
  156.      * @param object $node        Root node
  157.      * @param bool   $direct      Obtain direct children?
  158.      * @param array  $options     Options
  159.      * @param bool   $includeNode Include node in results?
  160.      *
  161.      * @return QueryBuilder QueryBuilder object
  162.      */
  163.     abstract public function getNodesHierarchyQueryBuilder($node null$direct false, array $options = [], $includeNode false);
  164.     /**
  165.      * Returns a Query configured to return an array of nodes suitable for buildTree method
  166.      *
  167.      * @param object $node        Root node
  168.      * @param bool   $direct      Obtain direct children?
  169.      * @param array  $options     Options
  170.      * @param bool   $includeNode Include node in results?
  171.      *
  172.      * @return Query Query object
  173.      */
  174.     abstract public function getNodesHierarchyQuery($node null$direct false, array $options = [], $includeNode false);
  175.     /**
  176.      * Get list of children followed by given $node. This returns a QueryBuilder object
  177.      *
  178.      * @param object|null          $node        If null, all tree nodes will be taken
  179.      * @param bool                 $direct      True to take only direct children
  180.      * @param string|string[]|null $sortByField Field name or array of fields names to sort by
  181.      * @param string|string[]      $direction   Sort order ('ASC'|'DESC'). If $sortByField is an array, this may also be an array with matching number of elements
  182.      * @param bool                 $includeNode Include the root node in results?
  183.      *
  184.      * @return QueryBuilder QueryBuilder object
  185.      */
  186.     abstract public function getChildrenQueryBuilder($node null$direct false$sortByField null$direction 'ASC'$includeNode false);
  187.     /**
  188.      * Get list of children followed by given $node. This returns a Query
  189.      *
  190.      * @param object|null          $node        If null, all tree nodes will be taken
  191.      * @param bool                 $direct      True to take only direct children
  192.      * @param string|string[]|null $sortByField Field name or array of fields names to sort by
  193.      * @param string|string[]      $direction   Sort order ('ASC'|'DESC'). If $sortByField is an array, this may also be an array with matching number of elements
  194.      * @param bool                 $includeNode Include the root node in results?
  195.      *
  196.      * @return Query Query object
  197.      */
  198.     abstract public function getChildrenQuery($node null$direct false$sortByField null$direction 'ASC'$includeNode false);
  199.     /**
  200.      * @return QueryBuilder
  201.      */
  202.     protected function getQueryBuilder()
  203.     {
  204.         return $this->getEntityManager()->createQueryBuilder();
  205.     }
  206.     /**
  207.      * Checks if current repository is right
  208.      * for currently used tree strategy
  209.      *
  210.      * @return bool
  211.      */
  212.     abstract protected function validate();
  213. }