Completed
Push — develop-3.2.x ( dcd8c5...afa453 )
by Matt
04:15 queued 02:03
created

similar_topics_module::update_forum()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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