2012-12-11 57 views
6

我看到這個paginate can't sort two columns at the same time票據仍然打開,這讓我相信,我想要做的事情是不可能的,沒有解決方法。所以我想我正在尋找的是一種解決方法。CakePHP分頁:如何按多列進行排序以實現「粘性」功能?

我試圖做很多留言板的工作:有一個「sticky」函數。我希望這樣做以便無論用戶點擊哪個表頭鏈接進行排序,我的模型的「sticky」字段始終是排序的第一件事,然後是用戶點擊的任何列。我知道你可以設置$this->paginate['Model']['order']爲任何你想要的,所以你可以破解它把「sticky」字段放在第一位,用戶選擇的列放在第二位。這種方法的問題在於,執行分頁後表現不正確。表格標題鏈接無法正常工作,切換頁面也無法正常工作。有其他解決方法嗎?

回答

15

CakePHP IRC頻道上的用戶ten1幫助我找到了解決方案。我告訴他,如果他在這裏發佈了答案,我會將其標記爲正確的,但他說我應該自己做,因爲他還沒有Stack Overflow帳戶。

訣竅是「粘性」字段注入查詢的「命令」使用模型的「beforeFind」回調方法的設置,像這樣:

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; 
} 
+0

整潔而簡單!謝謝:-) – Angad

+2

一個簡單的upvote沒有顯示我對這個答案是多麼感激,所以這裏有一條評論真的讓你知道! – WOUNDEDStevenJones

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過濾掉一些數據的東西,它工作得很好。

+0

我很感激你的時間,但事情是我想讓「粘性」字段對用戶100%透明。他們永遠不應該*不能*先粘貼物品。它不應該出現在網址或任何內容中,但排序鏈接和頁面鏈接仍然可以正常工作。 – Nick

+0

您可以在我發佈的代碼中使用您的「粘性」字段,它對於最終用戶來說是完全透明的。其他類型,與CakePHP類型一起使用,可以一如既往地通過URL顯示。 – Alvaro

+0

我已經編輯它來定購它始終由粘性字段和可選的URL參數。 – Alvaro

0

您可以使用自定義字段進行排序和更新分頁零件。

控制器代碼

$順序[ 'Document.DATE'] = 'ASC';

 $this->paginate = array(

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

      ); 

分頁組件的變化。

公共函數validateSort($對象,$選項,$白名單=陣列()){

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; 
} 
0

易於插入'paramType'=> '查詢字符串', 顯示代碼示例:

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

    ), 
    'paramType' => 'querystring', 

); 

$this->set('posts', $this->paginate('Post')); 
相關問題