CakePHPでソート順を追加する

トピックは何になりますか?


それを達成する方法については、CSSを使用するか、html出力でテーブルの列を並べ替えるのではなく、テーブルの列を並べ替える順序(asc | desc)を決定/確認することができます。



要するに、たとえば次のようなYandexスケジュールのように実行します。

ソート順



これをどのように行いますか?


いくつかのオプションがあります。 かつて、彼は大量の「ケーキ」ソースをシャベルで削ったため、以下を除いて正解の(リソース集約型ではない)ソリューションを見つけることができませんでした。 3つのソリューションのうち:

  1. コントローラーのどこかにあるオーバーロードされたafterRender()関数でhtmlを解析します(リソースを集中的に呼び出すことはありません)
  2. カーネルにパッチを当てる
  3. PaginatorHelperヘルパーから継承される独自のヘルパーを作成し、そこで必要なメソッドをオーバーロードします


私は3番目を選びました。 これには3つの理由もあります。

  1. これはパフォーマンスにほとんど影響しません。
  2. 私はここで記事を書くかどうかを考えていましたが、CakePHP 1.3.0のベータ版がリリースされ、すでに修正されています。ここには同様の質問のチケットもあります。 しかし、これはベータ版であるため、すべてが更新されているわけではなく、トピックはまだ関連しているため、すぐには更新されません
  3. これは、CakePHPのロジックと矛盾しません。




実装


少し追加します。 とても。 私たちのアイデアから達成するために必要なもの。 だから。



ファイル\ cake \ libs \ view \ helpers \ paginator.phpが見つかります。 調べて、sort()関数を見つけます。 ロジックを見てみましょう:

function sort($title, $key = null , $options = array()) {

$options = array_merge(array( 'url' => array(), 'model' => null ), $options);

$url = $options[ 'url' ];

unset($options[ 'url' ]);



if (empty($key)) {

$key = $title;

$title = __(Inflector::humanize(preg_replace( '/_id$/' , '' , $title)), true );

}

$dir = 'asc' ;

$sortKey = $ this ->sortKey($options[ 'model' ]);

$isSorted = ($sortKey === $key || $sortKey === $ this ->defaultModel() . '.' . $key);



if ($isSorted && $ this ->sortDir($options[ 'model' ]) === 'asc' ) {

$dir = 'desc' ;

}



if (is_array($title) && array_key_exists($dir, $title)) {

$title = $title[$dir];

}



$url = array_merge(array( 'sort' => $key, 'direction' => $dir), $url, array( 'order' => null ));

return $ this ->link($title, $url, $options);

}




* This source code was highlighted with Source Code Highlighter .








ソート順クラスを追加するために必要なものはすべて揃っていることがわかります。 著者の論理は理解不能であり、おそらく彼らは単に考えも忘れもしなかったのでしょう。

これで、このファイルに小さなコーデックを追加して、カーネルにパッチを適用し、リストにある対応するメソッド番号2を使用できます。

unset($options['url']);



unset($options['url']);



追加:

// patch:

if ($title == @$ this -> params [ 'named' ][ 'sort' ]) {

$options[ 'class' ] = $ this -> params [ 'named' ][ 'direction' ];

}

// endpatch




* This source code was highlighted with Source Code Highlighter .






これの利点は、異なるプロジェクトに同じフレームワークを使用する場合、個別に変更されたヘルパーを持ち歩く必要がないことです。



それでは、もっと興味深い方法に移りましょう。

ファイル\ app \ views \ helpers \ my_paginator.phpまたは必要に応じて他の名前を作成します(クラス名は後で変更することを忘れないでください)。 書き込みます:



<?php



App::import( 'Helper' , 'Paginator' );



class MyPaginatorHelper extends PaginatorHelper {



/**

* Generates a sorting link

*

* @param string $title Title for the link.

* @param string $key The name of the key that the recordset should be sorted.

* @param array $options Options for sorting link. See #options for list of keys.

* @return string A link sorting default by 'asc'. If the resultset is sorted 'asc' by the specified

* key the returned link will sort by 'desc'.

*/

function sort($title, $key = null , $options = array()) {

$options = array_merge(array( 'url' => array(), 'model' => null ), $options);

$url = $options[ 'url' ];

unset($options[ 'url' ]);



// patch:

if ($title == @$ this -> params [ 'named' ][ 'sort' ]) {

$options[ 'class' ] = $ this -> params [ 'named' ][ 'direction' ];

}

// endpath



if (empty($key)) {

$key = $title;

$title = __(Inflector::humanize(preg_replace( '/_id$/' , '' , $title)), true );

}

$dir = 'asc' ;

$sortKey = $ this ->sortKey($options[ 'model' ]);

$isSorted = ($sortKey === $key || $sortKey === $ this ->defaultModel() . '.' . $key);



if ($isSorted && $ this ->sortDir($options[ 'model' ]) === 'asc' ) {

$dir = 'desc' ;

}



if (is_array($title) && array_key_exists($dir, $title)) {

$title = $title[$dir];

}



$url = array_merge(array( 'sort' => $key, 'direction' => $dir), $url, array( 'order' => null ));

return $ this ->link($title, $url, $options);

}

}

?>



* This source code was highlighted with Source Code Highlighter .








そして、AppControllerでそれを使用することを忘れないでください:

// ...

class AppController extends Controller {

var $helpers = array( 'Html' , 'Form' , 'Ajax' , 'Javascript' , 'MyPaginator' );



// ...




* This source code was highlighted with Source Code Highlighter .








以上です! Webアプリケーションは次のようになります。

< a class ="asc" id ="link1091361951" href ="/search/page:1/sort:first_name/direction:desc" > First Name </ a >



* This source code was highlighted with Source Code Highlighter .






したがって、クラスasc | descが存在する場合、この列はソートされ、クラス自体によってどの程度正確に検索できるかがわかります。



頑張って!



UPD:コメントを考えると、$ this-> paramsの存在について知っており、すべての情報がそこにあると言いたいです。 しかし、毎回、各列に対して条件を記述することは良い考えではありません。特に、この機能を追加する必要がある既製のプロジェクトがあります。



All Articles