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

Using the paginator directly and defining the sort on an associated column not working

CakePHP 版本:4.0.1

简介

这个问题源于我遇到的另一个问题 ,其中一个不理想的解决方案是重定向回自身。不幸的是,我正在测试的控制器没有任何关联的列,因此没有发现这个新问题。

我在食谱中引用了 this

希望下面的代码能够重现问题。


联系人Table

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 为字符串,第 264 行 C:\xampp\htdocs\crm\vendor\cakephp\cakephp\src\View\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

请求URL:/联系人
推荐人 URL:https://localhost/crm/welcome


问题

为什么显示类型错误而不是加载索引模板 account_name?

谢谢 Z.


编辑

我刚刚尝试使用

进行全新安装

composer 自我更新 && composer create-project --prefer-dist cakephp/app:4.* crm

以及烘焙用户、联系人和帐户。

新版本是4.0.8,我在新项目中添加了上面的代码,但不幸的是得到了完全相同的类型错误。

如果排序相同 table,即:Contacts.last_name 姓有排序,但如果我将其更改为关联的 table Accounts.account_name 显示类型错误。

直接使用分页器时,必须在配置中传递排序字段白名单。

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