Passed
Pull Request — master (#1)
by Dark❶
03:30
created

auto_reduce_sync::get_topic_ary()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 31
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 21
nc 3
nop 0
dl 0
loc 31
rs 9.584
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * Reduce Search Index [RSI]. An extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) 2020, Dark❶, https://dark1.tech
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace dark1\reducesearchindex\cron;
12
13
/**
14
 * @ignore
15
 */
16
use phpbb\cron\task\base;
17
use phpbb\config\config;
18
use phpbb\db\driver\driver_interface;
19
use phpbb\log\log;
20
use Symfony\Component\DependencyInjection\ContainerInterface;
21
22
/**
23
 * Reduce Search Index Cron Task.
24
 */
25
class auto_reduce_sync extends base
26
{
27
28
	/** @var \phpbb\config\config */
29
	protected $config;
30
31
	/** @var \phpbb\db\driver\driver_interface */
32
	protected $db;
33
34
	/** @var \phpbb\log\log */
35
	protected $phpbb_log;
36
37
	/** @var ContainerInterface */
38
	protected $phpbb_container;
39
40
	/**
41
	* Constructor for cron task
42
	*
43
	* @param \phpbb\config\config				$config			phpBB config
44
	* @param \phpbb\db\driver\driver_interface	$db				phpBB DBAL object
45
	* @param \phpbb\log\log						$phpbb_log		phpBB log
46
	* @param ContainerInterface					$phpbb_container
47
	* @access public
48
	*/
49
	public function __construct(config $config, driver_interface $db, log $phpbb_log, ContainerInterface $phpbb_container)
50
	{
51
		$this->config					= $config;
52
		$this->db						= $db;
53
		$this->phpbb_log				= $phpbb_log;
54
		$this->phpbb_container			= $phpbb_container;
55
	}
56
57
	/**
58
	* Returns whether this cron task can run, given current board configuration.
59
	*
60
	* @return bool
61
	*/
62
	public function is_runnable()
63
	{
64
		return ($this->config['dark1_rsi_auto_reduce_sync_enable'] && $this->config['dark1_rsi_enable']);
65
	}
66
67
	/**
68
	* Returns whether this cron task should run now, because enough time has passed since it was last run.
69
	*
70
	* @return bool
71
	*/
72
	public function should_run()
73
	{
74
		return (($this->config['dark1_rsi_auto_reduce_sync_last_gc'] < (time() - $this->config['dark1_rsi_auto_reduce_sync_gc'])) && ($this->config['dark1_rsi_time'] < (time() - $this->config['dark1_rsi_interval'])));
75
	}
76
77
	/**
78
	* Runs this cron task.
79
	*
80
	* @return null
81
	*/
82
	public function run()
83
	{
84
		if ($this->config['dark1_rsi_enable'] && ($this->config['dark1_rsi_time'] < (time() - $this->config['dark1_rsi_interval'])))
85
		{
86
			$this->config->set('dark1_rsi_time', (time() - $this->config['dark1_rsi_interval']), false);
87
88
			// Get Data
89
			$topic_ary = $this->get_topic_ary();
90
			$post_ary = $this->get_post_ary();
91
92
			// Set Data
93
			$post_ids = $this->array_unique_sort(array_merge($topic_ary['post_ids'], $post_ary['post_ids']));
94
			$poster_ids = $this->array_unique_sort(array_merge($topic_ary['poster_ids'], $post_ary['poster_ids']));
95
			$forum_ids = $this->array_unique_sort(array_merge($topic_ary['forum_ids'], $post_ary['forum_ids']));
96
97
			// Lock Topics
98
			$this->lock_topics($topic_ary['topic_ids']);
99
100
			// Remove the message from the search index
101
			$this->reduce_search_index($post_ids, $poster_ids, $forum_ids);
102
103
			$dark1_rsi_interval = $this->config['dark1_rsi_interval'] / 86400;
104
			$dark1_rsi_time = date('Y-m-d h:i:s A P', (int) $this->config['dark1_rsi_time']);
105
			$this->phpbb_log->add('admin', '', '', 'RSI_AUTO_LOG', time(), array($dark1_rsi_interval, $dark1_rsi_time));
106
		}
107
108
		// Update the last backup time
109
		$this->config->set('dark1_rsi_auto_reduce_sync_last_gc', time(), false);
110
	}
111
112
	/**
113
	* Array to Uniquely Sort the IDs.
114
	*
115
	* @param array		$ary_ids		Array with IDs
116
	* @return array
117
	* @access private
118
	*/
119
	private function array_unique_sort($ary_ids)
120
	{
121
		$ary_ids = array_unique($ary_ids);
122
		sort($ary_ids, SORT_NUMERIC);
123
		return $ary_ids;
124
	}
125
126
	/**
127
	* Get Topic Array.
128
	*
129
	* @return array
130
	* @access private
131
	*/
132
	private function get_topic_ary()
133
	{
134
		$post_ids = $poster_ids = $forum_ids = $topic_ids = array();
135
136
		$sql = 'SELECT t.topic_id, p.post_id, p.poster_id, p.forum_id, f.dark1_rsi_f_enable' . PHP_EOL .
137
				'FROM ' . POSTS_TABLE . ' as p' . PHP_EOL .
138
				'LEFT JOIN ' . TOPICS_TABLE . ' as t' . PHP_EOL .
139
				'ON t.topic_id = p.topic_id' . PHP_EOL .
140
				'LEFT JOIN ' . FORUMS_TABLE . ' as f' . PHP_EOL .
141
				'ON f.forum_id = p.forum_id' . PHP_EOL .
142
				'WHERE f.dark1_rsi_f_enable >= 2 AND t.topic_time <= ' . (int) $this->config['dark1_rsi_time'];
143
		$result = $this->db->sql_query($sql);
144
145
		while ($row = $this->db->sql_fetchrow($result))
146
		{
147
			$post_ids[] = (int) $row['post_id'];
148
			$poster_ids[] = (int) $row['poster_id'];
149
			$forum_ids[] = (int) $row['forum_id'];
150
151
			if ($row['dark1_rsi_f_enable'] == 3)
152
			{
153
				$topic_ids[] = (int) $row['topic_id'];
154
			}
155
		}
156
		$this->db->sql_freeresult($result);
157
158
		return array(
159
			'post_ids' => $post_ids,
160
			'poster_ids' => $poster_ids,
161
			'forum_ids' => $forum_ids,
162
			'topic_ids' => $topic_ids,
163
		);
164
	}
165
166
	/**
167
	* Get Post Array.
168
	*
169
	* @return array
170
	* @access private
171
	*/
172
	private function get_post_ary()
173
	{
174
		$post_ids = $poster_ids = $forum_ids = array();
175
176
		$sql = 'SELECT p.post_id, p.poster_id, p.forum_id' . PHP_EOL .
177
				'FROM ' . POSTS_TABLE . ' as p' . PHP_EOL .
178
				'LEFT JOIN ' . FORUMS_TABLE . ' as f' . PHP_EOL .
179
				'ON f.forum_id = p.forum_id' . PHP_EOL .
180
				'WHERE f.dark1_rsi_f_enable = 1 AND p.post_time <= ' . (int) $this->config['dark1_rsi_time'];
181
		$result = $this->db->sql_query($sql);
182
183
		while ($row = $this->db->sql_fetchrow($result))
184
		{
185
			$post_ids[] = (int) $row['post_id'];
186
			$poster_ids[] = (int) $row['poster_id'];
187
			$forum_ids[] = (int) $row['forum_id'];
188
		}
189
		$this->db->sql_freeresult($result);
190
191
		return array(
192
			'post_ids' => $post_ids,
193
			'poster_ids' => $poster_ids,
194
			'forum_ids' => $forum_ids,
195
		);
196
	}
197
198
	/**
199
	* Lock Topics using Topic IDs.
200
	*
201
	* @param array		$topic_ids		Array with Topic IDs
202
	* @return void
203
	* @access private
204
	*/
205
	private function lock_topics($topic_ids)
206
	{
207
		if (count($topic_ids) > 0)
208
		{
209
			$sql = 'UPDATE ' . TOPICS_TABLE . PHP_EOL .
210
					'SET topic_status = ' . ITEM_LOCKED  . PHP_EOL .
211
					'WHERE ' . $this->db->sql_in_set('topic_id', $topic_ids);
212
			$this->db->sql_query($sql);
213
		}
214
	}
215
216
	/**
217
	* Reduce Search Index using Post & Poster & Forum IDs.
218
	*
219
	* @param array		$post_ids		Array with Post IDs
220
	* @param array		$poster_ids		Array with Poster IDs
221
	* @param array		$forum_ids		Array with Forum IDs
222
	* @return void
223
	* @access private
224
	*/
225
	private function reduce_search_index($post_ids, $poster_ids, $forum_ids)
226
	{
227
		$search_type = $this->config['search_type'];
228
		$identifier = substr($search_type, strrpos($search_type, '\\') + 1);
229
		if ($identifier == 'fulltext_native' && class_exists($search_type))
230
		{
231
			$error = false;
232
			$phpbb_root_path = $this->phpbb_container->getParameter('core.root_path');
233
			$phpEx = $this->phpbb_container->getParameter('core.php_ext');
234
			$auth = $this->phpbb_container->get('auth');
235
			$user = $this->phpbb_container->get('user');
236
			$phpbb_dispatcher = $this->phpbb_container->get('dispatcher');
237
238
			$search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $this->config, $this->db, $user, $phpbb_dispatcher);
239
			if ($error === false)
0 ignored issues
show
introduced by
The condition $error === false is always true.
Loading history...
240
			{
241
				@$search->index_remove($post_ids, $poster_ids, $forum_ids);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for index_remove(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

241
				/** @scrutinizer ignore-unhandled */ @$search->index_remove($post_ids, $poster_ids, $forum_ids);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
242
			}
243
		}
244
	}
245
246
}
247