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

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