環境
PHP 7.2.21
CakePHP 2.10.18
MySQL 5.7.27
内容
ページネイトは便利機能であるが単純なfindのデータのみでしか出来ないっぽい
別DBに接続して得たデータやPHP側で修正をかけた自作の配列でもページネイトできればうれしい
ページネイトは内部でfindを実行しているのでControllerで用意した配列をセットしてそれをfindとして返すのみのページネイト専用Modelを作成してそれを利用した
やったこと
Paginate専用のModelを新規作成し、Controllerでそれをuse
Controllerでデータを加工した後にPaginate専用Modelにデータをセットしてからpaginate関数にModel名を渡す
Model/CustomArrayPaginator.php
<?php
class CustomArrayPaginator extends AppModel {
public $useTable = false;
// Paginatorに渡す配列データ
public $data = [];
/**
* 受け取ったデータをpagingする為にfindをoverride
*
* @return array
*/
public function find($type = 'first', $query = []): array {
if (is_null($this->data)) {
$this->data = [];
}
$page = Hash::get($query, 'page', 1);
$limit = Hash::get($query, 'limit', 10);
if ($page === 1) {
// 1ページ目はoffset無し
$offset = 0;
} else {
// 2ページ目以降はページ数-1に分割数をかけたものをoffsetとする
$offset = ($page - 1) * $limit;
}
$result = array_slice($this->data, $offset, $limit);
return $result;
}
/**
* 配列数の独自計算の為にpaginateCountをoverride
*
* @param array|null $conditions
* @param integer|null $recursive
* @param array|null $extra
* @return integer カウント数
*/
public function paginateCount($conditions = null, $recursive = 0, $extra = []) {
$this->recursive = $recursive;
return count($this->data);
}
}
Controller/HogeController.php
<?php
// 追加Modelをuseに追加
App::uses('CustomArrayPaginator', 'Model');
App::uses('Fuga', 'Model');
class HogeController extends AppController {
// 追加Modelを$uses配列に追加
public $uses = [
'CustomArrayPaginator',
'Fuga',
];
public $paginate = [
'limit' => 10,
];
public function index() {
// 加工前のデータを取得
// ※limitは設定しない!!!
$tmpData = $this->Fuga->find('all', [
'fields' => ['*'],
'conditions' => ['del_flg' => '0'],
'order' => [
'Fuga.id' => 'asc',
]
]);
// 関数で取得したデータを色々加工
$dispData = $this->modDispData($tmpData);
// 加工したデータをModelの$dataにセットし、overrideしたfindでページネイトすることでセットした値をそのまま使用
$this->CustomArrayPaginator->data = $dispData;
// Model名を渡す
$result = $this->paginate('CustomArrayPaginator');
}
}
結果
自分で任意に加工したデータをpaginateすることができた!!
今回の例ではFugaテーブルから単純なfindしかしていないげどJOINなども思いのままです