Completed
Pull Request — master (#22)
by Matt
02:52
created

similar_topics_module::submit_settings()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
cc 1
eloc 14
nc 1
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
	protected $form_key;
50
51
	/** @var string */
52
	public $page_title;
53
54
	/** @var string */
55
	public $tpl_name;
56
57
	/** @var string */
58
	public $u_action;
59
60
	/**
61
	 * ACP module constructor
62
	 *
63
	 * @throws \Exception
64
	 */
65
	public function __construct()
66
	{
67
		global $phpbb_container;
68
69
		$this->config    = $phpbb_container->get('config');
70
		$this->db        = $phpbb_container->get('dbal.conn');
71
		$this->fulltext  = $phpbb_container->get('vse.similartopics.fulltext_support');
72
		$this->log       = $phpbb_container->get('log');
73
		$this->request   = $phpbb_container->get('request');
74
		$this->template  = $phpbb_container->get('template');
75
		$this->user      = $phpbb_container->get('user');
76
		$this->root_path = $phpbb_container->getParameter('core.root_path');
77
		$this->php_ext   = $phpbb_container->getParameter('core.php_ext');
78
		$this->form_key  = 'acp_similar_topics';
79
		$this->times     = array(
80
			'd' => 86400, // one day
81
			'w' => 604800, // one week
82
			'm' => 2626560, // one month
83
			'y' => 31536000, // one year
84
		);
85
	}
86
87
	/**
88
	 * Main ACP module
89
	 */
90
	public function main()
91
	{
92
		$this->user->add_lang_ext('vse/similartopics', 'acp_similar_topics');
93
94
		$this->tpl_name = 'acp_similar_topics';
95
		$this->page_title = $this->user->lang('PST_TITLE_ACP');
96
97
		add_form_key($this->form_key);
98
99
		$action = $this->request->variable('action', '');
100
101
		switch ($action)
102
		{
103
			case 'advanced':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
104
105
				$forum_id = $this->request->variable('f', 0);
106
107
				if ($this->request->is_set_post('submit'))
108
				{
109
					$this->submit_advanced($forum_id);
110
				}
111
112
				$this->display_advanced($forum_id);
113
114
			break;
115
116
			default:
0 ignored issues
show
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

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