From 3827a131ae11dcd3adf852f80ff4d85e7a7d470b Mon Sep 17 00:00:00 2001
From: JoshyPHP <s9e.dev@gmail.com>
Date: Sat, 9 May 2015 20:12:30 +0200
Subject: [PATCH] [ticket/13803] Rewrote the poll_option plugin

As it turns out, poll_option_id is not a primary key.

PHPBB3-13803
---
 .../textreparser/plugins/poll_option.php      | 50 ++++++++----
 tests/text_reparser/fixtures/poll_options.xml | 63 +++++++--------
 tests/text_reparser/poll_option_test.php      | 78 ++++++++++++++++++-
 3 files changed, 142 insertions(+), 49 deletions(-)

diff --git a/phpBB/phpbb/textreparser/plugins/poll_option.php b/phpBB/phpbb/textreparser/plugins/poll_option.php
index cc28599737..3249e21694 100644
--- a/phpBB/phpbb/textreparser/plugins/poll_option.php
+++ b/phpBB/phpbb/textreparser/plugins/poll_option.php
@@ -13,38 +13,62 @@
 
 namespace phpbb\textreparser\plugins;
 
-class poll_option extends \phpbb\textreparser\row_based_plugin
+class poll_option extends \phpbb\textreparser\base
 {
 	/**
-	* {@inheritdoc}
+	* @var \phpbb\db\driver\driver_interface
 	*/
-	public function get_columns()
+	protected $db;
+
+	/**
+	* Constructor
+	*
+	* @param \phpbb\db\driver\driver_interface $db Database connection
+	*/
+	public function __construct(\phpbb\db\driver\driver_interface $db)
 	{
-		return array(
-			'id'   => 'poll_option_id',
-			'text' => 'poll_option_text',
-		);
+		$this->db = $db;
 	}
 
 	/**
 	* {@inheritdoc}
 	*/
-	protected function get_records_query($min_id, $max_id)
+	public function get_max_id()
 	{
-		$sql = 'SELECT o.poll_option_id AS id, o.poll_option_text AS text, p.bbcode_uid
+		$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($min_id, $max_id)
+	{
+		$sql = 'SELECT o.topic_id, o.poll_option_id, o.poll_option_text AS text, p.bbcode_uid
 			FROM ' . POLL_OPTIONS_TABLE . ' o, ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p
-			WHERE o.poll_option_id BETWEEN ' . $min_id . ' AND ' . $max_id .'
+			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 $sql;
+		return $records;
 	}
 
 	/**
 	* {@inheritdoc}
 	*/
-	public function get_table_name()
+	protected function save_record(array $record)
 	{
-		return POLL_OPTIONS_TABLE;
+		$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/tests/text_reparser/fixtures/poll_options.xml b/tests/text_reparser/fixtures/poll_options.xml
index f0ed54aafb..c2fad9f764 100644
--- a/tests/text_reparser/fixtures/poll_options.xml
+++ b/tests/text_reparser/fixtures/poll_options.xml
@@ -12,48 +12,33 @@
 		<row>
 			<value>2</value>
 			<value>1</value>
-			<value>[b]Not bold[/b] :) http://example.org</value>
+			<value>This row should be [b:abcd1234]ignored[/b:abcd1234]</value>
+		</row>
+		<row>
+			<value>1</value>
+			<value>2</value>
+			<value>[b:abcd1234]Bold[/b:abcd1234]</value>
+		</row>
+		<row>
+			<value>2</value>
+			<value>2</value>
+			<value><![CDATA[<!-- s:) --><img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile" /><!-- s:) -->]]></value>
 		</row>
 		<row>
 			<value>3</value>
-			<value>1</value>
-			<value>[b:abcd1234]Bold[/b:abcd1234] :) http://example.org</value>
+			<value>2</value>
+			<value><![CDATA[<!-- m --><a class="postlink" href="http://example.org">http://example.org</a><!-- m -->]]></value>
 		</row>
 		<row>
-			<value>4</value>
-			<value>1</value>
-			<value><![CDATA[[b]Not bold[/b] <!-- s:) --><img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile" /><!-- s:) --> http://example.org]]></value>
-		</row>
-		<row>
-			<value>5</value>
-			<value>1</value>
-			<value><![CDATA[[b]Not bold[/b] :) <!-- m --><a class="postlink" href="http://example.org">http://example.org</a><!-- m -->]]></value>
-		</row>
-		<row>
-			<value>6</value>
-			<value>1</value>
-			<value><![CDATA[[flash=123,345:abcd1234]http&#58;//example&#46;org/flash&#46;swf[/flash:abcd1234]]]></value>
-		</row>
-		<row>
-			<value>7</value>
-			<value>1</value>
-			<value><![CDATA[[flash=123,345]http://example.org/flash.swf[/flash]]]></value>
-		</row>
-		<row>
-			<value>8</value>
-			<value>1</value>
-			<value><![CDATA[[img:abcd1234]http&#58;//example&#46;org/img&#46;png[/img:abcd1234]]]></value>
-		</row>
-		<row>
-			<value>9</value>
-			<value>1</value>
-			<value><![CDATA[[img]http://example.org/img.png[/img]]]></value>
-		</row>
-		<row>
-			<value>1000</value>
 			<value>1</value>
+			<value>123</value>
 			<value>This row should be [b]ignored[/b]</value>
 		</row>
+		<row>
+			<value>2</value>
+			<value>123</value>
+			<value>This row should be [b:abcd1234]ignored[/b:abcd1234]</value>
+		</row>
 	</table>
 	<table name="phpbb_posts">
 		<column>post_id</column>
@@ -74,5 +59,15 @@
 			<value>1</value>
 			<value>This row should be [b]ignored[/b]</value>
 		</row>
+		<row>
+			<value>2</value>
+			<value>1</value>
+			<value>This row should be [b]ignored[/b]</value>
+		</row>
+		<row>
+			<value>123</value>
+			<value>1</value>
+			<value>This row should be [b]ignored[/b]</value>
+		</row>
 	</table>
 </dataset>
diff --git a/tests/text_reparser/poll_option_test.php b/tests/text_reparser/poll_option_test.php
index 0f08f720ff..669d859f9a 100644
--- a/tests/text_reparser/poll_option_test.php
+++ b/tests/text_reparser/poll_option_test.php
@@ -10,10 +10,14 @@
 * the docs/CREDITS.txt file.
 *
 */
-include_once __DIR__ . '/test_row_based_plugin.php';
+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_poll_option_test extends phpbb_textreparser_test_row_based_plugin
+class phpbb_textreparser_poll_option_test extends phpbb_database_test_case
 {
+	protected $db;
+
 	public function getDataSet()
 	{
 		return $this->createXMLDataSet(__DIR__ . '/fixtures/poll_options.xml');
@@ -23,4 +27,74 @@ class phpbb_textreparser_poll_option_test extends phpbb_textreparser_test_row_ba
 	{
 		return new \phpbb\textreparser\plugins\poll_option($this->db);
 	}
+
+	public function setUp()
+	{
+		global $config;
+		if (!isset($config))
+		{
+			$config = new \phpbb\config\config(array());
+		}
+		$this->get_test_case_helpers()->set_s9e_services();
+		$this->db = $this->new_dbal();
+		parent::setUp();
+	}
+
+	public function test_get_max_id()
+	{
+		$reparser = $this->get_reparser();
+		$this->assertEquals(123, $reparser->get_max_id());
+	}
+
+	public function testReparse()
+	{
+		$reparser = $this->get_reparser();
+		$reparser->reparse_range(2, 3);
+
+		$sql = 'SELECT topic_id, poll_option_id, poll_option_text
+			FROM ' . POLL_OPTIONS_TABLE . '
+			ORDER BY topic_id, poll_option_id';
+		$result = $this->db->sql_query($sql);
+		$rows = $this->db->sql_fetchrowset($result);
+		$this->db->sql_freeresult($result);
+
+		$expected = array(
+			array(
+				'topic_id'         => 1,
+				'poll_option_id'   => 1,
+				'poll_option_text' => 'This row should be [b]ignored[/b]',
+			),
+			array(
+				'topic_id'         => 1,
+				'poll_option_id'   => 2,
+				'poll_option_text' => 'This row should be [b:abcd1234]ignored[/b:abcd1234]',
+			),
+			array(
+				'topic_id'         => 2,
+				'poll_option_id'   => 1,
+				'poll_option_text' => '<r><B><s>[b]</s>Bold<e>[/b]</e></B></r>',
+			),
+			array(
+				'topic_id'         => 2,
+				'poll_option_id'   => 2,
+				'poll_option_text' => '<r><E>:)</E></r>',
+			),
+			array(
+				'topic_id'         => 2,
+				'poll_option_id'   => 3,
+				'poll_option_text' => '<r><URL url="http://example.org">http://example.org</URL></r>',
+			),
+			array(
+				'topic_id'         => 123,
+				'poll_option_id'   => 1,
+				'poll_option_text' => 'This row should be [b]ignored[/b]',
+			),
+			array(
+				'topic_id'         => 123,
+				'poll_option_id'   => 2,
+				'poll_option_text' => 'This row should be [b:abcd1234]ignored[/b:abcd1234]',
+			),
+		);
+		$this->assertEquals($expected, $rows);
+	}
 }