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; }
/** * 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; }