diff options
Diffstat (limited to 'phpBB/phpbb')
| -rw-r--r-- | phpBB/phpbb/console/command/reparser/reparse.php | 14 | ||||
| -rw-r--r-- | phpBB/phpbb/di/ordered_service_collection.php | 117 | ||||
| -rw-r--r-- | phpBB/phpbb/di/pass/collection_pass.php | 11 | ||||
| -rw-r--r-- | phpBB/phpbb/di/service_collection_iterator.php | 2 | ||||
| -rw-r--r-- | phpBB/phpbb/template/twig/node/includecss.php | 2 | ||||
| -rw-r--r-- | phpBB/phpbb/textformatter/s9e/factory.php | 33 | ||||
| -rw-r--r-- | phpBB/phpbb/textformatter/s9e/quote_helper.php | 81 | ||||
| -rw-r--r-- | phpBB/phpbb/textformatter/s9e/renderer.php | 19 | ||||
| -rw-r--r-- | phpBB/phpbb/textformatter/s9e/utils.php | 19 | ||||
| -rw-r--r-- | phpBB/phpbb/textformatter/utils_interface.php | 5 | ||||
| -rw-r--r-- | phpBB/phpbb/textreparser/base.php | 52 | ||||
| -rw-r--r-- | phpBB/phpbb/textreparser/plugins/forum_description.php | 1 | ||||
| -rw-r--r-- | phpBB/phpbb/textreparser/plugins/forum_rules.php | 1 | ||||
| -rw-r--r-- | phpBB/phpbb/textreparser/plugins/group_description.php | 1 | ||||
| -rw-r--r-- | phpBB/phpbb/textreparser/plugins/poll_option.php | 2 | ||||
| -rw-r--r-- | phpBB/phpbb/textreparser/plugins/poll_title.php | 2 | 
16 files changed, 322 insertions, 40 deletions
diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php index 52075dd0ac..151e196358 100644 --- a/phpBB/phpbb/console/command/reparser/reparse.php +++ b/phpBB/phpbb/console/command/reparser/reparse.php @@ -57,6 +57,12 @@ class reparse extends \phpbb\console\command\command  			->setDescription($this->user->lang('CLI_DESCRIPTION_REPARSER_REPARSE'))  			->addArgument('reparser-name', InputArgument::OPTIONAL, $this->user->lang('CLI_DESCRIPTION_REPARSER_REPARSE_ARG_1'))  			->addOption( +				'dry-run', +				null, +				InputOption::VALUE_NONE, +				$this->user->lang('CLI_DESCRIPTION_REPARSER_REPARSE_OPT_DRY_RUN') +			) +			->addOption(  				'range-min',  				null,  				InputOption::VALUE_REQUIRED, @@ -124,6 +130,14 @@ class reparse extends \phpbb\console\command\command  	protected function reparse(InputInterface $input, OutputInterface $output, $name)  	{  		$reparser = $this->reparsers[$name]; +		if ($input->getOption('dry-run')) +		{ +			$reparser->disable_save(); +		} +		else +		{ +			$reparser->enable_save(); +		}  		// Start at range-max if specified or at the highest ID otherwise  		$max  = (is_null($input->getOption('range-max'))) ? $reparser->get_max_id() : $input->getOption('range-max'); diff --git a/phpBB/phpbb/di/ordered_service_collection.php b/phpBB/phpbb/di/ordered_service_collection.php new file mode 100644 index 0000000000..046012ae5b --- /dev/null +++ b/phpBB/phpbb/di/ordered_service_collection.php @@ -0,0 +1,117 @@ +<?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\di; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Collection of services in a specified order + */ +class ordered_service_collection extends service_collection +{ +	/** +	 * @var bool +	 */ +	protected $is_ordered; + +	/** +	 * @var array +	 */ +	protected $service_ids; + +	/** +	 * Constructor +	 * +	 * @param ContainerInterface $container Container object +	 */ +	public function __construct(ContainerInterface $container) +	{ +		$this->is_ordered = false; +		$this->service_ids = array(); + +		parent::__construct($container); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function getIterator() +	{ +		if (!$this->is_ordered) +		{ +			$this->sort_services(); +		} + +		return new service_collection_iterator($this); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function offsetExists($index) +	{ +		if (!$this->is_ordered) +		{ +			$this->sort_services(); +		} + +		return parent::offsetExists($index); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function offsetGet($index) +	{ +		if (!$this->is_ordered) +		{ +			$this->sort_services(); +		} + +		return parent::offsetGet($index); +	} + +	/** +	 * Adds a service ID to the collection +	 * +	 * @param string	$service_id +	 * @param int		$order +	 */ +	public function add($service_id, $order = 0) +	{ +		$order = (int) $order; +		$this->service_ids[$order][] = $service_id; +		$this->is_ordered = false; +	} + +	protected function sort_services() +	{ +		if ($this->is_ordered) +		{ +			return; +		} + +		$this->exchangeArray(array()); +		ksort($this->service_ids); +		foreach ($this->service_ids as $service_order_group) +		{ +			foreach ($service_order_group as $service_id) +			{ +				$this->offsetSet($service_id, null); +			} +		} + +		$this->is_ordered = true; +	} +} diff --git a/phpBB/phpbb/di/pass/collection_pass.php b/phpBB/phpbb/di/pass/collection_pass.php index a5c054674e..ccc1250c20 100644 --- a/phpBB/phpbb/di/pass/collection_pass.php +++ b/phpBB/phpbb/di/pass/collection_pass.php @@ -37,7 +37,16 @@ class collection_pass implements CompilerPassInterface  			foreach ($container->findTaggedServiceIds($data[0]['tag']) as $service_id => $service_data)  			{ -				$definition->addMethodCall('add', array($service_id)); +				if (substr($definition->getClass(), -strlen('ordered_service_collection')) === 'ordered_service_collection') +				{ +					$arguments = array($service_id, $service_data[0]['order']); +				} +				else +				{ +					$arguments = array($service_id); +				} + +				$definition->addMethodCall('add', $arguments);  			}  		}  	} diff --git a/phpBB/phpbb/di/service_collection_iterator.php b/phpBB/phpbb/di/service_collection_iterator.php index 0d031ab52d..31bc156e99 100644 --- a/phpBB/phpbb/di/service_collection_iterator.php +++ b/phpBB/phpbb/di/service_collection_iterator.php @@ -32,7 +32,7 @@ class service_collection_iterator extends \ArrayIterator  	*/  	public function __construct(service_collection $collection, $flags = 0)  	{ -		parent::__construct($collection, $flags); +		parent::__construct($collection->getArrayCopy(), $flags);  		$this->collection = $collection;  	} diff --git a/phpBB/phpbb/template/twig/node/includecss.php b/phpBB/phpbb/template/twig/node/includecss.php index 2ce63402aa..2dac154036 100644 --- a/phpBB/phpbb/template/twig/node/includecss.php +++ b/phpBB/phpbb/template/twig/node/includecss.php @@ -31,7 +31,7 @@ class includecss extends \phpbb\template\twig\node\includeasset  		$compiler  			->raw("<link href=\"' . ")  			->raw("\$asset_file . '\"") -			->raw(' rel="stylesheet" type="text/css" media="screen, projection" />') +			->raw(' rel="stylesheet" type="text/css" media="screen" />')  		;  	}  } diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 7ad728e6cc..2aab97b667 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -77,7 +77,12 @@ class factory implements \phpbb\textformatter\cache_interface  		'quote' =>  			"[QUOTE  				author={TEXT1;optional} +				post_id={UINT;optional} +				post_url={URL;optional;postFilter=#false} +				profile_url={URL;optional;postFilter=#false} +				time={UINT;optional}  				url={URL;optional} +				user_id={UINT;optional}  				author={PARSE=/^\\[url=(?'url'.*?)](?'author'.*)\\[\\/url]$/i}  				author={PARSE=/^\\[url](?'author'(?'url'.*?))\\[\\/url]$/i}  				author={PARSE=/(?'url'https?:\\/\\/[^[\\]]+)/i} @@ -319,6 +324,11 @@ class factory implements \phpbb\textformatter\cache_interface  		$configurator->registeredVars['max_img_height'] = 0;  		$configurator->registeredVars['max_img_width'] = 0; +		// Load the Emoji plugin and modify its tag's template to obey viewsmilies +		$configurator->Emoji->setImageSize(18); +		$tag = $configurator->Emoji->getTag(); +		$tag->template = '<xsl:choose><xsl:when test="$S_VIEWSMILIES">' . str_replace('class="emoji"', 'class="smilies"', $tag->template) . '</xsl:when><xsl:otherwise><xsl:value-of select="."/></xsl:otherwise></xsl:choose>'; +  		/**  		* Modify the s9e\TextFormatter configurator after the default settings are set  		* @@ -471,24 +481,11 @@ class factory implements \phpbb\textformatter\cache_interface  		$templates['li'] = $fragments['listitem'] . '<xsl:apply-templates/>' . $fragments['listitem_close']; -		$fragments['quote_username_open'] = str_replace( -			'{USERNAME}', -			'<xsl:choose> -				<xsl:when test="@url">' . str_replace('{DESCRIPTION}', '{USERNAME}', $fragments['url']) . '</xsl:when> -				<xsl:otherwise>{USERNAME}</xsl:otherwise> -			</xsl:choose>', -			$fragments['quote_username_open'] -		); - -		$templates['quote'] = -			'<xsl:choose> -				<xsl:when test="@author"> -					' . $fragments['quote_username_open'] . '<xsl:apply-templates/>' . $fragments['quote_close'] . ' -				</xsl:when> -				<xsl:otherwise> -					' . $fragments['quote_open'] . '<xsl:apply-templates/>' . $fragments['quote_close'] . ' -				</xsl:otherwise> -			</xsl:choose>'; +		// Replace the regular quote template with the extended quote template if available +		if (isset($fragments['quote_extended'])) +		{ +			$templates['quote'] = $fragments['quote_extended']; +		}  		// The [attachment] BBCode uses the inline_attachment template to output a comment that  		// is post-processed by parse_attachments() diff --git a/phpBB/phpbb/textformatter/s9e/quote_helper.php b/phpBB/phpbb/textformatter/s9e/quote_helper.php new file mode 100644 index 0000000000..24109ac8cc --- /dev/null +++ b/phpBB/phpbb/textformatter/s9e/quote_helper.php @@ -0,0 +1,81 @@ +<?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 quote_helper +{ +	/** +	* @var string Base URL for a post link, uses {POST_ID} as placeholder +	*/ +	protected $post_url; + +	/** +	* @var string Base URL for a profile link, uses {USER_ID} as placeholder +	*/ +	protected $profile_url; + +	/** +	* @var \phpbb\user +	*/ +	protected $user; + +	/** +	* Constructor +	* +	* @param \phpbb\user $user +	* @param string $root_path +	* @param string $php_ext +	*/ +	public function __construct(\phpbb\user $user, $root_path, $php_ext) +	{ +		$this->post_url = append_sid($root_path . 'viewtopic.' . $php_ext, 'p={POST_ID}#p{POST_ID}'); +		$this->profile_url = append_sid($root_path . 'memberlist.' . $php_ext, 'mode=viewprofile&u={USER_ID}'); +		$this->user = $user; +	} + +	/** +	* Inject dynamic metadata into QUOTE tags in given XML +	* +	* @param  string $xml Original XML +	* @return string      Modified XML +	*/ +	public function inject_metadata($xml) +	{ +		$post_url = $this->post_url; +		$profile_url = $this->profile_url; +		$user = $this->user; + +		return \s9e\TextFormatter\Utils::replaceAttributes( +			$xml, +			'QUOTE', +			function ($attributes) use ($post_url, $profile_url, $user) +			{ +				if (isset($attributes['post_id'])) +				{ +					$attributes['post_url'] = str_replace('{POST_ID}', $attributes['post_id'], $post_url); +				} +				if (isset($attributes['time'])) +				{ +					$attributes['date'] = $user->format_date($attributes['time']); +				} +				if (isset($attributes['user_id'])) +				{ +					$attributes['profile_url'] = str_replace('{USER_ID}', $attributes['user_id'], $profile_url); +				} + +				return $attributes; +			} +		); +	} +} diff --git a/phpBB/phpbb/textformatter/s9e/renderer.php b/phpBB/phpbb/textformatter/s9e/renderer.php index 51bc44f339..2206605ba2 100644 --- a/phpBB/phpbb/textformatter/s9e/renderer.php +++ b/phpBB/phpbb/textformatter/s9e/renderer.php @@ -29,6 +29,11 @@ class renderer implements \phpbb\textformatter\renderer_interface  	protected $dispatcher;  	/** +	* @var quote_helper +	*/ +	protected $quote_helper; + +	/**  	* @var \s9e\TextFormatter\Renderer  	*/  	protected $renderer; @@ -113,6 +118,16 @@ class renderer implements \phpbb\textformatter\renderer_interface  	}  	/** +	* Configure the quote_helper object used to display extended information in quotes +	* +	* @param  quote_helper $quote_helper +	*/ +	public function configure_quote_helper(quote_helper $quote_helper) +	{ +		$this->quote_helper = $quote_helper; +	} + +	/**  	* Automatically set the smilies path based on config  	*  	* @param  \phpbb\config\config $config @@ -214,6 +229,10 @@ class renderer implements \phpbb\textformatter\renderer_interface  	*/  	public function render($xml)  	{ +		if (isset($this->quote_helper)) +		{ +			$xml = $this->quote_helper->inject_metadata($xml); +		}  		$renderer = $this;  		/** diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index 803c71a5a2..40479b3423 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -35,16 +35,22 @@ class utils implements \phpbb\textformatter\utils_interface  	}  	/** -	* Return given string between quotes +	* Format given string to be used as an attribute value  	* -	* Will use either single- or double- quotes depending on whichever requires less escaping. +	* Will return the string as-is if it can be used in a BBCode without quotes. Otherwise, +	* it will use either single- or double- quotes depending on whichever requires less escaping.  	* Quotes and backslashes are escaped with backslashes where necessary  	*  	* @param  string $str Original string -	* @return string      Escaped string within quotes +	* @return string      Same string if possible, escaped string within quotes otherwise  	*/ -	protected function enquote($str) +	protected function format_attribute_value($str)  	{ +		if (!preg_match('/[ "\'\\\\\\]]/', $str)) +		{ +			// Return as-is if it contains none of: space, ' " \ or ] +			return $str; +		}  		$singleQuoted = "'" . addcslashes($str, "\\'") . "'";  		$doubleQuoted = '"' . addcslashes($str, '\\"') . '"'; @@ -61,12 +67,13 @@ class utils implements \phpbb\textformatter\utils_interface  		if (isset($attributes['author']))  		{  			// Add the author as the BBCode's default attribute -			$quote .= '=' . $this->enquote($attributes['author']); +			$quote .= '=' . $this->format_attribute_value($attributes['author']);  			unset($attributes['author']);  		} +		ksort($attributes);  		foreach ($attributes as $name => $value)  		{ -			$quote .= ' ' . $name . '=' . $this->enquote($value); +			$quote .= ' ' . $name . '=' . $this->format_attribute_value($value);  		}  		$quote .= ']';  		$newline = (strlen($quote . $text . '[/quote]') > 80 || strpos($text, "\n") !== false) ? "\n" : ''; diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php index 41a6ba2345..4810453cd1 100644 --- a/phpBB/phpbb/textformatter/utils_interface.php +++ b/phpBB/phpbb/textformatter/utils_interface.php @@ -32,7 +32,10 @@ interface utils_interface  	* Create a quote block for given text  	*  	* Possible attributes: -	*   - author +	*   - author:  author's name (usually a username) +	*   - post_id: post_id of the post being quoted +	*   - user_id: user_id of the user being quoted +	*   - time:    timestamp of the original message  	*  	* @param  string $text       Quote's text  	* @param  array  $attributes Quote's attributes diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php index 87a4268d0d..3e5ee248a1 100644 --- a/phpBB/phpbb/textreparser/base.php +++ b/phpBB/phpbb/textreparser/base.php @@ -16,6 +16,11 @@ namespace phpbb\textreparser;  abstract class base implements reparser_interface  {  	/** +	* @var bool Whether to save changes to the database +	*/ +	protected $save_changes = true; + +	/**  	* {@inheritdoc}  	*/  	abstract public function get_max_id(); @@ -47,11 +52,22 @@ abstract class base implements reparser_interface  	{  		if (!isset($record['enable_bbcode'], $record['enable_smilies'], $record['enable_magic_url']))  		{ -			$record += array( -				'enable_bbcode'    => $this->guess_bbcodes($record), -				'enable_smilies'   => $this->guess_smilies($record), -				'enable_magic_url' => $this->guess_magic_url($record), -			); +			if (isset($record['options'])) +			{ +				$record += array( +					'enable_bbcode'    => (bool) ($record['options'] & OPTION_FLAG_BBCODE), +					'enable_smilies'   => (bool) ($record['options'] & OPTION_FLAG_SMILIES), +					'enable_magic_url' => (bool) ($record['options'] & OPTION_FLAG_LINKS), +				); +			} +			else +			{ +				$record += array( +					'enable_bbcode'    => $this->guess_bbcodes($record), +					'enable_smilies'   => $this->guess_smilies($record), +					'enable_magic_url' => $this->guess_magic_url($record), +				); +			}  		}  		// Those BBCodes are disabled based on context and user permissions and that value is never @@ -74,6 +90,22 @@ abstract class base implements reparser_interface  	}  	/** +	* Disable saving changes to the database +	*/ +	public function disable_save() +	{ +		$this->save_changes = false; +	} + +	/** +	* Enable saving changes to the database +	*/ +	public function enable_save() +	{ +		$this->save_changes = true; +	} + +	/**  	* Guess whether given BBCode is in use in given record  	*  	* @param  array  $record @@ -92,7 +124,7 @@ abstract class base implements reparser_interface  			}  		} -		if (substr($record['text'], 0, 2) == '<r') +		if (substr($record['text'], 0, 2) === '<r')  		{  			// Look for the closing tag inside of a e element, in an element of the same name, e.g.  			// <e>[/url]</e></URL> @@ -124,7 +156,7 @@ abstract class base implements reparser_interface  			}  		} -		if (substr($record['text'], 0, 2) == '<r') +		if (substr($record['text'], 0, 2) === '<r')  		{  			// Look for a closing tag inside of an e element  			return (bool) preg_match('(<e>\\[/\\w+\\]</e>)', $match); @@ -170,7 +202,7 @@ abstract class base implements reparser_interface  	/**  	* Reparse given record  	* -	* @param  array $record Associative array containing the record's data +	* @param array $record Associative array containing the record's data  	*/  	protected function reparse_record(array $record)  	{ @@ -201,8 +233,8 @@ abstract class base implements reparser_interface  			$unparsed['enable_url_bbcode']  		); -		// Save the new text if it has changed -		if ($text !== $record['text']) +		// Save the new text if it has changed and it's not a dry run +		if ($text !== $record['text'] && $this->save_changes)  		{  			$record['text'] = $text;  			$this->save_record($record); diff --git a/phpBB/phpbb/textreparser/plugins/forum_description.php b/phpBB/phpbb/textreparser/plugins/forum_description.php index 7798e4b20b..0302dc3082 100644 --- a/phpBB/phpbb/textreparser/plugins/forum_description.php +++ b/phpBB/phpbb/textreparser/plugins/forum_description.php @@ -24,6 +24,7 @@ class forum_description extends \phpbb\textreparser\row_based_plugin  			'id'         => 'forum_id',  			'text'       => 'forum_desc',  			'bbcode_uid' => 'forum_desc_uid', +			'options'    => 'forum_desc_options',  		);  	} diff --git a/phpBB/phpbb/textreparser/plugins/forum_rules.php b/phpBB/phpbb/textreparser/plugins/forum_rules.php index 57c666a556..ce550225f2 100644 --- a/phpBB/phpbb/textreparser/plugins/forum_rules.php +++ b/phpBB/phpbb/textreparser/plugins/forum_rules.php @@ -24,6 +24,7 @@ class forum_rules extends \phpbb\textreparser\row_based_plugin  			'id'         => 'forum_id',  			'text'       => 'forum_rules',  			'bbcode_uid' => 'forum_rules_uid', +			'options'    => 'forum_rules_options',  		);  	} diff --git a/phpBB/phpbb/textreparser/plugins/group_description.php b/phpBB/phpbb/textreparser/plugins/group_description.php index ddd0e1d1c5..3346ccf25e 100644 --- a/phpBB/phpbb/textreparser/plugins/group_description.php +++ b/phpBB/phpbb/textreparser/plugins/group_description.php @@ -24,6 +24,7 @@ class group_description extends \phpbb\textreparser\row_based_plugin  			'id'         => 'group_id',  			'text'       => 'group_desc',  			'bbcode_uid' => 'group_desc_uid', +			'options'    => 'group_desc_options',  		);  	} diff --git a/phpBB/phpbb/textreparser/plugins/poll_option.php b/phpBB/phpbb/textreparser/plugins/poll_option.php index 7b803146c4..44cacfae62 100644 --- a/phpBB/phpbb/textreparser/plugins/poll_option.php +++ b/phpBB/phpbb/textreparser/plugins/poll_option.php @@ -48,7 +48,7 @@ class poll_option extends \phpbb\textreparser\base  	*/  	protected function get_records_by_range($min_id, $max_id)  	{ -		$sql = 'SELECT o.topic_id, o.poll_option_id, o.poll_option_text AS text, p.bbcode_uid +		$sql = 'SELECT o.topic_id, o.poll_option_id, o.poll_option_text AS text, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.bbcode_uid  			FROM ' . POLL_OPTIONS_TABLE . ' o, ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p  			WHERE o.topic_id BETWEEN ' . $min_id . ' AND ' . $max_id .'  				AND t.topic_id = o.topic_id diff --git a/phpBB/phpbb/textreparser/plugins/poll_title.php b/phpBB/phpbb/textreparser/plugins/poll_title.php index b447004527..038ae0c366 100644 --- a/phpBB/phpbb/textreparser/plugins/poll_title.php +++ b/phpBB/phpbb/textreparser/plugins/poll_title.php @@ -31,7 +31,7 @@ class poll_title extends \phpbb\textreparser\row_based_plugin  	*/  	protected function get_records_by_range_query($min_id, $max_id)  	{ -		$sql = 'SELECT t.topic_id AS id, t.poll_title AS text, p.bbcode_uid +		$sql = 'SELECT t.topic_id AS id, t.poll_title AS text, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.bbcode_uid  			FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p  			WHERE t.topic_id BETWEEN ' . $min_id . ' AND ' . $max_id .'  				AND t.poll_max_options > 0  | 
