0

我有一个 Doctrine 1.2 项目,我正在重构它,以便使用具有多个根的教义行为 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

我想要执行的是:

  • 检索某个类别是否处于活动状态,这意味着验证是否所有祖先都处于活动状态
  • 如果给定类别缺少另一个属性,则从存在的最近祖先那里继承它
  • 检索给定类别的标签;如果标签丢失,则从最近的祖先处检索它们

为了最大限度地提高速度和灵活性,您建议采用什么最佳方法?

4

1 回答 1

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。这允许在循环时调用 $nodes 上的方法。您可以创建一个 Model::getClosestProperty() 方法,例如,从最近的父级获取属性。但是,这不如阵列水合有效。

于 2011-05-12T15:39:52.993 回答