Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Update of README and identation fixes

  • Loading branch information...
commit 42325be9385c2bd1659914e3c1285da74dbdf7db 1 parent 9985c45
Gediminas Morkevicius authored
Showing with 70 additions and 30 deletions.
  1. +5 −4 README.markdown
  2. +65 −26 lib/Gedmo/Tree/Strategy/ORM/Closure.php
9 README.markdown
View
@@ -5,7 +5,7 @@ offer new functionality or tools to use Doctrine 2 more efficently. This package
used behaviors which can be easily attached to your event system of Doctrine 2 and handle the
records being flushed in the behavioral way. List of extensions:
-- Tree - this extension automates the tree handling process and adds some tree specific functions on repository.
+- Tree - this extension automates the tree handling process and adds some tree specific functions on repository. (closure or nestedset)
- Translatable - gives you a very handy solution for translating records into diferent languages. Easy to setup, easier to use.
- Sluggable - urlizes your specified fields into single unique slug
- Timestampable - updates date fields on create, update and even property change.
@@ -28,10 +28,10 @@ If you are using windows, there is **msysgit** tool available.
### Latest updates
-**2011-03-05**
+**2011-03-27**
-- Merged Boussekeyt Jules pull request for Loggable extension, tweeked to support versioning
-- Added typehints for object manager and classmetadata in all extensions
+- Merged Gustavo Adrian pull request for **Tree-closure** adapter
+- Now tree extension supports nestedset or closure strategies, it can be used on same manager. Keep in mind that closure adapter is not stable yet
### ODM MongoDB support
@@ -69,6 +69,7 @@ To setup and run tests follow these steps:
### Contributors:
+- Gustavo Adrian [comfortablynumb](http://github.com/comfortablynumb)
- Boussekeyt Jules [gordonslondon](http://github.com/gordonslondon)
- Christophe Coevoet [stof](http://github.com/stof)
- Kudryashov Konstantin [everzet](http://github.com/everzet)
91 lib/Gedmo/Tree/Strategy/ORM/Closure.php
View
@@ -11,9 +11,6 @@
* This strategy makes tree act like
* a closure table.
*
- * Some Tree logic is copied from -
- * CakePHP: Rapid Development Framework (http://cakephp.org)
- *
* @author Gustavo Adrian <comfortablynumb84@gmail.com>
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @package Gedmo.Tree.Strategy.ORM
@@ -84,8 +81,7 @@ public function processPrePersist($em, $entity)
public function processPostPersist($em, $entity)
{
if (count($this->pendingChildNodeInserts)) {
- while ($e = array_shift($this->pendingChildNodeInserts))
- {
+ while ($e = array_shift($this->pendingChildNodeInserts)) {
$this->insertNode($em, $e);
}
@@ -93,17 +89,25 @@ public function processPostPersist($em, $entity)
$meta = $em->getClassMetadata(get_class($entity));
$config = $this->listener->getConfiguration($em, $meta->name);
if (isset($config['childCount'])) {
- $this->recalculateChildCountForEntities($em, get_class( $entity ));
+ $this->recalculateChildCountForEntities($em, get_class($entity));
}
}
}
+ /**
+ * Insert node and closures
+ *
+ * @param EntityManager $em
+ * @param object $entity
+ * @param bool $addNodeChildrenToAncestors
+ * @throws \Gedmo\Exception\RuntimeException - if closure insert fails
+ */
public function insertNode(EntityManager $em, $entity, $addNodeChildrenToAncestors = false)
{
$meta = $em->getClassMetadata(get_class($entity));
$config = $this->listener->getConfiguration($em, $meta->name);
$identifier = $meta->getSingleIdentifierFieldName();
- $id = $this->extractIdentifier( $em, $entity );
+ $id = $this->extractIdentifier($em, $entity);
$closureMeta = $em->getClassMetadata($config['closure']);
$entityTable = $meta->getTableName();
$closureTable = $closureMeta->getTableName();
@@ -122,7 +126,7 @@ public function insertNode(EntityManager $em, $entity, $addNodeChildrenToAncesto
$parent = $meta->getReflectionProperty($config['parent'])->getValue($entity);
- if ( $parent ) {
+ if ($parent) {
$parentId = $meta->getReflectionProperty($identifier)->getValue($parent);
$dql = "SELECT c.ancestor, c.depth FROM {$closureMeta->name} c";
$dql .= " WHERE c.descendant = {$parentId}";
@@ -142,8 +146,7 @@ public function insertNode(EntityManager $em, $entity, $addNodeChildrenToAncesto
$children = $em->createQuery($dql)
->getArrayResult();
- foreach ($children as $child)
- {
+ foreach ($children as $child) {
$entries[] = array(
'ancestor' => $ancestor['ancestor'],
'descendant' => $child['descendant'],
@@ -178,10 +181,17 @@ public function processScheduledUpdate($em, $entity)
// If "childCount" property is in the schema, we recalculate child count of all entities
if (isset($config['childCount'])) {
- $this->recalculateChildCountForEntities($em, get_class( $entity ));
+ $this->recalculateChildCountForEntities($em, get_class($entity));
}
}
+ /**
+ * Update node and closures
+ *
+ * @param EntityManager $em
+ * @param object $entity
+ * @param array $change - changeset of parent
+ */
public function updateNode(EntityManager $em, $entity, array $change)
{
$meta = $em->getClassMetadata(get_class($entity));
@@ -193,7 +203,6 @@ public function updateNode(EntityManager $em, $entity, array $change)
if ($oldParent) {
$this->removeClosurePathsOfNodeID($em, $table, $nodeId);
-
$this->insertNode($em, $entity, true);
}
}
@@ -214,53 +223,75 @@ public function processScheduledDelete($em, $entity)
}
}
+ /**
+ * Remove node and associated closures
+ *
+ * @param EntityManager $em
+ * @param object $entity
+ * @param bool $maintainSelfReferencingRow
+ * @param bool $maintainSelfReferencingRowOfChildren
+ */
public function removeNode(EntityManager $em, $entity, $maintainSelfReferencingRow = false, $maintainSelfReferencingRowOfChildren = false)
{
$meta = $em->getClassMetadata(get_class($entity));
$config = $this->listener->getConfiguration($em, $meta->name);
$closureMeta = $em->getClassMetadata($config['closure']);
- $id = $this->extractIdentifier( $em, $entity );
+ $id = $this->extractIdentifier($em, $entity);
$this->removeClosurePathsOfNodeID($em, $closureMeta->getTableName(), $id, $maintainSelfReferencingRow, $maintainSelfReferencingRowOfChildren);
}
+ /**
+ * Remove closures for node $nodeId
+ *
+ * @param EntityManager $em
+ * @param string $table
+ * @param integer $nodeId
+ * @param bool $maintainSelfReferencingRow
+ * @param bool $maintainSelfReferencingRowOfChildren
+ * @throws \Gedmo\Exception\RuntimeException - if deletion of closures fails
+ */
public function removeClosurePathsOfNodeID(EntityManager $em, $table, $nodeId, $maintainSelfReferencingRow = true, $maintainSelfReferencingRowOfChildren = true)
{
$subquery = "SELECT c1.id FROM {$table} c1 ";
- $subquery .= "WHERE c1.descendant IN ( SELECT c2.descendant FROM {$table} c2 WHERE c2.ancestor = :id ) ";
- $subquery .= "AND ( c1.ancestor IN ( SELECT c3.ancestor FROM {$table} c3 WHERE c3.descendant = :id ";
+ $subquery .= "WHERE c1.descendant IN (SELECT c2.descendant FROM {$table} c2 WHERE c2.ancestor = :id) ";
+ $subquery .= "AND (c1.ancestor IN (SELECT c3.ancestor FROM {$table} c3 WHERE c3.descendant = :id ";
- if ($maintainSelfReferencingRow === true)
- {
+ if ($maintainSelfReferencingRow === true) {
$subquery .= "AND c3.descendant != c3.ancestor ";
}
- if ( $maintainSelfReferencingRowOfChildren === false )
- {
+ if ( $maintainSelfReferencingRowOfChildren === false) {
$subquery .= " OR c1.descendant = c1.ancestor ";
}
- $subquery .= " ) ) ";
-
- $subquery = "DELETE FROM {$table} WHERE {$table}.id IN ( SELECT temp_table.id FROM ( {$subquery} ) temp_table )";
+ $subquery .= " )) ";
+ $subquery = "DELETE FROM {$table} WHERE {$table}.id IN (SELECT temp_table.id FROM ({$subquery}) temp_table)";
if (!$em->getConnection()->executeQuery($subquery, array('id' => $nodeId))) {
throw new \Gedmo\Exception\RuntimeException('Failed to delete old Closure records');
}
}
- public function recalculateChildCountForEntities($em, $entityClass)
+ /**
+ * Childcount recalculation
+ *
+ * @param EntityManager $em
+ * @param string $entityClass
+ * @throws \Gedmo\Exception\RuntimeException - if update fails
+ */
+ public function recalculateChildCountForEntities(EntityManager $em, $entityClass)
{
$meta = $em->getClassMetadata($entityClass);
$config = $this->listener->getConfiguration($em, $meta->name);
$entityIdentifierField = $meta->getIdentifierColumnNames();
- $entityIdentifierField = $entityIdentifierField[ 0 ];
+ $entityIdentifierField = $entityIdentifierField[0];
$childCountField = $config['childCount'];
$closureMeta = $em->getClassMetadata($config['closure']);
$entityTable = $meta->getTableName();
$closureTable = $closureMeta->getTableName();
- $subquery = "( SELECT COUNT( c2.descendant ) FROM {$closureTable} c2 WHERE c2.ancestor = c1.{$entityIdentifierField} AND c2.ancestor != c2.descendant )";
+ $subquery = "(SELECT COUNT( c2.descendant ) FROM {$closureTable} c2 WHERE c2.ancestor = c1.{$entityIdentifierField} AND c2.ancestor != c2.descendant)";
$sql = "UPDATE {$entityTable} c1 SET c1.{$childCountField} = {$subquery}";
if (!$em->getConnection()->executeQuery($sql)) {
@@ -268,7 +299,15 @@ public function recalculateChildCountForEntities($em, $entityClass)
}
}
- private function extractIdentifier($em, $entity, $single = true)
+ /**
+ * Extracts identifiers from object or proxy
+ *
+ * @param EntityManager $em
+ * @param object $entity
+ * @param bool $single
+ * @return mixed - array or single identifier
+ */
+ private function extractIdentifier(EntityManager $em, $entity, $single = true)
{
if ($entity instanceof Proxy) {
$id = $em->getUnitOfWork()->getEntityIdentifier($entity);
Please sign in to comment.
Something went wrong with that request. Please try again.