views:

316

answers:

3

Hi there,

I have some models witch are using Doctrine nestedset feature. I want to add delete functionaly of elements from tree since that is required in my application. I was trying with snippets from documentation but I am getting a very strange error with that code.

YAML is here: http://pastie.org/820978

And I am trying with this code in my Menu class witch extends generated abstract class BaseMenu and BaseMenu extends Doctrine_Record :)

Anyway my code:

 public function getMenuItem($id)
 {
     return Doctrine::getTable('Menu')->find($id);
 }

 public function delete($id)
 {
     $item = $this->getMenuItem($id);

     //echo get_class($item); will return Menu so object exists !?

     $item->getNode()->delete();
 }

And I get this an error:

Fatal error: Call to a member function getNode() on a non-object

And I just noticed that get_class($item) is trowing a warring (so that probabbly is reason for this strange behavior):

Warning: get_class() expects parameter 1 to be object, boolean given in...

However I need a solution for this and all hints are welcome...

A: 

I personally don't like using Doctrine::getTable("table_name") because it doesn't make the code very dry. If for some reason "table_name" ever changes, you'll have to change it in alot of places.

I used Doctrine in Zend Framework apps, so my typical pattern of use involves instantiating a protected instance of every model in my module.

Using that pattern, I would just do this in my controller

$this->_Menu
     ->getTable()
     ->find($id)
     ->getNode()
     ->delete();

If you really want to keep your functions similar, I would use something like this

 public function getMenuItem($id)
 {
     if (empty($id))
     {
         throw new Exception ("A parameter of id is required to retrieve a menu item".);
     }
     return $this->getTable()->find($id);
 }

 public function delete($id)
 {
     $item = $this->getMenuItem($id);

     if ($item instanceof Doctrine_Record == false)
     {
          throw new Exception("Item is not a valid Menu Record.");
     }

     $item->getNode()->delete();
 }
Travis
Thanks, for the coding hints but this doesn't solving my problem since I am getting the exception Item is not a valid Menu Record.Do you have any idea how to solve it and why it isn't a Doctrine_Record at all ?
Splendid
A: 

Answer is in your question: $item is not object (i guess it's value is false, but you can use var_dump($item)), because there is no row with such id in DB (also I guess your $id is null)

Warning: get_class() expects parameter 1 to be object, boolean given in...

Fatal error: Call to a member function getNode() on a non-object

Vladimir
Dude, did u read my question!? I can access to all attributes of $item. Also get_class($item) returns Menu which yeap is confusing but Menu is class and it looks like an object :P And for sure id is not null since I am just testing the app it's not on some live website or something.
Splendid
So, how can u explain this: Fatal error: Call to a member function getNode() on a non-object
Vladimir
To be honest I can't explain it, and that is confusing since I don't know where the error is. I don't get it how I am able to access to object attributes like $menu->title with this code. Do u have some snippet with nested set tree and delete function since I can't get this to work ?
Splendid
Provided code is correct. I can only recommend you to ensure that your environment set toerror_reporting(E_ALL);ini_set('display_errors', true);and check output for all errors.
Vladimir
A: 

getNode() returns a Doctrine_Node, not a Doctrine_Record.

A Doctrine_Record can be deleted, but a Doctrine_Node cannot be deleted -- because it is not persistent anyway.

The correct logic would simply be:

$item = $this->getMenuItem($id)->delete();

Also, don't name a method in your model 'delete'!! This will override Doctrine_Record's delete() method, which will drive you crazy trying to debug it.

mehaase