Skip to content

Instantly share code, notes, and snippets.

@somoza
Created August 16, 2013 21:07
Show Gist options
  • Save somoza/6253526 to your computer and use it in GitHub Desktop.
Save somoza/6253526 to your computer and use it in GitHub Desktop.
NestedSet, Categorias anidadas...
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