goutte/tree-bundle

Goutte 的树库

安装量: 1,013

依赖者: 0

建议者: 0

安全性: 0

星标: 3

关注者: 3

分支: 1

开放性问题: 0

类型:symfony-bundle

v1.7.5 2013-01-07 07:21 UTC

This package is not auto-updated.

Last update: 2024-09-28 13:45:58 UTC


README

当前树结构仅设计了一个模型,即 Node

提供序列化和反序列化节点服务的功能,从字符串如 A(B,C(D)) 到节点,以及从节点到字符串。

提供的驱动器

  • 括号 : A(B,C(D))

  • 简单的(愚蠢的!)timbre : T("*",T(6),T("sin",T(55.2)))

  • Ascii

    A
    +--B
    |  +--C
    |  +--D
    |     +--E
    +--Fork
    

查看 测试 了解驱动器支持的更多示例。

使用方法

此库不用于在数据库中存储嵌套集合,如果您正在寻找这个,您应该查看 Doctrine 扩展。此包的原始目的是提供一套用于阅读/编写功能代码的工具,例如配置菜单的层次结构的纯文本。

请随意扩展以满足您的需求。

安装

使用 composer 将此包添加到您的项目中

composer require goutte/tree-bundle

服务

从容器中使用服务

    // get the serializer service
    $serializer = $container->get('goutte_tree.serializer');

    // this will create the nodes and return the root node
    $rootNode = $serializer->toNode('root(childA,childB(grandchildC))');

    // this will return the string for the subtree below the passed node
    $string = $serializer->toString($rootNode); // returns 'root(childA,childB(grandchildC))'

    // ... or use another driver
    $string = $serializer->useDriver('ascii')->toString($rootNode);
    // will return:
    // root
    // +--childA
    // +--childB
    //    +--grandchildC

查看 Goutte\TreeBundle\Is\Node 以获取抽象类 Goutte\TreeBundle\Model\AbstractNode 提供的方法列表。

使用自己的 Node

扩展

    use Goutte\TreeBundle\Model\Node as AbstractNode;
    class MyNode extends AbstractNode {
        // ...
    }

实现

    use Goutte\TreeBundle\Is\Node as NodeInterface;
    class MyNode implements NodeInterface {
        // ...
    }

然后,配置服务以使用您的自己的 Node 类。

编写一个驱动器

如下实现 Goutte\TreeBundle\Is\Driver

    use Goutte\TreeBundle\Is\Driver;
    use Goutte\TreeBundle\Factory\NodeFactoryInterface;

    class MyDriver implements Driver
    {
        protected $factory

        public function __construct(NodeFactoryInterface $factory)
        {
            $this->factory = $factory;
        }

        // ... implement Driver
    }

__construct 部分是可选的,但您可能需要一个 NodeFactory 来创建节点。我们提供了一个默认的 Node Factory 作为服务,请参阅下面服务的定义中的 <argument>

将您的驱动器添加到您的 services.xml 中,并标记为 goutte_tree.driver

    <service id="goutte_tree.driver.mydriver" class="MyVendor\MyBundle\Driver\MyDriver" public="false">
        <argument type="service" id="goutte_tree.node.factory" />
        <tag name="goutte_tree.driver" />
    </service>

(警告) 服务 ID 将定义驱动别名,因此它需要以 goutte_tree.driver. 开头。这不是官方的做法(这将有一个在标签中的别名属性),但这会使代码更简洁。这可能以后会改变,我还在做决定。

使用 ->useDriver() 配置服务以使用您的自定义驱动器

    // Get the service, tell it to use your driver
    $serializer = $container->get('goutte_tree.serializer')->useDriver('mydriver');

您可以通过在 services.xml 中将服务告诉使用您的驱动器作为默认值来省略对 ->useDriver() 的使用

    <tag name="goutte_tree.driver" default="true" />

测试

此包被无情地测试了,除了某些服务配置异常(如果您知道如何测试这些,我很乐意听!)

使用 --dev 选项运行 composer,以便创建自动加载器并自动加载所需的 sf2 DIC 类。 奇怪的是,当我尝试使用 --testrequire-testcomposer.json 中安装时,我被赶了出来。(字面意思)

composer install --dev

然后,只需运行

phpunit

陷阱

括号驱动器

带有空标签的节点可以转换为字符串,但不能反向转换回节点。

例如:A(B,C) 树,如果节点标签被清空,将转换回 (,)

预期的解决方案

  • 如果标签为空则在 toString 转换时抛出异常 -> 功能丢失
  • 微调 toNode 正则表达式以允许空标签 -> 如 A() 将创建两个节点,这会令人不安

Timbre 驱动器

节点的标签没有被驱动程序转义,所以没有 (),。因为这些字符在 Timbre 的节点中没有被使用,所以这不应该是一个问题。

数字标签必须用 T() 括起来,例如:T(66.2)

Ascii 驱动程序

换行符将被(未)转义,以便标签在字符串表示中保持在同一行。

因为读者期望 正好 2 个 - 作为缩进,所以如果你添加更多,节点标签将保留额外的 -

例如

A
+---B

=> 子节点标签将是 -B,而不是 B

变更日志

v1.0

  • TreeIntegrityException
  • DriverException
  • 节点基础方法
  • 路径查找
  • 树完整性测试
  • 驱动程序的 DIC
  • 文档

v1.5

  • 括号驱动程序
  • Timbre 驱动程序
  • 用于多行 ASCII 根树的多行 ASCII 驱动程序
  • 使用 ->replaceBy() 替换节点

v1.6

  • 节点克隆

v1.7.1

  • ->getDescendants()(默认为广度优先 TWA)
  • ->getRandomDescendant($includeSelf=false)

v1.7.4

  • 解耦 Random 工具,以便更容易/更深入地进行确定性测试
  • ->removeChildren()

v1.7.5

  • 在驱动程序中使用工厂

路线图

这些没有时间表,不要等待它们。

v1.8

  • ->getAncestors()
  • ->getRandomAncestor($includeSelf=false)

v2.0

  • 括号驱动程序中的空标签
  • 图论,请参阅 BLACKBOARD
    • -> 可能会在另一个包中
  • 用于树展平的自定义树遍历
    • 广度优先
    • 深度优先