Completed
Push — master ( db7709...24ebcc )
by Daniel
10:24
created

data::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 13
ccs 11
cts 11
cp 1
rs 9.4286
cc 1
eloc 10
nc 1
nop 8
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/**
3
 *
4
 * @package sitemaker
5
 * @copyright (c) 2013 Daniel A. (blitze)
6
 * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
7
 *
8
 */
9
10
namespace blitze\sitemaker\services\forum;
11
12
use phpbb\auth\auth;
13
use phpbb\config\config;
14
use phpbb\content_visibility;
15
use phpbb\db\driver\driver_interface;
16
use phpbb\user;
17
18
class data
19
{
20
	/** @var auth */
21
	protected $auth;
22
23
	/** @var config */
24
	protected $config;
25
26
	/** @var content_visibility */
27
	protected $content_visibility;
28
29
	/** @var driver_interface */
30
	protected $db;
31
32
	/** @var user */
33
	protected $user;
34
35
	/** @var string */
36
	protected $phpbb_root_path;
37
38
	/** @var string */
39
	protected $php_ext;
40
41
	/** @var array */
42
	protected $store;
43
44
	/** @var array */
45
	protected $ex_fid_ary;
46
47
	/** @var integer */
48
	protected $cache_time;
49
50
	/**
51
	 * Constructor
52
	 *
53
	 * @param auth					$auth					Auth object
54
	 * @param config				$config					Config object
55
	 * @param content_visibility	$content_visibility		Content visibility
56
	 * @param driver_interface		$db     				Database connection
57
	 * @param user					$user					User object
58
	 * @param string				$phpbb_root_path		Path to the phpbb includes directory.
59
	 * @param string				$php_ext				php file extension
60
	 * @param integer				$cache_time				Cache results for 3 hours by default
61
	 */
62 15
	public function __construct(auth $auth, config $config, content_visibility $content_visibility, driver_interface $db, user $user, $phpbb_root_path, $php_ext, $cache_time = 10800)
63
	{
64 15
		$this->auth = $auth;
65 15
		$this->config = $config;
66 15
		$this->content_visibility = $content_visibility;
67 15
		$this->db = $db;
68 15
		$this->user = $user;
69 15
		$this->phpbb_root_path = $phpbb_root_path;
70 15
		$this->php_ext = $php_ext;
71 15
		$this->cache_time = $cache_time;
72
73 15
		$this->ex_fid_ary = array_unique(array_keys($this->auth->acl_getf('!f_read', true)));
74 15
	}
75
76
	/**
77
	 * Begin query
78
	 *
79
	 * @return $this
80
	 */
81 9
	public function query()
82
	{
83 9
		$this->_reset();
84
85 9
		$this->store['sql_array'] = array(
86 9
			'SELECT'	=> array('t.*, f.*'),
87
88 9
			'FROM'		=> array(FORUMS_TABLE => 'f'),
89
90 9
			'LEFT_JOIN'	=> array(),
91
92 9
			'WHERE'		=> array(),
93
		);
94
95
		// Topics table need to be the last in the chain
96 9
		$this->store['sql_array']['FROM'][TOPICS_TABLE] = 't';
97
98 9
		return $this;
99
	}
100
101
	/**
102
	 * Fetch Forum by id(s)
103
	 *
104
	 * @param $forum_id
105
	 * @return $this
106
	 */
107 6
	public function fetch_forum($forum_id)
108
	{
109 6
		$this->_fetch($forum_id, 'f.forum_id');
110
111 6
		return $this;
112
	}
113
114
	/**
115
	 * Fetch Topic by id(s)
116
	 *
117
	 * @param mixed $topic_id	Limit by topic id: single id or array of topic ids
118
	 * @return $this
119
	 */
120
	public function fetch_topic($topic_id)
121
	{
122
		$this->_fetch($topic_id, 't.topic_id');
123
124
		return $this;
125
	}
126
127
	/**
128
	 * Fetch Topic by Poster id(s)
129
	 *
130
	 * @param mixed $user_id	User id of topic poster: single id or array of user ids
131
	 * @return $this
132
	 */
133
	public function fetch_topic_poster($user_id)
134
	{
135
		$this->_fetch($user_id, 't.topic_poster');
136
137
		return $this;
138
	}
139
140
	/**
141
	 * Fetch Post by id(s)
142
	 *
143
	 * @param mixed $post_id	Limit by post id: single id or array of post ids
144
	 * @return $this
145
	 */
146
	public function fetch_post($post_id)
147
	{
148
		$this->store['sql_array']['SELECT'][] = 'p.post_visibility, p.post_time, p.post_id';
149
		$this->store['sql_array']['FROM'][POSTS_TABLE] = 'p';
150
		$this->store['sql_array']['WHERE'][] = ((is_array($post_id)) ? $this->db->sql_in_set('p.post_id', $post_id) : 'p.post_id = ' . (int) $post_id) . ' AND t.topic_id = p.topic_id';
151
152
		return $this;
153
	}
154
155
	/**
156
	 * Fetch by Topic Type
157
	 *
158
	 * @param array $topic_type
159
	 * @return $this
160
	 */
161 6
	public function fetch_topic_type(array $topic_type)
162
	{
163 6
		if (sizeof($topic_type))
164 6
		{
165 3
			$this->store['sql_array']['WHERE'][] = $this->db->sql_in_set('t.topic_type', $topic_type);
166 3
		}
167
168 6
		if (in_array($topic_type, array(POST_STICKY, POST_ANNOUNCE)))
169 6
		{
170
			$this->store['sql_array']['WHERE'][] = '(t.topic_time_limit > 0 AND (t.topic_time + t.topic_time_limit) < ' . time() . ')';
171
		}
172
173 6
		return $this;
174
	}
175
176
	/**
177
	 * Fetch Topic Watch info
178
	 *
179
	 * @return $this
180
	 */
181
	public function fetch_watch_status()
182
	{
183
		if ($this->user->data['is_registered'])
184
		{
185
			$this->store['sql_array']['SELECT'][] = 'tw.notify_status';
186
			$this->store['sql_array']['LEFT_JOIN'][] = array(
187
				'FROM'	=> array(TOPICS_WATCH_TABLE => 'tw'),
188
				'ON'	=> 'tw.user_id = ' . $this->user->data['user_id'] . ' AND t.topic_id = tw.topic_id'
189
			);
190
191
			$this->store['sql_array']['SELECT'][] = 'fw.notify_status';
192
			$this->store['sql_array']['LEFT JOIN'][] = array(
193
				'FROM'	=> array(FORUMS_WATCH_TABLE => 'fw'),
194
				'ON'	=> '(fw.forum_id = f.forum_id AND fw.user_id = ' . $this->user->data['user_id'] . ')',
195
			);
196
		}
197
198
		return $this;
199
	}
200
201
	/**
202
	 * Fetch Topic Bookmark Info
203
	 *
204
	 * @return $this
205
	 */
206
	public function fetch_bookmark_status()
207
	{
208
		if ($this->user->data['is_registered'] && $this->config['allow_bookmarks'])
209
		{
210
			$this->store['sql_array']['SELECT'][] = 'bm.topic_id as bookmarked';
211
			$this->store['sql_array']['LEFT_JOIN'][] = array(
212
				'FROM'	=> array(BOOKMARKS_TABLE => 'bm'),
213
				'ON'	=> 'bm.user_id = ' . $this->user->data['user_id'] . ' AND t.topic_id = bm.topic_id'
214
			);
215
		}
216
217
		return $this;
218
	}
219
220
	/**
221
	 * Fetch Topic Tracking Info
222
	 *
223
	 * @param bool $track
224
	 * @return $this
225
	 */
226 4
	public function fetch_tracking_info($track = true)
227
	{
228 4
		if ($track && $this->user->data['is_registered'] && $this->config['load_db_lastread'])
229 4
		{
230 3
			$this->cache_time = 0;
231
232 3
			$this->store['sql_array']['SELECT'][] = 'tt.mark_time, ft.mark_time as forum_mark_time';
233 3
			$this->store['sql_array']['LEFT_JOIN'][] = array(
234 3
				'FROM'	=> array(TOPICS_TRACK_TABLE => 'tt'),
235 3
				'ON'	=> 'tt.user_id = ' . $this->user->data['user_id'] . ' AND t.topic_id = tt.topic_id'
236 3
			);
237
238 3
			$this->store['sql_array']['LEFT_JOIN'][] = array(
239 3
				'FROM'	=> array(FORUMS_TRACK_TABLE => 'ft'),
240 3
				'ON'	=> 'ft.user_id = ' . $this->user->data['user_id'] . ' AND t.forum_id = ft.forum_id'
241 3
			);
242 3
		}
243
244 4
		return $this;
245
	}
246
247
	/**
248
	 * Fetch by Date Range
249
	 *
250
	 * @param int $start	Unix start time
251
	 * @param int $stop		Unix stop time
252
	 * @param string $mode
253
	 * @return $this
254
	 */
255 4
	public function fetch_date_range($start, $stop, $mode = 'topic')
256
	{
257 4
		if ($start && $stop)
258 4
		{
259 1
			$this->store['sql_array']['WHERE'][] = (($mode == 'topic') ? 't.topic_time' : 'p.post_time') . " BETWEEN $start AND $stop";
260 1
		}
261
262 4
		return $this;
263
	}
264
265
	/**
266
	 * Fetch by Custom Query
267
	 *
268
	 * @param array	$sql_array		Array of elements to merge into query
269
	 * 										array(
270
	 * 											'SELECT'	=> array('p.*'),
271
	 * 											'WHERE'		=> array('p.post_id = 2'),
272
	 * 										)
273
	 * @return $this
274
	 */
275 5
	public function fetch_custom(array $sql_array)
276
	{
277 5
		$this->store['sql_array'] = array_merge_recursive($this->store['sql_array'], $sql_array);
278
279 5
		return $this;
280
	}
281
282
	/**
283
	 * Set Sorting Order
284
	 *
285
	 * @param string $sort_key		The sorting key e.g. t.topic_time
286
	 * @param string $sort_dir		Sort direction: ASC/DESC
287
	 * @return $this
288
	 */
289 9
	public function set_sorting($sort_key, $sort_dir = 'DESC')
290
	{
291 9
		$this->store['sql_array']['ORDER_BY'] = $sort_key . ' ' . $sort_dir;
292
293 9
		return $this;
294
	}
295
296
	/**
297
	 * Build the query
298
	 *
299
	 * @param bool|true $check_visibility	Should we only return data from forums the user is allowed to see?
300
	 * @param bool|true $enable_caching		Should the query be cached where possible?
301
	 * @return $this
302
	 */
303 9
	public function build($check_visibility = true, $enable_caching = true)
304
	{
305 9
		$this->_set_cache_time($enable_caching);
306 9
		$this->_set_topic_visibility($check_visibility);
307
308 9
		$this->store['sql_array']['WHERE'][] = 'f.forum_id = t.forum_id';
309 9
		$this->store['sql_array']['WHERE'][] = 't.topic_moved_id = 0';
310
311 9
		$this->store['sql_array']['SELECT'] = join(', ', array_filter($this->store['sql_array']['SELECT']));
312 9
		$this->store['sql_array']['WHERE'] = join(' AND ', array_filter($this->store['sql_array']['WHERE']));
313
314 9
		return $this;
315
	}
316
317
	/**
318
	 * Get the query array
319
	 *
320
	 * @return array	The sql array that can be used with sql_build_query
321
	 */
322
	public function get_sql_array()
323
	{
324
		return $this->store['sql_array'];
325
	}
326
327
	/**
328
	 * Get topic data
329
	 *
330
	 * @param mixed|false $limit
331
	 * @param int $start
332
	 * @return array
333
	 */
334 9
	public function get_topic_data($limit = false, $start = 0)
335
	{
336 9
		$sql = $this->db->sql_build_query('SELECT', $this->store['sql_array']);
337 9
		$result = $this->db->sql_query_limit($sql, $limit, $start, $this->cache_time);
338
339 9
		while ($row = $this->db->sql_fetchrow($result))
340
		{
341 8
			$this->store['topic'][$row['topic_id']] = $row;
342
343 8
			$this->store['tracking'][$row['forum_id']]['topic_list'][] = $row['topic_id'];
344 8
			$this->store['tracking'][$row['forum_id']]['mark_time'] =& $row['forum_mark_time'];
345 8
			$this->store['post_ids']['first'][] = $row['topic_first_post_id'];
346 8
			$this->store['post_ids']['last'][] = $row['topic_last_post_id'];
347 8
		}
348 9
		$this->db->sql_freeresult($result);
349
350 9
		return $this->store['topic'];
351
	}
352
353
	/**
354
	 * Get post data
355
	 *
356
	 * @param string $topic_first_or_last_post
357
	 * @param array $post_ids
358
	 * @param bool|false $limit
359
	 * @param int $start
360
	 * @param array $sql_array
361
	 * @return array
362
	 */
363 3
	public function get_post_data($topic_first_or_last_post = '', $post_ids = array(), $limit = false, $start = 0, $sql_array = array())
364
	{
365 3
		$sql_array = array_merge_recursive(
366
			array(
367 3
				'SELECT'	=> array('p.*'),
368 3
				'FROM'		=> array(POSTS_TABLE => 'p'),
369 3
				'WHERE'		=> $this->_get_post_data_where($post_ids, $topic_first_or_last_post),
370 3
				'ORDER_BY'	=> 'p.topic_id, p.post_time ASC',
371 3
			),
372
			$sql_array
373 3
		);
374
375 3
		$sql_array['SELECT'] = join(', ', array_filter($sql_array['SELECT']));
376 3
		$sql_array['WHERE'] = join(' AND ', array_filter($sql_array['WHERE']));
377
378 3
		$sql = $this->db->sql_build_query('SELECT', $sql_array);
379 3
		$result = $this->db->sql_query_limit($sql, $limit, $start, $this->cache_time);
380
381 3
		$post_data = array();
382 3
		while ($row = $this->db->sql_fetchrow($result))
383
		{
384 3
			$parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES;
385 3
			$row['post_text'] = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, true);
386
387 3
			$post_data[$row['topic_id']][$row['post_id']] = $row;
388 3
			$this->store['poster_ids'][] = $row['poster_id'];
389 3
			$this->store['poster_ids'][] = $row['post_edit_user'];
390 3
			$this->store['poster_ids'][] = $row['post_delete_user'];
391 3
			$this->store['attachments'][$row['post_id']] = $row['post_attachment'];
392 3
		}
393 3
		$this->db->sql_freeresult($result);
394
395 3
		return $post_data;
396
	}
397
398
	/**
399
	 * Get attachments...
400
	 *
401
	 * @param int $forum_id
402
	 * @return array
403
	 */
404
	public function get_attachments($forum_id)
405
	{
406
		$this->store['attachments'] = array_flip(array_filter($this->store['attachments']));
407
408
		$attachments = array();
409
		if ($this->_attachments_allowed($forum_id))
410
		{
411
			$sql = 'SELECT *
412
				FROM ' . ATTACHMENTS_TABLE . '
413
				WHERE ' . $this->db->sql_in_set('post_msg_id', $this->store['attachments']) . '
414
					AND in_message = 0
415
				ORDER BY filetime DESC, post_msg_id ASC';
416
			$result = $this->db->sql_query($sql);
417
418
			while ($row = $this->db->sql_fetchrow($result))
419
			{
420
				$attachments[$row['post_msg_id']][] = $row;
421
			}
422
			$this->db->sql_freeresult($result);
423
		}
424
		$this->store['attachments'] = array();
425
426
		return $attachments;
427
	}
428
429
	/**
430
	 * Get topic tracking info
431
	 *
432
	 * @param int $forum_id
433
	 * @return array
434
	 */
435 4
	public function get_topic_tracking_info($forum_id = 0)
436
	{
437 4
		if (!sizeof($this->store['tracking']))
438 4
		{
439
			return array();
440
		}
441
442 4
		$tracking_info = $this->_get_tracking_info();
443
444 4
		return ($forum_id) ? (isset($tracking_info[$forum_id]) ? $tracking_info[$forum_id] : array()) : $tracking_info;
445
	}
446
447
	/**
448
	 * Returns an array of topic first post or last post ids
449
	 *
450
	 * @return array
451
	 */
452
	public function get_posters_info()
453
	{
454
		$this->store['poster_ids'] = array_filter(array_unique($this->store['poster_ids']));
455
456
		$sql = 'SELECT *
457
			FROM ' . USERS_TABLE . '
458
			WHERE ' . $this->db->sql_in_set('user_id', $this->store['poster_ids']);
459
		$result = $this->db->sql_query($sql);
460
461
		$poster = array();
462
		while ($row = $this->db->sql_fetchrow($result))
463
		{
464
			$poster[$row['user_id']] = $row;
465
		}
466
		$this->db->sql_freeresult($result);
467
468
		return $poster;
469
	}
470
471
	/**
472
	 * Returns an array of topic first post or last post ids
473
	 *
474
	 * @param string $first_or_last_post
475
	 * @return array
476
	 */
477 3
	public function get_topic_post_ids($first_or_last_post = 'first')
478
	{
479 3
		return (isset($this->store['post_ids'][$first_or_last_post])) ? $this->store['post_ids'][$first_or_last_post] : array();
480
	}
481
482
	/**
483
	 * Reset data
484
	 */
485 9
	private function _reset()
486
	{
487 9
		$this->store = array(
488 9
			'attachments'	=> array(),
489 9
			'post_ids'		=> array(),
490 9
			'poster_ids'	=> array(),
491 9
			'sql_array'		=> array(),
492 9
			'topic'			=> array(),
493 9
			'tracking'		=> array(),
494
		);
495 9
	}
496
497
	/**
498
	 * @param int $column_id
499
	 * @param string $column
500
	 */
501 6
	private function _fetch($column_id, $column)
502
	{
503 6
		if (!empty($column_id))
504 6
		{
505 1
			$this->store['sql_array']['WHERE'][] = (is_array($column_id)) ? $this->db->sql_in_set($column, $column_id) : $column . ' = ' . (int) $column_id;
506 1
		}
507 6
	}
508
509
	/**
510
	 * @param bool $enable_caching
511
	 */
512 9
	protected function _set_cache_time($enable_caching)
513
	{
514 9
		if ($enable_caching === false)
515 9
		{
516 3
			$this->cache_time = 0;
517 3
		}
518 9
	}
519
520
	/**
521
	 * @param bool $check_visibility
522
	 */
523 9
	private function _set_topic_visibility($check_visibility)
524
	{
525
		if ($check_visibility)
526 9
		{
527 9
			$this->store['sql_array']['WHERE'][] = 't.topic_time <= ' . time();
528 9
			$this->store['sql_array']['WHERE'][] = $this->content_visibility->get_global_visibility_sql('topic', $this->ex_fid_ary, 't.');
529 9
		}
530 9
	}
531
532
	/**
533
	 * @param array $post_ids
534
	 * @param string $topic_first_or_last_post
535
	 * @return array
536
	 */
537 3
	private function _get_post_data_where(array $post_ids, $topic_first_or_last_post)
538
	{
539 3
		$sql_where = array();
540 3
		if (sizeof($this->store['topic']))
541 3
		{
542 3
			$sql_where[] = $this->db->sql_in_set('topic_id', array_keys($this->store['topic']));
543
544
			if ($topic_first_or_last_post)
545 3
			{
546 3
				$post_ids = array_merge($post_ids, $this->get_topic_post_ids($topic_first_or_last_post));
547 3
				$sql_where[] = $this->db->sql_in_set('post_id', $post_ids);
548 3
			}
549 3
		}
550
551 3
		$sql_where[] = $this->content_visibility->get_global_visibility_sql('post', $this->ex_fid_ary, 'p.');
552
553 3
		return $sql_where;
554
	}
555
556
	/**
557
	 * @return array
558
	 */
559 4
	private function _get_tracking_info()
560
	{
561 4
		$info = array();
562 4
		if ($this->_can_track_by_lastread())
563 4
		{
564 4
			$info = $this->_build_tracking_info('get_topic_tracking');
565 4
		}
566
		else if ($this->_can_track_anonymous())
567
		{
568
			$info = $this->_build_tracking_info('get_complete_topic_tracking');
569
		}
570
571 4
		return $info;
572
	}
573
574
	/**
575
	 * @param string $function
576
	 * @return array
577
	 */
578 4
	private function _build_tracking_info($function)
579
	{
580 4
		$tracking_info = array();
581 4
		foreach ($this->store['tracking'] as $fid => $forum)
582
		{
583 4
			$tracking_info[$fid] = call_user_func_array($function, array($fid, $forum['topic_list'], &$this->store['topic'], array($fid => $forum['mark_time'])));
584 4
		}
585
586 4
		return $tracking_info;
587
	}
588
589
	/**
590
	 * @return bool
591
	 */
592 4
	private function _can_track_by_lastread()
593
	{
594 4
		return ($this->config['load_db_lastread'] && $this->user->data['is_registered']) ? true : false;
595
	}
596
597
	/**
598
	 * @return bool
599
	 */
600
	private function _can_track_anonymous()
601
	{
602
		return ($this->config['load_anon_lastread'] || $this->user->data['is_registered']) ? true : false;
603
	}
604
605
	/**
606
	 * @param int $forum_id
607
	 * @return bool
608
	 */
609
	private function _attachments_allowed($forum_id)
610
	{
611
		return (sizeof($this->store['attachments']) && $this->auth->acl_get('u_download') && $this->auth->acl_get('f_download', $forum_id)) ? true : false;
612
	}
613
}
614