Добавление условия для множественного поля термина таксономии в запросе для hook_views_query_alter

Главные вкладки

Аватар пользователя erbie erbie 27 сентября 2018 в 9:07

Добрый день! Помогите решить задачку.

Необходимо переопределить запрос для вьюса в hook_views_query_alter

Пример:

<?php
$definition 
= [
                    
'table' => 'node__field_characs',
                    
'field' => 'entity_id',
                    
'left_table' => 'node',
                    
'left_field' => 'nid',
                    
'operator' => '='
                
];
$join = \Drupal::service('plugin.manager.views.join')->createInstance('standard'$definition);
$rel $query->addRelationship('node__field_characs'$join'node');
?>
<?php
$q_and 
db_and();
 
$i 1;
foreach(
$ch_id as $key => $val_array){
         
$q_and->condition('node__field_characs.field_characs_target_id'$val_array'IN');
         
$i++;
}
 
$query->addWhere(0$q_and);
?>

То есть необходимо добавить условие для множественного поля термина таксономии. Если в массиве $ch_id один элемент, запрос выводится правильно, но если больше одного, то не выводится ни одной ноды.

Результат сформированного условия примерно такой

<?php
Drupal
\Core\Database\Query\Condition Object
        
(
            [
conditions:protected] => Array
                (
                    [
#conjunction] => AND
                    
[0] => Array
                        (
                            [
field] => node__field_characs.field_characs_target_id
                            
[value] => Array
                                (
                                    [
0] => 187
                                    
[1] => 188
                                
)
                            [
operator] => IN
                        
)
                    [
1] => Array
                        (
                            [
field] => node__field_characs.field_characs_target_id
                            
[value] => Array
                                (
                                    [
0] => 375
                                    
[1] => 17
                                
)
                            [
operator] => IN
                        
)
                )
            [
arguments:protected] => Array
                (
                )
            [
changed:protected] => 1
            
[queryPlaceholderIdentifier:protected] => 
            [
stringVersion:protected] => 
?>

Комментарии

Аватар пользователя erbie erbie 27 сентября 2018 в 9:35

Нужен именно AND. Так как условие, чтобы в нодах были термины из одной группы И из другой. Если ставить ИЛИ - то выводятся ноды, где есть любой из этих терминов.

Аватар пользователя erbie erbie 27 сентября 2018 в 13:19

Здесь дело не в операторах. Само условие правильное, но при формировании объекта условия, названия полей должны быть с разными индексами. Вот здесь примерное объяснение - QueryInterface::condition - "tags" "is the same as "tags.value" as value is the default column. If two or more conditions have the same field names they apply to the same delta within that field.
Но delta у полей с одним и тем же значением может быть разным.

Аватар пользователя erbie erbie 27 сентября 2018 в 13:26

Для понимания, вот такое условие формирует вьюс по умолчанию. В фильтрах - множественное значение термина таксономии.

<?php
Drupal
\Core\Database\Query\Condition Object
        
(
            [
conditions:protected] => Array
                (
                    [
#conjunction] => OR
                    
[0] => Array
                        (
                            [
field] => node__field_characs_value_0.field_characs_target_id
                            
[value] => 187
                            
[operator] => =
                        )
                    [
1] => Array
                        (
                            [
field] => node__field_characs_value_1.field_characs_target_id
                            
[value] => 188
                            
[operator] => =
                        )
                    [
2] => Array
                        (
                            [
field] => node__field_characs_value_2.field_characs_target_id
                            
[value] => 375
                            
[operator] => =
                        )
                    [
3] => Array
                        (
                            [
field] => node__field_characs_value_3.field_characs_target_id
                            
[value] => 17
                            
[operator] => =
                        )
                )
            [
arguments:protected] => Array
                (
                )
            [
changed:protected] => 1
            
[queryPlaceholderIdentifier:protected] => 
            [
stringVersion:protected] => 
        )

?>
Аватар пользователя erbie erbie 27 сентября 2018 в 13:24

Как сделать так, чтоб собственное условие тоже формировалось с добавлением индексов к названиям полей? Это должно как то делаться автоматом.
Если добавлять поля с помощью $query->addField, то выдает ошибку.

Аватар пользователя merlin merlin 27 сентября 2018 в 15:06

Я решил подобную задачу по другому - https://drupal.ru/node/137969#comment-718050
В контекстном фильтре задал множественный параметр, добавил агрегацию и через хук ограничил сумму по агрегации. Сработало как надо.
Может и для 8ки сработает?