Completed
Push — master ( d5fbc8...4c9094 )
by Erwan
03:26
created

qte.php (7 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 *
4
 * @package Quick Title Edition Extension
5
 * @copyright (c) 2015 ABDev
6
 * @copyright (c) 2015 PastisD
7
 * @copyright (c) 2015 Geolim4 <http://geolim4.com>
8
 * @copyright (c) 2015 Zoddo <[email protected]>
9
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
10
 *
11
 */
12
13
namespace ernadoo\qte;
14
15
class qte
16
{
17
	const KEEP = -2;
18
	const REMOVE = -1;
19
20
	/** @var \phpbb\request\request */
21
	protected $request;
22
23
	/** @var \phpbb\cache\driver\driver_interface */
24
	protected $cache;
25
26
	/** @var \phpbb\config\config */
27
	protected $config;
28
29
	/** @var \phpbb\db\driver\driver_interface */
30
	protected $db;
31
32
	/** @var \phpbb\template\template */
33
	protected $template;
34
35
	/** @var \phpbb\user */
36
	protected $user;
37
38
	/** @var \phpbb\log\log */
39
	protected $log;
40
41
	/** @var string */
42
	protected $root_path;
43
44
	/** @var string */
45
	protected $php_ext;
46
47
	/** @var string */
48
	protected $table_prefix;
49
50
	/** @var array */
51
	private $_attr = array();
52
53
	/** @var array */
54
	private $_name = array();
55
56
	/**
57
	* Constructor
58
	*
59
	* @param \phpbb\request\request					$request			Request object
60
	* @param \phpbb\cache\driver\driver_interface	$cache				Cache object
61
	* @param \phpbb\config\config					$config				Config object
62
	* @param \phpbb\db\driver\driver_interface 		$db					Database object
63
	* @param \phpbb\template\template				$template			Template object
64
	* @param \phpbb\user							$user				User object
65
	* @param \phpbb\log\log							$log				Log object
66
	* @param string									$root_path			phpBB root path
67
	* @param string									$php_ext   			phpEx
68
	* @param string									$table_prefix   	Prefix tables
69
	*/
70
	public function __construct(\phpbb\request\request $request, \phpbb\cache\driver\driver_interface $cache, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\template\template $template, \phpbb\user $user, \phpbb\log\log $log, $root_path, $php_ext, $table_prefix)
71
	{
72
		$this->request		= $request;
73
		$this->cache		= $cache;
74
		$this->config		= $config;
75
		$this->db			= $db;
76
		$this->template		= $template;
77
		$this->user			= $user;
78
		$this->log			= $log;
79
80
		$this->root_path	= $root_path;
81
		$this->php_ext		= $php_ext;
82
		$this->table_prefix = $table_prefix;
83
84
		$this->_get_attributes();
85
	}
86
87
	/**
88
	* Get topic attributes username
89
	*
90
	* @param	array	$topic_list	Topic ids
91
	*
92
	* @return	null
93
	*/
94
	public function get_users_by_topic_id($topic_list)
95
	{
96
		if (!empty($topic_list))
97
		{
98
			$sql = 'SELECT u.user_id, u.username, u.user_colour
99
				FROM ' . USERS_TABLE . ' u
100
				LEFT JOIN ' . TOPICS_TABLE . ' t ON (u.user_id = t.topic_attr_user)
101
				WHERE ' . $this->db->sql_in_set('t.topic_id', array_map('intval', $topic_list)) . '
102
					AND t.topic_attr_user <> ' . ANONYMOUS;
103
			$result = $this->db->sql_query($sql);
104
105
			while ($row = $this->db->sql_fetchrow($result))
106
			{
107
				$this->_name[$row['user_id']] = array(
108
					'user_id' => (int) $row['user_id'],
109
					'username' => $row['username'],
110
					'user_colour' => $row['user_colour'],
111
				);
112
			}
113
			$this->db->sql_freeresult();
114
		}
115
	}
116
117
	/**
118
	* Get attribute name
119
	*
120
	* @param	int		$attr_id	The attribute id
121
	*
122
	* @return	string
123
	*/
124
	public function get_attr_name_by_id($attr_id)
125
	{
126
		return $this->_attr[$attr_id]['attr_name'];
127
	}
128
129
	/**
130
	* Get attribute author
131
	*
132
	* @param	int		$user_id	User id
133
	*
134
	* @return	string
135
	*/
136
	public function get_users_by_user_id($user_id)
137
	{
138
		$sql = 'SELECT user_id, username, user_colour
139
			FROM ' . USERS_TABLE . '
140
			WHERE user_id = ' . (int) $user_id;
141
		$result = $this->db->sql_query($sql);
142
143
		$this->name = array();
0 ignored issues
show
The property name does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
144
		while ( $row = $this->db->sql_fetchrow($result) )
145
		{
146
			$this->name[$row['user_id']] = array(
147
				'user_id'		=> (int) $row['user_id'],
148
				'username'		=> $row['username'],
149
				'user_colour'	=> $row['user_colour'],
150
			);
151
		}
152
		$this->db->sql_freeresult();
153
	}
154
155
	/**
156
	* Generate a list of attributes based on permissions
157
	*
158
	* @param	int		$forum_id		Forum id
159
	* @param	int		$author_id		Topic author id
160
	* @param	int		$attribute_id	Current attribute id
161
	* @param	array	$hide_attr		Groups which can't delete attribute in this forum
162
	* @param	string	$viewtopic_url	Topic's url
163
	*
164
	* @return	null
165
	*/
166
	public function attr_select($forum_id = 0, $author_id = 0, $attribute_id = 0, $hide_attr = array(), $viewtopic_url = '')
167
	{
168
		// load language
169
		$this->user->add_lang_ext('ernadoo/qte', 'attributes');
170
171
		// get current time once !
172
		$current_time = time();
173
174
		$show_select = false;
175
		$user_groups = array();
176
		$show_remove = $this->_check_auth_remove_attr($user_groups, $hide_attr);
177
178
		foreach ($this->_attr as $attr)
179
		{
180
			if (empty($attr['attr_auths']))
181
			{
182
				$attr_auths = array(array(
183
					'forums_ids'	=> array(),
184
					'groups_ids'	=> array(),
185
					'author'		=> false,
186
				));
187
			}
188
			else
189
			{
190
				$attr_auths = json_decode($attr['attr_auths'], true);
191
			}
192
193
			foreach ($attr_auths as $attr_auth)
194
			{
195
				if (!$this->_check_auth_attribute($attr_auth, $forum_id, $user_groups, $author_id))
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->_check_auth_attri...ser_groups, $author_id) of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
196
				{
197
					continue;
198
				}
199
200
				// show the selector !
201
				$show_select = true;
202
203
				// parse the attribute name
204
				$attribute_name = str_replace(array('%mod%', '%date%'), array($this->user->data['username'], $this->user->format_date($current_time, $attr['attr_date'])), $this->attr_lng_key($attr['attr_name']));
205
206
				$this->template->assign_block_vars('attributes', array(
207
					'QTE_ID'		=> $attr['attr_id'],
208
					'QTE_TYPE'		=> $attr['attr_type'],
209
					'QTE_NAME'		=> $attribute_name,
210
					'QTE_DESC'		=> $this->attr_lng_key($attr['attr_desc']),
211
					'QTE_COLOUR'	=> $this->attr_colour($attr['attr_name'], $attr['attr_colour']),
212
213
					'IS_SELECTED'	=> (!empty($attribute_id) && ($attr['attr_id'] == $attribute_id)),
214
215
					'S_QTE_DESC'	=> !empty($attr['attr_desc']) ? true : false,
216
					'U_QTE_URL'		=> !empty($viewtopic_url) ? append_sid($viewtopic_url, array('attr_id' => $attr['attr_id'])) : false,
217
				));
218
			}
219
		}
220
221
		if ($show_select)
222
		{
223
			$this->template->assign_vars(array(
224
				'S_QTE_SELECT'		=> true,
225
				'S_QTE_REMOVE'		=> $show_remove,
226
				'S_QTE_EMPTY'		=> (empty($attribute_id) || ($attribute_id == -1) || ($attribute_id == -2)),
227
				'S_QTE_SELECTED'	=> ($show_remove && ($attribute_id == -1)),
228
229
				'L_QTE_SELECT'		=> $this->user->lang['QTE_ATTRIBUTE_' . (!empty($attribute_id) ? ($show_remove ? 'REMOVE' : 'RESTRICT') : 'ADD')],
230
				'U_QTE_URL'			=> !empty($viewtopic_url) ? append_sid($viewtopic_url, array('attr_id' => -1)) : false,
231
			));
232
		}
233
	}
234
235
	/**
236
	* Generate a list of all attributes for search page
237
	*
238
	* @return	null
239
	*/
240
	public function attr_search()
241
	{
242
		// load language
243
		$this->user->add_lang_ext('ernadoo/qte', array('attributes', 'attributes_acp'));
244
245
		$show_select = false;
246
247
		foreach ($this->_attr as $attr)
248
		{
249
			if (empty($attr['attr_auths']))
250
			{
251
				$attr_auths = array(array(
252
					'forums_ids'	=> array(),
253
					'groups_ids'	=> array(),
254
					'author'		=> false,
255
				));
256
			}
257
			else
258
			{
259
				$attr_auths = json_decode($attr['attr_auths'], true);
260
			}
261
262
			foreach ($attr_auths as $attr_auth)
263
			{
264
				// show the selector !
265
				$show_select = true;
266
267
				// parse the attribute name
268
				$attribute_name = str_replace(array('%mod%', '%date%'), array($this->user->lang['QTE_KEY_USERNAME'], $this->user->lang['QTE_KEY_DATE']), $this->attr_lng_key($attr['attr_name']));
269
270
				$this->template->assign_block_vars('attributes', array(
271
					'QTE_ID'		=> $attr['attr_id'],
272
					'QTE_TYPE'		=> $attr['attr_type'],
273
					'QTE_NAME'		=> $attribute_name,
274
					'QTE_DESC'		=> $this->attr_lng_key($attr['attr_desc']),
275
					'QTE_COLOUR'	=> $this->attr_colour($attr['attr_name'], $attr['attr_colour']),
276
277
					'S_QTE_DESC'	=> !empty($attr['attr_desc']) ? true : false,
278
				));
279
			}
280
		}
281
282
		if ($show_select)
283
		{
284
			$this->template->assign_var('S_QTE_SELECT', true);
285
		}
286
	}
287
288
	/**
289
	* Generate a list of attributes for viewforum page
290
	*
291
	* @param	int		$forum_id		Forum id
292
	* @param	int		$attribute_id	Current attribute id
293
	*
294
	* @return	null
295
	*/
296 View Code Duplication
	public function attr_sort($forum_id = 0, $attribute_id = 0)
297
	{
298
		// load language
299
		$this->user->add_lang_ext('ernadoo/qte', array('attributes', 'attributes_acp'));
300
301
		$show_select = false;
302
303
		foreach ($this->_attr as $attr)
304
		{
305
			if (empty($attr['attr_auths']))
306
			{
307
				$attr_auths = array(array(
308
					'forums_ids'	=> array(),
309
					'groups_ids'	=> array(),
310
					'author'		=> false,
311
				));
312
			}
313
			else
314
			{
315
				$attr_auths = json_decode($attr['attr_auths'], true);
316
			}
317
318
			foreach ($attr_auths as $attr_auth)
319
			{
320
				$forum_ids = $attr_auth['forums_ids'];
321
322
				if (is_array($forum_ids) && in_array($forum_id, $forum_ids))
323
				{
324
					// show the selector !
325
					$show_select = true;
326
327
					// parse the attribute name
328
					$attribute_name = str_replace(array('%mod%', '%date%'), array($this->user->lang['QTE_KEY_USERNAME'], $this->user->lang['QTE_KEY_DATE']), $this->attr_lng_key($attr['attr_name']));
329
330
					$this->template->assign_block_vars('attributes', array(
331
						'QTE_ID'		=> $attr['attr_id'],
332
						'QTE_TYPE'		=> $attr['attr_type'],
333
						'QTE_NAME'		=> $attribute_name,
334
						'QTE_DESC'		=> $this->attr_lng_key($attr['attr_desc']),
335
						'QTE_COLOUR'	=> $this->attr_colour($attr['attr_name'], $attr['attr_colour']),
336
337
						'IS_SELECTED' => (!empty($attribute_id) && ($attr['attr_id'] == $attribute_id)) ? true : false,
338
339
						'S_QTE_DESC'	=> !empty($attr['attr_desc']) ? true : false,
340
					));
341
				}
342
			}
343
		}
344
345
		if ($show_select)
346
		{
347
			$this->template->assign_var('S_QTE_SELECT', true);
348
		}
349
	}
350
351
	/**
352
	* Generate a default attribute list for a forum
353
	*
354
	* @param	int		$forum_id		Forum id
355
	* @param	int		$attribute_id	Current attribute id
356
	*
357
	* @return	null
358
	*/
359 View Code Duplication
	public function attr_default($forum_id = 0, $attribute_id = 0)
360
	{
361
		// load language
362
		$this->user->add_lang_ext('ernadoo/qte', array('attributes', 'attributes_acp'));
363
364
		$show_select = false;
365
366
		foreach ($this->_attr as $attr)
367
		{
368
			if (empty($attr['attr_auths']))
369
			{
370
				$attr_auths = array(array(
371
					'forums_ids'	=> array(),
372
					'groups_ids'	=> array(),
373
					'author'		=> false,
374
				));
375
			}
376
			else
377
			{
378
				$attr_auths = json_decode($attr['attr_auths'], true);
379
			}
380
381
			foreach ($attr_auths as $attr_auth)
382
			{
383
				$forum_ids = $attr_auth['forums_ids'];
384
385
				if (is_array($forum_ids) && in_array($forum_id, $forum_ids))
386
				{
387
					// show the selector !
388
					$show_select = true;
389
390
					// parse the attribute name
391
					$attribute_name = str_replace(array('%mod%', '%date%'), array($this->user->lang['QTE_KEY_USERNAME'], $this->user->lang['QTE_KEY_DATE']), $this->attr_lng_key($attr['attr_name']));
392
393
					$this->template->assign_block_vars('attributes', array(
394
						'QTE_ID'		=> $attr['attr_id'],
395
						'QTE_TYPE'		=> $attr['attr_type'],
396
						'QTE_NAME'		=> $attribute_name,
397
						'QTE_DESC'		=> $this->attr_lng_key($attr['attr_desc']),
398
						'QTE_COLOUR'	=> $this->attr_colour($attr['attr_name'], $attr['attr_colour']),
399
400
						'IS_SELECTED'	=> (!empty($attribute_id) && ($attr['attr_id'] == $attribute_id)),
401
402
						'S_QTE_DESC'	=> !empty($attr['attr_desc']) ? true : false,
403
					));
404
				}
405
			}
406
		}
407
408
		if ($show_select)
409
		{
410
			$this->template->assign_var('S_QTE_SELECT', true);
411
		}
412
	}
413
414
	/**
415
	* Generate attribute for topic title
416
	*
417
	* @param	int		$attribute_id	Current attribute id
418
	* @param	int		$user_id		Current attribute user id
419
	* @param	int		$timestamp		Attribute timestamp
420
	*
421
	* @return	string					Attribute html code
422
	*/
423
	public function attr_display($attribute_id = 0, $user_id = 0, $timestamp = 0)
424
	{
425
		if (empty($attribute_id) || empty($user_id) || empty($timestamp))
426
		{
427
			return false;
428
		}
429
430
		if (isset($this->_attr[$attribute_id]))
431
		{
432
			$attribute_colour = $this->attr_colour($this->_attr[$attribute_id]['attr_name'], $this->_attr[$attribute_id]['attr_colour']);
433
434
			if (isset($this->_name[$user_id]['user_id']))
435
			{
436
				$attribute_username = get_username_string(($this->_attr[$attribute_id]['attr_user_colour'] ? 'no_profile' : 'username'), $this->_name[$user_id]['user_id'], $this->_name[$user_id]['username'], $this->_name[$user_id]['user_colour']);
437
			}
438
			else
439
			{
440
				$attribute_username = $this->user->lang['GUEST'];
441
			}
442
443
			$attribute_date = $this->user->format_date($timestamp, $this->_attr[$attribute_id]['attr_date']);
444
445
			$attribute_name = str_replace(array('%mod%', '%date%'), array($attribute_username, $attribute_date), $this->attr_lng_key($this->_attr[$attribute_id]['attr_name']));
446
447
			return !$this->_attr[$attribute_id]['attr_type'] ? '<span' . $attribute_colour . '>' . $attribute_name . '</span>' : $this->attr_img_key($this->_attr[$attribute_id]['attr_img'], $attribute_name);
448
		}
449
	}
450
451
	/**
452
	* Generate attribute for page title
453
	*
454
	* @param	int		$attribute_id	Current attribute id
455
	* @param	int		$user_id		Current attribute user id
456
	* @param	int		$timestamp		Attribute timestamp
457
	*
458
	* @return	string					attribute html code
459
	*/
460
	public function attr_title($attribute_id = 0, $user_id = 0, $timestamp = 0)
461
	{
462
		if (empty($attribute_id) || empty($user_id) || empty($timestamp))
463
		{
464
			return false;
465
		}
466
467
		if (isset($this->_attr[$attribute_id]))
468
		{
469
			if (isset($this->_name[$user_id]['user_id']))
470
			{
471
				$attribute_username = get_username_string('username', $this->_name[$user_id]['user_id'], $this->_name[$user_id]['username'], $this->_name[$user_id]['user_colour']);
472
			}
473
			else
474
			{
475
				$attribute_username = $this->user->lang['GUEST'];
476
			}
477
478
			$attribute_date = $this->user->format_date($timestamp, $this->_attr[$attribute_id]['attr_date']);
479
480
			$attribute_name = str_replace(array('%mod%', '%date%'), array($attribute_username, $attribute_date), $this->attr_lng_key($this->_attr[$attribute_id]['attr_name']));
481
482
			return $attribute_name;
483
		}
484
	}
485
486
487
	/**
488
	* Change topic attribute
489
	*
490
	* @param	int		$attribute_id		New attribute id
491
	* @param	int		$topic_id			The id of the topic
492
	* @param	int		$forum_id			The id of the forum
493
	* @param	int		$topic_attribute	Current attribute id
0 ignored issues
show
Should the type for parameter $topic_attribute not be string|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
494
	* @param	array	$hide_attr			Groups which can't delete attribute in this forum
495
	*
496
	* @return	null
497
	*/
498
	public function attr_apply($attribute_id = 0, $topic_id = 0, $forum_id = 0, $topic_attribute = '', $hide_attr = array())
499
	{
500
		if (empty($topic_id) || empty($forum_id) || empty($attribute_id))
501
		{
502
			return;
503
		}
504
505
		if ($attribute_id == \ernadoo\qte\qte::REMOVE && !$this->_check_auth_remove_attr($user_groups, $hide_attr))
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->_check_auth_remov...ser_groups, $hide_attr) of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
506
		{
507
			return;
508
		}
509
510
		// time !
511
		$current_time = time();
512
513
		if ($attribute_id == \ernadoo\qte\qte::REMOVE)
0 ignored issues
show
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
514
		{
515
			$fields = array(
516
				'topic_attr_id'		=> 0,
517
				'topic_attr_user'	=> 0,
518
				'topic_attr_time'	=> 0,
519
			);
520
		}
521
		else
522
		{
523
			$fields = array(
524
				'topic_attr_id'		=> $attribute_id,
525
				'topic_attr_user'	=> $this->user->data['user_id'],
526
				'topic_attr_time'	=> $current_time,
527
			);
528
		}
529
530
		$sql = 'UPDATE ' . TOPICS_TABLE . '
531
			SET ' . $this->db->sql_build_array('UPDATE', $fields) . '
532
			WHERE topic_id = ' . (int) $topic_id;
533
		$this->db->sql_query($sql);
534
535
		$sql = 'SELECT topic_id
536
			FROM ' . TOPICS_TABLE . '
537
			WHERE topic_moved_id = ' . (int) $topic_id;
538
		$result = $this->db->sql_query($sql);
539
		$shadow_topic_id = (int) $this->db->sql_fetchfield('topic_id');
540
		$this->db->sql_freeresult($result);
541
542
		if (!empty($shadow_topic_id))
543
		{
544
			$sql = 'UPDATE ' . TOPICS_TABLE . '
545
				SET ' . $this->db->sql_build_array('UPDATE', $fields) . '
546
				WHERE topic_id = ' . $shadow_topic_id;
547
			$this->db->sql_query($sql);
548
		}
549
550
		$meta_url = append_sid("{$this->root_path}viewtopic.$this->php_ext", "f=$forum_id&amp;t=$topic_id");
551
		meta_refresh(3, $meta_url);
552
553
		// load language
554
		$this->user->add_lang('posting');
555
		$this->user->add_lang_ext('ernadoo/qte', 'attributes');
556
557
		$message = $this->user->lang['QTE_ATTRIBUTE_' . ($attribute_id == -1 ? 'REMOVED' : (empty($topic_attribute) ? 'ADDED' : 'UPDATED'))] . '<br /><br />' . sprintf($this->user->lang['VIEW_MESSAGE'], '<a href="' . $meta_url . '">', '</a>');
558
		$message .= '<br /><br />' . sprintf($this->user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$this->root_path}viewforum.$this->php_ext", 'f=' . $forum_id) . '">', '</a>');
559
560
		if ($this->request->is_ajax())
561
		{
562
			$json_response = new \phpbb\json_response;
563
			$json_response->send(array(
564
				'success' => true,
565
566
				'MESSAGE_TITLE'	=> $this->user->lang['INFORMATION'],
567
				'MESSAGE_TEXT'	=> $message,
568
				'NEW_ATTRIBUTE'	=> $this->attr_display($attribute_id, $this->user->data['user_id'], $current_time),
569
			));
570
		}
571
572
		trigger_error($message);
573
	}
574
575
	/**
576
	* Change topic attribute in mcp
577
	*
578
	* @param	int		$attribute_id		New attribute id
579
	* @param	array	$topic_ids			Topics ids
580
	*
581
	* @return	null
582
	*/
583
	public function mcp_attr_apply($attribute_id = 0, $topic_ids = array())
584
	{
585
		// load language
586
		$this->user->add_lang_ext('ernadoo/qte', 'attributes');
587
588
		if (!sizeof($topic_ids))
589
		{
590
			trigger_error('NO_TOPIC_SELECTED');
591
		}
592
593
		if (!phpbb_check_ids($topic_ids, TOPICS_TABLE, 'topic_id'))
594
		{
595
			return;
596
		}
597
598
		// time !
599
		$current_time = time();
600
601
		$sql = 'SELECT topic_id, forum_id, topic_title, topic_attr_id
602
			FROM ' . TOPICS_TABLE . '
603
			WHERE ' . $this->db->sql_in_set('topic_id', array_map('intval', $topic_ids));
604
		$result = $this->db->sql_query($sql);
605
606
		// log this action
607
		while ($row = $this->db->sql_fetchrow($result))
608
		{
609
			$message = ($attribute_id == -1) ? 'REMOVED' : (empty($row['topic_attr_id']) ? 'ADDED' : 'UPDATED');
610
			$additional_data = array(
611
				'forum_id'	=> $row['forum_id'],
612
				'topic_id'	=> $row['topic_id'],
613
				$row['topic_title'],
614
			);
615
			$this->log->add('mod', $this->user->data['user_id'], $this->user->ip, 'MCP_ATTRIBUTE_' . $message, $current_time, $additional_data);
616
		}
617
		$this->db->sql_freeresult($result);
618
619
		if ($attribute_id == -1)
620
		{
621
			$fields = array(
622
				'topic_attr_id'		=> 0,
623
				'topic_attr_user'	=> 0,
624
				'topic_attr_time'	=> 0,
625
			);
626
		}
627
		else
628
		{
629
			$fields = array(
630
				'topic_attr_id'		=> $attribute_id,
631
				'topic_attr_user'	=> $this->user->data['user_id'],
632
				'topic_attr_time'	=> $current_time,
633
			);
634
		}
635
636
		$sql = 'UPDATE ' . TOPICS_TABLE . '
637
			SET ' . $this->db->sql_build_array('UPDATE', $fields) . '
638
			WHERE ' . $this->db->sql_in_set('topic_id', array_map('intval', $topic_ids));
639
		$this->db->sql_query($sql);
640
641
		$sql = 'SELECT topic_id
642
			FROM ' . TOPICS_TABLE . '
643
			WHERE ' . $this->db->sql_in_set('topic_moved_id', array_map('intval', $topic_ids));
644
		$result = $this->db->sql_query($sql);
645
646
		$shadow_topic_ids = array();
647
		while ($row = $this->db->sql_fetchrow($result))
648
		{
649
			$shadow_topic_ids[] = (int) $row['topic_id'];
650
		}
651
		$this->db->sql_freeresult($result);
652
653
		if (sizeof($shadow_topic_ids))
654
		{
655
			$sql = 'UPDATE ' . TOPICS_TABLE . '
656
				SET ' . $this->db->sql_build_array('UPDATE', $fields) . '
657
				WHERE ' . $this->db->sql_in_set('topic_id', array_map('intval', $shadow_topic_ids));
658
			$this->db->sql_query($sql);
659
		}
660
661
		$redirect = $this->request->variable('redirect', $this->user->data['session_page']);
662
663
		meta_refresh(3, $redirect);
664
		trigger_error($this->user->lang['QTE_TOPIC' . (sizeof($topic_ids) == 1 ? '' : 'S') . '_ATTRIBUTE_' . $message] . '<br /><br />' . sprintf($this->user->lang['RETURN_PAGE'], '<a href="' . $redirect . '">', '</a>'));
665
666
		return;
667
	}
668
669
	/**
670
	* Getter...
671
	*
672
	* @return	array
673
	*/
674
	public function getAttr()
675
	{
676
		return $this->_attr;
677
	}
678
679
	/**
680
	* Generate list of groups
681
	*
682
	* @param int	$group_ids		The default groups id to mark as selected
683
	* @param array	$exclude_ids	The group ids to exclude from the list, false (default) if you whish to exclude no id
684
	* @param int	$manage_founder If set to false (default) all groups are returned, if 0 only those groups returned not being managed by founders only, if 1 only those groups returned managed by founders only.
0 ignored issues
show
Should the type for parameter $manage_founder not be false|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
685
	*
686
	* @return string The list of options.
687
	*/
688
	public function qte_group_select($group_ids, $exclude_ids = array(), $manage_founder = false)
689
	{
690
		$exclude_sql = ($exclude_ids !== false && sizeof($exclude_ids)) ? 'WHERE ' . $this->db->sql_in_set('group_id', array_map('intval', $exclude_ids), true) : '';
691
		$sql_and = !$this->config['coppa_enable'] ? ($exclude_sql ? ' AND ' : ' WHERE ') . "group_name <> 'REGISTERED_COPPA'" : '';
692
		$sql_founder = ($manage_founder !== false) ? (($exclude_sql || $sql_and) ? ' AND ' : ' WHERE ') . 'group_founder_manage = ' . (int) $manage_founder : '';
693
694
		$sql = 'SELECT group_id, group_name, group_type
695
			FROM ' . GROUPS_TABLE . "
696
			$exclude_sql
697
			$sql_and
698
			$sql_founder
699
			ORDER BY group_type DESC, group_name ASC";
700
		$result = $this->db->sql_query($sql);
701
702
		$s_group_options = '';
703
		while ($row = $this->db->sql_fetchrow($result))
704
		{
705
			$selected = in_array($row['group_id'], $group_ids) ? ' selected="selected"' : '';
706
			$s_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '"' . $selected . '>' . (($row['group_type'] == GROUP_SPECIAL) ? $this->user->lang['G_' . $row['group_name']] : $row['group_name']) . '</option>';
707
		}
708
		$this->db->sql_freeresult($result);
709
710
		return $s_group_options;
711
	}
712
713
	/**
714
	* borrowed from "Categories Hierarchy" : used to check if a language key exists
715
	* @todo delete
716
	*/
717
	public function attr_lng_key($key)
718
	{
719
		// load language
720
		$this->user->add_lang_ext('ernadoo/qte', 'attributes');
721
722
		return isset($this->user->lang[$key]) ? $this->user->lang[$key] : $key;
723
	}
724
725
	// borrowed from "Categories Hierarchy" : used to check if a image key exists
726
	public function attr_img_key($key, $alt)
727
	{
728
		return empty($key) ? '' : (preg_match('#^[a-z0-9_-]+$#i', $key) ? $this->user->img($key, $alt) : '<img src="' . (preg_match('#^(ht|f)tp[s]?\://#i', $key) ? $key : $this->root_path . $key) . '" alt="' . $alt . '" title="' . $alt . '" />');
729
	}
730
731
	/**
732
	* Build class and style attribute
733
	*
734
	* @param	string	$a_name			Attribute name
735
	* @param	string	$a_colour		Attribute color
736
	* @return	string					html code
737
	*/
738
	public function attr_colour($a_name, $a_colour)
739
	{
740
		$a_name = preg_replace("#[^a-z0-9 _-]#", '', strtolower($a_name));
741
		if (!empty($a_name))
742
		{
743
			$a_name .= '-qte';
744
		}
745
746
		return ' class="qte-attr ' . $a_name . '"' . (!empty($a_colour) ? ' style="color:#' . $a_colour . '; font-weight:bold;"' : '');
747
	}
748
749
	/**
750
	* Check if user can apply an attribute
751
	*
752
	* @param	array	$attr_auth		Forum auth
753
	* @param	int		$forum_id		Forum id
754
	* @param	array	$user_groups	User's groups
755
	* @param	int		$author_id		Topic author id
756
	* @return	bool
757
	*/
758
	private function _check_auth_attribute($attr_auth, $forum_id, $user_groups, $author_id)
759
	{
760
		$forum_ids = $attr_auth['forums_ids'];
761
		$group_ids = $attr_auth['groups_ids'];
762
763
		if (is_array($forum_ids) && in_array($forum_id, $forum_ids))
764
		{
765
			if (is_array($group_ids) && array_intersect($group_ids, $user_groups) || ($attr_auth['author'] && ($author_id == $this->user->data['user_id']) && ($this->user->data['user_id'] != ANONYMOUS)))
766
			{
767
				return true;
768
			}
769
		}
770
	}
771
772
	/**
773
	* Check if user can delete an attribute
774
	*
775
	* @param	array	$user_groups	User's groups
776
	* @param	array	$hide_attr		Groups which can't delete attribute in a forum
777
	* @return	bool
778
	*/
779
	private function _check_auth_remove_attr(&$user_groups, $hide_attr)
780
	{
781
		// include that file !
782
		if (!function_exists('group_memberships'))
783
		{
784
			include $this->root_path . 'includes/functions_user.' . $this->php_ext;
785
		}
786
787
		// get groups membership !
788
		$user_membership = group_memberships(false, $this->user->data['user_id']);
789
790
		$user_groups = array();
791
		if (!empty($user_membership))
792
		{
793
			foreach ($user_membership as $row)
794
			{
795
				$user_groups[$row['group_id']] = (int) $row['group_id'];
796
			}
797
		}
798
799
		$groups_removed = array_intersect($user_groups, $hide_attr);
800
		if (empty($hide_attr) || (count($groups_removed) < count($user_groups)))
801
		{
802
			return true;
803
		}
804
	}
805
806
	/**
807
	* Get attributes from database
808
	*
809
	* @return	null
810
	*/
811
	private function _get_attributes()
812
	{
813
		if (($this->_attr = $this->cache->get('_attr')) === false)
814
		{
815
			$sql = 'SELECT *
816
				FROM ' . $this->table_prefix . 'topics_attr
817
				ORDER BY left_id ASC';
818
			$result = $this->db->sql_query($sql);
819
820
			$this->_attr = array();
821
			while ($row = $this->db->sql_fetchrow($result))
822
			{
823
				$this->_attr[$row['attr_id']] = array(
824
					'attr_id'			=> (int) $row['attr_id'],
825
					'attr_type'			=> (bool) $row['attr_type'],
826
					'attr_name'			=> $row['attr_name'],
827
					'attr_desc'			=> $row['attr_desc'],
828
					'attr_img'			=> $row['attr_img'],
829
					'attr_colour'		=> $row['attr_colour'],
830
					'attr_date'			=> $row['attr_date'],
831
					'attr_user_colour'	=> (bool) $row['attr_user_colour'],
832
					'attr_auths'		=> $row['attr_auths'],
833
				);
834
			}
835
			$this->db->sql_freeresult();
836
837
			$this->cache->put('_attr', $this->_attr);
838
		}
839
	}
840
}
841