cakePHP5でちょっとしたシステムを構築していたときのことでした。
cake/bakeで作ったビューとコントローラーをカスタムしていき作業が進んでいる間に、ちょっとデータの表示を確認しようと一覧ページを開きました。
普段はidの昇順で表示するのですが、タイトル順でどうなるかを試したところ、何も変わることなく通常の表示をしました。
では、日付順(created)ではどうかと思ったのですが、これも同じく動かないのです。
まさか、ページネーションもできなくなってる?と思い、10件ほど登録していたデータを5件分毎の表示にしてみると、それは動く。
良かった(汗)
一覧ページのデフォルトで生成されたビューの項目には最初からsortのURLが付いた状態で出力されていて、クリックすると以下のようなURLが生まれます。
例:タイトル順にソート
http://localhost/hogehoge/index/?sort=title&direction=asc
例:登録順にソート
http://localhost/hogehoge/index/?sort=created&direction=asc
けど、これが機能してないっぽいのです。
まああまりタイトル順でソートすることはないのですが、登録日順でのソートはする可能性あるかもなので、ひとまず手作業でページネーションにソート機能を追加してみました。
他の案件で同じようなことがあるかもということでメモ。
class HogehogeController extends AppController
{
// ページネーション機能
protected array $paginate = [
'limit' => 5,
'order' => [
'Hogehoge.id' => 'asc',
],
'sortableFields' => [ // いらないかも
'id', 'title', 'genre', 'duration', 'created', 'modified',
],
];
public function index() {
// ソートに関するクエリパラメータを取得
$sort = $this->request->getQuery('sort'); // デフォルトは'id'
$direction = $this->request->getQuery('direction'); // デフォルトは'asc'
// sortの値を指定
$sort_ary = ['id', 'title', 'created'];
$direction_ary = ['asc', 'desc'];
// 指定以外はソートに関係させない
if((!empty($sort) and in_array($sort, $sort_ary)) and (!empty($direction) and in_array($direction, $direction_ary))) {
$order_ary = [$sort => $direction];
} else {
$order_ary = ['id' => 'DESC'];
}
$query = $this->Hogehoge->find()->order($order_ary);
$results = $this->paginate($query, [
'limit' => 5, // 1ページあたりの表示件数 // 最初に設定してるからいらないかも
]);
$this->set(compact('results'));
}
この結果、ビューにはソートで並び替えられたデータが5件ずつ表示されるようになりました。