diff options
Diffstat (limited to 'phpBB/phpbb/textformatter/s9e')
-rw-r--r-- | phpBB/phpbb/textformatter/s9e/factory.php | 53 | ||||
-rw-r--r-- | phpBB/phpbb/textformatter/s9e/link_helper.php | 118 |
2 files changed, 168 insertions, 3 deletions
diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 6ac55e82a8..8c273c342e 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -23,6 +23,11 @@ use s9e\TextFormatter\Configurator\Items\UnsafeTemplate; class factory implements \phpbb\textformatter\cache_interface { /** + * @var \phpbb\textformatter\s9e\link_helper + */ + protected $link_helper; + + /** * @var \phpbb\cache\driver\driver_interface */ protected $cache; @@ -133,12 +138,14 @@ class factory implements \phpbb\textformatter\cache_interface * @param \phpbb\cache\driver\driver_interface $cache * @param \phpbb\event\dispatcher_interface $dispatcher * @param \phpbb\config\config $config + * @param \phpbb\textformatter\s9e\link_helper $link_helper * @param string $cache_dir Path to the cache dir * @param string $cache_key_parser Cache key used for the parser * @param string $cache_key_renderer Cache key used for the renderer */ - public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, $cache_dir, $cache_key_parser, $cache_key_renderer) + public function __construct(\phpbb\textformatter\data_access $data_access, \phpbb\cache\driver\driver_interface $cache, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\config\config $config, \phpbb\textformatter\s9e\link_helper $link_helper, $cache_dir, $cache_key_parser, $cache_key_renderer) { + $this->link_helper = $link_helper; $this->cache = $cache; $this->cache_dir = $cache_dir; $this->cache_key_parser = $cache_key_parser; @@ -332,8 +339,7 @@ class factory implements \phpbb\textformatter\cache_interface } // Load the magic links plugins. We do that after BBCodes so that they use the same tags - $configurator->plugins->load('Autoemail'); - $configurator->plugins->load('Autolink', array('matchWww' => true)); + $this->configure_autolink($configurator); // Register some vars with a default value. Those should be set at runtime by whatever calls // the parser @@ -395,6 +401,47 @@ class factory implements \phpbb\textformatter\cache_interface } /** + * Configure the Autolink / Autoemail plugins used to linkify text + * + * @param \s9e\TextFormatter\Configurator $configurator + * @return void + */ + protected function configure_autolink(Configurator $configurator) + { + $configurator->plugins->load('Autoemail'); + $configurator->plugins->load('Autolink', array('matchWww' => true)); + + // Add a tag filter that creates a tag that stores and replace the + // content of a link created by the Autolink plugin + $configurator->Autolink->getTag()->filterChain + ->add(array($this->link_helper, 'generate_link_text_tag')) + ->resetParameters() + ->addParameterByName('tag') + ->addParameterByName('parser'); + + // Create a tag that will be used to display the truncated text by + // replacing the original content with the content of the @text attribute + $tag = $configurator->tags->add('LINK_TEXT'); + $tag->attributes->add('text'); + $tag->template = '<xsl:value-of select="@text"/>'; + + $tag->filterChain + ->add(array($this->link_helper, 'truncate_local_url')) + ->resetParameters() + ->addParameterByName('tag') + ->addParameterByValue(generate_board_url() . '/'); + $tag->filterChain + ->add(array($this->link_helper, 'truncate_text')) + ->resetParameters() + ->addParameterByName('tag'); + $tag->filterChain + ->add(array($this->link_helper, 'cleanup_tag')) + ->resetParameters() + ->addParameterByName('tag') + ->addParameterByName('parser'); + } + + /** * Return the default BBCodes configuration * * @return array 2D array. Each element has a 'usage' key, a 'template' key, and an optional 'options' key diff --git a/phpBB/phpbb/textformatter/s9e/link_helper.php b/phpBB/phpbb/textformatter/s9e/link_helper.php new file mode 100644 index 0000000000..0f44603dec --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/link_helper.php @@ -0,0 +1,118 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\textformatter\s9e; + +class link_helper +{ + /** + * Clean up and invalidate a LINK_TEXT tag if applicable + * + * Will invalidate the tag if its replacement text is the same as the original + * text and would have no visible effect + * + * @param \s9e\TextFormatter\Parser\Tag $tag LINK_TEXT tag + * @param \s9e\TextFormatter\Parser $parser Parser + * @return bool Whether the tag is valid + */ + public function cleanup_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser) + { + // Invalidate if the content of the tag matches the text attribute + $text = substr($parser->getText(), $tag->getPos(), $tag->getLen()); + + return ($text !== $tag->getAttribute('text')); + } + + /** + * Create a LINK_TEXT tag inside of a link + * + * Meant to only apply to linkified URLs and [url] BBCodes without a parameter + * + * @param \s9e\TextFormatter\Parser\Tag $tag URL tag (start tag) + * @param \s9e\TextFormatter\Parser $parser Parser + * @return bool Always true to indicate that the tag is valid + */ + public function generate_link_text_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser) + { + // Only create a LINK_TEXT tag if the start tag is paired with an end + // tag, which is the case with tags from the Autolink plugins and with + // the [url] BBCode when its content is used for the URL + if (!$tag->getEndTag() || !$this->should_shorten($tag, $parser->getText())) + { + return true; + } + + // Capture the text between the start tag and its end tag + $start = $tag->getPos() + $tag->getLen(); + $end = $tag->getEndTag()->getPos(); + $length = $end - $start; + $text = substr($parser->getText(), $start, $length); + + // Create a tag that consumes the link's text + $parser->addSelfClosingTag('LINK_TEXT', $start, $length)->setAttribute('text', $text); + + return true; + } + + /** + * Test whether we should shorten this tag's text + * + * Will test whether the tag either does not use any markup or uses a single + * [url] BBCode + * + * @param \s9e\TextFormatter\Parser\Tag $tag URL tag + * @param string $text Original text + * @return bool + */ + protected function should_shorten(\s9e\TextFormatter\Parser\Tag $tag, $text) + { + return ($tag->getLen() === 0 || strtolower(substr($text, $tag->getPos(), $tag->getLen())) === '[url]'); + } + + /** + * Remove the board's root URL from a the start of a string + * + * @param \s9e\TextFormatter\Parser\Tag $tag LINK_TEXT tag + * @param string $board_url Forum's root URL (with trailing slash) + * @return bool Always true to indicate that the tag is valid + */ + public function truncate_local_url(\s9e\TextFormatter\Parser\Tag $tag, $board_url) + { + $text = $tag->getAttribute('text'); + if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url)) + { + $tag->setAttribute('text', substr($text, strlen($board_url))); + } + + return true; + } + + /** + * Truncate the replacement text set in a LINK_TEXT tag + * + * @param \s9e\TextFormatter\Parser\Tag $tag LINK_TEXT tag + * @return bool Always true to indicate that the tag is valid + */ + public function truncate_text(\s9e\TextFormatter\Parser\Tag $tag) + { + $text = $tag->getAttribute('text'); + if (utf8_strlen($text) > 55) + { + $text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10); + } + + $tag->setAttribute('text', $text); + + return true; + } +} |