Doctrine 1
  1. Doctrine 1
  2. DC-515

HYDRATE_RECORD_HIERARCHY broken with many roots

    Details

    • Type: Bug Bug
    • Status: Reopened
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: 1.2.0
    • Fix Version/s: None
    • Component/s: Nested Set
    • Labels:
      None

      Description

      DB schema:

      Category:
      actAs:
      NestedSet:
      hasManyRoots: true
      rootColumnName: root_id
      columns:
      id:
      type: integer(4)
      primary: true
      autoincrement: true
      name:
      type: string(64)
      notnull: true
      image: string(64)
      indexes:
      tree:
      fields: [lft, rgt, root_id]

      Sample data:

      id: '1'
      name: 'Przykładowa kategoria 1'
      image: null
      root_id: '1'
      lft: '1'
      rgt: '6'
      level: '0'

      • id: '2'
        name: 'Przykładowa kategoria 2'
        image: null
        root_id: '2'
        lft: '1'
        rgt: '6'
        level: '0'
        -
        id: '3'
        name: 'Przykładowa podkategoria 1'
        image: null
        root_id: '2'
        lft: '2'
        rgt: '5'
        level: '1'
        -
        id: '4'
        name: 'Przykładowa podkategoria 2'
        image: null
        root_id: '2'
        lft: '3'
        rgt: '4'
        level: '2'
        -
        id: '5'
        name: teset1
        image: null
        root_id: '1'
        lft: '2'
        rgt: '5'
        level: '1'
        -
        id: '6'
        name: test2
        image: null
        root_id: '1'
        lft: '3'
        rgt: '4'
        level: '2'

      When using HYDRATE_RECORD_HIERARCHY, the first top-level category is empty. Everything is assigned to the other one. Only single-root trees work properly.

        Activity

        Hide
        Kamil Rojewski added a comment -

        A Doctrine_Collection with root nodes seems to work fine. It allows to traverse the tree for each root.

        Show
        Kamil Rojewski added a comment - A Doctrine_Collection with root nodes seems to work fine. It allows to traverse the tree for each root.
        Hide
        Jonathan H. Wage added a comment -

        I think it was intended that you would only convert a single tree to a hierarchy. What would the structure of the returned data be like?

        Show
        Jonathan H. Wage added a comment - I think it was intended that you would only convert a single tree to a hierarchy. What would the structure of the returned data be like?
        Hide
        Kamil Rojewski added a comment -

        If you look at Doctrine_Collection::toHierarchy() you'll notice that there is NO reference to root_id, therefore it treats the entire collection as 1 tree (which is false). The bug is 100% repeatable. I've made a fast walkaround ba adding a multi-tree hydrator:

        class MultiRootHydrator extends Doctrine_Hydrator_RecordDriver
        {
          public function hydrateResultSet($stmt)
          {
            $result = parent::hydrateResultSet($stmt);
        
            $collection = array();
            foreach ($result as $item)
            {
              if (!isset($collection[$item->root_id]))
                $collection[$item->root_id] = new Doctrine_Collection($result->getTable());
        
              $collection[$item->root_id]->add($item);
            }
        
            $result = new Doctrine_Collection($result->getTable());
            foreach ($collection as $tree)
            {
              $tree = $tree->toHierarchy();
              $record = $tree->getFirst();
        
              $result->add($record, $record->root_id);
            }
        
            return $result;
          }
        }
        

        It should clarify the problem.

        Show
        Kamil Rojewski added a comment - If you look at Doctrine_Collection::toHierarchy() you'll notice that there is NO reference to root_id, therefore it treats the entire collection as 1 tree (which is false). The bug is 100% repeatable. I've made a fast walkaround ba adding a multi-tree hydrator: class MultiRootHydrator extends Doctrine_Hydrator_RecordDriver { public function hydrateResultSet($stmt) { $result = parent::hydrateResultSet($stmt); $collection = array(); foreach ($result as $item) { if (!isset($collection[$item->root_id])) $collection[$item->root_id] = new Doctrine_Collection($result->getTable()); $collection[$item->root_id]->add($item); } $result = new Doctrine_Collection($result->getTable()); foreach ($collection as $tree) { $tree = $tree->toHierarchy(); $record = $tree->getFirst(); $result->add($record, $record->root_id); } return $result; } } It should clarify the problem.

          People

          • Assignee:
            Guilherme Blanco
            Reporter:
            Kamil Rojewski
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: