xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Кэширование Views с товарами в Drupal Commerce

Опубликовано в

Все формы в друпале защищены с помощью токенов, которые предотвращают подделку межсайтовых запросов. Отсюда вытекает невозможность по умолчанию кэшировать html с формами, например вывод представлений с товарами и кнопкой "Добавить в корзину".

Решаем проблему:

1. В форме "Добавить в корзину" подменяем токен на заглушку

/**
 * Implements hook_form_BASE_FORM_ID_alter: commerce_cart_add_to_cart_form.
 */
function MODULENAME_form_commerce_cart_add_to_cart_form_alter(&$form, &$form_state) {
  if (!empty($form['#token']) && $view = views_get_current_view()) {
    $cache_options = $view->display_handler->get_option('cache');
    if ($cache_options['type'] != 'none') {
      $form['form_token']['#default_value'] = $form['#token'];
    }
  }
}

2. В момент вывода вьюса заменяем заглушку на реальный токен

/**
 * Implements hook_views_post_render().
 */
function MODULENAME_views_post_render(&$view, &$output, &$cache) {
  $cache_options = $view->display_handler->get_option('cache');
  if ($cache_options['type'] != 'none') {
    $output = preg_replace_callback('/<input type="hidden" name="form_token" value="commerce_cart_add_to_cart_form_(\d+)" \/>/', function ($matches) {
      return '<input type="hidden" name="form_token" value="' . drupal_get_token('commerce_cart_add_to_cart_form_' . $matches[1]) . '" />';
    }, $output);
  }
}

3. Отключаем кэширование вьюса при сабмите формы

/**
 * Implements hook_views_pre_view().
 */
function MODULENAME_views_pre_view(&$view, &$display_id, &$args) {
  if (isset($_POST['form_id']) && strpos($_POST['form_id'], 'commerce_cart_add_to_cart_form') === 0) {
    $view->display_handler->override_option('cache', array('type' => 'none'));
  }
}

Код доступен в виде модуля — Commerce Views Cache.

Способ прекрасно работает с модулем Commerce Fast Ajax Add to Cart.

Написанное актуально для Commerce 1
Похожие записи

Комментарии RSS

Спасибо за решение. Недавно с этим сам столкнулся

Можно в form_alter для этой формы просто отключить проверку токена:

$form['#token'] = FALSE;

тогда закэшированные формы не будут сабмититься

А если есть BEF. Это не помешает и будет работать с фильтрами?

не должно помешать

Здравствуйте, у меня с корзиной Commerce Cart Ajax (dc_cart_ajax) не работает. что это может быть? я бы с радостью перешел на вашу корзину, но не имею такой возможности, а кешировать вьюс очень надобно

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

После этого модуль заработал, как нужно.

/<input type="hidden" name="form_token" value="commerce_cart_add_to_cart_form_([]\d[_]+)" \/>/

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании