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件ずつ表示されるようになりました。