Permalink
Browse files

sortable behavior: when scope column is a FK and onDelete="setnull", …

…removing related object now moves all objects to the end of null scope
  • Loading branch information...
1 parent 19dc671 commit 924839c44d4b2657627a49bb6d72a4fe1fba29f2 @rozwell committed Aug 25, 2012
View
19 generator/lib/behavior/sortable/SortableBehavior.php
@@ -11,12 +11,14 @@
require_once dirname(__FILE__) . '/SortableBehaviorObjectBuilderModifier.php';
require_once dirname(__FILE__) . '/SortableBehaviorQueryBuilderModifier.php';
require_once dirname(__FILE__) . '/SortableBehaviorPeerBuilderModifier.php';
+require_once dirname(__FILE__) . '/SortableRelationBehavior.php';
/**
* Gives a model class the ability to be ordered
* Uses one additional column storing the rank
*
* @author Massimiliano Arione
+ * @author rozwell
* @version $Revision$
* @package propel.generator.behavior.sortable
*/
@@ -42,13 +44,28 @@ public function modifyTable()
'type' => 'INTEGER'
));
}
- if ($this->getParameter('use_scope') == 'true' &&
+ if ($this->useScope() &&
!$this->getTable()->containsColumn($this->getParameter('scope_column'))) {
$this->getTable()->addColumn(array(
'name' => $this->getParameter('scope_column'),
'type' => 'INTEGER'
));
}
+
+ if ($this->useScope()) {
+ $table = $this->getTable();
+ $keys = $table->getColumnForeignKeys($this->getParameter('scope_column'));
+ foreach ($keys as $key) {
+ if ($key->isForeignPrimaryKey() && $key->getOnDelete() == ForeignKey::SETNULL) {
+ $foreignTable = $key->getForeignTable();
+ $relationBehavior = new SortableRelationBehavior();
+ $relationBehavior->addParameter(array('name' => 'foreign_table', 'value' => $table->getName()));
+ $relationBehavior->addParameter(array('name' => 'foreign_scope_column', 'value' => $this->getParameter('scope_column')));
+ $relationBehavior->addParameter(array('name' => 'foreign_rank_column', 'value' => $this->getParameter('rank_column')));
+ $foreignTable->addBehavior($relationBehavior);
+ }
+ }
+ }
}
public function getObjectBuilderModifier()
View
1 generator/lib/behavior/sortable/SortableBehaviorObjectBuilderModifier.php
@@ -13,6 +13,7 @@
*
* @author François Zaninotto
* @author heltem <heltem@o2php.com>
+ * @author rozwell
* @package propel.generator.behavior.sortable
*/
class SortableBehaviorObjectBuilderModifier
View
106 generator/lib/behavior/sortable/SortableRelationBehavior.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * This file is part of the Propel package.
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @license MIT License
+ */
+
+/**
+ * Moves objects to the end of null scope of related table
+ *
+ * @author rozwell
+ * @version $Revision$
+ * @package propel.generator.behavior.sortable
+ */
+class SortableRelationBehavior extends Behavior
+{
+ protected $builder;
+ protected $name = 'sortable_relation';
+ // default parameters value
+ protected $parameters = array(
+ 'foreign_table' => '',
+ 'foreign_scope_column' => '',
+ 'foreign_rank_column' => '',
+ );
+
+ public function objectMethods($builder)
+ {
+ $script = '';
+ $this->addObjectMoveRelatedToNullScope($script);
+
+ return $script;
+ }
+
+ public function preDelete($builder)
+ {
+ $this->builder = $builder;
+
+ $script = "\$this->{$this->getObjectMoveRelatedToNullScopeMethodName()}(\$con);
+";
+ return $script;
+ }
+
+ protected function getForeignTable()
+ {
+ return $this->getTable()->getDatabase()->getTable($this->getParameter('foreign_table'));
+ }
+
+ protected function getForeignColumnForParameter($param)
+ {
+ return $this->getForeignTable()->getColumn($this->getParameter($param));
+ }
+
+ protected function getRelatedClassPluralForm()
+ {
+ $relatedClass = $this->getForeignTable()->getPhpName();
+ return $this->builder->getPluralizer()->getPluralForm($relatedClass);
+ }
+
+ protected function getObjectMoveRelatedToNullScopeMethodName()
+ {
+
+ return "moveRelated{$this->getRelatedClassPluralForm()}ToNullScope";
+ }
+
+ protected function addObjectMoveRelatedToNullScope(&$script)
+ {
+ $database = $this->getTable()->getDatabase();
+ $tableName = $database->getTablePrefix() . $this->getParameter('foreign_table');
+
+ $maxSql = sprintf('SELECT MAX(%s) FROM %s WHERE %s IS NULL',
+ $this->getForeignColumnForParameter('foreign_rank_column')->getName(),
+ $database->getPlatform()->quoteIdentifier($tableName),
+ $this->getForeignColumnForParameter('foreign_scope_column')->getFullyQualifiedName()
+ );
+ $updateSql = sprintf('UPDATE %s SET %s = %s+:p1 WHERE %s = :p2',
+ $database->getPlatform()->quoteIdentifier($tableName),
+ $this->getForeignColumnForParameter('foreign_rank_column')->getName(),
+ $this->getForeignColumnForParameter('foreign_rank_column')->getName(),
+ $this->getForeignColumnForParameter('foreign_scope_column')->getFullyQualifiedName()
+ );
+
+ $script .= "
+/**
+ * Moves related {$this->getRelatedClassPluralForm()} to null scope
+ * @param PropelPDO \$con A connection object
+ */
+public function {$this->getObjectMoveRelatedToNullScopeMethodName()}(PropelPDO \$con)
+{
+ \$stmt = \$con->prepare('$maxSql');
+ \$stmt->execute();
+ \$maxRank = (int)\$stmt->fetchColumn();
+
+ \$stmt = \$con->prepare('$updateSql');
+ \$stmt->bindValue(':p1', \$maxRank);
+ \$stmt->bindValue(':p2', \$this->getPrimaryKey());
+ \$stmt->execute();
+}
+";
+
+ return $script;
+ }
+
+}

0 comments on commit 924839c

Please sign in to comment.