Symfony2: Pagerを実装する方法


Symfony2にはページャーが標準ではありません。と言っても標準につけるくらいの機能ではないというのも実際で。

まずは準備から。

config.ymlにはこうのように登録

services:
    pager:
        class: Acme\BlogBundle\Classes\Pager
        arguments: ["@service_container", "@doctrine.orm.entity_manager"]
        scope: request

Acme\BlogBundle\Classes\Pager に Pager.php を作成して下記の内容にします。

<?php

namespace App\BlogBundle\Classes;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class Pager
{
    
    var $entityManager;
    var $serviceContainer;
    
    var $inc;
    var $offset;
    var $count;
    var $is_next = true;
    var $path;
    
    public function __construct($serviceContainer, $entityManager)
    {
        $this->serviceContainer = $serviceContainer;
        $this->entityManager = $entityManager;
        
        $this->offset = $this->serviceContainer->get('request')->get('offset');
        if(!$this->offset) $this->offset = 0;
        if(!preg_match('/^\d{1,}$/', $this->offset)) $this->offset = 0;
        
    }
    public function setPath($path){
        $this->path = $path;
    }    
    public function setInc($inc){
        $this->inc = $inc;
    }
    public function getRepository($namespace, $where = array(), $orderby = array()){
        
        $entities = $this->entityManager->getRepository($namespace)->findBy(
            $where,
            $orderby,
            $this->inc,
            $this->offset
        );
        $this->count = count($entities);
        $this->is_next = $this->count >= $this->inc ? true : false;
        
        return $entities;
        
    }
    public function getParameters(){
        
        return array(
            'next' => $this->offset + $this->inc, 
            'prev' => $this->offset - $this->inc, 
            'current' => $this->offset, 
            'is_next' => $this->is_next, 
            'inc' => $this->inc, 
            'count' => $this->count,
            'path' => $this->path
        );
    }
}

Acme/BlogBundle/Blog/Resources/Views/Blog に pager.parts.html.twig を保存内容は下記の通り

<p>
{% if pager.prev >= 0 %}
<a href="{{ path(pager.path, {'offset': pager.prev}) }}" class="btn">前へ</a> 
{% endif %}

{{ pager.current }}件 から {{ pager.count }} 件を表示

{% if (pager.next >= 0 and pager.is_next) %}
<a href="{{ path(pager.path, {'offset': pager.next}) }}" class="btn">次へ</a>
{% endif %}
</p>

これで準備は整いました。ではControeller、Templateの2箇所にコードを書きます。

Controllerでは下記のように。


$pager = $this->get('pager');
$pager->setInc(20); // 20件表示
$pager->setPath('blog'); // ページのrouting path

$entities = $pager->getRepository('AcmeBlogBundle:Blog',array('createdUser' => $this->getUser()), array('id' => 'DESC')); /* namespace, where, orderby の引数です */

return $this->render('AcmeBlogBundle:Blog:index.html.twig', array(
    'pager' => $pager->getParameters(),
    'entities' => $entities,
));

AcmeBlogBundle:Blog:index.html.twigのテンプレートにはこう書いてください

{% include 'AcmeBlogBundle:Blog:pager.parts.html.twig' %}
  • このエントリーをはてなブックマークに追加

コメント

  1. 悠木 彩斗 より:

    Acme\BlogBundle\Classes\Pager.php
    namespace App\CommonBundle\Classes;

    のところは
    namespace Acme\BlogBundle\Classes;

    と記述しないと動かないのでは?

    PagerクラスはCommonBundleの名前の方がしっくり来ますが。

    • yuta より:

      コメントありがとうございます。namespaceなどはブログ用に書き換えているので多少動作しているものと違うかもしれません。ご指摘ありがとうございますー。確認してみます!

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です