直接使用分页器并在关联列上定义排序不起作用
Posted
技术标签:
【中文标题】直接使用分页器并在关联列上定义排序不起作用【英文标题】:Using the paginator directly and defining the sort on an associated column not working 【发布时间】:2020-09-19 16:04:27 【问题描述】:Cakephp 版本:4.0.1
简介
这个问题源于我遇到的另一个问题here,其中一个不理想的解决方案是重定向回自身。不幸的是,我正在测试的控制器没有任何关联的列,因此没有发现这个新问题。
我在食谱中引用了this。
希望下面的代码可以重现问题。
联系人表
public function initialize(array $config): void
parent::initialize($config);
$this->setTable('contacts');
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Accounts', [
'foreignKey' => 'account_id'
]);
// Custom Finder
public function findSuperuserAllContacts(Query $query, array $options): object
$query
->where(['Contacts.status' => $options['status']])
->andWhere([
'Users.client_id' => $options['client_id'],
'Users.status' => 1
]);
return $query;
联系人控制器
public $paginate = [
'sortWhitelist' => [
'Contacts.first_name',
'Contacts.last_name',
'Accounts.account_name',
'Users.first_name',
'Users.last_name',
'Contacts.primary_tel',
'Contacts.mobile',
'Contacts.email'
]
];
public function index()
$query = (object) $this->Contacts->find('superuserAllContacts', [
'contain' => ['Users', 'Accounts'],
'status' => 1,
'client_id' => 1001
]);
$page = '';
$sort = 'Accounts.account_name';
$direction = 'asc';
$config = $this->paginate = [
'page' => $page,
'sort' => $sort,
'direction' => $direction,
'limit' => 10
];
$contacts = $this->Paginator->paginate($query, $config);
$this->set(compact('contacts'));
会发生什么
页面在框架中显示类型错误。
C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\View\Helper\PaginatorHelper.php
strtolower() 期望参数 1 是一个字符串,bool 给定
public function sortDir(?string $model = null, array $options = []): string
$dir = null;
if (empty($options))
$options = $this->params($model);
if (isset($options['direction']))
debug($options['direction']); // THIS IS FALSE NOT asc or desc?
$dir = strtolower($options['direction']);
if ($dir === 'desc')
return 'desc';
return 'asc';
来自 error.log 的堆栈跟踪
2020-06-01 10:33:20 错误:[TypeError] strtolower() 期望参数 1 为字符串,布尔值在 C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\View\第 264 行的 Helper\PaginatorHelper.php
堆栈跟踪: - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\View\Helper\PaginatorHelper.php:264 - C:\xampp\htdocs\crm\templates\Contacts\index.php:5 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\View\View.php:1164 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\View\View.php:1125 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\View\View.php:750 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Controller\Controller.php:691 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Controller\Controller.php:533 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Controller\ControllerFactory.php:79 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\BaseApplication.php:229 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:77 - C:\xampp\htdocs\crm\vendor\cakephp\authentication\src\Middleware\AuthenticationMiddleware.php:122 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:73 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\I18n\Middleware\LocaleSelectorMiddleware.php:70 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:73 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:77 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Middleware\CsrfProtectionMiddleware.php:132 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:73 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:58 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Routing\Middleware\RoutingMiddleware.php:162 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:73 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Routing\Middleware\AssetMiddleware.php:68 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:73 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Error\Middleware\ErrorHandlerMiddleware.php:118 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:73 - C:\xampp\htdocs\crm\vendor\cakephp\debug_kit\src\Middleware\DebugKitMiddleware.php:60 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:73 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Runner.php:58 - C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\Http\Server.php:90 - C:\xampp\htdocs\crm\webroot\index.php:40
请求网址:/contacts 参考网址:https://localhost/crm/welcome
问题
为什么会显示类型错误,而不是使用 account_name 上的排序加载索引模板?
谢谢 Z。
编辑
我刚刚尝试了全新安装
composer self-update && composer create-project --prefer-dist cakephp/app:4.* crm
以及烘焙的用户、联系人和帐户。
新版本是 4.0.8,我在新项目中添加了上面的代码,但不幸的是得到了完全相同的类型错误。
如果排序在同一个表上,即:Contacts.last_name,姓氏有排序,但如果我将其更改为关联表 Accounts.account_name,则会显示类型错误。
【问题讨论】:
你的Contacts\index.php
模板在5
线上有什么作用?
另请注意,您没有传递排序字段白名单,这是使用关联字段所必需的。
@ndm - 5
线上的 Contacts\index.php
模板是:debug($this->Paginator->sortDir());。我也可以请您扩展一下,不要像我想的那样通过排序字段白名单。我已经在公共分页属性中声明了排序字段白名单,如帖子所示。这不是通过排序字段白名单吗?
Controller::paginate()
方法没有使用该属性,分页器组件不会自行拾取它,但即使它会,你也完全覆盖它在您的控制器操作中。
@ndm - 啊 - 那么我不确定如何通过排序字段白名单。我在这里引用了 4 食谱:book.cakephp.org/4/en/controllers/components/…,它没有说明其他任何内容。你介意让我知道怎么做吗?或者我可以在哪里找到怎么做。
【参考方案1】:
直接使用分页器时,必须在配置中传递排序字段白名单。
$config = $this->paginate = [
'sortWhitelist' => [
'Contacts.first_name',
'Contacts.last_name',
'Accounts.account_name',
'Users.first_name',
'Users.last_name',
'Contacts.primary_tel',
'Contacts.mobile',
'Contacts.email'
],
'page' => $page,
'sort' => $sort,
'direction' => $direction,
'limit' => 10
];
$contacts = $this->Paginator->paginate($query, $config);
$this->set(compact('contacts'));
排序现在显示在 account_name 上。
【讨论】:
以上是关于直接使用分页器并在关联列上定义排序不起作用的主要内容,如果未能解决你的问题,请参考以下文章