直接使用分页器并在关联列上定义排序不起作用

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 上。

【讨论】:

以上是关于直接使用分页器并在关联列上定义排序不起作用的主要内容,如果未能解决你的问题,请参考以下文章

动态数据的分页器/排序不起作用

使用 ajax 时,Tablesorter 禁用分页器按钮不起作用

jqx - 地址列上的网格排序不起作用

带有连接表字段排序的 Cakephp 分页不起作用

DataTables - 排序,搜索,分页不起作用

为啥分页不起作用并在 wordpress 网站上出现 404 错误?