Doctrine 1.2 NestedSet属性和祖先的关系继承

时间:2011-05-12 14:02:57

标签: php symfony1 doctrine nested-sets hierarchical-trees

我有一个我正在重构的Doctrine 1.2项目,以便使用具有多个根的doctrine beahaviour NestedSet为表创建树结构。

我需要的是从祖先到后代的继承(不是OO常识),其中后代从最近的祖先继承属性,其中缺少自己的属性。关系也会发生同样的事情。

让我用一个例子来解释:

Category:
  actAs:
    NestedSet:
      hasManyRoots: true
      rootColumnName: root_id
  columns:
    name: string(50)
    another_property: string(50)
    active: boolean
Tag:
  columns:
    value: string(50)
CategoryTag:
  columns:
    category_id: integer
    tag_id: integer

我想要表现的是:

  • 检索类别是否处于活动状态,这意味着验证是否所有类别 祖先活跃
  • 如果给定类别缺少another_property,则从中继承 最近的祖先
  • 检索给定类别的标签;如果标签丢失,请检索它们 来自最近的祖先

为了最大限度地提高速度和灵活性,您认为最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

嗯,这很简单。只需使用您需要的关系获取树:

    class ModelTable extends Doctrine_Table
    {
      /**
       * Gets tree element in one query
       */
      public function getModelTree()
      {

        $q = $this->createQuery('g')
          ->leftJoin('g.Tags t')
          ->orderBy('g.root_id')
          ->addOrderBy('g.lft')
          ->where('g.root_id NOT NULL')
;
        return $q->execute(array(),  Doctrine_Core::HYDRATE_ARRAY_HIERARCHY);
      }
    }

然后,您可以像这样渲染它:

<?php function echoNode($tree, $parent=null) { ?>
  <ul>
  <?php foreach ($tree as $node): ?>
    <li data-property='<?php echo false != $node['property'] ? $node['property'] : $parent['property']  ?>'>
      <?php echo $node['name'] ?>
      <?php if (count($node['__children']) > 0): ?>
        <?php echo echoNode($node['__children'], $node) ?>
      <?php endif; ?>
    </li>
  <?php endforeach; ?>       
  </ul>
<?php } ?>

<?php echo echoNode($tree) ?>

请注意,如果不存在,您可以从父节点获取“属性”。解决此问题的另一种方法是使用Doctrine_Core :: HYDRATE_RECORD_HIERARCHY。这允许在循环时用于在$节点上调用方法。例如,您可以创建Model :: getClosestProperty()方法,以从最近的父级获取属性。但是,这不如阵列水合效率高。