私はどうにもページャと聞くと瞬間的に邪魔くさいと感じるのだけど、これは過去の体験のせいで、今となってはすごく簡単だ。
方法はいろいろあるだろうが、とにかくCakePHP3を使えばよい。
以下のリンクのページネータコンポーネントとページネータヘルパーを使う。
https://book.cakephp.org/3.0/ja/controllers/pages-controller.html
https://book.cakephp.org/3.0/ja/views/helpers/paginator.html
使う方法は説明されている。まったく付け入るすきがない。口を挟む余地がない。黙って上のドキュメントを読んでほしい。
こんなのはどうだろう
しかし、こんな人間でも人のためになりたい。いや、こんな人間だからかも知れない。とにかく今は人の役に立ちたいのだ。
例えば、同じページで複数一覧を同時にページングする方法をご存知だろうか?なんなら私が記載致しましょうか?これが人のためになるのですか?
けれど、これもドキュメントに書いてあるのだ。
https://book.cakephp.org/3.0/ja/controllers/components/pagination.html#paginating-multiple-queries
https://book.cakephp.org/3.0/ja/views/helpers/paginator.html#paginator-helper-multiple
ただただ、ありがたい。そもそも考えてみれば公式ドキュメントに戦いを挑むのは無謀だ。
ひとのため、ありました
一つ問題がありまして、複数一覧の同時ページャはCakePHPバージョン3.3から追加された新機能です。もしそれ以前のバージョンでやりたかったらどうしますか?
それはこれ、以下のようにすると、動きます。
検証version: 3.1.13
use Cake\Controller\Component\PaginatorComponent;
use Cake\Utility\Hash;
class AppPaginatorComponent extends PaginatorComponent
{
public function paginate($object, array $settings = [])
{
if ($object instanceof QueryInterface) {
$query = $object;
$object = $query->repository();
}
$alias = $object->alias();
$options = $this->mergeOptions($alias, $settings);
$options = $this->validateSort($object, $options);
$options = $this->checkLimit($options);
$options += ['page' => 1, 'scope' => null];
$options['page'] = (int)$options['page'] < 1 ? 1 : (int)$options['page'];
list($finder, $options) = $this->_extractFinder($options);
if (empty($query)) {
$query = $object->find($finder, $options);
} else {
$query->applyOptions($options);
}
$results = $query->all();
$numResults = count($results);
$count = $numResults ? $query->count() : 0;
$defaults = $this->getDefaults($alias, $settings);
unset($defaults[0]);
$page = $options['page'];
$limit = $options['limit'];
$pageCount = (int)ceil($count / $limit);
$requestedPage = $page;
$page = max(min($page, $pageCount), 1);
$request = $this->_registry->getController()->request;
$order = (array)$options['order'];
$sortDefault = $directionDefault = false;
if (!empty($defaults['order']) && count($defaults['order']) == 1) {
$sortDefault = key($defaults['order']);
$directionDefault = current($defaults['order']);
}
$paging = [
'finder' => $finder,
'page' => $page,
'current' => $numResults,
'count' => $count,
'perPage' => $limit,
'prevPage' => ($page > 1),
'nextPage' => ($count > ($page * $limit)),
'pageCount' => $pageCount,
'sort' => key($order),
'direction' => current($order),
'limit' => $defaults['limit'] != $limit ? $limit : null,
'sortDefault' => $sortDefault,
'directionDefault' => $directionDefault,
'scope' => $options['scope'],
];
if (!isset($request['paging'])) {
$request['paging'] = [];
}
$request['paging'] = [$alias => $paging] + (array)$request['paging'];
if ($requestedPage > $page) {
throw new NotFoundException();
}
return $results;
}
public function mergeOptions($alias, $settings)
{
$defaults = $this->getDefaults($alias, $settings);
$request = $this->_registry->getController()->request;
$scope = Hash::get($settings, 'scope', null);
$query = $request->query;
if ($scope) {
$query = Hash::get($query, $scope, []);
}
$request = array_intersect_key($query, array_flip($this->_config['whitelist']));
return array_merge($defaults, $request);
}
}
use Cake\View\Helper;
use Cake\View\Helper\PaginatorHelper;
use Cake\Utility\Hash;
class AppPaginatorHelper extends PaginatorHelper
{
public function generateUrl(array $options = [], $model = null, $full = false)
{
$paging = $this->params($model);
$paging += ['page' => null, 'sort' => null, 'direction' => null, 'limit' => null];
$url = [
'page' => $paging['page'],
'limit' => $paging['limit'],
'sort' => $paging['sort'],
'direction' => $paging['direction'],
];
if (!empty($this->_config['options']['url'])) {
$key = implode('.', array_filter(['options.url', Hash::get($paging, 'scope', null)]));
$url = array_merge($url, Hash::get($this->_config, $key, []));
}
$url = array_filter($url, function ($value) {
return ($value || is_numeric($value));
});
$url = array_merge($url, $options);
if (!empty($url['page']) && $url['page'] == 1) {
$url['page'] = false;
}
if (isset($paging['sortDefault'], $paging['directionDefault'], $url['sort'], $url['direction']) &&
$url['sort'] === $paging['sortDefault'] &&
$url['direction'] === $paging['directionDefault']
) {
$url['sort'] = $url['direction'] = null;
}
if (!empty($paging['scope'])) {
$scope = $paging['scope'];
$currentParams = $this->_config['options']['url'];
// Merge existing query parameters in the scope.
if (isset($currentParams['?'][$scope]) && is_array($currentParams['?'][$scope])) {
$url += $currentParams['?'][$scope];
unset($currentParams['?'][$scope]);
}
$url = [$scope => $url] + $currentParams;
if (empty($url[$scope]['page'])) {
unset($url[$scope]['page']);
}
}
return $this->Url->build($url, $full);
}
}
わざわざ書くまでも無いですが、最新のソースを参考に移植しただけです。
人のためになるのは難しい。
大体、人のためになって何を望むのか。何を得ようというのか。何が得られれば満足なのか。人のためになる目的はなんなのか。
今回の記事の目的は査定のためです。ひいては・・・。
以上