aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb')
-rw-r--r--phpBB/phpbb/console/command/reparser/reparse.php14
-rw-r--r--phpBB/phpbb/di/ordered_service_collection.php117
-rw-r--r--phpBB/phpbb/di/pass/collection_pass.php11
-rw-r--r--phpBB/phpbb/di/service_collection_iterator.php2
-rw-r--r--phpBB/phpbb/template/twig/node/includecss.php2
-rw-r--r--phpBB/phpbb/textformatter/s9e/factory.php33
-rw-r--r--phpBB/phpbb/textformatter/s9e/quote_helper.php81
-rw-r--r--phpBB/phpbb/textformatter/s9e/renderer.php19
-rw-r--r--phpBB/phpbb/textformatter/s9e/utils.php19
-rw-r--r--phpBB/phpbb/textformatter/utils_interface.php5
-rw-r--r--phpBB/phpbb/textreparser/base.php52
-rw-r--r--phpBB/phpbb/textreparser/plugins/forum_description.php1
-rw-r--r--phpBB/phpbb/textreparser/plugins/forum_rules.php1
-rw-r--r--phpBB/phpbb/textreparser/plugins/group_description.php1
-rw-r--r--phpBB/phpbb/textreparser/plugins/poll_option.php2
-rw-r--r--phpBB/phpbb/textreparser/plugins/poll_title.php2
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