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 getChildrenQueryBuilder($node = null, $direct = false, $sortByField = null, $direction = 'asc', $includeNode = false)
 {
     $meta = $this->getClassMetadata();
     $config = $this->listener->getConfiguration($this->_em, $meta->name);
     $separator = addcslashes($config['path_separator'], '%');
     $alias = 'materialized_path_entity';
     $path = $config['path'];
     $qb = $this->getQueryBuilder()->select($alias)->from($config['useObjectClass'], $alias);
     $expr = '';
     $includeNodeExpr = '';
     if (is_object($node) && $node instanceof $meta->name) {
         $node = new EntityWrapper($node, $this->_em);
         $nodePath = $node->getPropertyValue($path);
         $expr = $qb->expr()->andx()->add($qb->expr()->like($alias . '.' . $path, $qb->expr()->literal($nodePath . ($config['path_ends_with_separator'] ? '' : $separator) . '%')));
         if ($includeNode) {
             $includeNodeExpr = $qb->expr()->eq($alias . '.' . $path, $qb->expr()->literal($nodePath));
         } else {
             $expr->add($qb->expr()->neq($alias . '.' . $path, $qb->expr()->literal($nodePath)));
         }
         if ($direct) {
             $expr->add($qb->expr()->orx($qb->expr()->eq($alias . '.' . $config['level'], $qb->expr()->literal($node->getPropertyValue($config['level']))), $qb->expr()->eq($alias . '.' . $config['level'], $qb->expr()->literal($node->getPropertyValue($config['level']) + 1))));
         }
     } elseif ($direct) {
         $expr = $qb->expr()->not($qb->expr()->like($alias . '.' . $path, $qb->expr()->literal(($config['path_starts_with_separator'] ? $separator : '') . '%' . $separator . '%' . ($config['path_ends_with_separator'] ? $separator : ''))));
     }
     if ($expr) {
         $qb->where('(' . $expr . ')');
     }
     if ($includeNodeExpr) {
         $qb->orWhere('(' . $includeNodeExpr . ')');
     }
     $orderByField = is_null($sortByField) ? $alias . '.' . $config['path'] : $alias . '.' . $sortByField;
     $orderByDir = $direction === 'asc' ? 'asc' : 'desc';
     $qb->orderBy($orderByField, $orderByDir);
     return $qb;
 }
 /**
  * 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;
 }
Exemple #4
0
    /**
     * Reorders the sibling nodes and child nodes by given $node,
     * according to the $sortByField and $direction specified
     *
     * @param object $node - from which node to start reordering the tree
     * @param string $sortByField - field name to sort by
     * @param string $direction - sort direction : "ASC" or "DESC"
     * @param boolean $verify - true to verify tree first
     * @return void
     */
    public function reorder($node, $sortByField = null, $direction = 'ASC', $verify = true)
    {
        $meta = $this->getClassMetadata();
        if ($node instanceof $meta->name) {
            $config = $this->listener->getConfiguration($this->_em, $meta->name);
            if ($verify && is_array($this->verify())) {
                return false;
            }

            $nodes = $this->children($node, true, $sortByField, $direction);
            foreach ($nodes as $node) {
                $wrapped = new EntityWrapper($node, $this->_em);
                $right = $wrapped->getPropertyValue($config['right']);
                $left = $wrapped->getPropertyValue($config['left']);
                $this->moveDown($node, true);
                if ($left != ($right - 1)) {
                    $this->reorder($node, $sortByField, $direction, false);
                }
            }
        } else {
            throw new InvalidArgumentException("Node is not related to this repository");
        }
    }
 /**
  * @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);
 }
 /**
  * {@inheritdoc}
  */
 public function persistAsNextSiblingOf(MenuItemInterface $node, MenuItemInterface $sibling)
 {
     $wrapped = new EntityWrapper($node, $this->_em);
     $meta = $this->getClassMetadata();
     $config = $this->treeListener->getConfiguration($this->_em, $meta->name);
     $wrappedSibling = new EntityWrapper($sibling, $this->_em);
     $newParent = $wrappedSibling->getPropertyValue($config['parent']);
     if (null === $newParent && isset($config['root'])) {
         throw new UnexpectedValueException('Cannot persist sibling for a root node, tree operation is not possible');
     }
     $node->sibling = $sibling;
     $sibling = $newParent;
     $wrapped->setPropertyValue($config['parent'], $sibling);
     $wrapped->setPropertyValue($config['left'], 0);
     $oid = spl_object_hash($node);
     $this->treeListener->getStrategy($this->_em, $meta->name)->setNodePosition($oid, 'NextSibling');
     $this->_em->persist($node);
     return $this;
 }
 /**
  * Get children from node
  *
  * @return Doctrine\ORM\QueryBuilder
  */
 public function getChildrenQueryBuilder($node = null, $direct = false, $sortByField = null, $direction = 'asc')
 {
     $meta = $this->getClassMetadata();
     $config = $this->listener->getConfiguration($this->_em, $meta->name);
     $separator = addcslashes($config['path_separator'], '%');
     $alias = 'materialized_path_entity';
     $path = $config['path'];
     $qb = $this->_em->createQueryBuilder($meta->name)->select($alias)->from($meta->name, $alias);
     if (is_object($node) && $node instanceof $meta->name) {
         $node = new EntityWrapper($node, $this->_em);
         $nodePath = $node->getPropertyValue($path);
         $expr = $qb->expr()->andx()->add($qb->expr()->like($alias . '.' . $path, $qb->expr()->literal($nodePath . '%')));
         $expr->add($qb->expr()->neq($alias . '.' . $path, $qb->expr()->literal($nodePath)));
         if ($direct) {
             $expr->add($qb->expr()->not($qb->expr()->like($alias . '.' . $path, $qb->expr()->literal($nodePath . '%' . $separator . '%' . $separator))));
         }
         $qb->where('(' . $expr . ')');
     } else {
         if ($direct) {
             $expr = $qb->expr()->not($qb->expr()->like($alias . '.' . $path, $qb->expr()->literal('%' . $separator . '%' . $separator . '%')));
             $qb->where('(' . $expr . ')');
         }
     }
     $orderByField = is_null($sortByField) ? $alias . '.' . $config['path'] : $alias . '.' . $sortByField;
     $orderByDir = $direction === 'asc' ? 'asc' : 'desc';
     $qb->orderBy($orderByField, $orderByDir);
     return $qb;
 }