class XBBCodeFilter in Extensible BBCode 4.0.x
Same name and namespace in other branches
- 8.3 src/Plugin/Filter/XBBCodeFilter.php \Drupal\xbbcode\Plugin\Filter\XBBCodeFilter
- 8.2 src/Plugin/Filter/XBBCodeFilter.php \Drupal\xbbcode\Plugin\Filter\XBBCodeFilter
Provides a filter that converts BBCode to HTML.
Plugin annotation
@Filter(
id = "xbbcode",
module = "xbbcode",
title = @Translation("Extensible BBCode"),
description = @Translation("Render <code>[bbcode]</code> tags to HTML."),
type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
settings = {
"linebreaks" = TRUE,
"tags" = "",
"xss" = TRUE,
}
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\filter\Plugin\FilterBase implements FilterInterface
- class \Drupal\xbbcode\Plugin\Filter\XBBCodeFilter implements ContainerFactoryPluginInterface
- class \Drupal\filter\Plugin\FilterBase implements FilterInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of XBBCodeFilter
1 file declares its use of XBBCodeFilter
- TagFormBase.php in src/
Form/ TagFormBase.php
File
- src/
Plugin/ Filter/ XBBCodeFilter.php, line 39
Namespace
Drupal\xbbcode\Plugin\FilterView source
class XBBCodeFilter extends FilterBase implements ContainerFactoryPluginInterface {
/**
* The tag set storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $storage;
/**
* The tag plugin manager.
*
* @var \Drupal\xbbcode\TagPluginManager
*/
protected $manager;
/**
* The tag plugins.
*
* @var \Drupal\xbbcode\TagPluginCollection
*/
protected $tags;
/**
* The tag set (optional).
*
* @var \Drupal\xbbcode\Entity\TagSetInterface
*/
protected $tagSet;
/**
* The parser.
*
* @var \Drupal\xbbcode\Parser\ParserInterface
*/
protected $parser;
/**
* The cache tags that invalidate this filter.
*
* @var string[]
*/
protected $cacheTags = [];
/**
* XBBCodeFilter constructor.
*
* @param array $configuration
* Plugin configuration.
* @param string $plugin_id
* Plugin ID.
* @param mixed $plugin_definition
* Plugin definition.
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
* The tag set storage.
* @param \Drupal\xbbcode\TagPluginManager $manager
* The tag plugin manager.
*/
public function __construct(array $configuration, string $plugin_id, $plugin_definition, EntityStorageInterface $storage, TagPluginManager $manager) {
$this->storage = $storage;
$this->manager = $manager;
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager')
->getStorage('xbbcode_tag_set'), $container
->get('plugin.manager.xbbcode'));
}
/**
* {@inheritdoc}
*/
public function setConfiguration(array $configuration) : XBBCodeFilter {
parent::setConfiguration($configuration);
if ($this->settings['tags'] && ($this->tagSet = $this->storage
->load($this->settings['tags']))) {
$this->tags = $this->tagSet
->getPluginCollection();
$this->cacheTags = $this->tagSet
->getCacheTags();
}
else {
$this->tags = $this->manager
->getDefaultCollection();
// Without a tag set, invalidate it when any custom tag is created.
$this->cacheTags = [
'xbbcode_tag_new',
];
}
$this->parser = new XBBCodeParser($this->tags);
return $this;
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) : array {
$form['linebreaks'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Convert linebreaks to HTML.'),
'#default_value' => $this->settings['linebreaks'],
'#description' => $this
->t('Newline <code>\\n</code> characters will become <code><br /></code> tags.'),
];
$form['xss'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Restrict unsafe HTML by escaping.'),
'#default_value' => $this->settings['xss'],
'#description' => $this
->t('Do not disable this feature unless it interferes with other filters. Disabling it can make your site vulnerable to script injection, unless HTML is already restricted by other filters.'),
];
$options = [];
foreach ($this->storage
->loadMultiple() as $id => $tag) {
$options[$id] = $tag
->label();
}
$form['tags'] = [
'#type' => 'select',
'#title' => $this
->t('Tag set'),
'#empty_value' => '',
'#default_value' => $this->settings['tags'],
'#options' => $options,
'#description' => $this
->t('Without a <a href=":url">tag set</a>, this filter will use all available tags with default settings.', [
':url' => Url::fromRoute('entity.xbbcode_tag_set.collection')
->toString(),
]),
];
if ($collisions = $this->manager
->getDefaultNameCollisions()) {
$form['collisions'] = [
'#theme' => 'item_list',
'#items' => array_map(static function ($x) {
return "[{$x}]";
}, array_keys($collisions)),
'#prefix' => $this
->t('The following default names are each used by multiple plugins. A tag set is needed to assign unique names; otherwise each name will be assigned to one of its plugins arbitrarily.'),
];
}
return $form;
}
/**
* {@inheritdoc}
*/
public function tips($long = FALSE) : string {
if ($long) {
$output = $this->tags
->getTable();
$output['#caption'] = $this
->t('You may use the following BBCode tags:');
}
else {
$output = $this->tags
->getSummary();
$output['#prefix'] = $this
->t('You may use the following BBCode tags:') . ' ';
}
$output['#cache']['tags'] = $this->cacheTags;
// @todo Remove once FilterInterface::tips() is modernized.
$output = \Drupal::service('renderer')
->render($output);
return $output;
}
/**
* {@inheritdoc}
*/
public function prepare($text, $langcode) : string {
$tree = $this->parser
->parse($text);
return static::doPrepare($tree);
}
/**
* {@inheritdoc}
*/
public function process($text, $langcode) : FilterProcessResult {
$tree = $this->parser
->parse($text);
if ($this->settings['xss']) {
static::filterXss($tree);
}
// Reverse any HTML filtering in attribute and option strings.
static::decodeHtml($tree);
// The core AutoP filter breaks inline tags that span multiple paragraphs.
// Since there is no advantage in using <p></p> tags, this filter uses
// ordinary <br /> tags which are usable inside inline tags.
if ($this->settings['linebreaks']) {
static::addLinebreaks($tree);
}
$output = $tree
->render();
$result = new FilterProcessResult($output);
$result
->addCacheTags($this->cacheTags);
foreach ($tree
->getRenderedChildren() as $child) {
if ($child instanceof TagProcessResult) {
$result = $result
->merge($child);
}
}
return $result;
}
/**
* Recursively apply source transformations to each tag element.
*
* @param \Drupal\xbbcode\Parser\Tree\ElementInterface $node
* The parse tree.
*
* @return string
* The fully prepared source.
*/
public static function doPrepare(ElementInterface $node) : string {
if ($node instanceof NodeElementInterface) {
$content = [];
foreach ($node
->getChildren() as $child) {
$content[] = static::doPrepare($child);
}
$content = implode('', $content);
if ($node instanceof TagElementInterface) {
$processor = $node
->getProcessor();
if ($processor instanceof TagPluginInterface) {
$content = $processor
->prepare($content, $node);
}
return "[{$node->getOpeningName()}{$node->getArgument()}]{$content}[/{$node->getClosingName()}]";
}
return $content;
}
return $node
->render();
}
/**
* Reverse HTML encoding that other filters may have applied.
*
* The "option" and "attribute" values are provided to plugins as raw input
* (and will be filtered by them before printing).
*
* @param \Drupal\xbbcode\Parser\Tree\NodeElementInterface $tree
* The parse tree.
*/
public static function decodeHtml(NodeElementInterface $tree) : void {
$filter = static function (string $text) : string {
// If the string is free of raw HTML, decode its entities.
if (!preg_match('/[<>"\']/', $text)) {
$text = Html::decodeEntities($text);
}
return $text;
};
foreach ($tree
->getDescendants() as $node) {
if ($node instanceof TagElementInterface) {
$node
->setOption($filter($node
->getOption()));
$node
->setAttributes(array_map($filter, $node
->getAttributes()));
$node
->setSource($filter($node
->getSource()));
}
}
}
/**
* Escape unsafe markup in text elements and the source of tag elements.
*
* This is a safety feature that allows the BBCode processor to be used
* on its own (without HTML restrictors) while still maintaining
* markup safety.
*
* @param \Drupal\xbbcode\Parser\Tree\NodeElementInterface $tree
* The parse tree.
*/
public static function filterXss(NodeElementInterface $tree) : void {
foreach ($tree
->getDescendants() as $node) {
if ($node instanceof TextElement) {
$node
->setText(XssEscape::filterAdmin($node
->getText()));
}
if ($node instanceof TagElementInterface) {
$node
->setSource(XssEscape::filterAdmin($node
->getSource()));
}
}
}
/**
* Add linebreaks inside text elements.
*
* @param \Drupal\xbbcode\Parser\Tree\NodeElementInterface $tree
* The parse tree.
*/
public static function addLinebreaks(NodeElementInterface $tree) : void {
foreach ($tree
->getDescendants() as $node) {
if ($node instanceof TextElement) {
$node
->setText(nl2br($node
->getText()));
}
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
public | function | 2 | |
DependencySerializationTrait:: |
public | function | 2 | |
FilterBase:: |
public | property | The name of the provider that owns this filter. | |
FilterBase:: |
public | property | An associative array containing the configured settings of this filter. | |
FilterBase:: |
public | property | A Boolean indicating whether this filter is enabled. | |
FilterBase:: |
public | property | The weight of this filter compared to others in a filter collection. | |
FilterBase:: |
public | function |
Calculates dependencies for the configured plugin. Overrides DependentPluginInterface:: |
1 |
FilterBase:: |
public | function |
Gets default configuration for this plugin. Overrides ConfigurableInterface:: |
|
FilterBase:: |
public | function |
Gets this plugin's configuration. Overrides ConfigurableInterface:: |
|
FilterBase:: |
public | function |
Returns the administrative description for this filter plugin. Overrides FilterInterface:: |
|
FilterBase:: |
public | function |
Returns HTML allowed by this filter's configuration. Overrides FilterInterface:: |
4 |
FilterBase:: |
public | function |
Returns the administrative label for this filter plugin. Overrides FilterInterface:: |
|
FilterBase:: |
public | function |
Returns the processing type of this filter plugin. Overrides FilterInterface:: |
|
FilterInterface:: |
constant | HTML tag and attribute restricting filters to prevent XSS attacks. | ||
FilterInterface:: |
constant | Non-HTML markup language filters that generate HTML. | ||
FilterInterface:: |
constant | Irreversible transformation filters. | ||
FilterInterface:: |
constant | Reversible transformation filters. | ||
MessengerTrait:: |
protected | property | The messenger. | 27 |
MessengerTrait:: |
public | function | Gets the messenger. | 27 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
2 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 4 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
XBBCodeFilter:: |
protected | property | The cache tags that invalidate this filter. | |
XBBCodeFilter:: |
protected | property | The tag plugin manager. | |
XBBCodeFilter:: |
protected | property | The parser. | |
XBBCodeFilter:: |
protected | property | The tag set storage. | |
XBBCodeFilter:: |
protected | property | The tag plugins. | |
XBBCodeFilter:: |
protected | property | The tag set (optional). | |
XBBCodeFilter:: |
public static | function | Add linebreaks inside text elements. | |
XBBCodeFilter:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
|
XBBCodeFilter:: |
public static | function | Reverse HTML encoding that other filters may have applied. | |
XBBCodeFilter:: |
public static | function | Recursively apply source transformations to each tag element. | |
XBBCodeFilter:: |
public static | function | Escape unsafe markup in text elements and the source of tag elements. | |
XBBCodeFilter:: |
public | function |
Prepares the text for processing. Overrides FilterBase:: |
|
XBBCodeFilter:: |
public | function |
Performs the filter processing. Overrides FilterInterface:: |
|
XBBCodeFilter:: |
public | function |
Sets the configuration for this plugin instance. Overrides FilterBase:: |
|
XBBCodeFilter:: |
public | function |
Generates a filter's settings form. Overrides FilterBase:: |
|
XBBCodeFilter:: |
public | function |
Generates a filter's tip. Overrides FilterBase:: |
|
XBBCodeFilter:: |
public | function |
XBBCodeFilter constructor. Overrides FilterBase:: |