ある時点で、Viewsによって生成されたSQLクエリを変更する必要があることに気づき、最終views_pre_execute
的にその特定のビューのクエリをオーバーライドして変更しました。
これは私にとっていハックのように感じられ、それを行うためのよりエレガントで保守可能な方法があるのだろうかと思います。ビューUIからクエリを直接変更できる方法が理想的です。
ある時点で、Viewsによって生成されたSQLクエリを変更する必要があることに気づき、最終views_pre_execute
的にその特定のビューのクエリをオーバーライドして変更しました。
これは私にとっていハックのように感じられ、それを行うためのよりエレガントで保守可能な方法があるのだろうかと思います。ビューUIからクエリを直接変更できる方法が理想的です。
回答:
hook_views_query_alter()
クエリを実行する前に変更することもできます。これはに似ていると思いますhook_views_pre_execute
が、クエリの変更が簡単になります。基本的に、キー配列を介してクエリの各部分にアクセスできます。公式のドキュメントはあまり見つけていませんが、https://www.appnovation.com/blog/using-hook-views-query-alterにかなり良い例があります。これは、カレンダーモジュールの日付のバグを修正するために使用しなければならなかったアプローチでもあります。
hook_views_pre_execute()
。
一般に、これはユースケースに依存します。
特定の方法で動作するフィールド/フィルター/引数が必要な場合は、そのハンドラーを作成することをお勧めします。詳細については、ビューの高度なヘルプを参照してください。
クエリの一部を変更したい場合は、hook_views_query_alter()を使用することもできます。悪い点hook_views_query_alter()
は、そこでコードを実際に再利用できないことです。
これは、ドキュメントに示されているサンプルコードです。フックができることの例を示します。
function mymodule_views_query_alter(&$view, &$query) {
// (Example assuming a view with an exposed filter on node title.)
// If the input for the title filter is a positive integer, filter against
// node ID instead of node title.
if ($view->name == 'my_view' && is_numeric($view->exposed_raw_input['title']) && $view->exposed_raw_input['title'] > 0) {
// Traverse through the 'where' part of the query.
foreach ($query->where as &$condition_group) {
foreach ($condition_group['conditions'] as &$condition) {
// If this is the part of the query filtering on title, chang the
// condition to filter on node ID.
if ($condition['field'] == 'node.title') {
$condition = array(
'field' => 'node.nid',
'value' => $view->exposed_raw_input['title'],
'operator' => '=',
);
}
}
}
}
}
を使用しhook_views_query_alter()
て、ビューのmysqlクエリを変更しました。次の例は、Drupal 7でテストされており、クエリに7.x-3.0
カスタムORDER BY
句を追加します。
function MYTHEME_views_query_alter(&$view, &$query) {
// check so it's the correct view
if($view->name == 'product_view') {
// set a custom 'ORDER BY' clause in the query
$query->orderby[0] = array(
'field' => 'SUBSTR(taxonomy_term_data_name,3,4)',
'direction' => 'ASC'
);
$query->orderby[1] = array(
'field' => 'SUBSTR(taxonomy_term_data_name,1,2)',
'direction' => 'ASC'
);
}
}
sqlを直接変更できるかどうかはわかりませんが、独自のフィールドハンドラを作成し、独自のクエリを作成できます。