1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14namespace phpbb\textformatter\s9e;
15
16class link_helper
17{
18	/**
19	* Clean up and invalidate a LINK_TEXT tag if applicable
20	*
21	* Will invalidate the tag if its replacement text is the same as the original
22	* text and would have no visible effect
23	*
24	* @param  \s9e\TextFormatter\Parser\Tag $tag    LINK_TEXT tag
25	* @param  \s9e\TextFormatter\Parser     $parser Parser
26	* @return void
27	*/
28	public function cleanup_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser)
29	{
30		// Invalidate if the content of the tag matches the text attribute
31		$text = substr($parser->getText(), $tag->getPos(), $tag->getLen());
32		if ($text === $tag->getAttribute('text'))
33		{
34			$tag->invalidate();
35		}
36	}
37
38	/**
39	* Create a LINK_TEXT tag inside of a link
40	*
41	* Meant to only apply to linkified URLs and [url] BBCodes without a parameter
42	*
43	* @param  \s9e\TextFormatter\Parser\Tag $tag    URL tag (start tag)
44	* @param  \s9e\TextFormatter\Parser     $parser Parser
45	* @return void
46	*/
47	public function generate_link_text_tag(\s9e\TextFormatter\Parser\Tag $tag, \s9e\TextFormatter\Parser $parser)
48	{
49		// Only create a LINK_TEXT tag if the start tag is paired with an end
50		// tag, which is the case with tags from the Autolink plugins and with
51		// the [url] BBCode when its content is used for the URL
52		if (!$tag->getEndTag() || !$this->should_shorten($tag, $parser->getText()))
53		{
54			return;
55		}
56
57		// Capture the text between the start tag and its end tag
58		$start  = $tag->getPos() + $tag->getLen();
59		$end    = $tag->getEndTag()->getPos();
60		$length = $end - $start;
61		$text   = substr($parser->getText(), $start, $length);
62
63		// Create a tag that consumes the link's text and make it depends on this tag
64		$link_text_tag = $parser->addSelfClosingTag('LINK_TEXT', $start, $length, 10);
65		$link_text_tag->setAttribute('text', $text);
66		$tag->cascadeInvalidationTo($link_text_tag);
67	}
68
69	/**
70	* Test whether we should shorten this tag's text
71	*
72	* Will test whether the tag either does not use any markup or uses a single
73	* [url] BBCode
74	*
75	* @param  \s9e\TextFormatter\Parser\Tag $tag  URL tag
76	* @param  string                        $text Original text
77	* @return bool
78	*/
79	protected function should_shorten(\s9e\TextFormatter\Parser\Tag $tag, $text)
80	{
81		return ($tag->getLen() === 0 || strtolower(substr($text, $tag->getPos(), $tag->getLen())) === '[url]');
82	}
83
84	/**
85	* Remove the board's root URL from a the start of a string
86	*
87	* @param  \s9e\TextFormatter\Parser\Tag $tag       LINK_TEXT tag
88	* @param  string                        $board_url Forum's root URL (with trailing slash)
89	* @return void
90	*/
91	public function truncate_local_url(\s9e\TextFormatter\Parser\Tag $tag, $board_url)
92	{
93		$text = $tag->getAttribute('text');
94		if (stripos($text, $board_url) === 0 && strlen($text) > strlen($board_url))
95		{
96			$tag->setAttribute('text', substr($text, strlen($board_url)));
97		}
98	}
99
100	/**
101	* Truncate the replacement text set in a LINK_TEXT tag
102	*
103	* @param  \s9e\TextFormatter\Parser\Tag $tag LINK_TEXT tag
104	* @return void
105	*/
106	public function truncate_text(\s9e\TextFormatter\Parser\Tag $tag)
107	{
108		$text = $tag->getAttribute('text');
109		if (utf8_strlen($text) > 55)
110		{
111			$text = utf8_substr($text, 0, 39) . ' ... ' . utf8_substr($text, -10);
112			$tag->setAttribute('text', $text);
113		}
114	}
115}
116