Completed
Push — master ( 2119b9...5efbef )
by Matt
02:16
created

similar_topics_module::validate_config_length()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 0
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
	 * @access public
87
	 */
88
	public function main()
89
	{
90
		$this->user->add_lang_ext('vse/similartopics', 'acp_similar_topics');
91
92
		$this->tpl_name = 'acp_similar_topics';
93
		$this->page_title = $this->user->lang('PST_TITLE_ACP');
94
95
		$form_key = 'acp_similar_topics';
96
		add_form_key($form_key);
97
98
		$action = $this->request->variable('action', '');
99
100
		switch ($action)
101
		{
102
			case 'advanced':
103
				$forum_id = $this->request->variable('f', 0);
104
105
				if ($this->request->is_set_post('submit'))
106
				{
107
					$this->check_form_key($form_key);
108
109
					$similar_topic_forums = $this->request->variable('similar_forums_id', array(0));
110
					$similar_topic_forums = !empty($similar_topic_forums) ? json_encode($similar_topic_forums) : '';
111
112
					$sql = 'UPDATE ' . FORUMS_TABLE . "
113
						SET similar_topic_forums = '" . $this->db->sql_escape($similar_topic_forums) . "'
114
						WHERE forum_id = $forum_id";
115
					$this->db->sql_query($sql);
116
117
					$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'PST_LOG_MSG');
118
119
					$this->end('PST_SAVED');
120
				}
121
122
				$forum_name = '';
123
				$selected = array();
124
				if ($forum_id > 0)
125
				{
126
					$sql = 'SELECT forum_name, similar_topic_forums
127
						FROM ' . FORUMS_TABLE . "
128
						WHERE forum_id = $forum_id";
129
					$result = $this->db->sql_query($sql);
130
					while ($fid = $this->db->sql_fetchrow($result))
131
					{
132
						$selected = json_decode($fid['similar_topic_forums'], true);
133
						$forum_name = $fid['forum_name'];
134
					}
135
					$this->db->sql_freeresult($result);
136
				}
137
138
				$this->template->assign_vars(array(
139
					'S_ADVANCED_SETTINGS'		=> true,
140
					'SIMILAR_FORUMS_OPTIONS'	=> make_forum_select($selected, false, false, true),
141
					'PST_FORUM_NAME'			=> $forum_name,
142
					'PST_ADVANCED_EXP'			=> $this->user->lang('PST_ADVANCED_EXP', $forum_name),
143
					'U_ACTION'					=> $this->u_action . '&amp;action=advanced&amp;f=' . $forum_id,
144
					'U_BACK'					=> $this->u_action,
145
				));
146
			break;
147
148
			default:
149
				if ($this->request->is_set_post('submit'))
150
				{
151
					$this->check_form_key($form_key);
152
153
					// Set basic config settings
154
					$this->config->set('similar_topics', $this->request->variable('pst_enable', 0));
155
					$this->config->set('similar_topics_limit', abs($this->request->variable('pst_limit', 0))); // use abs for positive values only
156
					$this->config->set('similar_topics_cache', abs($this->request->variable('pst_cache', 0))); // use abs for positive values only
157
					$this->config->set('similar_topics_words', $this->request->variable('pst_words', '', true));
158
159
					// Set date/time config settings
160
					$pst_time = abs($this->request->variable('pst_time', 0)); // use abs for positive values only
161
					$pst_time_type = $this->request->variable('pst_time_type', '');
162
					$this->config->set('similar_topics_type', $pst_time_type);
163
					$this->config->set('similar_topics_time', $this->set_pst_time($pst_time, $pst_time_type));
164
165
					// Set checkbox array form data
166
					$this->update_forum('similar_topics_hide', $this->request->variable('mark_noshow_forum', array(0), true));
167
					$this->update_forum('similar_topics_ignore', $this->request->variable('mark_ignore_forum', array(0), true));
168
169
					$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'PST_LOG_MSG');
170
171
					$this->end('PST_SAVED');
172
				}
173
174
				// Allow option to update the database to enable FULLTEXT support
175
				if ($this->request->is_set_post('fulltext'))
176
				{
177
					if (confirm_box(true))
178
					{
179
						// If FULLTEXT is not supported, lets make it so
180
						if (!$this->fulltext_support_enabled())
181
						{
182
							// Alter the database to support FULLTEXT
183
							$this->enable_fulltext_support();
184
185
							// Store the original database storage engine in a config var for recovery on uninstall
186
							$this->config->set('similar_topics_fulltext', (string) $this->fulltext->get_engine());
187
188
							$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'PST_LOG_FULLTEXT', time(), array(TOPICS_TABLE));
189
190
							$this->end('PST_SAVE_FULLTEXT');
191
						}
192
						$this->end('PST_ERR_FULLTEXT', E_USER_WARNING);
193
					}
194
					confirm_box(false, $this->user->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
195
						'fulltext' => 1,
196
					)));
197
				}
198
199
				// Build the time options select menu
200
				$time_options = array(
201
					'd' => $this->user->lang('PST_DAYS'),
202
					'w' => $this->user->lang('PST_WEEKS'),
203
					'm' => $this->user->lang('PST_MONTHS'),
204
					'y' => $this->user->lang('PST_YEARS')
205
				);
206
				foreach ($time_options as $value => $label)
207
				{
208
					$this->template->assign_block_vars('similar_time_options', array(
209
						'VALUE'			=> $value,
210
						'LABEL'			=> $label,
211
						'S_SELECTED'	=> $value == $this->config['similar_topics_type'],
212
					));
213
				}
214
215
				$this->template->assign_vars(array(
216
					'S_PST_ENABLE'		=> $this->isset_or_default($this->config['similar_topics'], false),
217
					'PST_LIMIT'			=> $this->isset_or_default($this->config['similar_topics_limit'], ''),
218
					'PST_CACHE'			=> $this->isset_or_default($this->config['similar_topics_cache'], ''),
219
					'PST_WORDS'			=> $this->isset_or_default($this->config['similar_topics_words'], ''),
220
					'PST_TIME'			=> $this->get_pst_time($this->config['similar_topics_time'], $this->config['similar_topics_type']),
221
					'S_PST_NO_SUPPORT'	=> !$this->fulltext_support_enabled(),
222
					'S_PST_NO_MYSQL'	=> !$this->fulltext->is_mysql(),
223
					'U_ACTION'			=> $this->u_action,
224
				));
225
226
				$forum_list = $this->get_forum_list();
227
				foreach ($forum_list as $row)
228
				{
229
					$this->template->assign_block_vars('forums', array(
230
						'FORUM_NAME'			=> $row['forum_name'],
231
						'FORUM_ID'				=> $row['forum_id'],
232
						'CHECKED_IGNORE_FORUM'	=> $row['similar_topics_ignore'] ? 'checked="checked"' : '',
233
						'CHECKED_NOSHOW_FORUM'	=> $row['similar_topics_hide'] ? 'checked="checked"' : '',
234
						'S_IS_ADVANCED'			=> (bool) $row['similar_topic_forums'],
235
						'U_ADVANCED'			=> "{$this->u_action}&amp;action=advanced&amp;f=" . $row['forum_id'],
236
						'U_FORUM'				=> append_sid("{$this->root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']),
237
					));
238
				}
239
			break;
240
		}
241
	}
242
243
	/**
244
	 * Check form key, trigger error if invalid
245
	 *
246
	 * @access protected
247
	 * @param string $form_key The form key value
248
	 */
249
	protected function check_form_key($form_key)
250
	{
251
		if (!check_form_key($form_key))
252
		{
253
			$this->end('FORM_INVALID', E_USER_WARNING);
254
		}
255
	}
256
257
	/**
258
	 * Get forums list
259
	 *
260
	 * @access protected
261
	 * @return array forum data rows
262
	 */
263
	protected function get_forum_list()
264
	{
265
		$sql = 'SELECT forum_id, forum_name, similar_topic_forums, similar_topics_hide, similar_topics_ignore
266
			FROM ' . FORUMS_TABLE . '
267
			WHERE forum_type = ' . FORUM_POST . '
268
			ORDER BY left_id ASC';
269
		$result = $this->db->sql_query($sql);
270
		$forum_list = $this->db->sql_fetchrowset($result);
271
		$this->db->sql_freeresult($result);
272
273
		return $forum_list;
274
	}
275
276
	/**
277
	 * Update the similar topics columns in the forums table
278
	 *
279
	 * @param string $column    The name of the column to update
280
	 * @param array  $forum_ids An array of forum_ids
281
	 */
282
	protected function update_forum($column, $forum_ids)
283
	{
284
		$this->db->sql_transaction('begin');
285
286
		// Set marked forums (in set) to 1
287
		$sql = 'UPDATE ' . FORUMS_TABLE . "
288
			SET $column = 1
289
			WHERE " . $this->db->sql_in_set('forum_id', $forum_ids, false, true);
290
		$this->db->sql_query($sql);
291
292
		// Set unmarked forums (not in set) to 0
293
		$sql = 'UPDATE ' . FORUMS_TABLE . "
294
			SET $column = 0
295
			WHERE " . $this->db->sql_in_set('forum_id', $forum_ids, true, true);
296
		$this->db->sql_query($sql);
297
298
		$this->db->sql_transaction('commit');
299
	}
300
301
	/**
302
	 * Calculate the time in seconds based on requested time period length
303
	 *
304
	 * @access protected
305
	 * @param int    $length user entered value
306
	 * @param string $type   years, months, weeks, days (y|m|w|d)
307
	 * @return int time in seconds
308
	 */
309
	protected function set_pst_time($length, $type = 'y')
310
	{
311
		$type = isset($this->times[$type]) ? $type : 'y';
312
313
		return (int) ($length * $this->times[$type]);
314
	}
315
316
	/**
317
	 * Get the correct time period length value for the form
318
	 *
319
	 * @access protected
320
	 * @param int    $time as a timestamp
321
	 * @param string $type years, months, weeks, days (y|m|w|d)
322
	 * @return int time converted to the given $type
323
	 */
324
	protected function get_pst_time($time, $type = '')
325
	{
326
		return isset($this->times[$type]) ? (int) round($time / $this->times[$type]) : 0;
327
	}
328
329
	/**
330
	 * Check for FULLTEXT index support
331
	 *
332
	 * @access protected
333
	 * @return bool True if FULLTEXT is fully supported, false otherwise
334
	 */
335
	protected function fulltext_support_enabled()
336
	{
337
		if ($this->fulltext->is_supported())
338
		{
339
			return $this->fulltext->is_index('topic_title');
340
		}
341
342
		return false;
343
	}
344
345
	/**
346
	 * Enable FULLTEXT support for the topic_title
347
	 *
348
	 * @access protected
349
	 */
350
	protected function enable_fulltext_support()
351
	{
352
		if (!$this->fulltext->is_mysql())
353
		{
354
			$this->end('PST_NO_MYSQL', E_USER_WARNING);
355
		}
356
357
		// Alter the storage engine
358
		$sql = 'ALTER TABLE ' . TOPICS_TABLE . ' ENGINE = MYISAM';
359
		$this->db->sql_query($sql);
360
361
		// Prevent adding extra indeces.
362
		if ($this->fulltext->is_index('topic_title'))
363
		{
364
			return;
365
		}
366
367
		$sql = 'ALTER TABLE ' . TOPICS_TABLE . ' ADD FULLTEXT (topic_title)';
368
		$this->db->sql_query($sql);
369
	}
370
371
	/**
372
	 * Return a variable if it is set, otherwise default
373
	 *
374
	 * @access protected
375
	 * @param mixed $var     The variable to test
376
	 * @param mixed $default The default value to use
377
	 * @return mixed The value of the variable if set, otherwise default value
378
	 */
379
	protected function isset_or_default($var, $default)
380
	{
381
		return null !== $var ? $var : $default;
382
	}
383
384
	/**
385
	 * End script execution with a trigger_error message
386
	 *
387
	 * @access protected
388
	 * @param string $message Language key string
389
	 * @param int    $code    E_USER_NOTICE|E_USER_WARNING
390
	 * @return void
391
	 */
392
	protected function end($message, $code = E_USER_NOTICE)
393
	{
394
		trigger_error($this->user->lang($message) . adm_back_link($this->u_action), $code);
395
	}
396
}
397