similar_topics::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 1
eloc 16
c 6
b 0
f 0
nc 1
nop 16
dl 0
loc 19
rs 9.7333

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 *
4
 * Precise Similar Topics
5
 *
6
 * @copyright (c) 2013 Matt Friedman
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace vse\similartopics\core;
12
13
use phpbb\auth\auth;
0 ignored issues
show
Bug introduced by
The type phpbb\auth\auth was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use phpbb\cache\service as cache;
0 ignored issues
show
Bug introduced by
The type phpbb\cache\service was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use phpbb\config\config;
0 ignored issues
show
Bug introduced by
The type phpbb\config\config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use phpbb\config\db_text;
0 ignored issues
show
Bug introduced by
The type phpbb\config\db_text was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use phpbb\content_visibility;
0 ignored issues
show
Bug introduced by
The type phpbb\content_visibility was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use phpbb\db\driver\driver_interface as db;
0 ignored issues
show
Bug introduced by
The type phpbb\db\driver\driver_interface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use phpbb\event\dispatcher_interface as dispatcher;
0 ignored issues
show
Bug introduced by
The type phpbb\event\dispatcher_interface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use phpbb\extension\manager as ext_manager;
0 ignored issues
show
Bug introduced by
The type phpbb\extension\manager was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use phpbb\language\language;
0 ignored issues
show
Bug introduced by
The type phpbb\language\language was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use phpbb\pagination;
0 ignored issues
show
Bug introduced by
The type phpbb\pagination was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use phpbb\request\request;
0 ignored issues
show
Bug introduced by
The type phpbb\request\request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use phpbb\template\template;
0 ignored issues
show
Bug introduced by
The type phpbb\template\template was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
use phpbb\user;
0 ignored issues
show
Bug introduced by
The type phpbb\user was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
use vse\similartopics\driver\driver_interface as similartopics_driver;
27
use vse\similartopics\driver\manager as similartopics_manager;
28
29
class similar_topics
30
{
31
	/** @var auth */
32
	protected $auth;
33
34
	/** @var cache */
35
	protected $cache;
36
37
	/** @var config */
38
	protected $config;
39
40
	/** @var db_text */
41
	protected $config_text;
42
43
	/** @var db */
44
	protected $db;
45
46
	/** @var dispatcher */
47
	protected $dispatcher;
48
49
	/** @var ext_manager */
50
	protected $extension_manager;
51
52
	/** @var language */
53
	protected $language;
54
55
	/** @var pagination */
56
	protected $pagination;
57
58
	/** @var request */
59
	protected $request;
60
61
	/** @var template */
62
	protected $template;
63
64
	/** @var user */
65
	protected $user;
66
67
	/** @var content_visibility */
68
	protected $content_visibility;
69
70
	/** @var similartopics_driver */
71
	protected $similartopics;
72
73
	/** @var string phpBB root path  */
74
	protected $root_path;
75
76
	/** @var string PHP file extension */
77
	protected $php_ext;
78
79
	/** @var string String of custom ignore words */
80
	protected $ignore_words;
81
82
	/**
83
	 * Constructor
84
	 *
85
	 * @access public
86
	 * @param auth                  $auth
87
	 * @param cache                 $cache
88
	 * @param config                $config
89
	 * @param db_text               $config_text
90
	 * @param db                    $db
91
	 * @param dispatcher            $dispatcher
92
	 * @param ext_manager           $extension_manager
93
	 * @param language              $language
94
	 * @param pagination            $pagination
95
	 * @param request               $request
96
	 * @param template              $template
97
	 * @param user                  $user
98
	 * @param content_visibility    $content_visibility
99
	 * @param similartopics_manager $similartopics_manager
100
	 * @param string                $root_path
101
	 * @param string                $php_ext
102
	 */
103
	public function __construct(auth $auth, cache $cache, config $config, db_text $config_text, db $db, dispatcher $dispatcher, ext_manager $extension_manager, language $language, pagination $pagination, request $request, template $template, user $user, content_visibility $content_visibility, similartopics_manager $similartopics_manager, $root_path, $php_ext)
104
	{
105
		$this->auth = $auth;
106
		$this->cache = $cache;
107
		$this->config = $config;
108
		$this->config_text = $config_text;
109
		$this->db = $db;
110
		$this->dispatcher = $dispatcher;
111
		$this->extension_manager = $extension_manager;
112
		$this->language = $language;
113
		$this->pagination = $pagination;
114
		$this->request = $request;
115
		$this->template = $template;
116
		$this->user = $user;
117
		$this->content_visibility = $content_visibility;
118
		$this->root_path = $root_path;
119
		$this->php_ext = $php_ext;
120
121
		$this->similartopics = $similartopics_manager->get_driver($db->get_sql_layer());
122
	}
123
124
	/**
125
	 * Is similar topics available?
126
	 *
127
	 * @access public
128
	 * @return bool True if available, false otherwise
129
	 */
130
	public function is_available()
131
	{
132
		return $this->is_enabled() && $this->is_viewable() && $this->similartopics !== null;
133
	}
134
135
	/**
136
	 * Is similar topics configured?
137
	 *
138
	 * @access public
139
	 * @return bool True if configured, false otherwise
140
	 */
141
	public function is_enabled()
142
	{
143
		return !empty($this->config['similar_topics']) && !empty($this->config['similar_topics_limit']);
144
	}
145
146
	/**
147
	 * Is similar topics viewable by the user?
148
	 *
149
	 * @access public
150
	 * @return bool True if viewable, false otherwise
151
	 */
152
	public function is_viewable()
153
	{
154
		return !empty($this->user->data['user_similar_topics']) && $this->auth->acl_get('u_similar_topics');
155
	}
156
157
	/**
158
	 * Get similar topics by matching topic titles
159
	 * Loosely based on viewforum.php lines 840-1040
160
	 *
161
	 * NOTE: FULLTEXT has built-in English ignore words. We use phpBB's
162
	 * ignore words for non-English languages. We also remove any
163
	 * admin-defined special ignore words.
164
	 *
165
	 * @access public
166
	 * @param array $topic_data Array with topic data
167
	 */
168
	public function display_similar_topics($topic_data)
169
	{
170
		// If the forum should not display similar topics, no need to continue
171
		if ($topic_data['similar_topics_hide'])
172
		{
173
			return;
174
		}
175
176
		$topic_title = $this->clean_topic_title($topic_data['topic_title']);
177
178
		// If the cleaned up topic_title is empty, no need to continue
179
		if (empty($topic_title))
180
		{
181
			return;
182
		}
183
184
		// Get stored sensitivity value and divide by 10. In query, it should be a number between 0.0 to 1.0.
185
		$sensitivity = $this->config->offsetExists('similar_topics_sense') ? number_format($this->config['similar_topics_sense'] / 10, 1, '.', '') : '0.5';
186
187
		// Similar Topics SQL query is generated in similar topics driver
188
		$sql_array = $this->similartopics->get_query($topic_data['topic_id'], $topic_title, $this->config['similar_topics_time'], $sensitivity);
0 ignored issues
show
Bug introduced by
$sensitivity of type string is incompatible with the type double expected by parameter $sensitivity of vse\similartopics\driver..._interface::get_query(). ( Ignorable by Annotation )

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

188
		$sql_array = $this->similartopics->get_query($topic_data['topic_id'], $topic_title, $this->config['similar_topics_time'], /** @scrutinizer ignore-type */ $sensitivity);
Loading history...
189
190
		// Add topic tracking data to the query (only if query caching is off)
191
		if ($this->user->data['is_registered'] && $this->config['load_db_lastread'] && !$this->config['similar_topics_cache'])
192
		{
193
			$sql_array['LEFT_JOIN'][] = array('FROM' => array(TOPICS_TRACK_TABLE => 'tt'), 'ON' => 'tt.topic_id = t.topic_id AND tt.user_id = ' . $this->user->data['user_id']);
0 ignored issues
show
Bug introduced by
The constant vse\similartopics\core\TOPICS_TRACK_TABLE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
194
			$sql_array['LEFT_JOIN'][] = array('FROM' => array(FORUMS_TRACK_TABLE => 'ft'), 'ON' => 'ft.forum_id = f.forum_id AND ft.user_id = ' . $this->user->data['user_id']);
0 ignored issues
show
Bug introduced by
The constant vse\similartopics\core\FORUMS_TRACK_TABLE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
195
			$sql_array['SELECT'] .= ', tt.mark_time, ft.mark_time as f_mark_time';
196
		}
197
		else if ($this->config['load_anon_lastread'] || $this->user->data['is_registered'])
198
		{
199
			// Cookie based tracking copied from search.php
200
			$tracking_topics = $this->request->variable($this->config['cookie_name'] . '_track', '', true, \phpbb\request\request_interface::COOKIE);
0 ignored issues
show
Bug introduced by
The type phpbb\request\request_interface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
201
			$tracking_topics = $tracking_topics ? tracking_unserialize($tracking_topics) : array();
0 ignored issues
show
Bug introduced by
The function tracking_unserialize was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

201
			$tracking_topics = $tracking_topics ? /** @scrutinizer ignore-call */ tracking_unserialize($tracking_topics) : array();
Loading history...
202
		}
203
204
		// We need to exclude passworded forums, so we do not leak the topic title
205
		$passworded_forums = $this->user->get_passworded_forums();
206
207
		// See if the admin set this forum to only search a specific group of other forums, and include them
208
		if (!empty($topic_data['similar_topic_forums']))
209
		{
210
			// Remove any passworded forums from this group of forums we will be searching
211
			$included_forums = array_diff(json_decode($topic_data['similar_topic_forums'], true), $passworded_forums);
212
			// if there's nothing left to display (user has no access to the forums we want to search)
213
			if (empty($included_forums))
214
			{
215
				return;
216
			}
217
218
			$sql_array['WHERE'] .= ' AND ' . $this->db->sql_in_set('f.forum_id', $included_forums);
219
		}
220
		// Otherwise, exclude any ignored forums
221
		else
222
		{
223
			// Remove any passworded forums
224
			if (count($passworded_forums))
225
			{
226
				$sql_array['WHERE'] .= ' AND ' . $this->db->sql_in_set('f.forum_id', $passworded_forums, true);
227
			}
228
229
			$sql_array['WHERE'] .= ' AND f.similar_topics_ignore = 0';
230
		}
231
232
		/**
233
		 * Event to modify the sql_array for similar topics
234
		 *
235
		 * @event vse.similartopics.get_topic_data
236
		 * @var array sql_array SQL array to get similar topics data
237
		 * @since 1.3.0
238
		 */
239
		$vars = array('sql_array');
240
		extract($this->dispatcher->trigger_event('vse.similartopics.get_topic_data', compact($vars)));
241
242
		$rowset = array();
243
244
		$sql = $this->db->sql_build_query('SELECT', $sql_array);
245
		$result = $this->db->sql_query_limit($sql, $this->config['similar_topics_limit'], 0, $this->config['similar_topics_cache']);
246
		while ($row = $this->db->sql_fetchrow($result))
247
		{
248
			$rowset[(int) $row['topic_id']] = $row;
249
		}
250
		$this->db->sql_freeresult($result);
251
252
		// Grab icons
253
		$icons = $this->cache->obtain_icons();
254
255
		/**
256
		 * Modify the rowset data for similar topics
257
		 *
258
		 * @event vse.similartopics.modify_rowset
259
		 * @var	array rowset Array with the search results data
260
		 * @since 1.4.2
261
		 */
262
		$vars = array('rowset');
263
		extract($this->dispatcher->trigger_event('vse.similartopics.modify_rowset', compact($vars)));
264
265
		foreach ($rowset as $row)
266
		{
267
			$similar_forum_id = (int) $row['forum_id'];
268
			$similar_topic_id = (int) $row['topic_id'];
269
270
			if ($this->auth->acl_get('f_read', $similar_forum_id))
271
			{
272
				// Get topic tracking info
273
				if ($this->user->data['is_registered'] && $this->config['load_db_lastread'] && !$this->config['similar_topics_cache'])
274
				{
275
					$topic_tracking_info = get_topic_tracking($similar_forum_id, $similar_topic_id, $rowset, array($similar_forum_id => $row['f_mark_time']));
0 ignored issues
show
Bug introduced by
The function get_topic_tracking was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

275
					$topic_tracking_info = /** @scrutinizer ignore-call */ get_topic_tracking($similar_forum_id, $similar_topic_id, $rowset, array($similar_forum_id => $row['f_mark_time']));
Loading history...
276
				}
277
				else if ($this->config['load_anon_lastread'] || $this->user->data['is_registered'])
278
				{
279
					$topic_tracking_info = get_complete_topic_tracking($similar_forum_id, $similar_topic_id);
0 ignored issues
show
Bug introduced by
The function get_complete_topic_tracking was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

279
					$topic_tracking_info = /** @scrutinizer ignore-call */ get_complete_topic_tracking($similar_forum_id, $similar_topic_id);
Loading history...
280
281
					if (!$this->user->data['is_registered'])
282
					{
283
						$this->user->data['user_lastmark'] = isset($tracking_topics['l']) ? ((int) base_convert($tracking_topics['l'], 36, 10) + (int) $this->config['board_startdate']) : 0;
284
					}
285
				}
286
287
				// Replies
288
				$replies = $this->content_visibility->get_count('topic_posts', $row, $similar_forum_id) - 1;
289
290
				// Get folder img, topic status/type related information
291
				$folder_img = $folder_alt = $topic_type = '';
292
				$unread_topic = isset($topic_tracking_info[$similar_topic_id]) && $row['topic_last_post_time'] > $topic_tracking_info[$similar_topic_id];
293
				topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type);
0 ignored issues
show
Bug introduced by
The function topic_status was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

293
				/** @scrutinizer ignore-call */ 
294
    topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type);
Loading history...
294
295
				$view_topic_url_params = 't=' . $similar_topic_id;
296
297
				$topic_unapproved = $row['topic_visibility'] == ITEM_UNAPPROVED && $this->auth->acl_get('m_approve', $similar_forum_id);
0 ignored issues
show
Bug introduced by
The constant vse\similartopics\core\ITEM_UNAPPROVED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
298
				$posts_unapproved = $row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $this->auth->acl_get('m_approve', $similar_forum_id);
0 ignored issues
show
Bug introduced by
The constant vse\similartopics\core\ITEM_APPROVED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
299
				$u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$this->root_path}mcp.$this->php_ext", 'i=queue&amp;mode=' . ($topic_unapproved ? 'approve_details' : 'unapproved_posts') . "&amp;t=$similar_topic_id", true, $this->user->session_id) : '';
0 ignored issues
show
Bug introduced by
The function append_sid was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

299
				$u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? /** @scrutinizer ignore-call */ append_sid("{$this->root_path}mcp.$this->php_ext", 'i=queue&amp;mode=' . ($topic_unapproved ? 'approve_details' : 'unapproved_posts') . "&amp;t=$similar_topic_id", true, $this->user->session_id) : '';
Loading history...
300
301
				$base_url = append_sid("{$this->root_path}viewtopic.$this->php_ext", $view_topic_url_params);
302
303
				$topic_row = array(
304
					'TOPIC_AUTHOR_FULL'			=> get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
0 ignored issues
show
Bug introduced by
The function get_username_string was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

304
					'TOPIC_AUTHOR_FULL'			=> /** @scrutinizer ignore-call */ get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
Loading history...
305
					'FIRST_POST_TIME'			=> $this->user->format_date($row['topic_time']),
306
					'FIRST_POST_TIME_RFC3339'	=> gmdate(DATE_RFC3339, $row['topic_time']),
307
					'LAST_POST_TIME'			=> $this->user->format_date($row['topic_last_post_time']),
308
					'LAST_POST_TIME_RFC3339'	=> gmdate(DATE_RFC3339, $row['topic_last_post_time']),
309
					'LAST_POST_AUTHOR_FULL'		=> get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
310
311
					'TOPIC_REPLIES'			=> $replies,
312
					'TOPIC_VIEWS'			=> $row['topic_views'],
313
					'TOPIC_TITLE'			=> censor_text($row['topic_title']),
0 ignored issues
show
Bug introduced by
The function censor_text was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

313
					'TOPIC_TITLE'			=> /** @scrutinizer ignore-call */ censor_text($row['topic_title']),
Loading history...
314
					'FORUM_TITLE'			=> $row['forum_name'],
315
316
					'TOPIC_IMG_STYLE'		=> $folder_img,
317
					'TOPIC_FOLDER_IMG'		=> $this->user->img($folder_img, $folder_alt),
318
					'TOPIC_FOLDER_IMG_ALT'	=> $this->language->lang($folder_alt),
319
320
					'TOPIC_ICON_IMG'		=> !empty($icons[$row['icon_id']]) ? $icons[$row['icon_id']]['img'] : '',
321
					'TOPIC_ICON_IMG_WIDTH'	=> !empty($icons[$row['icon_id']]) ? $icons[$row['icon_id']]['width'] : '',
322
					'TOPIC_ICON_IMG_HEIGHT'	=> !empty($icons[$row['icon_id']]) ? $icons[$row['icon_id']]['height'] : '',
323
					'ATTACH_ICON_IMG'		=> ($this->auth->acl_get('u_download') && $this->auth->acl_get('f_download', $similar_forum_id) && $row['topic_attachment']) ? $this->user->img('icon_topic_attach', $this->language->lang('TOTAL_ATTACHMENTS')) : '',
324
					'UNAPPROVED_IMG'		=> ($topic_unapproved || $posts_unapproved) ? $this->user->img('icon_topic_unapproved', $topic_unapproved ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '',
325
326
					'S_UNREAD_TOPIC'		=> $unread_topic,
327
					'S_TOPIC_REPORTED'		=> !empty($row['topic_reported']) && $this->auth->acl_get('m_report', $similar_forum_id),
328
					'S_TOPIC_UNAPPROVED'	=> $topic_unapproved,
329
					'S_POSTS_UNAPPROVED'	=> $posts_unapproved,
330
					'S_HAS_POLL'			=> (bool) $row['poll_start'],
331
332
					'U_NEWEST_POST'			=> append_sid("{$this->root_path}viewtopic.$this->php_ext", $view_topic_url_params . '&amp;view=unread') . '#unread',
333
					'U_LAST_POST'			=> append_sid("{$this->root_path}viewtopic.$this->php_ext", $view_topic_url_params . '&amp;p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'],
334
					'U_VIEW_TOPIC'			=> $base_url,
335
					'U_VIEW_FORUM'			=> append_sid("{$this->root_path}viewforum.$this->php_ext", 'f=' . $similar_forum_id),
336
					'U_MCP_REPORT'			=> append_sid("{$this->root_path}mcp.$this->php_ext", 'i=reports&amp;mode=reports&amp;' . $view_topic_url_params, true, $this->user->session_id),
337
					'U_MCP_QUEUE'			=> $u_mcp_queue,
338
				);
339
340
				/**
341
				 * Event to modify the similar topics template block
342
				 *
343
				 * @event vse.similartopics.modify_topicrow
344
				 * @var array row       Array with similar topic data
345
				 * @var array topic_row Template block array
346
				 * @since 1.3.0
347
				 */
348
				$vars = array('row', 'topic_row');
349
				extract($this->dispatcher->trigger_event('vse.similartopics.modify_topicrow', compact($vars)));
350
351
				$this->template->assign_block_vars('similar', $topic_row);
352
353
				$this->pagination->generate_template_pagination($base_url, 'similar.pagination', 'start', $replies + 1, $this->config['posts_per_page'], 1, true, true);
354
			}
355
		}
356
357
		$this->language->add_lang('similar_topics', 'vse/similartopics');
358
359
		$this->template->assign_vars(array(
360
			'NEWEST_POST_IMG'	=> $this->user->img('icon_topic_newest', 'VIEW_NEWEST_POST'),
361
			'LAST_POST_IMG'		=> $this->user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
362
			'REPORTED_IMG'		=> $this->user->img('icon_topic_reported', 'TOPIC_REPORTED'),
363
			'POLL_IMG'			=> $this->user->img('icon_topic_poll', 'TOPIC_POLL'),
364
		));
365
	}
366
367
	/**
368
	 * Clean topic title (and if needed, ignore-words)
369
	 *
370
	 * @access public
371
	 * @param string $text The topic title
372
	 * @return string The topic title
373
	 */
374
	public function clean_topic_title($text)
375
	{
376
		// Strip quotes, ampersands
377
		$text = str_replace(array('&quot;', '&amp;'), '', $text);
378
379
		if (!$this->english_lang() || $this->get_ignore_words())
380
		{
381
			$text = $this->strip_stop_words($text);
382
		}
383
384
		return $text;
385
	}
386
387
	/**
388
	 * Remove any non-english and/or custom defined ignore-words
389
	 *
390
	 * @access protected
391
	 * @param string $text The topic title
392
	 * @return string The topic title
393
	 */
394
	protected function strip_stop_words($text)
395
	{
396
		$words = array();
397
398
		// If non-English, look for a list of stop-words to be ignored
399
		// in either the core or the extension (deprecated from core)
400
		if (!$this->english_lang())
401
		{
402
			$finder = $this->extension_manager->get_finder();
403
			$search_ignore_words = $finder
404
				->set_extensions(array('vse/similartopics'))
405
				->prefix('search_ignore_words')
406
				->suffix(".$this->php_ext")
407
				->extension_directory("/language/{$this->user->lang_name}")
408
				->core_path("language/{$this->user->lang_name}/")
409
				->get_files();
410
			if (current($search_ignore_words))
411
			{
412
				include current($search_ignore_words);
413
			}
414
		}
415
416
		if ($this->get_ignore_words())
417
		{
418
			// Merge any custom defined ignore words from the ACP to the stop-words array
419
			$words = array_merge($this->make_word_array($this->get_ignore_words()), $words);
420
		}
421
422
		// Remove stop-words from the topic title text
423
		$words = array_diff($this->make_word_array($text), $words);
424
425
		// Convert our words array back to a string
426
		return implode(' ', $words);
427
	}
428
429
	/**
430
	 * Helper function to split string into an array of words
431
	 *
432
	 * @access protected
433
	 * @param string $text String of plain text words
434
	 * @return array Array of plaintext words
435
	 */
436
	protected function make_word_array($text)
437
	{
438
		// Strip out any non-alpha-numeric characters using PCRE regex syntax
439
		$text = trim(preg_replace('#[^\p{L}\p{N}]+#u', ' ', $text));
440
441
		$words = explode(' ', utf8_strtolower($text));
0 ignored issues
show
Bug introduced by
The function utf8_strtolower was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

441
		$words = explode(' ', /** @scrutinizer ignore-call */ utf8_strtolower($text));
Loading history...
442
		foreach ($words as $key => $word)
443
		{
444
			// Strip words of 2 characters or fewer
445
			if (utf8_strlen(trim($word)) < 3)
0 ignored issues
show
Bug introduced by
The function utf8_strlen was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

445
			if (/** @scrutinizer ignore-call */ utf8_strlen(trim($word)) < 3)
Loading history...
446
			{
447
				unset($words[$key]);
448
			}
449
		}
450
451
		return $words;
452
	}
453
454
	/**
455
	 * Check if English is the current user's language
456
	 *
457
	 * @access protected
458
	 * @return bool True if lang is 'en' or 'en_us', false otherwise
459
	 */
460
	protected function english_lang()
461
	{
462
		return ($this->user->lang_name === 'en' || $this->user->lang_name === 'en_us');
463
	}
464
465
	/**
466
	 * Get custom ignore words if any were defined for similar topics
467
	 *
468
	 * @access protected
469
	 * @return string|null String of ignore words or null if there are none defined
470
	 */
471
	protected function get_ignore_words()
472
	{
473
		$key = 'similar_topics_words';
474
475
		$cache = $this->cache->get_driver();
476
477
		if ($this->ignore_words === null && (($this->ignore_words = $cache->get("_$key")) === false))
478
		{
479
			$this->ignore_words = $this->config_text->get($key);
480
481
			$cache->put("_$key", $this->ignore_words);
482
		}
483
484
		return $this->ignore_words;
485
	}
486
}
487