aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb/textreparser
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb/textreparser')
-rw-r--r--phpBB/phpbb/textreparser/base.php269
-rw-r--r--phpBB/phpbb/textreparser/manager.php148
-rw-r--r--phpBB/phpbb/textreparser/plugins/contact_admin_info.php69
-rw-r--r--phpBB/phpbb/textreparser/plugins/forum_description.php30
-rw-r--r--phpBB/phpbb/textreparser/plugins/forum_rules.php30
-rw-r--r--phpBB/phpbb/textreparser/plugins/group_description.php30
-rw-r--r--phpBB/phpbb/textreparser/plugins/pm_text.php32
-rw-r--r--phpBB/phpbb/textreparser/plugins/poll_option.php74
-rw-r--r--phpBB/phpbb/textreparser/plugins/poll_title.php42
-rw-r--r--phpBB/phpbb/textreparser/plugins/post_text.php32
-rw-r--r--phpBB/phpbb/textreparser/plugins/user_signature.php65
-rw-r--r--phpBB/phpbb/textreparser/reparser_interface.php46
-rw-r--r--phpBB/phpbb/textreparser/row_based_plugin.php117
13 files changed, 984 insertions, 0 deletions
diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php
new file mode 100644
index 0000000000..2ee6ea2cb3
--- /dev/null
+++ b/phpBB/phpbb/textreparser/base.php
@@ -0,0 +1,269 @@
+<?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\textreparser;
+
+abstract class base implements reparser_interface
+{
+ /**
+ * @var string The reparser name
+ */
+ protected $name;
+
+ /**
+ * @var bool Whether to save changes to the database
+ */
+ protected $save_changes = true;
+
+ /**
+ * {@inheritdoc}
+ */
+ abstract public function get_max_id();
+
+ /**
+ * Return all records in given range
+ *
+ * @param integer $min_id Lower bound
+ * @param integer $max_id Upper bound
+ * @return array Array of records
+ */
+ abstract protected function get_records_by_range($min_id, $max_id);
+
+ /**
+ * {@inheritdoc}
+ */
+ abstract protected function save_record(array $record);
+
+ /**
+ * Add fields to given record, if applicable
+ *
+ * The enable_* fields are not always saved to the database. Sometimes we need to guess their
+ * original value based on the text content or possibly other fields
+ *
+ * @param array $record Original record
+ * @return array Complete record
+ */
+ protected function add_missing_fields(array $record)
+ {
+ if (!isset($record['enable_bbcode'], $record['enable_smilies'], $record['enable_magic_url']))
+ {
+ 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
+ // stored in the database. Here we test whether they were used in the original text.
+ $bbcodes = array('flash', 'img', 'quote', 'url');
+ foreach ($bbcodes as $bbcode)
+ {
+ $field_name = 'enable_' . $bbcode . '_bbcode';
+ $record[$field_name] = $this->guess_bbcode($record, $bbcode);
+ }
+
+ // Magic URLs are tied to the URL BBCode, that's why if magic URLs are enabled we make sure
+ // that the URL BBCode is also enabled
+ if ($record['enable_magic_url'])
+ {
+ $record['enable_url_bbcode'] = true;
+ }
+
+ return $record;
+ }
+
+ /**
+ * Returns the name of the reparser
+ *
+ * @return string Name of reparser
+ */
+ public function get_name()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Sets the name of the reparser
+ *
+ * @param string $name The reparser name
+ */
+ public function set_name($name)
+ {
+ $this->name = $name;
+ }
+
+ /**
+ * 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
+ * @param string $bbcode
+ * @return bool
+ */
+ protected function guess_bbcode(array $record, $bbcode)
+ {
+ if (!empty($record['bbcode_uid']))
+ {
+ // Look for the closing tag, e.g. [/url]
+ $match = '[/' . $bbcode . ':' . $record['bbcode_uid'];
+ if (strpos($record['text'], $match) !== false)
+ {
+ return true;
+ }
+ }
+
+ 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>
+ $match = '<e>[/' . $bbcode . ']</e></' . $bbcode . '>';
+ if (stripos($record['text'], $match) !== false)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Guess whether any BBCode is in use in given record
+ *
+ * @param array $record
+ * @return bool
+ */
+ protected function guess_bbcodes(array $record)
+ {
+ if (!empty($record['bbcode_uid']))
+ {
+ // Test whether the bbcode_uid is in use
+ $match = ':' . $record['bbcode_uid'];
+ if (strpos($record['text'], $match) !== false)
+ {
+ return true;
+ }
+ }
+
+ 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);
+ }
+
+ return false;
+ }
+
+ /**
+ * Guess whether magic URLs are in use in given record
+ *
+ * @param array $record
+ * @return bool
+ */
+ protected function guess_magic_url(array $record)
+ {
+ // Look for <!-- m --> or for a URL tag that's not immediately followed by <s>
+ return (strpos($record['text'], '<!-- m -->') !== false || preg_match('(<URL [^>]++>(?!<s>))', $record['text']));
+ }
+
+ /**
+ * Guess whether smilies are in use in given record
+ *
+ * @param array $record
+ * @return bool
+ */
+ protected function guess_smilies(array $record)
+ {
+ return (strpos($record['text'], '<!-- s') !== false || strpos($record['text'], '<E>') !== false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reparse_range($min_id, $max_id)
+ {
+ foreach ($this->get_records_by_range($min_id, $max_id) as $record)
+ {
+ $this->reparse_record($record);
+ }
+ }
+
+ /**
+ * Reparse given record
+ *
+ * @param array $record Associative array containing the record's data
+ */
+ protected function reparse_record(array $record)
+ {
+ $record = $this->add_missing_fields($record);
+ $flags = ($record['enable_bbcode']) ? OPTION_FLAG_BBCODE : 0;
+ $flags |= ($record['enable_smilies']) ? OPTION_FLAG_SMILIES : 0;
+ $flags |= ($record['enable_magic_url']) ? OPTION_FLAG_LINKS : 0;
+ $unparsed = array_merge(
+ $record,
+ generate_text_for_edit($record['text'], $record['bbcode_uid'], $flags)
+ );
+
+ // generate_text_for_edit() and decode_message() actually return the text as HTML. It has to
+ // be decoded to plain text before it can be reparsed
+ $text = html_entity_decode($unparsed['text'], ENT_QUOTES, 'UTF-8');
+ $bitfield = $flags = null;
+ generate_text_for_storage(
+ $text,
+ $unparsed['bbcode_uid'],
+ $bitfield,
+ $flags,
+ $unparsed['enable_bbcode'],
+ $unparsed['enable_magic_url'],
+ $unparsed['enable_smilies'],
+ $unparsed['enable_img_bbcode'],
+ $unparsed['enable_flash_bbcode'],
+ $unparsed['enable_quote_bbcode'],
+ $unparsed['enable_url_bbcode'],
+ 'text_reparser.' . $this->get_name()
+ );
+
+ // 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/manager.php b/phpBB/phpbb/textreparser/manager.php
new file mode 100644
index 0000000000..7ca65d708d
--- /dev/null
+++ b/phpBB/phpbb/textreparser/manager.php
@@ -0,0 +1,148 @@
+<?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\textreparser;
+
+class manager
+{
+ /**
+ * @var \phpbb\config\config
+ */
+ protected $config;
+
+ /**
+ * @var \phpbb\config\db_text
+ */
+ protected $config_text;
+
+ /**
+ * @var \phpbb\di\service_collection
+ */
+ protected $reparsers;
+
+ /**
+ * @var array
+ */
+ protected $resume_data;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\config\config $config
+ * @param \phpbb\config\db_text $config_text
+ * @param \phpbb\di\service_collection $reparsers
+ */
+ public function __construct(\phpbb\config\config $config, \phpbb\config\db_text $config_text, \phpbb\di\service_collection $reparsers)
+ {
+ $this->config = $config;
+ $this->config_text = $config_text;
+ $this->reparsers = $reparsers;
+ }
+
+ /**
+ * Loads resume data from the database
+ *
+ * @param string $name Name of the reparser to which the resume data belongs
+ *
+ * @return array
+ */
+ public function get_resume_data($name)
+ {
+ if ($this->resume_data === null)
+ {
+ $resume_data = $this->config_text->get('reparser_resume');
+ $this->resume_data = !empty($resume_data) ? unserialize($resume_data) : array();
+ }
+
+ return isset($this->resume_data[$name]) ? $this->resume_data[$name] : array();
+ }
+
+ /**
+ * Updates the resume data in the database
+ *
+ * @param string $name Name of the reparser to which the resume data belongs
+ * @param int $min Lowest record ID
+ * @param int $current Current record ID
+ * @param int $size Number of records to process at a time
+ * @param bool $update_db True if the resume data should be written to the database, false if not. (default: true)
+ */
+ public function update_resume_data($name, $min, $current, $size, $update_db = true)
+ {
+ // Prevent overwriting the old, stored array
+ if ($this->resume_data === null)
+ {
+ $this->get_resume_data('');
+ }
+
+ $this->resume_data[$name] = array(
+ 'range-min' => $min,
+ 'range-max' => $current,
+ 'range-size' => $size,
+ );
+
+ if ($update_db)
+ {
+ $this->config_text->set('reparser_resume', serialize($this->resume_data));
+ }
+ }
+
+ /**
+ * Sets the interval for a text_reparser cron task
+ *
+ * @param string $name Name of the reparser to schedule
+ * @param int $interval Interval in seconds, 0 to disable the cron task
+ */
+ public function schedule($name, $interval)
+ {
+ if (isset($this->reparsers[$name]) && isset($this->config[$name . '_cron_interval']))
+ {
+ $this->config->set($name . '_cron_interval', $interval);
+ }
+ }
+
+ /**
+ * Sets the interval for all text_reparser cron tasks
+ *
+ * @param int $interval Interval in seconds, 0 to disable the cron task
+ */
+ public function schedule_all($interval)
+ {
+ // This way we don't construct every registered reparser
+ $reparser_array = array_keys($this->reparsers->getArrayCopy());
+
+ foreach ($reparser_array as $reparser)
+ {
+ $this->schedule($reparser, $interval);
+ }
+ }
+
+ /**
+ * Finds a reparser by name.
+ *
+ * If there is no reparser with the specified name, null is returned.
+ *
+ * @param string $name Name of the reparser to look up.
+ * @return string A reparser service name, or null.
+ */
+ public function find_reparser($name)
+ {
+ foreach ($this->reparsers as $service => $reparser)
+ {
+ if ($reparser->get_name() == $name)
+ {
+ return $service;
+ }
+ }
+ return null;
+ }
+}
diff --git a/phpBB/phpbb/textreparser/plugins/contact_admin_info.php b/phpBB/phpbb/textreparser/plugins/contact_admin_info.php
new file mode 100644
index 0000000000..8910f2256b
--- /dev/null
+++ b/phpBB/phpbb/textreparser/plugins/contact_admin_info.php
@@ -0,0 +1,69 @@
+<?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\textreparser\plugins;
+
+class contact_admin_info extends \phpbb\textreparser\base
+{
+ /**
+ * @var \phpbb\config\db_text
+ */
+ protected $config_text;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\config\db_text $config_text
+ */
+ public function __construct(\phpbb\config\db_text $config_text)
+ {
+ $this->config_text = $config_text;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_max_id()
+ {
+ return 1;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function get_records_by_range($min_id, $max_id)
+ {
+ $values = $this->config_text->get_array(array(
+ 'contact_admin_info',
+ 'contact_admin_info_uid',
+ 'contact_admin_info_flags',
+ ));
+
+ return array(array(
+ 'id' => 1,
+ 'text' => $values['contact_admin_info'],
+ 'bbcode_uid' => $values['contact_admin_info_uid'],
+ 'enable_bbcode' => $values['contact_admin_info_flags'] & OPTION_FLAG_BBCODE,
+ 'enable_magic_url' => $values['contact_admin_info_flags'] & OPTION_FLAG_LINKS,
+ 'enable_smilies' => $values['contact_admin_info_flags'] & OPTION_FLAG_SMILIES,
+ ));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function save_record(array $record)
+ {
+ $this->config_text->set('contact_admin_info', $record['text']);
+ }
+}
diff --git a/phpBB/phpbb/textreparser/plugins/forum_description.php b/phpBB/phpbb/textreparser/plugins/forum_description.php
new file mode 100644
index 0000000000..b0f5a42452
--- /dev/null
+++ b/phpBB/phpbb/textreparser/plugins/forum_description.php
@@ -0,0 +1,30 @@
+<?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\textreparser\plugins;
+
+class forum_description extends \phpbb\textreparser\row_based_plugin
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_columns()
+ {
+ return array(
+ '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
new file mode 100644
index 0000000000..d131d00707
--- /dev/null
+++ b/phpBB/phpbb/textreparser/plugins/forum_rules.php
@@ -0,0 +1,30 @@
+<?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\textreparser\plugins;
+
+class forum_rules extends \phpbb\textreparser\row_based_plugin
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_columns()
+ {
+ return array(
+ '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
new file mode 100644
index 0000000000..2c45c00474
--- /dev/null
+++ b/phpBB/phpbb/textreparser/plugins/group_description.php
@@ -0,0 +1,30 @@
+<?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\textreparser\plugins;
+
+class group_description extends \phpbb\textreparser\row_based_plugin
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_columns()
+ {
+ return array(
+ 'id' => 'group_id',
+ 'text' => 'group_desc',
+ 'bbcode_uid' => 'group_desc_uid',
+ 'options' => 'group_desc_options',
+ );
+ }
+}
diff --git a/phpBB/phpbb/textreparser/plugins/pm_text.php b/phpBB/phpbb/textreparser/plugins/pm_text.php
new file mode 100644
index 0000000000..867da624ee
--- /dev/null
+++ b/phpBB/phpbb/textreparser/plugins/pm_text.php
@@ -0,0 +1,32 @@
+<?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\textreparser\plugins;
+
+class pm_text extends \phpbb\textreparser\row_based_plugin
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_columns()
+ {
+ return array(
+ 'id' => 'msg_id',
+ 'enable_bbcode' => 'enable_bbcode',
+ 'enable_smilies' => 'enable_smilies',
+ 'enable_magic_url' => 'enable_magic_url',
+ 'text' => 'message_text',
+ 'bbcode_uid' => 'bbcode_uid',
+ );
+ }
+}
diff --git a/phpBB/phpbb/textreparser/plugins/poll_option.php b/phpBB/phpbb/textreparser/plugins/poll_option.php
new file mode 100644
index 0000000000..44cacfae62
--- /dev/null
+++ b/phpBB/phpbb/textreparser/plugins/poll_option.php
@@ -0,0 +1,74 @@
+<?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\textreparser\plugins;
+
+class poll_option extends \phpbb\textreparser\base
+{
+ /**
+ * @var \phpbb\db\driver\driver_interface
+ */
+ protected $db;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\db\driver\driver_interface $db Database connection
+ */
+ public function __construct(\phpbb\db\driver\driver_interface $db)
+ {
+ $this->db = $db;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_max_id()
+ {
+ $sql = 'SELECT MAX(topic_id) AS max_id FROM ' . POLL_OPTIONS_TABLE;
+ $result = $this->db->sql_query($sql);
+ $max_id = (int) $this->db->sql_fetchfield('max_id');
+ $this->db->sql_freeresult($result);
+
+ return $max_id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ 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.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
+ AND p.post_id = t.topic_first_post_id';
+ $result = $this->db->sql_query($sql);
+ $records = $this->db->sql_fetchrowset($result);
+ $this->db->sql_freeresult($result);
+
+ return $records;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function save_record(array $record)
+ {
+ $sql = 'UPDATE ' . POLL_OPTIONS_TABLE . "
+ SET poll_option_text = '" . $this->db->sql_escape($record['text']) . "'
+ WHERE topic_id = " . $record['topic_id'] . '
+ AND poll_option_id = ' . $record['poll_option_id'];
+ $this->db->sql_query($sql);
+ }
+}
diff --git a/phpBB/phpbb/textreparser/plugins/poll_title.php b/phpBB/phpbb/textreparser/plugins/poll_title.php
new file mode 100644
index 0000000000..5ca8bb063b
--- /dev/null
+++ b/phpBB/phpbb/textreparser/plugins/poll_title.php
@@ -0,0 +1,42 @@
+<?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\textreparser\plugins;
+
+class poll_title extends \phpbb\textreparser\row_based_plugin
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_columns()
+ {
+ return array(
+ 'id' => 'topic_id',
+ 'text' => 'poll_title',
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function get_records_by_range_query($min_id, $max_id)
+ {
+ $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_start > 0
+ AND p.post_id = t.topic_first_post_id';
+
+ return $sql;
+ }
+}
diff --git a/phpBB/phpbb/textreparser/plugins/post_text.php b/phpBB/phpbb/textreparser/plugins/post_text.php
new file mode 100644
index 0000000000..1c98e86067
--- /dev/null
+++ b/phpBB/phpbb/textreparser/plugins/post_text.php
@@ -0,0 +1,32 @@
+<?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\textreparser\plugins;
+
+class post_text extends \phpbb\textreparser\row_based_plugin
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_columns()
+ {
+ return array(
+ 'id' => 'post_id',
+ 'enable_bbcode' => 'enable_bbcode',
+ 'enable_smilies' => 'enable_smilies',
+ 'enable_magic_url' => 'enable_magic_url',
+ 'text' => 'post_text',
+ 'bbcode_uid' => 'bbcode_uid',
+ );
+ }
+}
diff --git a/phpBB/phpbb/textreparser/plugins/user_signature.php b/phpBB/phpbb/textreparser/plugins/user_signature.php
new file mode 100644
index 0000000000..647d3a7b14
--- /dev/null
+++ b/phpBB/phpbb/textreparser/plugins/user_signature.php
@@ -0,0 +1,65 @@
+<?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\textreparser\plugins;
+
+class user_signature extends \phpbb\textreparser\row_based_plugin
+{
+ /**
+ * @var array Bit numbers used for user options
+ * @see \phpbb\user
+ */
+ protected $keyoptions;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function add_missing_fields(array $row)
+ {
+ if (!isset($this->keyoptions))
+ {
+ $this->save_keyoptions();
+ }
+
+ $options = $row['user_options'];
+ $row += array(
+ 'enable_bbcode' => phpbb_optionget($this->keyoptions['sig_bbcode'], $options),
+ 'enable_smilies' => phpbb_optionget($this->keyoptions['sig_smilies'], $options),
+ 'enable_magic_url' => phpbb_optionget($this->keyoptions['sig_links'], $options),
+ );
+
+ return parent::add_missing_fields($row);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_columns()
+ {
+ return array(
+ 'id' => 'user_id',
+ 'text' => 'user_sig',
+ 'bbcode_uid' => 'user_sig_bbcode_uid',
+ 'user_options' => 'user_options',
+ );
+ }
+
+ /**
+ * Save the keyoptions var from \phpbb\user
+ */
+ protected function save_keyoptions()
+ {
+ $class_vars = get_class_vars('phpbb\\user');
+ $this->keyoptions = $class_vars['keyoptions'];
+ }
+}
diff --git a/phpBB/phpbb/textreparser/reparser_interface.php b/phpBB/phpbb/textreparser/reparser_interface.php
new file mode 100644
index 0000000000..912de10058
--- /dev/null
+++ b/phpBB/phpbb/textreparser/reparser_interface.php
@@ -0,0 +1,46 @@
+<?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\textreparser;
+
+interface reparser_interface
+{
+ /**
+ * Return the highest ID for all existing records
+ *
+ * @return integer
+ */
+ public function get_max_id();
+
+ /**
+ * Returns the name of the reparser
+ *
+ * @return string Name of reparser
+ */
+ public function get_name();
+
+ /**
+ * Sets the name of the reparser
+ *
+ * @param string $name The reparser name
+ */
+ public function set_name($name);
+
+ /**
+ * Reparse all records in given range
+ *
+ * @param integer $min_id Lower bound
+ * @param integer $max_id Upper bound
+ */
+ public function reparse_range($min_id, $max_id);
+}
diff --git a/phpBB/phpbb/textreparser/row_based_plugin.php b/phpBB/phpbb/textreparser/row_based_plugin.php
new file mode 100644
index 0000000000..2d32104493
--- /dev/null
+++ b/phpBB/phpbb/textreparser/row_based_plugin.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\textreparser;
+
+abstract class row_based_plugin extends base
+{
+ /**
+ * @var \phpbb\db\driver\driver_interface
+ */
+ protected $db;
+
+ /**
+ * @var string
+ */
+ protected $table;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\db\driver\driver_interface $db Database connection
+ * @param string $table
+ */
+ public function __construct(\phpbb\db\driver\driver_interface $db, $table)
+ {
+ $this->db = $db;
+ $this->table = $table;
+ }
+
+ /**
+ * Return the name of the column that correspond to each field
+ *
+ * @return array
+ */
+ abstract public function get_columns();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_max_id()
+ {
+ $columns = $this->get_columns();
+
+ $sql = 'SELECT MAX(' . $columns['id'] . ') AS max_id FROM ' . $this->table;
+ $result = $this->db->sql_query($sql);
+ $max_id = (int) $this->db->sql_fetchfield('max_id');
+ $this->db->sql_freeresult($result);
+
+ return $max_id;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function get_records_by_range($min_id, $max_id)
+ {
+ $sql = $this->get_records_by_range_query($min_id, $max_id);
+ $result = $this->db->sql_query($sql);
+ $records = $this->db->sql_fetchrowset($result);
+ $this->db->sql_freeresult($result);
+
+ return $records;
+ }
+
+ /**
+ * Generate the query that retrieves all records for given range
+ *
+ * @param integer $min_id Lower bound
+ * @param integer $max_id Upper bound
+ * @return string SQL query
+ */
+ protected function get_records_by_range_query($min_id, $max_id)
+ {
+ $columns = $this->get_columns();
+ $fields = array();
+ foreach ($columns as $field_name => $column_name)
+ {
+ if ($column_name === $field_name)
+ {
+ $fields[] = $column_name;
+ }
+ else
+ {
+ $fields[] = $column_name . ' AS ' . $field_name;
+ }
+ }
+
+ $sql = 'SELECT ' . implode(', ', $fields) . '
+ FROM ' . $this->table . '
+ WHERE ' . $columns['id'] . ' BETWEEN ' . $min_id . ' AND ' . $max_id;
+
+ return $sql;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function save_record(array $record)
+ {
+ $columns = $this->get_columns();
+
+ $sql = 'UPDATE ' . $this->table . '
+ SET ' . $columns['text'] . " = '" . $this->db->sql_escape($record['text']) . "'
+ WHERE " . $columns['id'] . ' = ' . $record['id'];
+ $this->db->sql_query($sql);
+ }
+}