从Doctrine 2渲染嵌套类别实体

时间:2017-04-07 05:30:16

标签: php doctrine-orm

我目前正在使用自引用实体,我必须基于该实体构建一个小型列表结构(<ul><li>)。但是,列表必须考虑深度,因此我需要使用父/子关系作为我的渲染器的基础。这是原始实体:

<?php

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 * @ORM\Table(name="categories")
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $name;

    /**
     * @var Category
     *
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="children")
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=true, onDelete="CASCADE")
     */
    protected $parent;

    /**
     * @var Collection
     *
     * @ORM\OneToMany(
     *     targetEntity="Category",
     *     mappedBy="parent",
     *     cascade={"ALL"}
     * )
     */
    protected $children;

    public function __construct()
    {
        $this->children = new ArrayCollection();
    }

    public function getId():
    {
        return $this->id;
    }

    public function setId(int $id)
    {
        $this->id = $id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function getParent()
    {
        return $this->parent;
    }

    public function setParent(Category $parent)
    {
        $this->parent = $parent;
    }

    public function setChildren(array $children)
    {
        $this->children = $children;
    }

    public function getChildren()
    {
        return $this->children;
    }

    public function addChild(Category $category)
    {
        if (!$this->children->contains($category)) {
            $category->setParent($this);
            $this->children->add($category);
        }
    }

    public function removeChild(Category $category)
    {
        if ($this->children->contains($category)) {
            $this->children->removeElement($category);
        }
    }
}

我已经实现了一个非常天真的实现:https://wildlyinaccurate.com/simple-nested-sets-in-doctrine-2/

但是,这种基于深度的填充逻辑对<ul><li>结构没有帮助。有没有人建议任何将自引用对象呈现为HTML列表的方​​法?

1 个答案:

答案 0 :(得分:-2)

以下是如何打印3个无序类别list()基于树的级别:

<?php $rootCategories = $em->getRepository('Entity\Category')->findBy(['parent' => null]) ?>

// Root categories container
<ul>
<?php foreach ($rootCategories as $rootCategory): ?>
    <li>
        <?= $rootCategory->getName() ?>
        <?php if ($rootCategory->getChildren()): ?>
            // First child categories container
            <ul>
                <?php foreach ($rootCategory->getChildren() as $firstChildCategory): ?>
                    <li>
                        <?= $firstChildCategory->getName() ?>
                        <?php if ($firstChildCategory->getChildren()): ?>
                            // Second child categories container
                            <ul>
                                <?php foreach ($firstChildCategory->getChildren() as $secondChildCategory): ?>
                                    <li><?= $secondChildCategory->getName() ?></li>
                                <?php endforeach ?>
                            </ul>
                        <?php endif ?>
                    </li>
                <?php endforeach ?>
            </ul>
        <?php endif ?>
    </li>
<?php endforeach ?>
</ul>