eu_cookie_compliance_rocketship-1.0.x-dev/src/Plugin/Filter/CookieContentBlockerAutoSrcFilter.php
src/Plugin/Filter/CookieContentBlockerAutoSrcFilter.php
<?php
namespace Drupal\eu_cookie_compliance_rocketship\Plugin\Filter;
use Drupal\Core\Url;
use function preg_match_all;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Render\RendererInterface;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Text filter that wraps iframes into <cookiecontentblocker> tags.
*
* @Filter(
* id = "cookie_content_blocker_filter_auto_src",
* title = @Translation("Cookie content blocker filter - autowrap entire field if external src found"),
* description = @Translation("This filter automatically wraps the entire field into Cookie content blocker's custom <cookiecontentblocker> tags if it finds any src attributes pointing to external domains. <br/><i>Note:</i> It <strong>requires</strong> and it must run <strong>before</strong> the 'Cookie content blocker filter'."),
* type = \Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE,
* )
*/
class CookieContentBlockerAutoSrcFilter extends FilterBase implements ContainerFactoryPluginInterface {
/**
* The renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
private $renderer;
/**
* Construct a CookieContentBlockerFilter plugin.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer.
*/
public function __construct(array $configuration, string $plugin_id, $plugin_definition, RendererInterface $renderer) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->renderer = $renderer;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): CookieContentBlockerAutoSrcFilter {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('renderer')
);
}
/**
* {@inheritdoc}
*/
public function process($text, $langcode): FilterProcessResult {
$result = new FilterProcessResult($text);
if (empty($text)) {
return $result;
}
return $result->setProcessedText($this->wrapContent($text));
}
/**
* Wrap entire text if there are src tags pointing to external domains.
*
* @param string $text
* The HTML/Text we want verify and wrap.
*
* @return string
* The original or the conditionally wrapped text.
*/
private function wrapContent(string $text): string {
$matches = $this->matchSrcAttrs($text);
$external_srcs = FALSE;
$front_url = Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString();
$current_url_parts = parse_url($front_url);
$current_domain = implode('.', array_slice(explode('.', $current_url_parts['host']), -2, 2));
foreach ($matches as $index => $src) {
$src_parts = parse_url($src);
if (isset($src_parts['host'])) {
$src_domain = implode('.', array_slice(explode('.', $src_parts['host']), -2, 2));
if ($src_domain !== $current_domain) {
$external_srcs = TRUE;
break;
}
}
}
if ($external_srcs) {
$blocked_content_element = [
// We depend on other filters to have sanitized the content.
'#markup' => Markup::create('<cookiecontentblocker>' . $text . '</cookiecontentblocker>'),
];
$text = $this->renderer->renderPlain($blocked_content_element);
}
return $text;
}
/**
* Match any src="" attributes.
*
* @param string $text
* The HTML/Text string.
*
* @return array
* An array containing full pattern matches.
*/
private function matchSrcAttrs(string $text): array {
preg_match_all('/src\s*=\s*"(.+?)".*?/s', $text, $matches);
return $matches[1];
}
}
