View source
<?php
namespace Drupal\views_custom_cache_tag\Plugin\views\cache;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\views\Plugin\views\cache\Tag;
class CustomTag extends Tag {
use MessengerTrait;
protected $usesOptions = TRUE;
public function summaryTitle() {
return $this
->t('Custom Tag');
}
public function defineOptions() {
$options = parent::defineOptions();
$options['custom_tag'] = array(
'default' => '',
);
return $options;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['custom_tag'] = array(
'#type' => 'textarea',
'#title' => $this
->t('Custom tag list'),
'#description' => $this
->t('Custom tag list, separated by new lines. Caching based on custom cache tag must be manually cleared using custom code.'),
'#default_value' => $this->options['custom_tag'],
);
$optgroup_arguments = (string) t('Arguments');
foreach ($this->view->display_handler
->getHandlers('argument') as $arg => $handler) {
$options[$optgroup_arguments]["{{ arguments.{$arg} }}"] = $this
->t('@argument title', array(
'@argument' => $handler
->adminLabel(),
));
$options[$optgroup_arguments]["{{ raw_arguments.{$arg} }}"] = $this
->t('@argument input', array(
'@argument' => $handler
->adminLabel(),
));
}
if (!empty($options)) {
$output['description'] = [
'#markup' => '<p>' . $this
->t("The following replacement tokens are available for this field. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.") . '</p>',
];
foreach (array_keys($options) as $type) {
if (!empty($options[$type])) {
$items = array();
foreach ($options[$type] as $key => $value) {
$items[] = $key . ' == ' . $value;
}
$item_list = array(
'#theme' => 'item_list',
'#items' => $items,
);
$output['list'] = $item_list;
}
}
$form['tokens'] = $output;
}
}
public function getCacheTags() {
$tags = parent::getCacheTags();
$entity_information = $this->view
->getQuery()
->getEntityTableInfo();
if (!empty($entity_information)) {
foreach ($entity_information as $table => $metadata) {
$remove = \Drupal::entityTypeManager()
->getDefinition($metadata['entity_type'])
->getListCacheTags();
$tags = array_diff($tags, $remove);
}
}
$custom_tags = preg_split('/\\r\\n|[\\r\\n]/', $this->options['custom_tag']);
$custom_tags = array_map('trim', $custom_tags);
$custom_tags = array_map(function ($tag) {
return $this->view
->getStyle()
->tokenizeValue($tag, 0);
}, $custom_tags);
return Cache::mergeTags($custom_tags, $tags);
}
public function cacheExpire($type) {
return FALSE;
}
public function cacheGet($type) {
$result = parent::cacheGet($type);
if ($type == 'results' && !$result && \Drupal::state()
->get('views_custom_cache_tag.execute_debug', FALSE)) {
$this
->messenger()
->addMessage('Executing view ' . $this->view->storage
->id() . ':' . $this->view->current_display . ':' . implode(',', $this->view->args) . ' (' . implode(',', $this->view
->getCacheTags()) . ')');
}
return $result;
}
}