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