Все формы в друпале защищены с помощью токенов, которые предотвращают подделку межсайтовых запросов. Отсюда вытекает невозможность по умолчанию кэшировать 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
Комментарии
Спасибо за решение. Недавно с этим сам столкнулся
Можно в form_alter для этой формы просто отключить проверку токена:
тогда закэшированные формы не будут сабмититься
А если есть BEF. Это не помешает и будет работать с фильтрами?
не должно помешать
Здравствуйте, у меня с корзиной Commerce Cart Ajax (dc_cart_ajax) не работает. что это может быть? я бы с радостью перешел на вашу корзину, но не имею такой возможности, а кешировать вьюс очень надобно
Добавить комментарий