无法获得与Symfony合作的doctrines paginator

时间:2013-09-09 06:33:29

标签: php symfony doctrine many-to-many paginator

有2个类Item和Categoy,一个项目可以有更多类别,一个类别可以有多个项目。这是类的样子:

项目类:

<?php

namespace m\r\Entity;
use Doctrine\ORM\Mapping as ORM;

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

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

    /**
     * @ORM\ManyToMany(targetEntity="Category")
     * @ORM\JoinTable(name="Item_Category",
     *      joinColumns={@ORM\JoinColumn(name="Item_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="Category_id", referencedColumnName="id")}
     *      )
     */
    private $categories;

    public function __construct() {
        $this->categories = new \Doctrine\Common\Collections\ArrayCollection();
    }
    // getters and setters removed to keep post short
    // Add categories removed
    // Remove categories removed
}
?>

分类:

<?php

namespace m\rBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

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

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

    /**
     * @ORM\ManyToMany(targetEntity="Item")
     * @ORM\JoinTable(name="Item_Category",
     *      joinColumns={@ORM\JoinColumn(name="Category_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="Item_id", referencedColumnName="id")}
     *      )
     */
    private $items;

    public function __construct() {
        $this->items = new \Doctrine\Common\Collections\ArrayCollection();
    }
    // bunch of getters and setters removed to keep post short(and addCategory)
}
?>

控制器:

public function indexAction() {
    $dql = "select i, c FROM mrBundle:Item i  join i.categories c";
    $query = $this->getDoctrine()->getManager()->createQuery($dql)
            ->setFirstResult(0)
            ->setMaxResults(5);
    $paginator = new Paginator($query, $fetchJoinCollection = true);
    var_dump(count($paginator));// shows 2143 no matter what setMaxResults is
    return "Doest really work";
}

[UPDATE]

在发布此问题时,我尝试了另外一件似乎有帮助的事情:

    var_dump(count($paginator->getIterator()));

当setMaxResults设置为500时,这给出5,当setMaxResults设置为500时,这给出5。必须检查返回的确切内容以及在显示时是否可以访问每个项目的类别。试图在paginator对象上做一个var_dump进行检查,但是如果我没有足够快速地使用它,就会崩溃Firefox并关闭Fedora。

3 个答案:

答案 0 :(得分:1)

所以,根据我从代码中读到的内容,

如果控制器返回array('items' => $paginator)

您可以使用{% for item in items %},因为paginator实现了IteratorAggregate

下一步:当您使用count($paginator)时,它会调用count(实现\Countable)。

此方法使用SQL执行实际COUNT(),并且行为与...不同 count($paginator->getIterator())仅计算结果数量。)

有一点,您是否尝试将fetchJoinCollection置为假? //不应该但是无论如何

答案 1 :(得分:0)

是的,看起来像$paginator->getIterator()返回正确数量的记录,树枝形式可以到达类别。这是代码:

public function indexAction() {
    $dql = "select i, c FROM mrBundle:Item i  join i.categories c";
    $query = $this->getDoctrine()->getManager()->createQuery($dql)
            ->setFirstResult(0)
            ->setMaxResults(5);
    $paginator = new Paginator($query, $fetchJoinCollection = true);
    return $this->render('mrBundle:Default:index.html.twig', 
            array('items' => $paginator->getIterator()));
}

Twig文件:

<ul id="items">
{% for item in items %}
        <li>
            <a href="{{ path('mr_open',{'id': item.id}) }}">
              {{ item.title }}</a>
            {% for category in item.categories %}
                {{category.CategoryName}}
            {% endfor %}
        </li>
{% endfor %}
</ul>

答案 2 :(得分:0)

这是我的分页器,对某人有用:

namespace XXX\YourBundle\Library;

/**
 * @author websky
 * 
 * Licensed MIT
 * Paginator 
 * 
 * instruction:
 * 1. Controller
 * use XXX\YourBundle\Library\Paginator;
 * new Paginator(data_array, limit, $current);
 * and metods
 * createPaginator()
 * createPaginatorData()
 * 
 * example:
 * controller
 * use XXX\YourBundle\Library\Paginator;
 * $page = ($request->query->get('page') ? $request->query->get('page') : 1);
 * $paginator = new Paginator($this->resultQueryArray(), 1, $page);
 * return $this->render('YourBundle:Your:your.html.twig', array('list' => $paginator->createPaginator(), 'resultData' => $paginator->createPaginatorData()));
 * 
 * 2. View - example
 * {% if resultData.allElements >= 2 %}
 *           <section class="pagination">
 *               {% if resultData.first == resultData.current %}
 *                   <a href="#" class="firstoff"></a>
 *               {% else %}
 *                   <a href="{{path('your_route',{'page' : resultData.first})}}" class="first"></a>
 *               {% endif %}    
 *               {% if resultData.previous == 0 %}
 *                   <a href="#" class="prevoff"></a>
 *               {% else %}
 *                   <a href="{{path('your_route',{'page' : resultData.previous})}}" class="prev"></a>
 *               {% endif %}    
 *               {% for i in 1..resultData.allElements %}
 *                   {% if resultData.allElements < 8 %}
 *                       {% if i == resultData.current %}
 *                           <a href="{{path('your_route',{'page' : i})}}"  class="page-number active">{{ i }}</a>
 *                       {% else %} 
 *                           <a href="{{path('your_route',{'page' : i})}}"  class="page-number">{{ i }}</a>
 *                       {% endif %}
 *                   {% else %}
 *                       {% if i == resultData.current %}
 *                           <a href="{{path('your_route',{'page' : i})}}"  class="page-number active">{{ i }}</a>
 *                       {% elseif (i == (resultData.current - 3)) or (i == (resultData.current - 2)) or (i == (resultData.current - 1)) or (i == (resultData.current + 1)) or (i == (resultData.current + 2)) or (i == (resultData.current + 3)) %}
 *                          <a href="{{path('your_route',{'page' : i})}}"  class="page-number">{{ i }}</a>         
 *                       {% endif %}
 *                   {% endif %}
 *                   
 *               {% endfor %} 
 *               of <a href="{{path('your_route',{'page' : resultData.allElements})}}"  class="page-number">{{resultData.allElements}}</a>
 *               {% if resultData.next  %}      
 *                   <a href="#{{path('your_route',{'page' : resultData.next})}}"  class="next"></a>
 *               {% else %}
 *                   <a href="#" class="nextoff"></a>
 *               {% endif %}
 *               {% if resultData.last == resultData.current %} 
 *                   <a href="#" class="lastoff"></a>  
 *               {% else %}
 *                   <a href="{{path('your_route',{'page' : resultData.last})}}" class="last"></a>
 *               {% endif %}
 *           </section>
 *           {% endif %}
 */
class Paginator 
{
    protected $limit;
    protected $current;
    protected $previous;
    protected $next;
    protected $jump;
    protected $last;
    protected $data;
    protected $numberElements;
    protected $allElements;
    protected $sourceLength;

    /**
     * Pagination construct object
     * @param array $data
     * @param integer $limit
     * @param integer $current
     */
    public function __construct($data, $limit = 5, $current = 1)
    {
        $this->data = $data;
        $this->limit = $limit;
        $this->current = $current;
        $this->sourceLength = count($data);
        $this->setAllElements();
        $this->setNumberElements();
    }

    /**
     * Set limit
     * @param integer $limit
     * @return \XXX\YourBundle\Library\Paginator
     */
    public function setLimit($limit)
    {
        $this->limit = $limit;

        return $this;
    }

    /**
     * Get limit
     * @return integer
     */
    public function getLimit()
    {
        return $this->limit;
    }  

    /**
     * Set current
     * @param integer $current
     * @return \XXX\YourBundle\Library\Paginator
     */
    public function setCurrent($current)
    {
        $this->current = $current;

        return $this;
    }

    /**
     * Get current
     * @return integer
     */
    public function getCurrent()
    {
        return $this->current;
    }

    /**
     * Set previous
     * @param integer $previous
     * @return \XXX\YourBundle\Library\Paginator
     */
    public function setPrevious($previous)
    {
        $this->previous = $previous;

        return $this;
    }

    /**
     * Get previous
     * @return integer
     */
    public function getPrevious()
    {
        return $this->previous;
    }

    /**
     * Set next
     * @param integer $next
     * @return \XXX\YourBundle\Library\Paginator
     */
    public function setNext($next)
    {
        $this->next = $next;

        return $this;
    }

    /**
     * Get next
     * @return integer
     */
    public function getNext()
    {
        return $this->next;
    }

    /**
     * Set last
     * @param integer $last
     * @return \XXX\YourBundle\Library\Paginator
     */
    public function setLast($last)
    {
        $this->last = $last;

        return $this;
    }

    /**
     * Get last
     * @return integer
     */
    public function getLast()
    {
        return $this->last;
    }

    /**
     * Set AllElements
     * These are all elements of an array.
     * @return \XXX\YourBundle\Library\Paginator
     */
    public function setAllElements()
    {
        $this->allElements = count($this->data);
        return $this;
    }

    /**
     * Set NumberElements
     * This is the number of pages for the paginator.
     * @return \XXX\YourBundle\Library\Paginator
     */
    public function setNumberElements()
    {
        $this->numberElements = ceil ($this->allElements / $this->limit);
        return $this;
    }

    /**
     * Creates an array of data to control.
     * @return array
     */
    public function createPaginatorData()
    {
        $shareArray['limit'] = $this->limit;
        $shareArray['allElements'] = $this->numberElements;
        $shareArray['current'] = $this->current;
        $shareArray['first'] = 1;
        $shareArray['previous'] = $this->current != 0 ? $this->current - 1 : false;
        $shareArray['next'] = $this->current != $this->numberElements ? $this->current + 1 : false;
        $shareArray['last'] = $this->numberElements;
        $shareArray['sourcelength'] = $this->sourceLength;

        return $shareArray;
    }

    /**
     * Returns the elements of the page.
     * @return array
     */
    public function createPaginator()
    {
        $result = array();
        for($i=(($this->current * $this->limit) - $this->limit); $i < ($this->current * $this->limit); $i++){
            if(array_key_exists($i, $this->data)){
                $result[] = $this->data[$i];
            }
        } 
        return $result;
    }
}