Created
August 16, 2013 21:07
-
-
Save somoza/6253526 to your computer and use it in GitHub Desktop.
NestedSet, Categorias anidadas...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Ponemos el Behaivor: | |
Category: | |
actAs: | |
Timestampable: ~ | |
NestedSet: | |
hasManyRoots: true | |
rootColumnName: root_id | |
columns: | |
name: { type: string(100) } | |
Ponemos en el configure del form: | |
// create a new widget to represent this category's "parent" | |
$this->setWidget('parent', new sfWidgetFormDoctrineChoiceNestedSet(array( | |
'model' => 'Category', | |
'add_empty' => true, | |
))); | |
// if the current category has a parent, make it the default choice | |
if ($this->getObject()->getNode()->hasParent()) | |
{ | |
$this->setDefault('parent', $this->getObject()->getNode()->getParent()->getId()); | |
} | |
// only allow the user to change the name of the category, and its parent | |
$this->useFields(array( | |
'name', | |
'parent', | |
)); | |
// set labels of fields | |
$this->widgetSchema->setLabels(array( | |
'name' => 'Category', | |
'parent' => 'Parent category', | |
)); | |
// set a validator for parent which prevents a category being moved to one of its own descendants | |
$this->setValidator('parent', new sfValidatorDoctrineChoiceNestedSet(array( | |
'required' => false, | |
'model' => 'Category', | |
'node' => $this->getObject(), | |
))); | |
$this->getValidator('parent')->setMessage('node', 'A category cannot be made a descendent of itself.'); | |
if ($this->isNew()) { | |
$this->getObject()->getNode()->insertAsLastChildOf($parent); | |
} | |
else | |
{ | |
if($this->getObject()->getNode()->getParent()->getId() != $this->getValue(‘parent’)) // test to see if the parent has changed | |
$this->getObject()->getNode()->moveAsLastChildOf($parent); | |
} | |
Y por último en el evento doSave() del form: | |
/** | |
* Updates and saves the current object. Overrides the parent method | |
* by treating the record as a node in the nested set and updating | |
* the tree accordingly. | |
* | |
* @param Doctrine_Connection $con An optional connection parameter | |
*/ | |
public function doSave($con = null) | |
{ | |
// save the record itself | |
parent::doSave($con); | |
// if a parent has been specified, add/move this node to be the child of that node | |
if ($this->getValue('parent')) | |
{ | |
$parent = Doctrine::getTable('Category')->findOneById($this->getValue('parent')); | |
if ($this->isNew()) | |
{ | |
$this->getObject()->getNode()->insertAsLastChildOf($parent); | |
} | |
else | |
{ | |
$this->getObject()->getNode()->moveAsLastChildOf($parent); | |
} | |
} | |
// if no parent was selected, add/move this node to be a new root in the tree | |
else | |
{ | |
$categoryTree = Doctrine::getTable('Category')->getTree(); | |
if ($this->isNew()) | |
{ | |
$categoryTree->createRoot($this->getObject()); | |
} | |
else | |
{ | |
$this->getObject()->getNode()->makeRoot($this->getObject()->getId()); | |
} | |
} | |
} | |
Creamos el un metodo en el table para ordenar el query por jerarquia. | |
public function retrieveSorted() | |
{ | |
return $this->createQuery() | |
->orderBy('root_id asc, lft asc') | |
->execute(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment