PageList オブジェクトで検索・ソートを行う

concrete5 の Concrete\Core\Page\PageList オブジェクトを使えば、開発者がconcrete5に様々な条件でページを一覧表示させることができます。このオブジェクトは、複雑なテーブル構造を気にせずに、権限やエイリアスを配慮した上で、いつでもソート、検索、フィルターを適用することができるAPIを提供します。

$list = new \Concrete\Core\Page\PageList();

デフォルトでは、このリストは何もフィルターされていない、サイト内のすべてのページを含みます。また、エイリアスと非アクティブなページ(ゴミ箱または下書きフォルダー内のページ)、権限設定を元にユーザーが閲覧できないページは除外されます。

$pages = $list->getResults();

上記は取得したリスト内の、件数を制限しないすべてのページの配列になります。配列内の各エントリーはページオブジェクトになります。

基本的なフィルターのサンプル

ページタイプでフィルター

$list->filterByPageTypeHandle('blog_entry');

複数のタイプでフィルター

$list->filterByPageTypeHandle(array('blog_entry', 'press_release'));

キーワードでフィルター(シンプル)

$list->filterByKeywords('foobar');

キーワードでのフィルターは、ページの名前、説明、テキストコンテンツ、「検索インデックスに含む」にマークされている検索可能なページ属性を対象に検索します。

キーワードでフィルター(フルテキスト)

$list->filterByFulltextKeywords('foobar');

ページの名前、説明、テキストコンテンツをMySQLのFULLTEXT検索インデックスを使って検索

属性でフィルター

PageList オブジェクトは、属性で絞り込むためのマジックメソッドを持っています。StudlyCaps(単語の先頭文字を大文字で表記する記法)記法に変換した属性ハンドルを filterBy の後ろにつけたメソッドにデータを渡すだけで使えます。

$list->filterByExcludeFromNav(true);

属性のタイプごとに、フィルターメソッドが取る値の種類は変わります。例えば、属性がトピックの場合、トピックツリーノードオブジェクトになります。

$node = \Concrete\Core\Tree\Node::getByID(10);
$list->filterByBlogEntryTopic($node);

ソート

表示日時でソート

$list->sortByPublicDate();

または降順

$list->sortByPublicDateDescending();

名前でソート

$list->sortByName();

サイトマップ順でソート

$list->sortByDisplayOrder();

権限と特殊なページ

権限を無視

$list->ignorePermissions();

特殊なページを含める

$list->includeInactivePages(); // 非アクティブページ
$list->includeAliases(); // エイリアス
$list->includeSystemPages(); // システムページ

高度な使い方

カスタムクエリー

PageList クラスは concrete5.7 から Doctrine DBAL QueryBuilder を用いて完全に書き直されました。PageList オブジェクトから直接 QueryBuilder オブジェクトを取得し操作することもできます。

$query = $list->getQueryObject();

サブクラス

PageList を継承してサブクラスを作成することもできます。特定のページタイプとカスタム属性を持ったページのみ表示するクラスを作成する例を示します。

<?php
 
namespace PortlandLabs\ClassifiedList;
 
use Concrete\Core\Page\PageList;
 
class ClassifiedList extends PageList
{
 
    /** @var boolean */
    protected $includeInactive = false;
 
    public function __construct()
    {
        parent::__construct();
 
        $this->ignorePermissions();
        $this->filterByPageTypeHandle('classified');
        $this->setItemsPerPage(10);
        $this->sortByPublicDateDescending();
    }
 
    public function deliverQueryObject()
    {
        if (!$this->includeInactive) {
            $this->filterByClassifiedIsDeactivated(false);
        }
        return parent::deliverQueryObject();
    }
 
    public function includeInactive()
    {
        $this->includeInactive = true;
    }
 
    public function filterByActive($start, $end = null)
    {
        if (!$end) {
            $end = $start;
        }
        $this->filterByPublicDate(date('Y-m-d H:i:s', $end), "<=");
        $this->filterByAttribute('special_offer_end_date', date('Y-m-d H:i:s', $start), ">=");
    }
 
}

ページネーション

PageList オブジェクトでフィルターを適用したあとで、getResults() を使ってページのリストを取得することができますが、多くの場合、一度にその一部を取得し、ページ送りで次の一部を表示したいと思います。このような場合に、Pagination オブジェクトを使用することができます。

$pagination = $list->getPagination();

権限を考慮する場合

ページリストで権限を考慮する場合、$pagination オブジェクトは Concrete\Core\Search\Pagination\PermissionablePagination オブジェクトのインスタンスになります。この場合、フィルター内容に該当する全ての結果(最大1000件)が取得され、権限のチェックが行われます。

権限を考慮しない場合

PageList オブジェクトで権限のチェックをしない場合、よりシンプルな Concrete\Core\Search\Pagination\Pagination オブジェクトが使われます。

Pagination オブジェクトから様々な操作が行えます。

結果の総数を取得

print $pagination->getTotalResults();

ページ数を取得

print $pagination->getTotalPages();

次/前のページが存在するか

$pagination->hasNexPage();
$pagination->hasPreviousPage();

そして、現在のページの結果を取得できます。

$pagination->setMaxPerPage(10)->setCurrentPage(2);
$results = $pagination->getCurrentPageResults();

ページネーションを表示

Bootstrap 2, Bootstrap 3, 基本形、concrete5 スタイル(Bootstrap 3にインスパイアされています)といった一般的なページネーションの出力をサポートしています。

print $pagination->renderDefaultView(); // Bootstrap 3 スタイルでHTMLに出力(管理画面などに最適)

ページネーションの出力は、Pagerfanteライブラリを使用しており、カスタマイズが可能です。詳細はこちら

API リファレンス

PageList API Reference 

Pagination API Reference 

原文:Searching and Sorting with the PageList object

その他の参考ページ