diff --git a/phpBB/config/default/container/services_text_reparser.yml b/phpBB/config/default/container/services_text_reparser.yml new file mode 100644 index 0000000000..3113c02f6d --- /dev/null +++ b/phpBB/config/default/container/services_text_reparser.yml @@ -0,0 +1,63 @@ +services: + text_reparser.admin_contact_info: + class: phpbb\textreparser\admincontactinfo + arguments: + - @dbal.conn + tags: + - { name: text_reparser.plugin } + + text_reparser.forum_description: + class: phpbb\textreparser\forumdescription + arguments: + - @dbal.conn + tags: + - { name: text_reparser.plugin } + + text_reparser.forum_rules: + class: phpbb\textreparser\forumrules + arguments: + - @dbal.conn + tags: + - { name: text_reparser.plugin } + + text_reparser.group_description: + class: phpbb\textreparser\groupdescription + arguments: + - @dbal.conn + tags: + - { name: text_reparser.plugin } + + text_reparser.pm_text: + class: phpbb\textreparser\pmtext + arguments: + - @dbal.conn + tags: + - { name: text_reparser.plugin } + + text_reparser.poll_option: + class: phpbb\textreparser\polloption + arguments: + - @dbal.conn + tags: + - { name: text_reparser.plugin } + + text_reparser.poll_title: + class: phpbb\textreparser\polltitle + arguments: + - @dbal.conn + tags: + - { name: text_reparser.plugin } + + text_reparser.post_text: + class: phpbb\textreparser\posttext + arguments: + - @dbal.conn + tags: + - { name: text_reparser.plugin } + + text_reparser.user_signature: + class: phpbb\textreparser\usersignature + arguments: + - @dbal.conn + tags: + - { name: text_reparser.plugin } diff --git a/phpBB/phpbb/textreparser/base.php b/phpBB/phpbb/textreparser/base.php new file mode 100644 index 0000000000..6aa20d0015 --- /dev/null +++ b/phpBB/phpbb/textreparser/base.php @@ -0,0 +1,97 @@ + +* @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 \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} + */ + 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 record + */ + abstract protected function get_records($min_id, $max_id); + + /** + * {@inheritdoc} + */ + public function reparse_range($min_id, $max_id) + { + foreach ($this->get_records($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) + { + $unparsed = array_merge( + $record, + generate_text_for_edit( + $record['text'], + $record['bbcode_uid'], + OPTION_FLAG_BBCODE | OPTION_FLAG_SMILIES | OPTION_FLAG_LINKS + ) + ); + $bitfield = $flags = null; + $parsed_text = $unparsed['text']; + generate_text_for_storage( + $parsed_text, + $unparsed['bbcode_uid'], + $bitfield, + $flags, + $unparsed['enable_bbcode'], + $unparsed['enable_smilies'], + $unparsed['enable_magic_url'] + ); + + // Save the new text if it has changed + if ($parsed_text !== $record['text']) + { + $record['text'] = $parsed_text; + $this->save_record($record); + } + } + + /** + * {@inheritdoc} + */ + abstract protected function save_record(array $record); +} diff --git a/phpBB/phpbb/textreparser/forumdescription.php b/phpBB/phpbb/textreparser/forumdescription.php new file mode 100644 index 0000000000..b715abd825 --- /dev/null +++ b/phpBB/phpbb/textreparser/forumdescription.php @@ -0,0 +1,63 @@ + +* @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 forumdescription extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_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($min_id, $max_id) + { + $sql = 'SELECT forum_id AS id, forum_desc AS text, forum_desc_uid AS bbcode_uid + FROM ' . FORUMS_TABLE . ' + WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Those fields are not saved to the database, we need to guess their original value + $row['enable_bbcode'] = !empty($row['bbcode_uid']); + $row['enable_smilies'] = (strpos($row['text'], '') !== false); + } + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . FORUMS_TABLE . " + SET forum_desc = '" . $this->db->sql_escape($record['text']) . "' + WHERE forum_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/forumrules.php b/phpBB/phpbb/textreparser/forumrules.php new file mode 100644 index 0000000000..c0538f6cce --- /dev/null +++ b/phpBB/phpbb/textreparser/forumrules.php @@ -0,0 +1,63 @@ + +* @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 forumrules extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(forum_id) AS max_id FROM ' . FORUMS_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($min_id, $max_id) + { + $sql = 'SELECT forum_id AS id, forum_rules AS text, forum_rules_uid AS bbcode_uid + FROM ' . FORUMS_TABLE . ' + WHERE forum_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Those fields are not saved to the database, we need to guess their original value + $row['enable_bbcode'] = !empty($row['bbcode_uid']); + $row['enable_smilies'] = (strpos($row['text'], '') !== false); + } + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . FORUMS_TABLE . " + SET forum_rules = '" . $this->db->sql_escape($record['text']) . "' + WHERE forum_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/groupdescription.php b/phpBB/phpbb/textreparser/groupdescription.php new file mode 100644 index 0000000000..608cc806b6 --- /dev/null +++ b/phpBB/phpbb/textreparser/groupdescription.php @@ -0,0 +1,63 @@ + +* @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 groupdescription extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(group_id) AS max_id FROM ' . GROUPS_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($min_id, $max_id) + { + $sql = 'SELECT group_id AS id, group_desc AS text, group_desc_uid AS bbcode_uid + FROM ' . GROUPS_TABLE . ' + WHERE group_id BETWEEN ' . $min_id . ' AND ' . $max_id; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // Those fields are not saved to the database, we need to guess their original value + $row['enable_bbcode'] = !empty($row['bbcode_uid']); + $row['enable_smilies'] = (strpos($row['text'], '') !== false); + } + $records = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + return $records; + } + + /** + * {@inheritdoc} + */ + protected function save_record(array $record) + { + $sql = 'UPDATE ' . GROUPS_TABLE . " + SET group_desc = '" . $this->db->sql_escape($record['text']) . "' + WHERE group_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/pmtext.php b/phpBB/phpbb/textreparser/pmtext.php new file mode 100644 index 0000000000..e1b27e60fe --- /dev/null +++ b/phpBB/phpbb/textreparser/pmtext.php @@ -0,0 +1,56 @@ + +* @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 pmtext extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(msg_id) AS max_id FROM ' . PRIVMSGS_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($min_id, $max_id) + { + $sql = 'SELECT msg_id AS id, enable_bbcode, enable_smilies, enable_magic_url, message_text AS text, bbcode_uid + FROM ' . PRIVMSGS_TABLE . ' + WHERE msg_id BETWEEN ' . $min_id . ' AND ' . $max_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 ' . PRIVMSGS_TABLE . " + SET message_text = '" . $this->db->sql_escape($record['text']) . "' + WHERE msg_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/posttext.php b/phpBB/phpbb/textreparser/posttext.php new file mode 100644 index 0000000000..916fc94bfa --- /dev/null +++ b/phpBB/phpbb/textreparser/posttext.php @@ -0,0 +1,56 @@ + +* @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 posttext extends base +{ + /** + * {@inheritdoc} + */ + public function get_max_id() + { + $sql = 'SELECT MAX(post_id) AS max_id FROM ' . POSTS_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($min_id, $max_id) + { + $sql = 'SELECT post_id AS id, enable_bbcode, enable_smilies, enable_magic_url, post_text AS text, bbcode_uid + FROM ' . POSTS_TABLE . ' + WHERE post_id BETWEEN ' . $min_id . ' AND ' . $max_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 ' . POSTS_TABLE . " + SET post_text = '" . $this->db->sql_escape($record['text']) . "' + WHERE post_id = " . $record['id']; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/textreparser/reparser_interface.php b/phpBB/phpbb/textreparser/reparser_interface.php new file mode 100644 index 0000000000..20f8d92b1a --- /dev/null +++ b/phpBB/phpbb/textreparser/reparser_interface.php @@ -0,0 +1,32 @@ + +* @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(); + + /** + * 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/tests/text_reparser/fixtures/posts.xml b/tests/text_reparser/fixtures/posts.xml new file mode 100644 index 0000000000..6485293361 --- /dev/null +++ b/tests/text_reparser/fixtures/posts.xml @@ -0,0 +1,19 @@ + + + + post_id + enable_bbcode + enable_smilies + enable_magic_url + post_text + bbcode_uid + + 1 + 1 + 1 + 1 + Plain text + abcd1234 + +
+
diff --git a/tests/text_reparser/posttext_test.php b/tests/text_reparser/posttext_test.php new file mode 100644 index 0000000000..4dec53dc63 --- /dev/null +++ b/tests/text_reparser/posttext_test.php @@ -0,0 +1,67 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ +require_once __DIR__ . '/../../phpBB/includes/functions.php'; +require_once __DIR__ . '/../../phpBB/includes/functions_content.php'; +require_once __DIR__ . '/../test_framework/phpbb_database_test_case.php'; + +class phpbb_textreparser_posttext_test extends phpbb_database_test_case +{ + public function setUp() + { + global $config; + if (!isset($config)) + { + $config = new \phpbb\config\config(array()); + } + $this->get_test_case_helpers()->set_s9e_services(); + parent::setUp(); + } + + public function getDataSet() + { + return $this->createXMLDataSet(__DIR__ . '/fixtures/posts.xml'); + } + + /** + * @dataProvider getReparseTests + */ + public function testReparse($min_id, $max_id, $expected) + { + $db = $this->new_dbal(); + $reparser = new \phpbb\textreparser\posttext($db); + $reparser->reparse_range($min_id, $max_id); + $sql = 'SELECT post_id, post_text + FROM ' . POSTS_TABLE . " + WHERE post_id BETWEEN $min_id AND $max_id"; + $result = $db->sql_query($sql); + $rows = $db->sql_fetchrowset($result); + $db->sql_freeresult($result); + $this->assertEquals($expected, $rows); + } + + public function getReparseTests() + { + return array( + array( + 1, + 1, + array( + array( + 'post_id' => 1, + 'post_text' => 'Plain text' + ) + ) + ), + ); + } +}