View source
<?php
namespace Drupal\gutenberg\Plugin\Filter;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Drupal\gutenberg\BlocksRendererHelper;
use Symfony\Component\DependencyInjection\ContainerInterface;
class BlockFilter extends FilterBase implements ContainerFactoryPluginInterface {
protected $blocksRenderer;
protected $renderer;
public function __construct(array $configuration, $plugin_id, $plugin_definition, BlocksRendererHelper $blocks_renderer, RendererInterface $renderer) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->blocksRenderer = $blocks_renderer;
$this->renderer = $renderer;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('gutenberg.blocks_renderer'), $container
->get('renderer'));
}
public function process($text, $langcode) {
$lines = explode("\n", $text);
$lines = preg_replace_callback('#<!-- wp:drupalblock\\/.*\\s(\\{.*\\})\\s\\/-->#', [
$this,
'renderBlock',
], $lines);
$text = implode("\n", $lines);
$result = new FilterProcessResult($text);
$metadata = $this
->cacheabilityMetadata($text);
$result
->setCacheTags($metadata['tags']);
$result
->setCacheContexts($metadata['contexts']);
$result
->setCacheMaxAge($metadata['max-age']);
return $result;
}
private function renderBlock($match) {
$comment = $match[0];
$attributes = json_decode($match[1]);
$plugin_id = $attributes->blockId;
$config = [];
$plugin_block = $this->blocksRenderer
->getBlockFromPluginId($plugin_id, $config);
$content = '';
if (!empty($plugin_block)) {
if ($this->blocksRenderer
->isAccessForbidden($plugin_block)) {
return [
'#type' => 'html_tag',
'#tag' => 'h2',
'#value' => $this
->t('Access required'),
];
}
$content = $this->blocksRenderer
->getRenderFromBlockPlugin($plugin_block);
}
if (!empty($attributes->className)) {
$prefixed = [
'#type' => 'html_tag',
'#tag' => 'div',
'#value' => $content,
'#attributes' => [
'class' => [
$attributes->className,
],
],
];
$content = $this->renderer
->render($prefixed);
}
return $comment . $content;
}
private function cacheabilityMetadata($text) {
$metadata = [
'tags' => [],
'contexts' => [],
'max-age' => 0,
];
preg_match_all('#<!-- wp:drupalblock\\/.*\\s(\\{.*\\})\\s\\/-->#', $text, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $match) {
$attributes = json_decode($match);
$block = $this->blocksRenderer
->getBlockFromPluginId($attributes->blockId, []);
$build = $block
->build();
$metadata['tags'] = array_merge($metadata['tags'], isset($build['#cache']['tags']) ? $build['#cache']['tags'] : $block
->getCacheTags());
$metadata['contexts'] = array_merge($metadata['contexts'], isset($build['#cache']['contexts']) ? $build['#cache']['contexts'] : $block
->getCacheContexts());
$max_age = isset($build['#cache']['max-age']) ? $build['#cache']['max-age'] : $block
->getCacheMaxAge();
if ($max_age < $metadata['max-age']) {
$metadata['max-age'] = $max_age;
}
}
$metadata['tags'] = array_unique($metadata['tags']);
$metadata['contexts'] = array_unique($metadata['contexts']);
}
return $metadata;
}
}