ある時点で、ビューによって生成されたSQLクエリを変更する必要があることに気付き、最終的にviews_pre_execute
を上書きして、その特定のビューのクエリを変更しました。
これは私にとって醜いハックのように感じられ、それを行うためのよりエレガントで保守可能な方法があるかどうか疑問に思います。ビューUIからクエリを直接変更できる方法が理想的です。
hook_views_query_alter()
を使用して、実行前にクエリを変更することもできます。これはhook_views_pre_execute
に似ていると思いますが、クエリの変更が簡単になります。基本的に、キー配列を介してクエリの各部分にアクセスできます。公式ドキュメントはあまり見つかりませんでしたが、- https://www.appnovation.com/blog/using-hook-views-query-alter にかなり良い例があります。これは、Calendarモジュールの日付のバグを修正するために使用しなければならないアプローチでもあります。
通常、これはユースケースによって異なります。
特定の方法で動作するフィールド/フィルター/引数が必要な場合は、そのハンドラーを作成することをお勧めします。詳細については、ビューの高度なヘルプを参照してください。
クエリの一部を変更する場合は、 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' => '=',
);
}
}
}
}
}
ビューmysqlクエリを変更するためにhook_views_query_alter()
を使用しました。次の例は、Drupal 7 with 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を変更できるかどうかはわかりませんが、独自のフィールドハンドラーを記述して独自のクエリを作成できます。