فهرست منبع

Update of README and identation fixes

Gediminas Morkevicius 14 سال پیش
والد
کامیت
42325be938
2فایلهای تغییر یافته به همراه70 افزوده شده و 30 حذف شده
  1. 5 4
      README.markdown
  2. 65 26
      lib/Gedmo/Tree/Strategy/ORM/Closure.php

+ 5 - 4
README.markdown

@@ -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)

+ 65 - 26
lib/Gedmo/Tree/Strategy/ORM/Closure.php

@@ -11,9 +11,6 @@ use Gedmo\Tree\Strategy,
  * 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 @@ class Closure implements Strategy
     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 @@ class Closure implements Strategy
             $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 @@ class Closure implements Strategy
         
         $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 @@ class Closure implements Strategy
                     $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 @@ class Closure implements Strategy
         
         // 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 @@ class Closure implements Strategy
         
         if ($oldParent) {
             $this->removeClosurePathsOfNodeID($em, $table, $nodeId);
-            
             $this->insertNode($em, $entity, true);
         }
     }
@@ -214,53 +223,75 @@ class Closure implements Strategy
         }
     }
 	
+    /**
+     * 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 @@ class Closure implements Strategy
         }
     }
     
-    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);