Doctrine2 + ZF2 - 与子类别一起迭代

时间:2013-07-27 01:13:43

标签: php recursion doctrine-orm iterator zend-framework2

我目前正在研究ZF2的Blog模块,我找到了一种方法来迭代我的类别并检查他们是否有孩子。

问题是,我总是得到这个错误:

Fatal error: Call to a member function isEmpty() on a non-object in /var/www/microweb2/module/Blog/src/Blog/Entity/CategoryIterator.php on line 19

以下是第19行:return $this->_data->current()->getSubCategories()->isEmpty();

嗯,目前,我的CategoryIterator是一个实现\RecursiveIterator的类,但它不起作用......我从这个博客中获取了这段代码:http://wildlyinaccurate.com/simple-nested-sets-in-doctrine-2

这是我的代码:

我的Entity\Category

<?php

namespace Blog\Entity;

use Doctrine\ORM\Mapping as ORM;
use \Application\Entity\AbstractEntity;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity
 * @ORM\Table(name="blog_categories")
 */
class Category extends AbstractEntity {

    // OTHER USELESS CODE

    /**
     * Set parent
     *
     * @param \Blog\Entity\Category $parent
     * @return Category
     */
    public function setParent(\Blog\Entity\Category $parent = null)
    {
        $this->parent = $parent;

        return $this;
    }

    /**
     * Get parent
     *
     * @return \Blog\Entity\Category 
     */
    public function getParent()
    {
        return $this->parent;
    }


    /**
     * Add subcategories
     *
     * @param \Blog\Entity\Category $subcategories
     * @return Category
     */
    public function addSubCategory(\Blog\Entity\Category $subcategories)
    {
        $this->subcategories[] = $subcategories;

        return $this;
    }

    /**
     * Remove subcategories
     *
     * @param \Blog\Entity\Category $subcategories
     */
    public function removeSubCategory(\Blog\Entity\Category $subcategories)
    {
        $this->subcategories->removeElement($subcategories);
    }

    /**
     * Get subcategories
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getSubCategories()
    {
        return $this->subcategories;
    }
}

我的CategoryIterator

<?php

namespace Blog\Entity;

use Doctrine\Common\Collections\Collection;

class CategoryIterator implements \RecursiveIterator
{

    private $_data;

    public function __construct(Collection $data)
    {
        $this->_data = $data;
    }

    public function hasChildren()
    {
        return $this->_data->current()->getSubCategories()->isEmpty();
    }

    public function getChildren()
    {
        return new CategoryIterator($this->_data->current()->getSubCategories());
    }

    public function current()
    {
        return $this->_data->current();
    }

    public function next()
    {
        $this->_data->next();
    }

    public function key()
    {
        return $this->_data->key();
    }

    public function valid()
    {
        return $this->_data->current() instanceof \Blog\Entity\Category;
    }

    public function rewind()
    {
        $this->_data->first();
    }

}

我的IndexController::indexAction()

public function indexAction()
{
    $adapter = new SelectableAdapter($this->doctrine()->getRepository('Blog\Entity\Article'));
    $paginator = new Paginator($adapter);
    $paginator->setCurrentPageNumber($this->params()->fromQuery('page', 1))
              ->setItemCountPerPage(10);


    $categories = $this->doctrine()->getRepository('Blog\Entity\Category')->findBy(array(), array('id' => 'ASC'));

    $iterator = new RecursiveIteratorIterator(
        new CategoryIterator(
            new ArrayCollection($categories)
        ),
        RecursiveIteratorIterator::SELF_FIRST
    );

    return new ViewModel(array(
        'articles' => $paginator,
        'categories' => $iterator,
    ));
}

不要生气,我的所有use陈述都是正确的!

这是我使用categories变量的部分视图(一切都很顺利,因为它之前没有子类别......):

<h3>Catégories</h3>
<ul class="unstyled side-links">
    <?php foreach ($this->categories as $index => $cat) : ?>
        <?php
        if ($cat->getParent() !== null) {
            continue;
        }

        $class = '';
        if (isset($this->current)) {
            if ($this->current === $cat->getId()) {
                $class = 'class="active"';
            }
        }
        ?>
        <li <?= $class; ?>>
            <a href="<?= $this->url('blog/category', array('alias' => $cat->getAlias())); ?>"><?= $cat->getName(); ?></a>
            <?php if ($this->categories->hasChildren()) : ?>
            <ul class="unstyled side-links">
                <?php foreach ($this->categories->getChildren() as $scat) : ?>
                <?php $class2 = ($scat->getId() === $this->current ? 'class="active"' : ''); ?>
                    <li <?= $class2; ?>>
                        <a href="<?= $this->url('blog/category', array('alias' => $scat->getAlias())); ?>"><?= $scat->getName(); ?></a>
                    </li>
                <?php endforeach; ?>
            </ul>
            <?php endif; ?>
        </li>
    <?php endforeach; ?>
</ul>

所以,如果有人可以告诉我为什么它适用于这个人而不适合我,那么,欢迎任何想法!

1 个答案:

答案 0 :(得分:0)

对于任何以相同问题登陆此处的人 - 帖子链接显示功能hasChildren略有不同。

public function hasChildren()
{
    return ( ! $this->_data->current()->getChildCategories()->isEmpty());
}

一旦添加了这个,迭代器就会显示子元素。