/**
  * {@inheritDoc}
  */
 public function childCount($node = null, $direct = false)
 {
     $meta = $this->getClassMetadata();
     if (is_object($node)) {
         if (!$node instanceof $meta->name) {
             throw new InvalidArgumentException("Node is not related to this repository");
         }
         $wrapped = new EntityWrapper($node, $this->_em);
         if (!$wrapped->hasValidIdentifier()) {
             throw new InvalidArgumentException("Node is not managed by UnitOfWork");
         }
     }
     $qb = $this->getChildrenQueryBuilder($node, $direct);
     // We need to remove the ORDER BY DQL part since some vendors could throw an error
     // in count queries
     $dqlParts = $qb->getDQLParts();
     // We need to check first if there's an ORDER BY DQL part, because resetDQLPart doesn't
     // check if its internal array has an "orderby" index
     if (isset($dqlParts['orderBy'])) {
         $qb->resetDQLPart('orderBy');
     }
     $aliases = $qb->getRootAliases();
     $alias = $aliases[0];
     $qb->select('COUNT(' . $alias . ')');
     return (int) $qb->getQuery()->getSingleScalarResult();
 }
 public function testSomeFunctions()
 {
     $test = new Article();
     $wrapped = new EntityWrapper($test, $this->em);
     $wrapped->populate(array('title' => 'test'));
     $this->assertEquals('test', $wrapped->getPropertyValue('title'));
     $this->assertFalse($wrapped->hasValidIdentifier());
 }
 /**
  * {@inheritDoc}
  */
 public function childCount($node = null, $direct = false)
 {
     $meta = $this->getClassMetadata();
     if (is_object($node)) {
         if (!$node instanceof $meta->name) {
             throw new InvalidArgumentException("Node is not related to this repository");
         }
         $wrapped = new EntityWrapper($node, $this->_em);
         if (!$wrapped->hasValidIdentifier()) {
             throw new InvalidArgumentException("Node is not managed by UnitOfWork");
         }
     }
     $qb = $this->getChildrenQueryBuilder($node, $direct);
     $aliases = $qb->getRootAliases();
     $alias = $aliases[0];
     $qb->select('COUNT(' . $alias . ')');
     return (int) $qb->getQuery()->getSingleScalarResult();
 }
 /**
  * Loads all translations with all translatable
  * fields from the given entity
  *
  * @param object $entity Must implement Translatable
  * @return array list of translations in locale groups
  */
 public function findTranslations($entity)
 {
     $result = array();
     $wrapped = new EntityWrapper($entity, $this->_em);
     if ($wrapped->hasValidIdentifier()) {
         $entityId = $wrapped->getIdentifier();
         $entityClass = $wrapped->getMetadata()->name;
         $translationMeta = $this->getClassMetadata();
         // table inheritance support
         $qb = $this->_em->createQueryBuilder();
         $qb->select('trans.content, trans.field, trans.locale')->from($translationMeta->rootEntityName, 'trans')->where('trans.foreignKey = :entityId', 'trans.objectClass = :entityClass')->orderBy('trans.locale');
         $q = $qb->getQuery();
         $data = $q->execute(compact('entityId', 'entityClass'), Query::HYDRATE_ARRAY);
         if ($data && is_array($data) && count($data)) {
             foreach ($data as $row) {
                 $result[$row['locale']][$row['field']] = $row['content'];
             }
         }
     }
     return $result;
 }
 /**
  * Removes given $node from the tree and reparents its descendants
  *
  * @todo: may be improved, to issue single query on reparenting
  * @param object $node
  * @throws RuntimeException - if something fails in transaction
  * @return void
  */
 public function removeFromTree($node)
 {
     $meta = $this->getClassMetadata();
     if (!$node instanceof $meta->name) {
         throw new InvalidArgumentException("Node is not related to this repository");
     }
     $wrapped = new EntityWrapper($node, $this->_em);
     if (!$wrapped->hasValidIdentifier()) {
         throw new InvalidArgumentException("Node is not managed by UnitOfWork");
     }
     $config = $this->listener->getConfiguration($this->_em, $meta->name);
     $pk = $meta->getSingleIdentifierFieldName();
     $nodeId = $wrapped->getIdentifier();
     $parent = $wrapped->getPropertyValue($config['parent']);
     $dql = "SELECT node FROM {$config['useObjectClass']} node";
     $dql .= " WHERE node.{$config['parent']} = :node";
     $q = $this->_em->createQuery($dql);
     $q->setParameters(compact('node'));
     $nodesToReparent = $q->getResult();
     // process updates in transaction
     $this->_em->getConnection()->beginTransaction();
     try {
         foreach ($nodesToReparent as $nodeToReparent) {
             $id = $meta->getReflectionProperty($pk)->getValue($nodeToReparent);
             $meta->getReflectionProperty($config['parent'])->setValue($nodeToReparent, $parent);
             $dql = "UPDATE {$config['useObjectClass']} node";
             $dql .= " SET node.{$config['parent']} = :parent";
             $dql .= " WHERE node.{$pk} = :id";
             $q = $this->_em->createQuery($dql);
             $q->setParameters(compact('parent', 'id'));
             $q->getSingleScalarResult();
             $this->listener->getStrategy($this->_em, $meta->name)->updateNode($this->_em, $nodeToReparent, $node);
             $oid = spl_object_hash($nodeToReparent);
             $this->_em->getUnitOfWork()->setOriginalEntityProperty($oid, $config['parent'], $parent);
         }
         $dql = "DELETE {$config['useObjectClass']} node";
         $dql .= " WHERE node.{$pk} = :nodeId";
         $q = $this->_em->createQuery($dql);
         $q->setParameters(compact('nodeId'));
         $q->getSingleScalarResult();
         $this->_em->getConnection()->commit();
     } catch (\Exception $e) {
         $this->_em->close();
         $this->_em->getConnection()->rollback();
         throw new \Gedmo\Exception\RuntimeException('Transaction failed', null, $e);
     }
     // remove from identity map
     $this->_em->getUnitOfWork()->removeFromIdentityMap($node);
     $node = null;
 }
Beispiel #6
0
    /**
     * Get hierarchy array of children followed by given $node
     *
     * @param object $node - from which node to start reordering the tree
     * @param boolean $direct - true to take only direct children
     * @param string $direction - sort direction : "ASC" or "DESC"
     * @return array $trees
     */
    public function childrenArrayHierarchy($node = null, $direct = false, $direction = "ASC")
    {
        $meta = $this->getClassMetadata();
        $config = $this->listener->getConfiguration($this->_em, $meta->name);

        if ($node !== null) {
            if ($node instanceof $meta->name) {
                $wrapped = new EntityWrapper($node, $this->_em);
                if (!$wrapped->hasValidIdentifier()) {
                    throw new InvalidArgumentException("Node is not managed by UnitOfWork");
                }
            }
        }

        // Gets the array of $node results.
        // It must be order by 'root' field
        $nodes = self::childrenQuery($node, $direct, 'root' , $direction)->getArrayResult();

        // Trees mapped
        $trees = array();
        $l = 0;

        if (count($nodes) > 0) {
            // Node Stack. Used to help building the hierarchy
            $stack = array();

            foreach ($nodes as $child) {
                $item = $child;

                $item['__children'] = array();

                // Number of stack items
                $l = count($stack);

                // Check if we're dealing with different levels
                while($l > 0 && $stack[$l - 1]['lvl'] >= $item['lvl']) {
                    array_pop($stack);
                    $l--;
                }

                // Stack is empty (we are inspecting the root)
                if ($l == 0) {
                    // Assigning the root child
                    $i = count($trees);
                    $trees[$i] = $item;
                    $stack[] = & $trees[$i];
                } else {
                    // Add child to parent
                    $i = count($stack[$l - 1]['__children']);
                    $stack[$l - 1]['__children'][$i] = $item;
                    $stack[] = & $stack[$l - 1]['__children'][$i];
                }
            }
        }
        return $trees;
    }
 /**
  * Loads all translations with all translatable
  * fields from the given entity
  *
  * @param object $entity Must implement Translatable
  *
  * @return array list of translations in locale groups
  */
 public function findTranslations($entity)
 {
     $result = array();
     $wrapped = new EntityWrapper($entity, $this->em);
     if ($wrapped->hasValidIdentifier()) {
         if (is_object($entity)) {
             $entityClass = $entity instanceof Proxy ? get_parent_class($entity) : get_class($entity);
         } else {
             throw new InvalidArgumentException('Argument 1 passed to TranslationRepository::translate must be an object');
         }
         $reflectionClass = new \ReflectionClass($entityClass);
         $translationClass = $this->isPersonnalTranslationRecursive($reflectionClass)->class;
         $qb = $this->em->createQueryBuilder();
         $qb->select('trans.content, trans.field, trans.locale')->from($translationClass, 'trans')->where('trans.object = :object')->orderBy('trans.locale');
         $q = $qb->getQuery();
         $data = $q->execute(array('object' => $entity), Query::HYDRATE_ARRAY);
         if ($data && is_array($data) && count($data)) {
             foreach ($data as $row) {
                 $result[$row['locale']][$row['field']] = $row['content'];
             }
         }
     }
     return $result;
 }
 /**
  * Get query builder for previous siblings of the given $node
  *
  * @param object $node
  * @param bool   $includeSelf - include the node itself
  *
  * @throws \Gedmo\Exception\InvalidArgumentException - if input is invalid
  *
  * @return \Doctrine\ORM\QueryBuilder
  */
 public function getPrevSiblingsQueryBuilder($node, $includeSelf = false)
 {
     $meta = $this->getClassMetadata();
     if (!$node instanceof $meta->name) {
         throw new InvalidArgumentException("Node is not related to this repository");
     }
     $wrapped = new EntityWrapper($node, $this->getEntityManager());
     if (!$wrapped->hasValidIdentifier()) {
         throw new InvalidArgumentException("Node is not managed by UnitOfWork");
     }
     $config = $this->listener->getConfiguration($this->getEntityManager(), $meta->name);
     $parent = $wrapped->getPropertyValue($config['parent']);
     if (isset($config['root']) && !$parent) {
         throw new InvalidArgumentException("Cannot get siblings from tree root node");
     }
     $left = $wrapped->getPropertyValue($config['left']);
     $qb = $this->getQueryBuilder();
     $qb->select('node')->from($config['useObjectClass'], 'node')->where($includeSelf ? $qb->expr()->lte('node.' . $config['left'], $left) : $qb->expr()->lt('node.' . $config['left'], $left))->orderBy("node.{$config['left']}", 'ASC');
     if ($parent) {
         $wrappedParent = new EntityWrapper($parent, $this->getEntityManager());
         $qb->andWhere($qb->expr()->eq('node.' . $config['parent'], ':pid'));
         $qb->setParameter('pid', $wrappedParent->getIdentifier());
     } else {
         $qb->andWhere($qb->expr()->isNull('node.' . $config['parent']));
     }
     return $qb;
 }
 /**
  * @see getChildrenQueryBuilder
  */
 public function childrenWithTranslations($node = null, $locale = null, $direct = false, $sortByField = null, $direction = 'ASC', $includeNode = false, $start = null, $limit = null)
 {
     $meta = $this->getClassMetadata();
     $config = $this->listener->getConfiguration($this->_em, $meta->name);
     $qb = $this->getQueryBuilder();
     $qb->select('node', 't')->from($config['useObjectClass'], 'node')->leftJoin('node.translations', 't');
     if ($node !== null) {
         if ($node instanceof $meta->name) {
             $wrapped = new EntityWrapper($node, $this->_em);
             if (!$wrapped->hasValidIdentifier()) {
                 throw new InvalidArgumentException("Node is not managed by UnitOfWork");
             }
             if ($direct) {
                 $id = $wrapped->getIdentifier();
                 $qb->where($id === null ? $qb->expr()->isNull('node.' . $config['parent']) : $qb->expr()->eq('node.' . $config['parent'], is_string($id) ? $qb->expr()->literal($id) : $id));
             } else {
                 $left = $wrapped->getPropertyValue($config['left']);
                 $right = $wrapped->getPropertyValue($config['right']);
                 if ($left && $right) {
                     $qb->where($qb->expr()->lt('node.' . $config['right'], $right))->andWhere($qb->expr()->gt('node.' . $config['left'], $left));
                 }
             }
             if (isset($config['root'])) {
                 $rootId = $wrapped->getPropertyValue($config['root']);
                 $qb->andWhere($rootId === null ? $qb->expr()->isNull('node.' . $config['root']) : $qb->expr()->eq('node.' . $config['root'], is_string($rootId) ? $qb->expr()->literal($rootId) : $rootId));
             }
             if ($includeNode) {
                 $idField = $meta->getSingleIdentifierFieldName();
                 $qb->where('(' . $qb->getDqlPart('where') . ') OR node.' . $idField . ' = :rootNode');
                 $qb->setParameter('rootNode', $node);
             }
         } else {
             throw new \InvalidArgumentException("Node is not related to this repository");
         }
     } else {
         if ($direct) {
             $qb->where($qb->expr()->isNull('node.' . $config['parent']));
         }
     }
     if (!$sortByField) {
         $qb->orderBy('node.' . $config['left'], 'ASC');
     } elseif (is_array($sortByField)) {
         $fields = '';
         foreach ($sortByField as $field) {
             $fields .= 'node.' . $field . ',';
         }
         $fields = rtrim($fields, ',');
         $qb->orderBy($fields, $direction);
     } else {
         if ($meta->hasField($sortByField) && in_array(strtolower($direction), array('asc', 'desc'))) {
             $qb->orderBy('node.' . $sortByField, $direction);
         } else {
             throw new InvalidArgumentException("Invalid sort options specified: field - {$sortByField}, direction - {$direction}");
         }
     }
     if ($start) {
         $qb->setFirstResult($start);
     }
     if ($limit) {
         $qb->setMaxResults($limit);
     }
     return $this->setTranslatableHint($qb->getQuery(), $locale);
 }
 /**
  * Retrieves the nested array or the html output
  *
  * @throws \Gedmo\Exception\InvalidArgumentException
  * @param object $node - from which node to start reordering the tree
  * @param boolean $direct - true to take only direct children
  * @param bool $html
  * @param array|null $options
  * @return array|string
  */
 public function childrenHierarchy($node = null, $direct = false, $html = false, array $options = null)
 {
     $meta = $this->getClassMetadata();
     $config = $this->listener->getConfiguration($this->_em, $meta->name);
     if ($node !== null) {
         if ($node instanceof $meta->name) {
             $wrapped = new EntityWrapper($node, $this->_em);
             if (!$wrapped->hasValidIdentifier()) {
                 throw new InvalidArgumentException("Node is not managed by UnitOfWork");
             }
         }
     }
     // Gets the array of $node results.
     // It must be order by 'root' field
     $nodes = self::childrenQuery($node, $direct, 'root', 'ASC')->getArrayResult();
     return $this->buildTree($nodes, $html, $options);
 }
 /**
  * Get query for previous siblings of the given $node
  *
  * @param object $node
  * @param bool $includeSelf - include the node itself
  * @throws \Gedmo\Exception\InvalidArgumentException - if input is invalid
  * @return Query
  */
 public function getPrevSiblingsQuery($node, $includeSelf = false)
 {
     $meta = $this->getClassMetadata();
     if (!$node instanceof $meta->name) {
         throw new InvalidArgumentException("Node is not related to this repository");
     }
     $wrapped = new EntityWrapper($node, $this->_em);
     if (!$wrapped->hasValidIdentifier()) {
         throw new InvalidArgumentException("Node is not managed by UnitOfWork");
     }
     $config = $this->listener->getConfiguration($this->_em, $meta->name);
     $parent = $wrapped->getPropertyValue($config['parent']);
     if (isset($config['root']) && !$parent) {
         throw new InvalidArgumentException("Cannot get siblings from tree root node");
     }
     $left = $wrapped->getPropertyValue($config['left']);
     $sign = $includeSelf ? '<=' : '<';
     $dql = "SELECT node FROM {$config['useObjectClass']} node";
     if ($parent) {
         $wrappedParent = new EntityWrapper($parent, $this->_em);
         $parentId = $wrappedParent->getIdentifier();
         $dql .= " WHERE node.{$config['parent']} = {$parentId}";
     } else {
         $dql .= " WHERE node.{$config['parent']} IS NULL";
     }
     $dql .= " AND node.{$config['left']} {$sign} {$left}";
     $dql .= " ORDER BY node.{$config['left']} ASC";
     return $this->_em->createQuery($dql);
 }