Completed
Push — master ( ca6d24...2fa203 )
by Matt
02:26
created

similar_topics_module::end()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 2
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\acp;
12
13
/**
14
* @package acp
15
*/
16
class similar_topics_module
17
{
18
	const TIMES = array(
19
		'd' => 86400, // one day
20
		'w' => 604800, // one week
21
		'm' => 2626560, // one month
22
		'y' => 31536000, // one year
23
	);
24
25
	/** @var \phpbb\config\config */
26
	protected $config;
27
28
	/** @var \phpbb\db\driver\driver_interface */
29
	protected $db;
30
31
	/** @var \vse\similartopics\core\fulltext_support */
32
	protected $fulltext;
33
34
	/** @var \phpbb\log\log */
35
	protected $log;
36
37
	/** @var \phpbb\request\request */
38
	protected $request;
39
40
	/** @var \phpbb\template\template */
41
	protected $template;
42
43
	/** @var \phpbb\user */
44
	protected $user;
45
46
	/** @var string */
47
	protected $root_path;
48
49
	/** @var string */
50
	protected $php_ext;
51
52
	/** @var string */
53
	public $page_title;
54
55
	/** @var string */
56
	public $tpl_name;
57
58
	/** @var string */
59
	public $u_action;
60
61
	/**
62
	* ACP module constructor
63
	*
64
	* @access public
65
	*/
66
	public function __construct()
67
	{
68
		global $config, $db, $request, $template, $user, $phpbb_log, $phpbb_root_path, $phpEx;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
69
70
		$this->config = $config;
71
		$this->db = $db;
72
		$this->request = $request;
73
		$this->template = $template;
74
		$this->user = $user;
75
		$this->log = $phpbb_log;
76
		$this->root_path = $phpbb_root_path;
77
		$this->php_ext = $phpEx;
78
		$this->fulltext = new \vse\similartopics\core\fulltext_support($this->db);
79
80
		$this->user->add_lang('acp/common');
81
		$this->user->add_lang_ext('vse/similartopics', 'acp_similar_topics');
82
83
		$this->tpl_name = 'acp_similar_topics';
84
		$this->page_title = $this->user->lang('PST_TITLE_ACP');
85
	}
86
87
	/**
88
	* Main ACP module
89
	*
90
	* @param int $id
91
	* @param string $mode
92
	* @access public
93
	*/
94
	public function main($id, $mode)
0 ignored issues
show
Unused Code introduced by
The parameter $id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $mode is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
95
	{
96
		$form_key = 'acp_similar_topics';
97
		add_form_key($form_key);
98
99
		$action = $this->request->variable('action', '');
100
101
		switch ($action)
102
		{
103
			case 'advanced':
104
				$forum_id = $this->request->variable('f', 0);
105
106
				if ($this->request->is_set_post('submit'))
107
				{
108
					$this->check_form_key($form_key);
109
110
					$similar_topic_forums = implode(',', $this->request->variable('similar_forums_id', array(0)));
111
					$this->validate_config_length($similar_topic_forums);
112
113
					$sql = 'UPDATE ' . FORUMS_TABLE . "
114
						SET similar_topic_forums = '" . $this->db->sql_escape($similar_topic_forums) . "'
115
						WHERE forum_id = $forum_id";
116
					$this->db->sql_query($sql);
117
118
					$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'PST_LOG_MSG');
119
120
					$this->end('PST_SAVED');
121
				}
122
123
				$forum_name = '';
124
				$selected = array();
125
				if ($forum_id > 0)
126
				{
127
					$sql = 'SELECT forum_name, similar_topic_forums
128
						FROM ' . FORUMS_TABLE . "
129
						WHERE forum_id = $forum_id";
130
					$result = $this->db->sql_query($sql);
131
					while ($fid = $this->db->sql_fetchrow($result))
132
					{
133
						$selected = explode(',', trim($fid['similar_topic_forums']));
134
						$forum_name = $fid['forum_name'];
135
					}
136
					$this->db->sql_freeresult($result);
137
				}
138
139
				$this->template->assign_vars(array(
140
					'S_ADVANCED_SETTINGS'		=> true,
141
					'SIMILAR_FORUMS_OPTIONS'	=> make_forum_select($selected, false, false, true),
142
					'PST_FORUM_NAME'			=> $forum_name,
143
					'PST_ADVANCED_EXP'			=> $this->user->lang('PST_ADVANCED_EXP', $forum_name),
144
					'U_ACTION'					=> $this->u_action . '&amp;action=advanced&amp;f=' . $forum_id,
145
					'U_BACK'					=> $this->u_action,
146
				));
147
			break;
148
149
			default:
150
				if ($this->request->is_set_post('submit'))
151
				{
152
					$this->check_form_key($form_key);
153
154
					// Get checkbox array form data and check string length
155
					$mark_noshow_forum = implode(',', $this->request->variable('mark_noshow_forum', array(0), true));
156
					$mark_ignore_forum = implode(',', $this->request->variable('mark_ignore_forum', array(0), true));
157
					$this->validate_config_length($mark_noshow_forum, $mark_ignore_forum);
158
159
					// Set basic config settings
160
					$this->config->set('similar_topics', $this->request->variable('pst_enable', 0));
161
					$this->config->set('similar_topics_limit', abs($this->request->variable('pst_limit', 0))); // use abs for positive values only
162
					$this->config->set('similar_topics_cache', abs($this->request->variable('pst_cache', 0))); // use abs for positive values only
163
					$this->config->set('similar_topics_words', $this->request->variable('pst_words', '', true));
164
					$this->config->set('similar_topics_hide', $mark_noshow_forum);
165
					$this->config->set('similar_topics_ignore', $mark_ignore_forum);
166
167
					// Set date/time config settings
168
					$pst_time = abs($this->request->variable('pst_time', 0)); // use abs for positive values only
169
					$pst_time_type = $this->request->variable('pst_time_type', '');
170
					$this->config->set('similar_topics_type', $pst_time_type);
171
					$this->config->set('similar_topics_time', $this->set_pst_time($pst_time, $pst_time_type));
172
173
					$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'PST_LOG_MSG');
174
175
					$this->end('PST_SAVED');
176
				}
177
178
				// Allow option to update the database to enable FULLTEXT support
179
				if ($this->request->is_set_post('fulltext'))
180
				{
181
					if (confirm_box(true))
182
					{
183
						// If FULLTEXT is not supported, lets make it so
184
						if (!$this->fulltext_support_enabled())
185
						{
186
							// Alter the database to support FULLTEXT
187
							$this->enable_fulltext_support();
188
189
							// Store the original database storage engine in a config var for recovery on uninstall
190
							$this->config->set('similar_topics_fulltext', (string) $this->fulltext->get_engine());
191
192
							$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'PST_LOG_FULLTEXT', time(), array(TOPICS_TABLE));
193
194
							$this->end('PST_SAVE_FULLTEXT');
195
						}
196
						else
197
						{
198
							$this->end('PST_ERR_FULLTEXT', E_USER_WARNING);
199
						}
200
					}
201
					else
202
					{
203
						confirm_box(false, $this->user->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
204
							'fulltext' => 1,
205
						)));
206
					}
207
				}
208
209
				// Build the time options select menu
210
				$time_options = array(
211
					'd' => $this->user->lang('PST_DAYS'),
212
					'w' => $this->user->lang('PST_WEEKS'),
213
					'm' => $this->user->lang('PST_MONTHS'),
214
					'y' => $this->user->lang('PST_YEARS')
215
				);
216
				foreach ($time_options as $value => $label)
217
				{
218
					$this->template->assign_block_vars('similar_time_options', array(
219
						'VALUE'			=> $value,
220
						'LABEL'			=> $label,
221
						'S_SELECTED'	=> $value == $this->config['similar_topics_type'],
222
					));
223
				}
224
225
				$this->template->assign_vars(array(
226
					'S_PST_ENABLE'		=> $this->isset_or_default($this->config['similar_topics'], false),
227
					'PST_LIMIT'			=> $this->isset_or_default($this->config['similar_topics_limit'], ''),
228
					'PST_CACHE'			=> $this->isset_or_default($this->config['similar_topics_cache'], ''),
229
					'PST_WORDS'			=> $this->isset_or_default($this->config['similar_topics_words'], ''),
230
					'PST_TIME'			=> $this->get_pst_time($this->config['similar_topics_time'], $this->config['similar_topics_type']),
231
					'S_PST_NO_SUPPORT'	=> !$this->fulltext_support_enabled(),
232
					'S_PST_NO_MYSQL'	=> !$this->fulltext->is_mysql(),
233
					'U_ACTION'			=> $this->u_action,
234
				));
235
236
				$ignore_forums = explode(',', trim($this->config['similar_topics_ignore']));
237
				$noshow_forums = explode(',', trim($this->config['similar_topics_hide']));
238
239
				$forum_list = $this->get_forum_list();
240
				foreach ($forum_list as $row)
241
				{
242
					$this->template->assign_block_vars('forums', array(
243
						'FORUM_NAME'			=> $row['forum_name'],
244
						'FORUM_ID'				=> $row['forum_id'],
245
						'CHECKED_IGNORE_FORUM'	=> (in_array($row['forum_id'], $ignore_forums)) ? 'checked="checked"' : '',
246
						'CHECKED_NOSHOW_FORUM'	=> (in_array($row['forum_id'], $noshow_forums)) ? 'checked="checked"' : '',
247
						'S_IS_ADVANCED'			=> (bool) $row['similar_topic_forums'],
248
						'U_ADVANCED'			=> "{$this->u_action}&amp;action=advanced&amp;f=" . $row['forum_id'],
249
						'U_FORUM'				=> append_sid("{$this->root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']),
250
					));
251
				}
252
			break;
253
		}
254
	}
255
256
	/**
257
	* Check if config field values exceed 255 chars
258
	*
259
	* @return null
260
	* @access protected
261
	*/
262
	protected function validate_config_length()
263
	{
264
		$arg_list = func_get_args();
265
		foreach ($arg_list as $arg)
266
		{
267
			if (strlen($arg) > 255)
268
			{
269
				$this->end('PST_ERR_CONFIG', E_USER_WARNING);
270
			}
271
		}
272
	}
273
274
	/**
275
	* Check form key, trigger error if invalid
276
	*
277
	* @param string $form_key The form key value
278
	* @return null
279
	* @access protected
280
	*/
281
	protected function check_form_key($form_key)
282
	{
283
		if (!check_form_key($form_key))
284
		{
285
			$this->end('FORM_INVALID', E_USER_WARNING);
286
		}
287
	}
288
289
	/**
290
	* Get forums list
291
	*
292
	* @return array	forum data rows
293
	* @access protected
294
	*/
295
	protected function get_forum_list()
296
	{
297
		$sql = 'SELECT forum_id, forum_name, similar_topic_forums
298
			FROM ' . FORUMS_TABLE . '
299
			WHERE forum_type = ' . FORUM_POST . '
300
			ORDER BY left_id ASC';
301
		$result = $this->db->sql_query($sql);
302
		$forum_list = $this->db->sql_fetchrowset($result);
303
		$this->db->sql_freeresult($result);
304
305
		return $forum_list;
306
	}
307
308
	/**
309
	* Calculate the $pst_time based on user input
310
	*
311
	* @param int $length user entered value
312
	* @param string $type years, months, weeks, days (y|m|w|d)
313
	* @return int time in seconds
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
314
	* @access protected
315
	*/
316
	protected function set_pst_time($length, $type = 'y')
317
	{
318
		$type = array_key_exists($type, self::TIMES) ? $type : 'y';
319
320
		return (int) $length * self::TIMES[$type];
321
	}
322
323
	/**
324
	* Get the correct time $length value for the form
325
	*
326
	* @param int $time as a timestamp
327
	* @param string $type years, months, weeks, days (y|m|w|d)
328
	* @return int time converted to the given $type
329
	* @access protected
330
	*/
331
	protected function get_pst_time($time, $type = '')
332
	{
333
		return array_key_exists($type, self::TIMES) ? (int) round($time / self::TIMES[$type]) : 0;
334
	}
335
336
	/**
337
	* Check for FULLTEXT index support
338
	*
339
	* @return bool True if FULLTEXT is fully supported, false otherwise
340
	* @access protected
341
	*/
342
	protected function fulltext_support_enabled()
343
	{
344
		if ($this->fulltext->is_supported())
345
		{
346
			return $this->fulltext->index('topic_title');
347
		}
348
349
		return false;
350
	}
351
352
	/**
353
	* Enable FULLTEXT support for the topic_title
354
	*
355
	* @return null
356
	* @access protected
357
	*/
358
	protected function enable_fulltext_support()
359
	{
360
		if (!$this->fulltext->is_mysql())
361
		{
362
			$this->end('PST_NO_MYSQL', E_USER_WARNING);
363
		}
364
365
		// Alter the storage engine
366
		$sql = 'ALTER TABLE ' . TOPICS_TABLE . ' ENGINE = MYISAM';
367
		$this->db->sql_query($sql);
368
369
		// Prevent adding extra indeces.
370
		if ($this->fulltext->index('topic_title'))
371
		{
372
			return;
373
		}
374
375
		$sql = 'ALTER TABLE ' . TOPICS_TABLE . ' ADD FULLTEXT (topic_title)';
376
		$this->db->sql_query($sql);
377
	}
378
379
	/**
380
	* Return a variable if it is set, otherwise default
381
	*
382
	* @param mixed $var The variable to test
383
	* @param mixed $default The default value to use
384
	* @return mixed The value of the variable if set, otherwise default value
385
	* @access protected
386
	*/
387
	protected function isset_or_default($var, $default)
388
	{
389
		return (isset($var)) ? $var : $default;
390
	}
391
392
	/**
393
	 * End script execution with a trigger_error message
394
	 *
395
	 * @param string $message Language key string
396
	 * @param int    $code    E_USER_NOTICE|E_USER_WARNING
397
	 * @return null
398
	 * @access protected
399
	 */
400
	protected function end($message, $code = E_USER_NOTICE)
401
	{
402
		trigger_error($this->user->lang($message) . adm_back_link($this->u_action), $code);
403
	}
404
}
405