CakePHPで素書きのSQLでもPaginatorを使いたい!
どうしてもCakePHPのfindで記述ができないSQLでページを実装する必要があることってあると思います。
CakePHPのPaginatorは利用できると非常に楽なので出来れば使用したいところなのです。
なんかできるっぽい!
<?php
App::uses('AppModel ', 'Model');
class RawSql extends AppModel {
public $useTable = false;
function paginate() {
$extra = func_get_arg(6);
$limit = func_get_arg(3);
$page = func_get_arg(4);
$sql = $extra['extra']['type'];
$sql .= ' LIMIT ' . $limit;
if ($page > 1){
$sql .= ' OFFSET ' . ($limit * ($page - 1));
}
return $this->query($sql);
}
function paginateCount() {
$extra = func_get_arg(2);
return count($this->query(
preg_replace(
'/LIMIT \d+ OFFSET \d+$/u',
'',
$extra['extra']['type']
)
));
}
}
こんな感じでモデルを作ると・・・
<?php
App::uses('AppController', 'Controller');
class PostsController extends AppController{
public $uses = ['RawSql'];
function index(){
$sql = 'SELECT * FROM posts';
$query = [
'limit' => 20,
'extra' => [
'type' => $sql
],
];
$this->Paginator->settings = $query;
$history_lists = $this->Paginator->paginate('RawSql');
$this->set('history_lists', $history_lists);
}
}
これだけでpaginateが動作します!
やってること
paginatorの第7引数にextraというカラムがあるので、そこにSQLを突っ込んで強引に実行しているだけです。
LIMITやらOFFSETやらは自分で計算して渡したSQLにくっつけているだけです。
ですが、Paginatorヘルパーの機能の件数やら、ページ番号やらが使えるので、ページングを素で実装するよりかなり楽になると思います。