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

26.07.2015

Все формы в друпале защищены с помощью токенов, которые предотвращают подделку межсайтовых запросов. Отсюда вытекает невозможность по умолчанию кэшировать 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
Похожие записи

Комментарии

Василий
21.08.2015, 14:22

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

Сергей
15.09.2015, 13:38

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

$form['#token'] = FALSE;

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

Николай
02.02.2016, 10:52

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

Виталий
16.05.2016, 23:35

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

Добавить комментарий