Completed
Push — master ( ed0b3e...4e9006 )
by Matt
02:35
created

similar_topics_module   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 391
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 22
Bugs 1 Features 1
Metric Value
wmc 32
c 22
b 1
f 1
lcom 1
cbo 1
dl 0
loc 391
rs 9.6

11 Methods

Rating   Name   Duplication   Size   Complexity  
A validate_config_length() 0 11 3
A check_form_key() 0 7 2
A get_forum_list() 0 12 1
A set_pst_time() 0 6 2
A get_pst_time() 0 4 2
A fulltext_support_enabled() 0 9 2
A enable_fulltext_support() 0 20 3
A isset_or_default() 0 4 2
A end() 0 4 1
A __construct() 0 20 1
D main() 0 167 13
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
	/** @var \phpbb\config\config */
19
	protected $config;
20
21
	/** @var \phpbb\db\driver\driver_interface */
22
	protected $db;
23
24
	/** @var \vse\similartopics\core\fulltext_support */
25
	protected $fulltext;
26
27
	/** @var \phpbb\log\log */
28
	protected $log;
29
30
	/** @var \phpbb\request\request */
31
	protected $request;
32
33
	/** @var \phpbb\template\template */
34
	protected $template;
35
36
	/** @var \phpbb\user */
37
	protected $user;
38
39
	/** @var string */
40
	protected $root_path;
41
42
	/** @var string */
43
	protected $php_ext;
44
45
	/** @var array */
46
	protected $times;
47
48
	/** @var string */
49
	public $page_title;
50
51
	/** @var string */
52
	public $tpl_name;
53
54
	/** @var string */
55
	public $u_action;
56
57
	/**
58
	* ACP module constructor
59
	*
60
	* @access public
61
	*/
62
	public function __construct()
63
	{
64
		global $phpbb_container;
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...
65
66
		$this->config    = $phpbb_container->get('config');
67
		$this->db        = $phpbb_container->get('dbal.conn');
68
		$this->fulltext  = $phpbb_container->get('vse.similartopics.fulltext_support');
69
		$this->log       = $phpbb_container->get('log');
70
		$this->request   = $phpbb_container->get('request');
71
		$this->template  = $phpbb_container->get('template');
72
		$this->user      = $phpbb_container->get('user');
73
		$this->root_path = $phpbb_container->getParameter('core.root_path');
74
		$this->php_ext   = $phpbb_container->getParameter('core.php_ext');
75
		$this->times     = array(
76
			'd' => 86400, // one day
77
			'w' => 604800, // one week
78
			'm' => 2626560, // one month
79
			'y' => 31536000, // one year
80
		);
81
	}
82
83
	/**
84
	* Main ACP module
85
	*
86
	* @param int $id
87
	* @param string $mode
88
	* @access public
89
	*/
90
	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...
91
	{
92
		$this->user->add_lang('acp/common');
93
		$this->user->add_lang_ext('vse/similartopics', 'acp_similar_topics');
94
95
		$this->tpl_name = 'acp_similar_topics';
96
		$this->page_title = $this->user->lang('PST_TITLE_ACP');
97
98
		$form_key = 'acp_similar_topics';
99
		add_form_key($form_key);
100
101
		$action = $this->request->variable('action', '');
102
103
		switch ($action)
104
		{
105
			case 'advanced':
106
				$forum_id = $this->request->variable('f', 0);
107
108
				if ($this->request->is_set_post('submit'))
109
				{
110
					$this->check_form_key($form_key);
111
112
					$similar_topic_forums = implode(',', $this->request->variable('similar_forums_id', array(0)));
113
					$this->validate_config_length($similar_topic_forums);
114
115
					$sql = 'UPDATE ' . FORUMS_TABLE . "
116
						SET similar_topic_forums = '" . $this->db->sql_escape($similar_topic_forums) . "'
117
						WHERE forum_id = $forum_id";
118
					$this->db->sql_query($sql);
119
120
					$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'PST_LOG_MSG');
121
122
					$this->end('PST_SAVED');
123
				}
124
125
				$forum_name = '';
126
				$selected = array();
127
				if ($forum_id > 0)
128
				{
129
					$sql = 'SELECT forum_name, similar_topic_forums
130
						FROM ' . FORUMS_TABLE . "
131
						WHERE forum_id = $forum_id";
132
					$result = $this->db->sql_query($sql);
133
					while ($fid = $this->db->sql_fetchrow($result))
134
					{
135
						$selected = explode(',', trim($fid['similar_topic_forums']));
136
						$forum_name = $fid['forum_name'];
137
					}
138
					$this->db->sql_freeresult($result);
139
				}
140
141
				$this->template->assign_vars(array(
142
					'S_ADVANCED_SETTINGS'		=> true,
143
					'SIMILAR_FORUMS_OPTIONS'	=> make_forum_select($selected, false, false, true),
144
					'PST_FORUM_NAME'			=> $forum_name,
145
					'PST_ADVANCED_EXP'			=> $this->user->lang('PST_ADVANCED_EXP', $forum_name),
146
					'U_ACTION'					=> $this->u_action . '&amp;action=advanced&amp;f=' . $forum_id,
147
					'U_BACK'					=> $this->u_action,
148
				));
149
			break;
150
151
			default:
152
				if ($this->request->is_set_post('submit'))
153
				{
154
					$this->check_form_key($form_key);
155
156
					// Get checkbox array form data and check string length
157
					$mark_noshow_forum = implode(',', $this->request->variable('mark_noshow_forum', array(0), true));
158
					$mark_ignore_forum = implode(',', $this->request->variable('mark_ignore_forum', array(0), true));
159
					$this->validate_config_length($mark_noshow_forum, $mark_ignore_forum);
160
161
					// Set basic config settings
162
					$this->config->set('similar_topics', $this->request->variable('pst_enable', 0));
163
					$this->config->set('similar_topics_limit', abs($this->request->variable('pst_limit', 0))); // use abs for positive values only
164
					$this->config->set('similar_topics_cache', abs($this->request->variable('pst_cache', 0))); // use abs for positive values only
165
					$this->config->set('similar_topics_words', $this->request->variable('pst_words', '', true));
166
					$this->config->set('similar_topics_hide', $mark_noshow_forum);
167
					$this->config->set('similar_topics_ignore', $mark_ignore_forum);
168
169
					// Set date/time config settings
170
					$pst_time = abs($this->request->variable('pst_time', 0)); // use abs for positive values only
171
					$pst_time_type = $this->request->variable('pst_time_type', '');
172
					$this->config->set('similar_topics_type', $pst_time_type);
173
					$this->config->set('similar_topics_time', $this->set_pst_time($pst_time, $pst_time_type));
174
175
					$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'PST_LOG_MSG');
176
177
					$this->end('PST_SAVED');
178
				}
179
180
				// Allow option to update the database to enable FULLTEXT support
181
				if ($this->request->is_set_post('fulltext'))
182
				{
183
					if (confirm_box(true))
184
					{
185
						// If FULLTEXT is not supported, lets make it so
186
						if (!$this->fulltext_support_enabled())
187
						{
188
							// Alter the database to support FULLTEXT
189
							$this->enable_fulltext_support();
190
191
							// Store the original database storage engine in a config var for recovery on uninstall
192
							$this->config->set('similar_topics_fulltext', (string) $this->fulltext->get_engine());
193
194
							$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'PST_LOG_FULLTEXT', time(), array(TOPICS_TABLE));
195
196
							$this->end('PST_SAVE_FULLTEXT');
197
						}
198
						else
199
						{
200
							$this->end('PST_ERR_FULLTEXT', E_USER_WARNING);
201
						}
202
					}
203
					else
204
					{
205
						confirm_box(false, $this->user->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
206
							'fulltext' => 1,
207
						)));
208
					}
209
				}
210
211
				// Build the time options select menu
212
				$time_options = array(
213
					'd' => $this->user->lang('PST_DAYS'),
214
					'w' => $this->user->lang('PST_WEEKS'),
215
					'm' => $this->user->lang('PST_MONTHS'),
216
					'y' => $this->user->lang('PST_YEARS')
217
				);
218
				foreach ($time_options as $value => $label)
219
				{
220
					$this->template->assign_block_vars('similar_time_options', array(
221
						'VALUE'			=> $value,
222
						'LABEL'			=> $label,
223
						'S_SELECTED'	=> $value == $this->config['similar_topics_type'],
224
					));
225
				}
226
227
				$this->template->assign_vars(array(
228
					'S_PST_ENABLE'		=> $this->isset_or_default($this->config['similar_topics'], false),
229
					'PST_LIMIT'			=> $this->isset_or_default($this->config['similar_topics_limit'], ''),
230
					'PST_CACHE'			=> $this->isset_or_default($this->config['similar_topics_cache'], ''),
231
					'PST_WORDS'			=> $this->isset_or_default($this->config['similar_topics_words'], ''),
232
					'PST_TIME'			=> $this->get_pst_time($this->config['similar_topics_time'], $this->config['similar_topics_type']),
233
					'S_PST_NO_SUPPORT'	=> !$this->fulltext_support_enabled(),
234
					'S_PST_NO_MYSQL'	=> !$this->fulltext->is_mysql(),
235
					'U_ACTION'			=> $this->u_action,
236
				));
237
238
				$ignore_forums = explode(',', trim($this->config['similar_topics_ignore']));
239
				$noshow_forums = explode(',', trim($this->config['similar_topics_hide']));
240
241
				$forum_list = $this->get_forum_list();
242
				foreach ($forum_list as $row)
243
				{
244
					$this->template->assign_block_vars('forums', array(
245
						'FORUM_NAME'			=> $row['forum_name'],
246
						'FORUM_ID'				=> $row['forum_id'],
247
						'CHECKED_IGNORE_FORUM'	=> (in_array($row['forum_id'], $ignore_forums)) ? 'checked="checked"' : '',
248
						'CHECKED_NOSHOW_FORUM'	=> (in_array($row['forum_id'], $noshow_forums)) ? 'checked="checked"' : '',
249
						'S_IS_ADVANCED'			=> (bool) $row['similar_topic_forums'],
250
						'U_ADVANCED'			=> "{$this->u_action}&amp;action=advanced&amp;f=" . $row['forum_id'],
251
						'U_FORUM'				=> append_sid("{$this->root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']),
252
					));
253
				}
254
			break;
255
		}
256
	}
257
258
	/**
259
	* Check if config field values exceed 255 chars
260
	*
261
	* @return null
262
	* @access protected
263
	*/
264
	protected function validate_config_length()
265
	{
266
		$arg_list = func_get_args();
267
		foreach ($arg_list as $arg)
268
		{
269
			if (strlen($arg) > 255)
270
			{
271
				$this->end('PST_ERR_CONFIG', E_USER_WARNING);
272
			}
273
		}
274
	}
275
276
	/**
277
	* Check form key, trigger error if invalid
278
	*
279
	* @param string $form_key The form key value
280
	* @return null
281
	* @access protected
282
	*/
283
	protected function check_form_key($form_key)
284
	{
285
		if (!check_form_key($form_key))
286
		{
287
			$this->end('FORM_INVALID', E_USER_WARNING);
288
		}
289
	}
290
291
	/**
292
	* Get forums list
293
	*
294
	* @return array	forum data rows
295
	* @access protected
296
	*/
297
	protected function get_forum_list()
298
	{
299
		$sql = 'SELECT forum_id, forum_name, similar_topic_forums
300
			FROM ' . FORUMS_TABLE . '
301
			WHERE forum_type = ' . FORUM_POST . '
302
			ORDER BY left_id ASC';
303
		$result = $this->db->sql_query($sql);
304
		$forum_list = $this->db->sql_fetchrowset($result);
305
		$this->db->sql_freeresult($result);
306
307
		return $forum_list;
308
	}
309
310
	/**
311
	* Calculate the $pst_time based on user input
312
	*
313
	* @param int $length user entered value
314
	* @param string $type years, months, weeks, days (y|m|w|d)
315
	* @return int time in seconds
316
	* @access protected
317
	*/
318
	protected function set_pst_time($length, $type = 'y')
319
	{
320
		$type = isset($this->times[$type]) ? $type : 'y';
321
322
		return (int) ($length * $this->times[$type]);
323
	}
324
325
	/**
326
	* Get the correct time $length value for the form
327
	*
328
	* @param int $time as a timestamp
329
	* @param string $type years, months, weeks, days (y|m|w|d)
330
	* @return int time converted to the given $type
331
	* @access protected
332
	*/
333
	protected function get_pst_time($time, $type = '')
334
	{
335
		return isset($this->times[$type]) ? (int) round($time / $this->times[$type]) : 0;
336
	}
337
338
	/**
339
	* Check for FULLTEXT index support
340
	*
341
	* @return bool True if FULLTEXT is fully supported, false otherwise
342
	* @access protected
343
	*/
344
	protected function fulltext_support_enabled()
345
	{
346
		if ($this->fulltext->is_supported())
347
		{
348
			return $this->fulltext->index('topic_title');
349
		}
350
351
		return false;
352
	}
353
354
	/**
355
	* Enable FULLTEXT support for the topic_title
356
	*
357
	* @return null
358
	* @access protected
359
	*/
360
	protected function enable_fulltext_support()
361
	{
362
		if (!$this->fulltext->is_mysql())
363
		{
364
			$this->end('PST_NO_MYSQL', E_USER_WARNING);
365
		}
366
367
		// Alter the storage engine
368
		$sql = 'ALTER TABLE ' . TOPICS_TABLE . ' ENGINE = MYISAM';
369
		$this->db->sql_query($sql);
370
371
		// Prevent adding extra indeces.
372
		if ($this->fulltext->index('topic_title'))
373
		{
374
			return;
375
		}
376
377
		$sql = 'ALTER TABLE ' . TOPICS_TABLE . ' ADD FULLTEXT (topic_title)';
378
		$this->db->sql_query($sql);
379
	}
380
381
	/**
382
	* Return a variable if it is set, otherwise default
383
	*
384
	* @param mixed $var The variable to test
385
	* @param mixed $default The default value to use
386
	* @return mixed The value of the variable if set, otherwise default value
387
	* @access protected
388
	*/
389
	protected function isset_or_default($var, $default)
390
	{
391
		return (isset($var)) ? $var : $default;
392
	}
393
394
	/**
395
	 * End script execution with a trigger_error message
396
	 *
397
	 * @param string $message Language key string
398
	 * @param int    $code    E_USER_NOTICE|E_USER_WARNING
399
	 * @return null
400
	 * @access protected
401
	 */
402
	protected function end($message, $code = E_USER_NOTICE)
403
	{
404
		trigger_error($this->user->lang($message) . adm_back_link($this->u_action), $code);
405
	}
406
}
407