[РЕШЕНО] Ограничить вывод представления в зависимости от значения date материала

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

Аватар пользователя vkapas vkapas 24 октября 2014 в 21:07

Задача: вывести views-блок на страницах старых материалов, поле date которых ≤ вчера. То есть на страницах, у которых поле date равно «сегодня» или где-то в будущем, выводить блок не нужно.

Не могу понять: как такое настраивается во Views?

Очень нужна ваша помощь.

UPD.

Решение: условие указывается в настройках блока.

Комментарии

Аватар пользователя Orion76 Orion76 25 октября 2014 в 10:32

Вьюс - Фильтры - Добавить - Содержимое: Дата публикации

Оператор: Меньше, чем
Тип значения: Смещение от текущего времени...
Значение "-1 day"

Теоретически должно работать...

Аватар пользователя vkapas vkapas 25 октября 2014 в 13:58

Да, верно, фильтровать нужно не результат, а ноды, на страницах которых появляется представление. Причём именно по полю, созданному с помощью Date, которое, как правило, всегда отличается от даты создания ноды. Практический пример: сайт мероприятий, где на страницах прошедших мероприятий нужно показывать ссылки на мероприятия ещё не прошедшие. Мероприятия публикуются задолго до своего начала.

"ХулиGUN" wrote:
Это настраивается в видимости блока а не во вьюхе. Выбираете вариант с пхп и там уже получаете объект ноды и проверяете её дату

Напомните, пжста, как «выбрать вариант с php». Помню, когда-то делал такие штуки с 6-кой, но в 7-ке с наскоку найти не удалось.

Аватар пользователя vkapas vkapas 25 октября 2014 в 16:22

О, спасибо, adamant08. Получилось вывести то, что нужно, с помощью кода

<?php
$node 
menu_get_object();
if ( !empty(
$node) && $node->type == 'football_match' ) {
if ( !empty(
$node->field_date) && !empty($node->field_date['und']) && !empty($node->field_date['und'][0]) ) {
     
$parts explode('T'$node->field_date['und'][0]['value']);
     
$date_parts explode('-'$parts[0]);
     
$date $date_parts[1] . '/' $date_parts[2] . '/' $date_parts[0] . ' ' $parts[1];
     
$on strtotime($date);
     
$now time();
if ( 
$on <= $now ) {
return 
TRUE;
     }
  }
}
return 
FALSE;
?>

, где:

  • football_match — тип материала;
  • date — название поля с датой мероприятия.

(Код-условие можно добавить в нужный блок в поле под названием «Если введённый PHP-код возвращает значение», которое появится после включения модуля PHP filter.)

Единственное, что на страницах, где появился нужный мне views-блок, появилось вот такая петрушка:

Notice: Undefined offset: 1 в функции eval() (строка 7 в файле /site.ru/modules/php/php.module(80) : eval()'d code).
Notice: Undefined offset: 1 в функции eval() (строка 7 в файле /site.ru/modules/php/php.module(80) : eval()'
d code).

Не критично, конечно, но и хорошего тоже ничего в этом нет. Видимо, где-то в условиях я всё же умудрился сделать ошибку (или она там уже была). PHP-шники, не подскажете, где именно?

Аватар пользователя vkapas vkapas 25 октября 2014 в 16:25

Немного погуглив, нашёл решение (увы, не программист, поэтому не знаю, насколько элегантное, но всё работает). Нужно сменить строку 7 в коде выше на
     $date = $date_parts[1] . '/' . $date_parts[2] . '/' . $date_parts[0] . ' ' . @$parts[1];

В итоге получается следующий код:

<?php
$node 
menu_get_object();
if ( !empty(
$node) && $node->type == 'football_match' ) {
if ( !empty(
$node->field_date) && !empty($node->field_date['und']) && !empty($node->field_date['und'][0]) ) {
     
$parts explode('T'$node->field_date['und'][0]['value']);
     
$date_parts explode('-'$parts[0]);
     
$date $date_parts[1] . '/' $date_parts[2] . '/' $date_parts[0] . ' ' . @$parts[1];
     
$on strtotime($date);
     
$now time();
if ( 
$on <= $now ) {
return 
TRUE;
     }
  }
}
return 
FALSE;
?>

Всем большое спасибо за помощь, задача решена.

Аватар пользователя vkapas vkapas 25 октября 2014 в 20:54

"ХулиGUN" wrote:
Явная наркомания

Возможно :-). В моём случае главное чтобы раболо.

...И, кстати, оказалось, что не работает, а с ликованием я поторопился. В общем, нужный мне блок появляется на страницах всех мероприятий — и старых и новых. Изначально я неправильно его проверял.

Поэтому продолжаю искать решение.

Аватар пользователя vkapas vkapas 26 октября 2014 в 0:31

orion76 wrote:
По-моему для подобных случаев сильно хвалили модуль context..
http://www.drupal.ru/node/70478[/quote]

Интересный модуль, да, но, по-моему, не очень подходит для моего случая. Поискав, я нашёл Context entity field, но ему можно передать только какое-то конкретное значение поля, а не условие:

Есть ещё вроде обнадёживающий Context Date, который, увы, не умеет взаимодействовать с полем, созданным через модуль Date.

Аватар пользователя Orion76 Orion76 26 октября 2014 в 0:56

А пробовали, если выборка вьюса-блока "пустая" - блок отображается?
Может во вьюсе-блоке в настройках можно чего-то наковырять (Поведение при отсутствии результатов)

UPD. если при отсутствии результатов можно блоку css-класс назначить, то топику можно ставить "РЕШЕНО"-)

Аватар пользователя vkapas vkapas 4 ноября 2014 в 20:47

Не без помощи добрых людей решение найдено.

В процессе поиска немного изменилось условие, а именно: скрытие материалов, поле date которых не ≤ вчера, а < сейчас (с точностью до минуты). То есть показываем только то, что ещё не началось. Это показалось мне более логичным, т.к. шанс, что кто-то будет покупать билеты на мероприятие, которое только что началось, всё равно стремится к нулю.

Итоговый код условия видимости блока в зависимости от значения поля date выглядит так:

<?php
if((arg(0) == 'node') && (is_numeric(arg(1)))){
 
$node node_load(arg(1));
  if(
$node->type == 'football_match'){
    
$now REQUEST_TIME;
   
$time strtotime($node->field_date['und'][0]['value']);
  if(
$time $now){
    return 
TRUE;
  }

}
}

?>

, где:

  • football_match — тип нашего материала с датой;
  • field_date — название поля с датой у этого материала.