Passed
Push — master ( 7b5730...609559 )
by Dark❶
02:37
created

cron/auto_reduce_sync.php (1 issue)

1
<?php
2
/**
3
 *
4
 * Reduce Search Index [RSI]. An extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) 2020-2021, 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 dark1\reducesearchindex\core\consts;
18
use phpbb\config\config;
19
use phpbb\db\driver\driver_interface as db_driver;
20
use phpbb\log\log;
21
use phpbb\auth\auth;
22
use phpbb\user;
23
use phpbb\event\dispatcher_interface as dispatcher;
24
25
/**
26
 * Reduce Search Index Cron Task.
27
 */
28
class auto_reduce_sync extends base
29
{
30
31
	/** @var config */
32
	protected $config;
33
34
	/** @var db_driver */
35
	protected $db;
36
37
	/** @var log */
38
	protected $phpbb_log;
39
40
	/** @var auth */
41
	protected $auth;
42
43
	/** @var user */
44
	protected $user;
45
46
	/** @var dispatcher */
47
	protected $phpbb_dispatcher;
48
49
	/** @var string phpBB root path */
50
	protected $phpbb_root_path;
51
52
	/** @var string phpBB php ext */
53
	protected $php_ext;
54
55
	/**
56
	* Constructor for cron task
57
	*
58
	* @param config			$config				phpBB config
59
	* @param db_driver		$db					phpBB DBAL object
60
	* @param log			$phpbb_log			phpBB log
61
	* @param auth			$auth				phpBB auth
62
	* @param user			$user				phpBB user
63
	* @param dispatcher		$dispatcher			phpBB dispatcher
64
	* @param string			$phpbb_root_path	phpBB root path
65
	* @param string			$php_ext			phpBB php ext
66
	* @access public
67
	*/
68
	public function __construct(config $config, db_driver $db, log $phpbb_log, auth $auth, user $user, dispatcher $phpbb_dispatcher, $phpbb_root_path, $php_ext)
69
	{
70
		$this->config			= $config;
71
		$this->db				= $db;
72
		$this->phpbb_log		= $phpbb_log;
73
		$this->auth				= $auth;
74
		$this->user				= $user;
75
		$this->phpbb_dispatcher	= $phpbb_dispatcher;
76
		$this->phpbb_root_path	= $phpbb_root_path;
77
		$this->php_ext			= $php_ext;
78
	}
79
80
	/**
81
	* Returns whether this cron task can run, given current board configuration.
82
	*
83
	* @return bool
84
	*/
85
	public function is_runnable()
86
	{
87
		return ($this->config['dark1_rsi_auto_reduce_sync_enable']);
88
	}
89
90
	/**
91
	* Returns whether this cron task should run now, because enough time has passed since it was last run.
92
	*
93
	* @return bool
94
	*/
95
	public function should_run()
96
	{
97
		return (($this->config['dark1_rsi_auto_reduce_sync_last_gc'] < (time() - $this->config['dark1_rsi_auto_reduce_sync_gc'])));
98
	}
99
100
	/**
101
	* Runs this cron task.
102
	*
103
	* @return null
104
	*/
105
	public function run()
106
	{
107
		if ($this->config['dark1_rsi_enable'] && ($this->config['dark1_rsi_time'] < (time() - $this->config['dark1_rsi_interval'])))
108
		{
109
			$this->config->set('dark1_rsi_time', (time() - $this->config['dark1_rsi_interval']), false);
110
111
			// Get Data
112
			$topic_ary = $this->get_topic_ary();
113
			$post_ary = $this->get_post_ary();
114
115
			// Set Data
116
			$post_ids = $this->array_unique_sort(array_merge($topic_ary['post_ids'], $post_ary['post_ids']));
117
			$poster_ids = $this->array_unique_sort(array_merge($topic_ary['poster_ids'], $post_ary['poster_ids']));
118
			$forum_ids = $this->array_unique_sort(array_merge($topic_ary['forum_ids'], $post_ary['forum_ids']));
119
120
			// Lock Topics
121
			$this->lock_topics($topic_ary['topic_ids']);
122
123
			// Remove the message from the search index
124
			$this->reduce_search_index($post_ids, $poster_ids, $forum_ids);
125
126
			$dark1_rsi_interval = $this->config['dark1_rsi_interval'] / 86400;
127
			$dark1_rsi_time = date(consts::TIME_FORMAT, (int) $this->config['dark1_rsi_time']);
128
			$this->phpbb_log->add('admin', ANONYMOUS, '127.0.0.1', 'RSI_AUTO_LOG', time(), [$dark1_rsi_interval, $dark1_rsi_time]);
129
		}
130
131
		// Update the last run time
132
		$this->config->set('dark1_rsi_auto_reduce_sync_last_gc', time(), false);
133
	}
134
135
	/**
136
	* Array to Uniquely Sort the IDs.
137
	*
138
	* @param array		$ary_ids		Array with IDs
139
	* @return array
140
	* @access private
141
	*/
142
	private function array_unique_sort($ary_ids)
143
	{
144
		$ary_ids = array_unique($ary_ids);
145
		sort($ary_ids, SORT_NUMERIC);
146
		return $ary_ids;
147
	}
148
149
	/**
150
	* Get Topic Array.
151
	*
152
	* @return array
153
	* @access private
154
	*/
155
	private function get_topic_ary()
156
	{
157
		$post_ids = $poster_ids = $forum_ids = $topic_ids = [];
158
159
		$sql_ary = [
160
			'SELECT'	=> 't.topic_id, p.post_id, p.poster_id, p.forum_id, f.dark1_rsi_f_enable',
161
			'FROM'		=> [
162
				POSTS_TABLE		=> 'p',
163
			],
164
			'LEFT_JOIN' => [
165
				[
166
					'FROM'	=> [TOPICS_TABLE => 't'],
167
					'ON'	=> 't.topic_id = p.topic_id',
168
				],
169
				[
170
					'FROM'	=> [FORUMS_TABLE => 'f'],
171
					'ON'	=> 'f.forum_id = p.forum_id',
172
				],
173
			],
174
			'WHERE'	=> 'f.dark1_rsi_f_enable >= ' . (int) consts::F_ENABLE_TOPIC . ' AND t.topic_time <= ' . (int) $this->config['dark1_rsi_time'],
175
		];
176
		$sql = $this->db->sql_build_query('SELECT', $sql_ary);
177
		$result = $this->db->sql_query($sql);
178
179
		while ($row = $this->db->sql_fetchrow($result))
180
		{
181
			$post_ids[] = (int) $row['post_id'];
182
			$poster_ids[] = (int) $row['poster_id'];
183
			$forum_ids[] = (int) $row['forum_id'];
184
185
			if ($row['dark1_rsi_f_enable'] == consts::F_ENABLE_LOCK)
186
			{
187
				$topic_ids[] = (int) $row['topic_id'];
188
			}
189
		}
190
		$this->db->sql_freeresult($result);
191
192
		return [
193
			'post_ids' => $post_ids,
194
			'poster_ids' => $poster_ids,
195
			'forum_ids' => $forum_ids,
196
			'topic_ids' => $topic_ids,
197
		];
198
	}
199
200
	/**
201
	* Get Post Array.
202
	*
203
	* @return array
204
	* @access private
205
	*/
206
	private function get_post_ary()
207
	{
208
		$post_ids = $poster_ids = $forum_ids = [];
209
210
		$sql_ary = [
211
			'SELECT'	=> 'p.post_id, p.poster_id, p.forum_id',
212
			'FROM'		=> [
213
				POSTS_TABLE		=> 'p',
214
			],
215
			'LEFT_JOIN' => [
216
				[
217
					'FROM'	=> [FORUMS_TABLE => 'f'],
218
					'ON'	=> 'f.forum_id = p.forum_id',
219
				],
220
			],
221
			'WHERE'	=> 'f.dark1_rsi_f_enable = ' . (int) consts::F_ENABLE_POST . ' AND p.post_time <= ' . (int) $this->config['dark1_rsi_time'],
222
		];
223
		$sql = $this->db->sql_build_query('SELECT', $sql_ary);
224
		$result = $this->db->sql_query($sql);
225
226
		while ($row = $this->db->sql_fetchrow($result))
227
		{
228
			$post_ids[] = (int) $row['post_id'];
229
			$poster_ids[] = (int) $row['poster_id'];
230
			$forum_ids[] = (int) $row['forum_id'];
231
		}
232
		$this->db->sql_freeresult($result);
233
234
		return [
235
			'post_ids' => $post_ids,
236
			'poster_ids' => $poster_ids,
237
			'forum_ids' => $forum_ids,
238
		];
239
	}
240
241
	/**
242
	* Lock Topics using Topic IDs.
243
	*
244
	* @param array		$topic_ids		Array with Topic IDs
245
	* @return void
246
	* @access private
247
	*/
248
	private function lock_topics($topic_ids)
249
	{
250
		if (count($topic_ids) > 0)
251
		{
252
			$sql = 'UPDATE ' . TOPICS_TABLE .
253
					' SET topic_status = ' . ITEM_LOCKED  .
254
					' WHERE ' . $this->db->sql_in_set('topic_id', $topic_ids);
255
			$this->db->sql_query($sql);
256
		}
257
	}
258
259
	/**
260
	* Reduce Search Index using Post & Poster & Forum IDs.
261
	*
262
	* @param array		$post_ids		Array with Post IDs
263
	* @param array		$poster_ids		Array with Poster IDs
264
	* @param array		$forum_ids		Array with Forum IDs
265
	* @return void
266
	* @access private
267
	*/
268
	private function reduce_search_index($post_ids, $poster_ids, $forum_ids)
269
	{
270
		$search_type = $this->config['search_type'];
271
		$identifier = substr($search_type, strrpos($search_type, '\\') + 1);
272
		if ($identifier == 'fulltext_native' && class_exists($search_type))
273
		{
274
			$error = false;
275
			$search = new $search_type($error, $this->phpbb_root_path, $this->php_ext, $this->auth, $this->config, $this->db, $this->user, $this->phpbb_dispatcher);
276
			if ($error === false)
277
			{
278
				@$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

278
				/** @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...
279
			}
280
		}
281
	}
282
283
}
284