0

I've a little trouble while trying to get all ancestors from a node;

This is my schema.yml:

Constante:
connection: doctrine
tableName: constante
actAs:
NestedSet:
  hasManyRoots: true
  rootColumnName: parent_id
columns:
id:
  type: integer(8)
  fixed: false
  unsigned: false
  primary: true
  autoincrement: true
parent_id:
  type: integer(8)
  fixed: false
  unsigned: false
  primary: false
  notnull: true
  autoincrement: false
lft:
  type: integer(8)
  fixed: false
  unsigned: false
  primary: false
  notnull: true
  autoincrement: false
rgt:
  type: integer(8)
  fixed: false
  unsigned: false
  primary: false
  notnull: true
  autoincrement: false
level:
  type: integer(8)
  fixed: false
  unsigned: false
  primary: false
  notnull: true
  autoincrement: false
cod_interno:
  type: string(5)
  fixed: false
  unsigned: false
  primary: false
  notnull: false
  autoincrement: false
nombre:
  type: string(64)
  fixed: false
  unsigned: false
  primary: false
  notnull: true
  autoincrement: false

And this is how I'm trying to get all ancestors from a node (which is not a root)

$path        = Doctrine_Core::getTable('Constante')->find($condicion); // $condicion = 57
$node        = $path->getNode();
$isLeaf      = $node->isLeaf(); //var_dump throws true
$ancestors   = $node->getAncestors(); //var_dump throws false
$isValidNode = $node->isValidNode(); //var_dump throws true

As $ancestors == false I cannot iterate over it and get all ancestors (I'm trying to build a simple breadcrumb)

This is what I have stored in DB, this is real data (for testing puporse only)

+---------++---------++---------++---------++----------++---------+
|ID       ||PARENT_ID||LFT      ||RGT      ||LEVEL     ||NOMBRE   |
|---------||---------||---------||---------||----------||---------|
|56       ||56       ||1        ||4        ||0         ||COUNTRY  | --> this is root
|57       ||56       ||2        ||3        ||1         ||CANADA   | --> child of root
+---------++---------++---------++---------++----------++---------+

According to this if Ancestors returns false, it means that the selected node is a root.

I've spent hours looking for a solution with no luck.

If you need further information, don't hesitate to ask for it!

EDIT: I've made a mistake when typing what is in the table, thanks to olivierw by alert me about this.

j0k
  • 22,600
  • 28
  • 79
  • 90
Manuel Serrano
  • 100
  • 1
  • 4
  • 7

2 Answers2

0

It seems you have an error in the rgt field in your table. If id 56 is the root, it should have rgt = 4 and id 57 should have rgt = 3. So your table should read:

+---------++---------++---------++---------++----------++---------+
|ID       ||PARENT_ID||LFT      ||RGT      ||LEVEL     ||NOMBRE   |
|---------||---------||---------||---------||----------||---------|
|56       ||56       ||1        ||4        ||0         ||COUNTRY  |
|57       ||56       ||2        ||3        ||1         ||CANADA   |
+---------++---------++---------++---------++----------++---------+

So you will get the ancestors correctly.

Visavì
  • 2,333
  • 1
  • 21
  • 29
0

I want to share my solution, hopefully it will be useful for somebody else:

Action:

//action.class.php
public function executeIndex(sfWebRequest $request) {

$condicion = $request->getParameter('id') ? $request->getParameter('id') : 0;

if ($condicion > 0) {
  $path = $tree = Doctrine_Core::getTable('Constante')->find($condicion);
} else {
  $tree = Doctrine_Core::getTable('Constante');
  $path = null;
}

$this->constantes = $tree;
$this->path = $path;
$this->setTemplate('index');

}

View:

//indexSuccess.php
<?php
$var = (is_null($sf_request->getParameter('id'))) ? $constantes->getTree()->fetchRoots() : $constantes->getNode()->getChildren();
?>

<?php if ($var): foreach ($var as $constante): ?>
    <tr>
      <td><?php echo $constante->getNombre() ?></td>
    </tr>
  <?php
  endforeach;
endif;
?>

Partial:

//_breadcrumb.php
<?php

if ($path) {

  echo '<ul class="breadcrumb">';

  $node = $path->getNode();
  $ancestors = $node->getAncestors();

  if ($ancestors)
    foreach ($ancestors AS $ancestor) {
      echo '<li>' . link_to($ancestor->getNombre(), 'constantes/more?id=' . $ancestor->getId()) . '<span class="divider">/</span></li>';
    }

  echo '</ul>';
}
?>

I think that the code is self-explanatory, but if you have any question, please let me know!

Manuel Serrano
  • 100
  • 1
  • 4
  • 7
  • Great! but I don't understand why `$node->getAncestors()` is working now and don't return `false` as in your question. – Visavì Jul 07 '12 at 17:27
  • Hi! I rewrote this function from scratch, I think that the problem in the previous function was a setBaseQuery with an incorrect statement. I think that this one is way elegant, best – Manuel Serrano Jul 07 '12 at 17:59
  • `setBaseQuery` ? Ho sure! this is way elegant! – Visavì Jul 07 '12 at 21:33