diff options
| -rw-r--r-- | phpBB/adm/style/acp_forums.html | 13 | ||||
| -rw-r--r-- | phpBB/config/cron_tasks.yml | 13 | ||||
| -rw-r--r-- | phpBB/includes/acp/acp_forums.php | 9 | ||||
| -rw-r--r-- | phpBB/includes/functions_admin.php | 5 | ||||
| -rw-r--r-- | phpBB/install/schemas/schema.json | 16 | ||||
| -rw-r--r-- | phpBB/language/en/acp/common.php | 1 | ||||
| -rw-r--r-- | phpBB/language/en/acp/forums.php | 2 | ||||
| -rw-r--r-- | phpBB/phpbb/cron/task/core/prune_shadow_topics.php | 191 | ||||
| -rw-r--r-- | phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php | 46 | ||||
| -rw-r--r-- | phpBB/viewforum.php | 12 | ||||
| -rw-r--r-- | tests/functional/prune_shadow_topic_test.php | 207 | 
11 files changed, 515 insertions, 0 deletions
| diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html index e8b20007dc..0bb5e10f57 100644 --- a/phpBB/adm/style/acp_forums.html +++ b/phpBB/adm/style/acp_forums.html @@ -278,6 +278,19 @@  			<dd><label><input type="radio" class="radio" name="prune_sticky" value="1"<!-- IF S_PRUNE_STICKY --> id="prune_sticky" checked="checked"<!-- ENDIF --> /> {L_YES}</label>  				<label><input type="radio" class="radio" name="prune_sticky" value="0"<!-- IF not S_PRUNE_STICKY --> id="prune_sticky" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>  		</dl> +		<dl> +			<dt><label for="enable_shadow_prune">{L_FORUM_PRUNE_SHADOW}{L_COLON}</label><br /><span>{L_FORUM_PRUNE_SHADOW_EXPLAIN}</span></dt> +			<dd><label><input type="radio" class="radio" name="enable_shadow_prune" value="1"<!-- IF S_PRUNE_SHADOW_ENABLE --> id="enable_shadow_prune" checked="checked"<!-- ENDIF --> /> {L_YES}</label> +				<label><input type="radio" class="radio" name="enable_shadow_prune" value="0"<!-- IF not S_PRUNE_SHADOW_ENABLE --> id="enable_shadow_prune" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd> +		</dl> +		<dl> +			<dt><label for="prune_shadow_freq">{L_AUTO_PRUNE_FREQ}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_FREQ_EXPLAIN}</span></dt> +			<dd><input type="number" id="prune_shadow_freq" name="prune_shadow_freq" value="{PRUNE_FREQ}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd> +		</dl> +		<dl> +			<dt><label for="prune_shadow_days">{L_AUTO_PRUNE_DAYS}{L_COLON}</label><br /><span>{L_AUTO_PRUNE_DAYS_EXPLAIN}</span></dt> +			<dd><input type="number" id="prune_shadow_days" name="prune_shadow_days" value="{PRUNE_DAYS}" maxlength="4" size="4" min="0" max="9999" /> {L_DAYS}</dd> +		</dl>  		</fieldset>  	</div> diff --git a/phpBB/config/cron_tasks.yml b/phpBB/config/cron_tasks.yml index fd3aea85dc..4fa5d1440e 100644 --- a/phpBB/config/cron_tasks.yml +++ b/phpBB/config/cron_tasks.yml @@ -23,6 +23,19 @@ services:          tags:              - { name: cron.task } +    cron.task.core.prune_shadow_topics: +        class: phpbb\cron\task\core\prune_shadow_topics +        arguments: +            - %core.root_path% +            - %core.php_ext% +            - @config +            - @dbal.conn +            - @log +        calls: +            - [set_name, [cron.task.core.prune_shadow_topics]] +        tags: +            - { name: cron.task } +      cron.task.core.prune_notifications:          class: phpbb\cron\task\core\prune_notifications          arguments: diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index a1af8c489d..c47d9bc185 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -138,12 +138,15 @@ class acp_forums  						'enable_prune'			=> request_var('enable_prune', false),  						'enable_post_review'	=> request_var('enable_post_review', true),  						'enable_quick_reply'	=> request_var('enable_quick_reply', false), +						'enable_shadow_prune'		=> request_var('enable_shadow_prune', false),  						'prune_days'			=> request_var('prune_days', 7),  						'prune_viewed'			=> request_var('prune_viewed', 7),  						'prune_freq'			=> request_var('prune_freq', 1),  						'prune_old_polls'		=> request_var('prune_old_polls', false),  						'prune_announce'		=> request_var('prune_announce', false),  						'prune_sticky'			=> request_var('prune_sticky', false), +						'prune_shadow_days'		=> request_var('prune_shadow_days', 7), +						'prune_shadow_freq'		=> request_var('prune_shadow_freq', 1),  						'forum_password'		=> request_var('forum_password', '', true),  						'forum_password_confirm'=> request_var('forum_password_confirm', '', true),  						'forum_password_unset'	=> request_var('forum_password_unset', false), @@ -457,6 +460,9 @@ class acp_forums  							'prune_days'			=> 7,  							'prune_viewed'			=> 7,  							'prune_freq'			=> 1, +							'enable_shadow_prune'		=> false, +							'prune_shadow_days'		=> 7, +							'prune_shadow_freq'		=> 1,  							'forum_flags'			=> FORUM_FLAG_POST_REVIEW + FORUM_FLAG_ACTIVE_TOPICS,  							'forum_options'			=> 0,  							'forum_password'		=> '', @@ -636,6 +642,8 @@ class acp_forums  					'PRUNE_FREQ'				=> $forum_data['prune_freq'],  					'PRUNE_DAYS'				=> $forum_data['prune_days'],  					'PRUNE_VIEWED'				=> $forum_data['prune_viewed'], +					'PRUNE_SHADOW_FREQ'			=> $forum_data['prune_shadow_freq'], +					'PRUNE_SHADOW_DAYS'			=> $forum_data['prune_shadow_days'],  					'TOPICS_PER_PAGE'			=> $forum_data['forum_topics_per_page'],  					'FORUM_RULES_LINK'			=> $forum_data['forum_rules_link'],  					'FORUM_RULES'				=> $forum_data['forum_rules'], @@ -668,6 +676,7 @@ class acp_forums  					'S_DISPLAY_SUBFORUM_LIST'	=> ($forum_data['display_subforum_list']) ? true : false,  					'S_DISPLAY_ON_INDEX'		=> ($forum_data['display_on_index']) ? true : false,  					'S_PRUNE_ENABLE'			=> ($forum_data['enable_prune']) ? true : false, +					'S_PRUNE_SHADOW_ENABLE'			=> ($forum_data['enable_shadow_prune']) ? true : false,  					'S_FORUM_LINK_TRACK'		=> ($forum_data['forum_flags'] & FORUM_FLAG_LINK_TRACK) ? true : false,  					'S_PRUNE_OLD_POLLS'			=> ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_POLL) ? true : false,  					'S_PRUNE_ANNOUNCE'			=> ($forum_data['forum_flags'] & FORUM_FLAG_PRUNE_ANNOUNCE) ? true : false, diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 81a381b326..2bf8e6dcf0 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2326,6 +2326,11 @@ function prune($forum_id, $prune_mode, $prune_date, $prune_flags = 0, $auto_sync  		$sql_and .= " AND topic_last_view_time < $prune_date";  	} +	if ($prune_mode == 'shadow') +	{ +		$sql_and .= ' AND topic_status = ' . ITEM_MOVED . " AND topic_last_post_time < $prune_date"; +	} +  	$sql = 'SELECT topic_id  		FROM ' . TOPICS_TABLE . '  		WHERE ' . $db->sql_in_set('forum_id', $forum_id) . " diff --git a/phpBB/install/schemas/schema.json b/phpBB/install/schemas/schema.json index 15d2fd6e84..176691f1a6 100644 --- a/phpBB/install/schemas/schema.json +++ b/phpBB/install/schemas/schema.json @@ -800,6 +800,22 @@                  "UINT:20",                  0              ], +            "enable_shadow_prune": [ +                "BOOL", +                0 +            ], +            "prune_shadow_days": [ +                "UINT", +                7 +            ], +            "prune_shadow_freq": [ +                "UINT", +                1 +            ], +            "prune_shadow_next": [ +                "INT:11", +                0 +            ],              "forum_posts_approved": [                  "UINT",                  0 diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index cf32c7c225..2dc58d8361 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -676,6 +676,7 @@ $lang = array_merge($lang, array(  	'LOG_PRUNE'					=> '<strong>Pruned forums</strong><br />» %s',  	'LOG_AUTO_PRUNE'			=> '<strong>Auto-pruned forums</strong><br />» %s', +	'LOG_PRUNE_SHADOW'		=> '<strong>Auto-pruned shadow topics</strong><br />» %s',  	'LOG_PRUNE_USER_DEAC'		=> '<strong>Users deactivated</strong><br />» %s',  	'LOG_PRUNE_USER_DEL_DEL'	=> '<strong>Users pruned and posts deleted</strong><br />» %s',  	'LOG_PRUNE_USER_DEL_ANON'	=> '<strong>Users pruned and posts retained</strong><br />» %s', diff --git a/phpBB/language/en/acp/forums.php b/phpBB/language/en/acp/forums.php index 756cb7ae0f..d64380b6b6 100644 --- a/phpBB/language/en/acp/forums.php +++ b/phpBB/language/en/acp/forums.php @@ -101,6 +101,8 @@ $lang = array_merge($lang, array(  	'FORUM_PASSWORD_OLD'				=> 'The forum password is using an old hashing method and should be changed.',  	'FORUM_PASSWORD_MISMATCH'			=> 'The passwords you entered did not match.',  	'FORUM_PRUNE_SETTINGS'				=> 'Forum prune settings', +	'FORUM_PRUNE_SHADOW'				=> 'Enable auto-pruning of shadow topics', +	'FORUM_PRUNE_SHADOW_EXPLAIN'			=> 'Prunes the forum of shadow topics, set the frequency/age parameters below.',  	'FORUM_RESYNCED'					=> 'Forum “%s” successfully resynced',  	'FORUM_RULES_EXPLAIN'				=> 'Forum rules are displayed at any page within the given forum.',  	'FORUM_RULES_LINK'					=> 'Link to forum rules', diff --git a/phpBB/phpbb/cron/task/core/prune_shadow_topics.php b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php new file mode 100644 index 0000000000..b30e665a87 --- /dev/null +++ b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php @@ -0,0 +1,191 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\cron\task\core; + +/** +* Prune one forum of its shadow topics cron task. +* +* It is intended to be used when cron is invoked via web. +* This task can decide whether it should be run using data obtained by viewforum +* code, without making additional database queries. +* +* @package phpBB3 +*/ +class prune_shadow_topics extends \phpbb\cron\task\base implements \phpbb\cron\task\parametrized +{ +	protected $phpbb_root_path; +	protected $php_ext; +	protected $config; +	protected $db; +	protected $log; + +	/** +	* If $forum_data is given, it is assumed to contain necessary information +	* about a single forum that is to be pruned. +	* +	* If $forum_data is not given, forum id will be retrieved via request_var +	* and a database query will be performed to load the necessary information +	* about the forum. +	*/ +	protected $forum_data; + +	/** +	* Constructor. +	* +	* @param string $phpbb_root_path The root path +	* @param string $php_ext The PHP extension +	* @param \phpbb\config\config $config The config +	* @param \phpbb\db\driver\driver $db The db connection +	* @param \phpbb\log\log $log The phpBB log system +	*/ +	public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\log\log $log) +	{ +		$this->phpbb_root_path = $phpbb_root_path; +		$this->php_ext = $php_ext; +		$this->config = $config; +		$this->db = $db; +		$this->log = $log; +	} + +	/** +	* Manually set forum data. +	* +	* @param array $forum_data Information about a forum to be pruned. +	*/ +	public function set_forum_data($forum_data) +	{ +		$this->forum_data = $forum_data; +	} + +	/** +	* Runs this cron task. +	* +	* @return null +	*/ +	public function run() +	{ +		if (!function_exists('auto_prune')) +		{ +			include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext); +		} + +		if ($this->forum_data['prune_shadow_days']) +		{ +			$this->auto_prune_shadow_topics($this->forum_data['forum_id'], 'shadow', $this->forum_data['forum_flags'], $this->forum_data['prune_shadow_days'], $this->forum_data['prune_shadow_freq']); +		} +	} + +	/** +	* Returns whether this cron task can run, given current board configuration. +	* +	* This cron task will not run when system cron is utilised, as in +	* such cases prune_all_forums task would run instead. +	* +	* Additionally, this task must be given the forum data, either via +	* the constructor or parse_parameters method. +	* +	* @return bool +	*/ +	public function is_runnable() +	{ +		return !$this->config['use_system_cron'] && $this->forum_data; +	} + +	/** +	* Returns whether this cron task should run now, because enough time +	* has passed since it was last run. +	* +	* Forum pruning interval is specified in the forum data. +	* +	* @return bool +	*/ +	public function should_run() +	{ +		return $this->forum_data['enable_shadow_prune'] && $this->forum_data['prune_shadow_next'] < time(); +	} + +	/** +	* Returns parameters of this cron task as an array. +	* The array has one key, f, whose value is id of the forum to be pruned. +	* +	* @return array +	*/ +	public function get_parameters() +	{ +		return array('f' => $this->forum_data['forum_id']); +	} + +	/** +	* Parses parameters found in $request, which is an instance of +	* \phpbb\request\request_interface. +	* +	* It is expected to have a key f whose value is id of the forum to be pruned. +	* +	* @param \phpbb\request\request_interface $request Request object. +	* +	* @return null +	*/ +	public function parse_parameters(\phpbb\request\request_interface $request) +	{ +		$this->forum_data = null; +		if ($request->is_set('f')) +		{ +			$forum_id = $request->variable('f', 0); + +			$sql = 'SELECT forum_id, prune_shadow_next, enable_shadow_prune, prune_shadow_days, forum_flags, prune_shadow_freq +				FROM ' . FORUMS_TABLE . " +				WHERE forum_id = $forum_id"; +			$result = $this->db->sql_query($sql); +			$row = $this->db->sql_fetchrow($result); +			$this->db->sql_freeresult($result); + +			if ($row) +			{ +				$this->forum_data = $row; +			} +		} +	} + +	/** +	* Automatically prune shadow topics +	* Based on fuunction auto_prune() +	* @param int $forum_id Forum ID of forum that should be pruned +	* @param string $prune_mode Prune mode +	* @param int $prune_flags Prune flags +	* @param int $prune_freq Prune frequency +	* @return null +	*/ +	protected function auto_prune_shadow_topics($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_freq) +	{ +		$sql = 'SELECT forum_name +			FROM ' . FORUMS_TABLE . " +			WHERE forum_id = $forum_id"; +		$result = $this->db->sql_query($sql, 3600); +		$row = $this->db->sql_fetchrow($result); +		$this->db->sql_freeresult($result); + +		if ($row) +		{ +			$prune_date = time() - ($prune_days * 86400); +			$next_prune = time() + ($prune_freq * 86400); + +			prune($forum_id, $prune_mode, $prune_date, $prune_flags, true); + +			$sql = 'UPDATE ' . FORUMS_TABLE . " +				SET prune_shadow_next = $next_prune +				WHERE forum_id = $forum_id"; +			$this->db->sql_query($sql); + +			$this->log->add('admin', 'LOG_PRUNE_SHADOW', $row['forum_name']); +		} + +		return; +	} +} diff --git a/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php b/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php new file mode 100644 index 0000000000..83f5f903e8 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php @@ -0,0 +1,46 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class prune_shadow_topics extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array('\phpbb\db\migration\data\v310\dev'); +	} + +	public function update_schema() +	{ +		return array( +			'add_columns'		=> array( +				$this->table_prefix . 'forums'		=> array( +					'enable_shadow_prune'	=> array('BOOL', 0), +					'prune_shadow_days'	=> array('UINT', 7), +					'prune_shadow_freq'	=> array('UINT', 1), +					'prune_shadow_next'	=> array('INT:11', 0), +				), +			), +		); +	} + +	public function revert_schema() +	{ +		return array( +			'drop_columns'		=> array( +				$this->table_prefix . 'forums'		=> array( +					'enable_shadow_prune', +					'prune_shadow_days', +					'prune_shadow_freq', +					'prune_shadow_next', +				), +			), +		); +	} +} diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 7f194bbcef..4da0267284 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -224,6 +224,18 @@ if (!$config['use_system_cron'])  		$url = $task->get_url();  		$template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="cron" />');  	} +	else +	{ +		// See if we should prune the shadow topics instead +		$task = $cron->find_task('cron.task.core.prune_shadow_topics'); +		$task->set_forum_data($forum_data); + +		if ($task->is_ready()) +		{ +			$url = $task->get_url(); +			$template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="cron" />'); +		} +	}  }  // Forum rules and subscription info diff --git a/tests/functional/prune_shadow_topic_test.php b/tests/functional/prune_shadow_topic_test.php new file mode 100644 index 0000000000..901cedb389 --- /dev/null +++ b/tests/functional/prune_shadow_topic_test.php @@ -0,0 +1,207 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @group functional +*/ +class phpbb_functional_prune_shadow_topic_test extends phpbb_functional_test_case +{ +	protected $data = array(); +	protected $post; + +	public function test_setup_forums() +	{ +		$this->login(); +		$this->admin_login(); + +		$crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}"); +		$form = $crawler->selectButton('addforum')->form(array( +			'forum_name'	=> 'Prune Shadow', +		)); +		$crawler = self::submit($form); +		$form = $crawler->selectButton('update')->form(array( +			'forum_perm_from'	=> 2, +			'enable_shadow_prune'	=> true, +			'prune_shadow_freq'	=> 1, +			'prune_shadow_days'	=> 1, +		)); +		$crawler = self::submit($form); +	} + +	public function test_create_post() +	{ +		$this->login(); +		$this->load_ids(array( +			'forums' => array( +				'Prune Shadow', +			), +		)); + +		$this->assert_forum_details($this->data['forums']['Prune Shadow'], array( +			'forum_posts_approved'		=> 0, +			'forum_posts_unapproved'	=> 0, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 0, +			'forum_topics_unapproved'	=> 0, +			'forum_topics_softdeleted'	=> 0, +			'forum_last_post_id'		=> 0, +		), 'initial comparison'); + +		// Test creating topic +		$this->post = $this->create_topic($this->data['forums']['Prune Shadow'], 'Prune Shadow #1', 'This is a test topic posted by the testing framework.'); +		$crawler = self::request('GET', "viewtopic.php?t={$this->post['topic_id']}&sid={$this->sid}"); + +		$this->assertContains('Prune Shadow #1', $crawler->filter('html')->text()); +		$this->data['topics']['Prune Shadow #1'] = (int) $post['topic_id']; +		$this->data['posts']['Prune Shadow #1'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + +		$this->assert_forum_details($this->data['forums']['Prune Shadow'], array( +			'forum_posts_approved'		=> 1, +			'forum_posts_unapproved'	=> 0, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 1, +			'forum_topics_unapproved'	=> 0, +			'forum_topics_softdeleted'	=> 0, +			'forum_last_post_id'		=> $this->data['posts']['Prune Shadow #1'], +		), 'after creating topic #1'); + +		// Test creating a reply +		$post2 = $this->create_post($this->data['forums']['Prune Shadow'], $this->post['topic_id'], 'Re: Prune Shadow #1-#2', 'This is a test post posted by the testing framework.'); +		$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); + +		$this->assertContains('Re: Prune Shadow #1-#2', $crawler->filter('html')->text()); +		$this->data['posts']['Re: Prune Shadow #1-#2'] = (int) $this->get_parameter_from_link($crawler->filter('.post')->eq(1)->selectLink($this->lang('POST', '', ''))->link()->getUri(), 'p'); + +		$this->assert_forum_details($this->data['forums']['Prune Shadow'], array( +			'forum_posts_approved'		=> 2, +			'forum_posts_unapproved'	=> 0, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 1, +			'forum_topics_unapproved'	=> 0, +			'forum_topics_softdeleted'	=> 0, +			'forum_last_post_id'		=> $this->data['posts']['Re: Prune Shadow #1-#2'], +		), 'after replying'); +	} + +	public function test_move_topic() +	{ +		$this->login(); +		$this->load_ids(array( +			'forums' => array( +				'Prune Shadow', +			), +			'topics' => array( +				'Prune Shadow #1', +			), +		)); + +		$crawler = self::request('GET', "mcp.php?f={$this->data['forums']['Prune Shadow']}&i=main&action=move&mode=forum_view&start=0&topic_id_list[]={$this->data['topics']['Prune Shadow #1']}&sid={$this->sid}"); +		$form = $crawler->selectButton('confirm')->form(array( +			'to_forum_id'	=> 2, +			'move_leave_shadow' => true, +		)); +		$crawler = self::submit($form); + +		$this->assert_forum_details($this->data['forums']['Prune Shadow'], array( +			'forum_posts_approved'		=> 0, +			'forum_posts_unapproved'	=> 0, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 1, +			'forum_topics_unapproved'	=> 0, +			'forum_topics_softdeleted'	=> 0, +		), 'after moving'); + +		$this->db = $this->get_db(); +		// Date topic 3 days back +		$sql = 'UPDATE phpbb_topics +			SET topic_last_post_time = ' . (time() - 60*60*24*3) . ' +			WHERE topic_id = ' . ($this->data['topics']['Prune Shadow #1'] + 1); +		$result = $this->db->sql_query($sql); + +		$crawler = self::request('GET', "viewforum.php?f={$this->data['forums']['Prune Shadow']}&sid={$this->sid}"); +		$cron_link = $crawler->filter('img')->last()->attr('src'); +		$crawler = self::request('GET', $cron_link . "&sid={$this->sid}", array(), false); + +		$this->assert_forum_details($this->data['forums']['Prune Shadow'], array( +			'forum_posts_approved'		=> 0, +			'forum_posts_unapproved'	=> 0, +			'forum_posts_softdeleted'	=> 0, +			'forum_topics_approved'		=> 0, +			'forum_topics_unapproved'	=> 0, +			'forum_topics_softdeleted'	=> 0, +		), 'after the cron job'); +	} + +	public function assert_forum_details($forum_id, $details, $additional_error_message = '') +	{ +		$this->db = $this->get_db(); + +		$sql = 'SELECT ' . implode(', ', array_keys($details)) . ' +			FROM phpbb_forums +			WHERE forum_id = ' . (int) $forum_id; +		$result = $this->db->sql_query($sql); +		$data = $this->db->sql_fetchrow($result); +		$this->db->sql_freeresult($result); + +		$this->assertEquals($details, $data, "Forum {$forum_id} does not match expected {$additional_error_message}"); +	} + +	public function load_ids($data) +	{ +		$this->db = $this->get_db(); + +		if (!empty($data['forums'])) +		{ +			$sql = 'SELECT * +				FROM phpbb_forums +				WHERE ' . $this->db->sql_in_set('forum_name', $data['forums']); +			$result = $this->db->sql_query($sql); +			while ($row = $this->db->sql_fetchrow($result)) +			{ +				if (in_array($row['forum_name'], $data['forums'])) +				{ +					$this->data['forums'][$row['forum_name']] = (int) $row['forum_id']; +				} +			} +			$this->db->sql_freeresult($result); +		} + +		if (!empty($data['topics'])) +		{ +			$sql = 'SELECT * +				FROM phpbb_topics +				WHERE ' . $this->db->sql_in_set('topic_title', $data['topics']); +			$result = $this->db->sql_query($sql); +			while ($row = $this->db->sql_fetchrow($result)) +			{ +				if (in_array($row['topic_title'], $data['topics'])) +				{ +					$this->data['topics'][$row['topic_title']] = (int) $row['topic_id']; +				} +			} +			$this->db->sql_freeresult($result); +		} + +		if (!empty($data['posts'])) +		{ +			$sql = 'SELECT * +				FROM phpbb_posts +				WHERE ' . $this->db->sql_in_set('post_subject', $data['posts']); +			$result = $this->db->sql_query($sql); +			while ($row = $this->db->sql_fetchrow($result)) +			{ +				if (in_array($row['post_subject'], $data['posts'])) +				{ +					$this->data['posts'][$row['post_subject']] = (int) $row['post_id']; +				} +			} +			$this->db->sql_freeresult($result); +		} +	} +} | 
