【问题标题】:Using the paginator directly is not recognising the configuration直接使用分页器是无法识别配置的
【发布时间】:2020-09-17 01:39:52
【问题描述】:

CakePHP 版本:4.0.1

简介

我有 2 个方法都使用索引视图,indexsearch。在索引上,可以从选择列表中选择列,并且可以通过输入表单控件输入值,从而可以按列和值进行搜索。该数据通过 GET 发送到搜索方法,在该方法中检查空值并执行查询并呈现索引视图。

在具有以下配置的后来的 3x 版本中,索引视图对所选列进行排序,这就是它的意思。

IE:索引视图在初始加载时对到期日期进行了排序,我选择了任务名称,然后将表单提交给搜索方法。 task_name 有视图渲染时的排序。


任务控制器

公共分页属性:

public $paginate = [
    'sortWhitelist' => [
       'Tasks.due_date',
       'Tasks.task_name',
       'Tasks.type',
       'Tasks.priority',
       'Tasks.related_to_name',
       'Contacts.first_name',
       'Contacts.last_name',
       'Accounts.account_name',
       'Tasks.task_desc'
    ]
];

搜索方法

我初始化从 index 方法接收到的数据并将配置应用到分页属性并将查询对象发送到视图。

$this->setPage('');
$this->setSort($this->request->getQuery('column'));
$this->setDirection('asc');

// Validation of the page, sort, direction and limit is done here.
// IE: The $this->getSort() must be a string and not be numeric and has a strlen check
// and the $this->getDirection() can only be a string with values 'asc' or 'desc' etc. 

if (!empty($this->getPage())) {
    $this->paginate['page'] = $this->getPage();
}
$this->paginate['sort'] = $this->getSort();
$this->paginate['direction'] = $this->getDirection();
$this->paginate['limit'] = $this->getLimit();

debug($this->paginate);

$tasks = $this->paginate($query);
$this->set(compact('tasks'));

调试的结果是:

[
    'sortWhitelist' => [
        (int) 0 => 'Tasks.due_date',
        (int) 1 => 'Tasks.task_name',
        (int) 2 => 'Tasks.type',
        (int) 3 => 'Tasks.priority',
        (int) 4 => 'Tasks.related_to_name',
        (int) 5 => 'Contacts.first_name',
        (int) 6 => 'Contacts.last_name',
        (int) 7 => 'Accounts.account_name',
        (int) 8 => 'Tasks.task_desc'
    ],
    'sort' => 'Tasks.task_name',
    'direction' => 'asc',
    'limit' => (int) 25
 ]

结果
排序在 task_name 上。


几个月前,我升级到了 4,并且刚刚修改了这个功能,发现排序是在索引中存在的列上,而不是在选择的列上。我尝试了以下方法来解决问题:

我在食谱中引用了this 信息。还有来自 SO 的this

$config = $this->paginate = [
    'page' => $this->getPage(),
    'sort' => $this->getSort(),
    'direction' => $this->getDirection(),
    'limit' => $this->getLimit()
];

debug($config);

$tasks = $this->Paginator->paginate($query, $config);

debug($this->Paginator);

$this->set(compact('tasks'));

debug $config 的结果是:

[
    'page' => '',
    'sort' => 'Tasks.task_name',
    'direction' => 'asc',
    'limit' => (int) 25
]

调试 $this->Paginator 的结果是:

object(Cake\Controller\Component\PaginatorComponent) {

    'components' => [],
    'implementedEvents' => [],
    '_config' => [
        'page' => (int) 1,
        'limit' => (int) 20,
        'maxLimit' => (int) 100,
        'whitelist' => [
            (int) 0 => 'limit',
            (int) 1 => 'sort',
            (int) 2 => 'page',
            (int) 3 => 'direction'
        ]
    ]

}

注意:白名单包含限制、排序、页面和方向?而且限制是 20,我什至没有选择 20?

结果
排序是在到期日期,我需要它在任务名称上。

额外信息
如果我然后单击 task_name 上的排序,则排序在 task_name 上。所有类型都不能在初始负载上工作?


问题
如何配置分页属性,以便从搜索方法的初始加载开始排序在 task_name 上。

谢谢 Z。

【问题讨论】:

  • 最初的原始代码到底在做什么?所有这些填充分页配置的 getter 方法,看起来好像您可能将用户输入注入到分页配置中?
  • @ndm 是的,这是可能的,用户可以更改 URL 中的页面、排序、方向和限制,并根据这些值更改显示。我不认为这是一个问题,这些值在设置之后并在确保它们是有效值之前进行验证,但我没有在帖子中显示。我已经编辑了帖子以反映这一点。
  • 我明白了,除非有特定原因,否则可能不应该这样做,因为分页器会自行清理/验证配置用户输入(请求数据)。分页器配置通常只用于配置分页默认值。
  • 很公平,我没有意识到这一点。我确实验证它的原因是为了否定用户将用户输入直接注入分页属性:-) 如果我是正确的,你是说如果我可以直接访问分页器,我就不需要再进行验证了,因为这将调用 $config ,正如您提到的那样,它无论如何都会清理/验证配置用户输入。请注意,仍然存在有效值,因此它们应该仍然可以在配置中使用...
  • 这不是直接访问组件,分页器将默认验证/清理limit/sort/page/direction(在合并用户请求数据和分页器配置后)。话虽如此,在分页配置中指定默认排序对我来说效果很好,帮助程序按预期正确“突出显示”(添加小箭头图标)。您可能需要将其归结为更通用、可重现的示例。

标签: cakephp


【解决方案1】:

修复有点昂贵且不理想,但它确实有效。我对初始负载进行重定向。基本上提交表单进行搜索,然后重定向回搜索。即:

if ($this->request->getQuery('initial') === 'yes') {

    $redirect = $this->request->getQuery('redirect', [
        'action' => 'search',
         '?' => [
             'method' => 'search',
             'column' => $this->getColumn(),
             'input' => $this->getInput(),
             'page' => $this->getPage(),
             'sort' => $this->getSort(),
             'direction' => $this->getDirection(),
             'limit' => $this->getLimit(),
             'filter' => $this->getFilter(),
         ]
    ]);

    return $this->redirect($redirect);
    exit(0);

}

$config = $this->paginate = [
    'sortWhitelist' => [
       'Tasks.due_date',
       'Tasks.task_name',
       'Tasks.type',
       'Tasks.priority',
       'Tasks.related_to_name',
       'Contacts.first_name',
       'Contacts.last_name',
       'Accounts.account_name',
       'Tasks.task_desc'
     ],
     'page' => $this->getPage(),
     'sort' => $this->getSort(),
     'direction' => $this->getDirection(),
     'limit' => $this->getLimit()
 ];

 $tasks = $this->Paginator->paginate($query, $config);
 $this->set(compact('tasks'));

排序现在在 task_name 上。

这消除了初始加载问题,并在我知道排序工作的页面初始加载后模拟了使用情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    相关资源
    最近更新 更多