CakePHP分页:我如何按多列排序以实现“粘性”功能?

时间:2012-12-11 23:54:32

标签: cakephp pagination

我看到这张paginate can't sort two columns at the same time票仍然打开,这让我相信如果没有解决方法,我想要做的就是不可能。所以我想我正在寻找的是一种解决方法。

我正在尝试做许多留言板的工作:拥有“sticky”功能。我想这样做,以便无论用户点击哪个表头链接进行排序,我的模型的“sticky”字段始终是第一个排序的,然后是用户点击的任何列。我知道您可以将$this->paginate['Model']['order']设置为您想要的任何内容,因此您可以将其设置为“sticky”字段并将用户选择的列放在第二位。这种方法的问题在于,在您执行此操作后,分页行为不正常。表头链接无法正常工作,切换页面也无法正常工作。还有其他一些解决方法吗?

4 个答案:

答案 0 :(得分:15)

CakePHP IRC频道上的用户ten1帮助我找到了解决方案。我告诉他,如果他在这里发布了答案,那么我会将其标记为正确答案,但他说我应该自己做,因为他还没有Stack Overflow帐户。

诀窍是使用模型的“beforeFind”回调方法将“sticky”字段注入查询的“order”设置,如下所示:

public function beforeFind($queryData) {
    $sticky = array('Model.sticky' => 'DESC');

    if (is_array($queryData['order'][0])) {
        $queryData['order'][0] = $sticky + $queryData['order'][0];
    }
    else {
        $queryData['order'][0] = $sticky;
    }

    return $queryData;
}

答案 1 :(得分:0)

您可以做的是在动作中对其进行编码。只需在URL上存在某些参数时创建所需的查询。 (参数必须由GET发送)

例如:

public function posts(){
    $optional= array();

    if(!empty($this->params->query['status'])){
                if(strlower($this->params->query['status']=='des')){
        $optional= array('Post.status DESC');
                }

                else if(strlower($this->params->query['status']=='asc')){
                    $optional= array('Post.status ASC');
                }
    }

    if(!empty($this->params->query['department'])){         
        //same...
    }

    //order first by the sticky field and then by the optional parameters.
    $order = array('Post.stickyField DESC') + $optional;


    $this->paginate = array(
            'conditions' => $conditions,
            'order' => $order,
            'paramType' => 'querystring',

    );

    $this->set('posts', $this->paginate('Post'));
}

我使用类似的内容来使用$conditions而不是$order来过滤一些数据,并且效果很好。

答案 2 :(得分:0)

您可以使用自定义字段进行排序和更新分页组件。

控制器代码

$ order ['Document.DATE'] ='asc';

        $this->paginate = array(

                "conditions"=> $conditions ,
                "order" => $order ,
                "limit" => 10,
            **"sortcustom" => array('field' =>'Document.DATE' , 'direction' =>'desc'),**

            );

分页组件的变化。

public function validateSort($ object,$ options,$ whitelist = array()){

    if (isset($options['sort'])) {
        $direction = null;
        if (isset($options['direction'])) {
            $direction = strtolower($options['direction']);
        }
        if ($direction != 'asc' && $direction != 'desc') {
            $direction = 'asc';
        }
        $options['order'] = array($options['sort'] => $direction);
    }

    if (!empty($whitelist) && isset($options['order']) && is_array($options['order'])) {
        $field = key($options['order']);
        if (!in_array($field, $whitelist)) {
            $options['order'] = null;
        }
    }

    if (!empty($options['order']) && is_array($options['order'])) {
        $order = array();
        foreach ($options['order'] as $key => $value) {
            $field = $key;
            $alias = $object->alias;
            if (strpos($key, '.') !== false) {
                list($alias, $field) = explode('.', $key);
            }

            if ($object->hasField($field)) {
                $order[$alias . '.' . $field] = $value;
            } elseif ($object->hasField($key, true)) {
                $order[$field] = $value;
            } elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
                $order[$alias . '.' . $field] = $value;
            }
        }


        **if(count($options['sortcustom']) > 0 )
          {
            $order[$options['sortcustom']['field']] = $options['sortcustom']['direction']; 
          }**


        $options['order'] = $order;
    }

    return $options;
}

答案 3 :(得分:0)

轻松插入'paramType'=> '查询字符串', 显示代码示例:

$this->paginate = array(
    'conditions' => $conditions,
    'order' => array(
        'Post.name' => 'ASC',
        'Post.created' => 'DESC',

    ),
    'paramType' => 'querystring',

);

$this->set('posts', $this->paginate('Post'));