0

有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";
}

[更新]

在发布这个问题时,我又尝试了一件似乎有帮助的事情:

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

这在 setMaxResults 设置为 5 时给出 5,当 setMaxResults 设置为 500 时给出 500。必须检查究竟返回了什么,以及在显示它们时是否可以访问每个项目的类别。试图在分页器对象上执行 var_dump 以进行检查,但如果我没有足够快地 xkill 它,它会使 Firefox 崩溃并导致 Fedora 崩溃。

4

3 回答 3

1

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

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

您可以使用{% for item in items %},因为分页器实现了IteratorAggregate.

Next: 当你使用count($paginator)它时会调用count (implements \Countable)。

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

有一点,你有没有试图把fetchJoinCollectionfalse ?// 不应该,但无论如何

于 2013-09-09T07:43:30.470 回答
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()));
}

树枝文件:

<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>
于 2013-09-09T07:07:01.700 回答
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;
    }
}
于 2014-12-09T09:01:33.347 回答