/**
  * Persists an ioMenuItem tree to the database.
  *
  * Typically, you'll persist your entire menu tree. This will save the root
  * menu item as a root in Doctrine's nested set with the whole tree under it:
  *
  * $menu = new ioMenuItem('root');
  * $menu->addChild('Home', '@homepage');
  * Doctrine_Core::getTable('ioDoctrineMenuItem')->persist($menu);
  *
  * You can also persist part of a tree or persist a full menu under an
  * existing Doctrine nested set node:
  *
  * $menu->addChild('Links');
  * $menu['Links']->addChild('Sympal', 'http://www.sympalphp.org');
  * $tbl = Doctrine_Core::getTable('ioDoctrineMenuItem');
  * $node = $tbl->findOneByName('some name'); // find an existing node
  * // save the Links submenu under the above node
  * $tbl->persist($menu['Links'], $node);
  *
  * @param  ioMenuItem $menu
  * @param  ioDoctrineMenuItem $parentDoctrineMenu Optional parent node, else
  *                                                it will save as root
  * @return ioDoctrineMenuItem
  * @throws sfException
  */
 public function persist(ioMenuItem $menu, ioDoctrineMenuItem $parent = null)
 {
     // run a few sanity checks and create the root node
     if (!$parent) {
         // protect against people calling persist on non-root objects, which
         // would otherwise cause those items to persist as new roots
         if (!$menu->isRoot()) {
             throw new sfException('Non-root menu items as root items. Either persist the entire
       tree or pass an ioDoctrineMenuItem parent as the second argument.');
         }
         // Make sure the root has a name
         if (!$menu->getName()) {
             throw new sfException('A root object cannot be persisted without a name. Call setName()
       on the root menu item to set its name');
         }
         $root = $this->fetchRootByName($menu->getName());
         if (!$root) {
             // create a new root
             $root = new ioDoctrineMenuItem();
             $root->name = $menu->getName();
             $root->save();
             $this->getTree()->createRoot($root);
         }
         $parent = $root;
     }
     // merge in the menu data into the parent menu
     $parent->persistFromMenuArray($menu->toArray());
 }
class ioMenuItemTest extends ioMenuItem
{
    // resets the isCurrent property so we can test for current repeatedly.
    public function resetIsCurrent()
    {
        $this->_isCurrent = null;
    }
    // resets the userAccess property so we can test for current repeatedly.
    public function resetUserAccess()
    {
        $this->_userAccess = null;
    }
}
$t->info('1 - Test basic getters, setters and constructor');
$menu = new ioMenuItem('test menu', '@homepage', array('title' => 'my menu'));
$t->is($menu->getName(), 'test menu', '->getName() returns the given name.');
$menu->setName('new menu name');
$t->is($menu->getName(), 'new menu name', '->setName() sets the name correctly.');
$t->is($menu->getLabel(), 'new menu name', '->getLabel() returns the name if the label does not exist.');
$menu->setLabel('menu label');
$t->is($menu->getLabel(), 'menu label', 'Once set, ->getLabel() returns the actual label.');
$t->is($menu->getRoute(), '@homepage', '->getRoute() returns the given route.');
$menu->setRoute('http://www.sympalphp.org');
$t->is($menu->getRoute(), 'http://www.sympalphp.org', '->setRoute() sets the route correctly.');
$t->is($menu->getAttributes(), array('title' => 'my menu'), '->getAttributes() returns the attributes array.');
$menu->setAttributes(array('id' => 'unit_test'));
$t->is($menu->getAttributes(), array('id' => 'unit_test'), '->setAttributes() sets the attributes array.');
$t->is($menu->getAttribute('id', 'default'), 'unit_test', '->getAttribute() returns an existing attribute correctly.');
$t->is($menu->getAttribute('fake', 'default'), 'default', '->getAttribute() returns the default for a non-existent attribute.');
$menu->setAttribute('class', 'testing classes');
$t->is($menu->getAttribute('class'), 'testing classes', '->setAttribute() correctly sets an attribute.');
 /**
  * Moves child to specified position. Rearange other children accordingly.
  *
  * @param ioMenuItem $child Child to move.
  * @param numeric $position Position to move child to.
  */
 public function moveChildToPosition(ioMenuItem $child, $position)
 {
     $name = $child->getName();
     $order = array_keys($this->_children);
     $oldPosition = array_search($name, $order);
     unset($order[$oldPosition]);
     $order = array_values($order);
     array_splice($order, $position, 0, $name);
     $this->reorderChildren($order);
 }