Completed
Push — develop ( 660ae6...f77be0 )
by Daniel
08:50
created

query_builder::fetch_topic_poster()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
ccs 3
cts 3
cp 1
cc 1
eloc 3
nc 1
nop 1
crap 1
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
class query_builder
13
{
14
	/** @var \phpbb\auth\auth */
15
	protected $auth;
16
17
	/** @var \phpbb\config\config */
18
	protected $config;
19
20
	/** @var \phpbb\content_visibility */
21
	protected $content_visibility;
22
23
	/** @var \phpbb\db\driver\driver_interface */
24
	protected $db;
25
26
	/** @var \phpbb\user */
27
	protected $user;
28
29
	/** @var array */
30
	protected $store;
31
32
	/** @var array */
33
	protected $ex_fid_ary;
34
35
	/** @var integer */
36
	protected $cache_time;
37
38
	/**
39
	 * Constructor
40
	 *
41
	 * @param \phpbb\auth\auth					$auth					Auth object
42
	 * @param \phpbb\config\config				$config					Config object
43
	 * @param \phpbb\content_visibility			$content_visibility		Content visibility
44
	 * @param \phpbb\db\driver\driver_interface	$db     				Database connection
45
	 * @param \phpbb\user						$user					User object
46
	 * @param integer							$cache_time				Cache results for 3 hours by default
47
	 */
48 42
	public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\content_visibility $content_visibility, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $cache_time)
49
	{
50 42
		$this->auth = $auth;
51 42
		$this->config = $config;
52 42
		$this->content_visibility = $content_visibility;
53 42
		$this->db = $db;
54 42
		$this->user = $user;
55 42
		$this->cache_time = $cache_time;
56
57 42
		$this->ex_fid_ary = array_unique(array_keys($this->auth->acl_getf('!f_read', true)));
58 42
	}
59
60
	/**
61
	 * Begin query
62
	 *
63
	 * @param bool $track_topics
64
	 * @param bool $get_forum_data
65
	 * @return $this
66
	 */
67 33
	public function query($track_topics = true, $get_forum_data = true)
68
	{
69 33
		$this->_reset();
70
71 33
		$this->store['sql_array'] = array_fill_keys(array('SELECT', 'FROM', 'LEFT_JOIN', 'WHERE'), array());
72
73
		if ($get_forum_data)
74 33
		{
75 23
			$this->store['sql_array']['SELECT'][] = 'f.*';
76 23
			$this->store['sql_array']['FROM'][FORUMS_TABLE] = 'f';
77 23
		}
78
79 33
		$this->store['sql_array']['SELECT'][] = 't.*';
80
81
		if ($track_topics)
82 33
		{
83 9
			$this->fetch_tracking_info();
84 9
		}
85
86 33
		return $this;
87
	}
88
89
	/**
90
	 * Fetch Forum by id(s)
91
	 *
92
	 * @param int|array $forum_id
93
	 * @return $this
94
	 */
95 21
	public function fetch_forum($forum_id)
96
	{
97 21
		$this->_fetch($forum_id, (isset($this->store['sql_array']['FROM'][FORUMS_TABLE])) ? 'f.forum_id' : 't.forum_Id');
0 ignored issues
show
Bug introduced by
It seems like $forum_id defined by parameter $forum_id on line 95 can also be of type array; however, blitze\sitemaker\service...query_builder::_fetch() does only seem to accept integer, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
98
99 21
		return $this;
100
	}
101
102
	/**
103
	 * Fetch Topic by id(s)
104
	 *
105
	 * @param mixed $topic_id	Limit by topic id: single id or array of topic ids
106
	 * @return $this
107
	 */
108 15
	public function fetch_topic($topic_id)
109
	{
110 15
		$this->_fetch($topic_id, 't.topic_id');
111
112 15
		return $this;
113
	}
114
115
	/**
116
	 * Fetch Topic by Poster id(s)
117
	 *
118
	 * @param mixed $user_id	User id of topic poster: single id or array of user ids
119
	 * @return $this
120
	 */
121 7
	public function fetch_topic_poster($user_id)
122
	{
123 7
		$this->_fetch($user_id, 't.topic_poster');
124
125 7
		return $this;
126
	}
127
128
	/**
129
	 * Fetch by Topic Type
130
	 *
131
	 * @param array $topic_type
132
	 * @return $this
133
	 */
134 17
	public function fetch_topic_type(array $topic_type)
135
	{
136 17
		if (sizeof($topic_type))
137 17
		{
138 5
			$this->store['sql_array']['WHERE'][] = $this->db->sql_in_set('t.topic_type', $topic_type);
139 5
		}
140
141 17
		return $this;
142
	}
143
144
	/**
145
	 * Fetch Topic Watch info
146
	 *
147
	 * @param $type
148
	 * @return $this
149
	 */
150 2
	public function fetch_watch_status($type = 'topic')
151
	{
152 2
		if ($this->user->data['is_registered'])
153 2
		{
154
			$keys = array(
155
				'forum'	=> array(
156 1
					'table'	=> FORUMS_WATCH_TABLE,
157 1
					'cond'	=> 'ws.forum_id = f.forum_id',
158 1
				),
159
				'topic'	=> array(
160 1
					'table'	=> TOPICS_WATCH_TABLE,
161 1
					'cond'	=> 'ws.topic_id = t.topic_id',
162 1
				),
163 1
			);
164
165 1
			$this->store['sql_array']['SELECT'][] = 'ws.notify_status';
166 1
			$this->store['sql_array']['LEFT_JOIN'][] = array(
167 1
				'FROM'	=> array($keys[$type]['table'] => 'ws'),
168 1
				'ON'	=> $keys[$type]['cond'] . ' AND ws.user_id = ' . (int) $this->user->data['user_id'],
169
			);
170 1
		}
171
172 2
		return $this;
173
	}
174
175
	/**
176
	 * Fetch Topic Bookmark Info
177
	 *
178
	 * @return $this
179
	 */
180 2
	public function fetch_bookmark_status()
181
	{
182 2
		if ($this->user->data['is_registered'] && $this->config['allow_bookmarks'])
183 2
		{
184 1
			$this->store['sql_array']['SELECT'][] = 'bm.topic_id as bookmarked';
185 1
			$this->store['sql_array']['LEFT_JOIN'][] = array(
186 1
				'FROM'	=> array(BOOKMARKS_TABLE => 'bm'),
187 1
				'ON'	=> 'bm.user_id = ' . (int) $this->user->data['user_id'] . ' AND t.topic_id = bm.topic_id'
188 1
			);
189 1
		}
190
191 2
		return $this;
192
	}
193
194
	/**
195
	 * Fetch Topic Tracking Info
196
	 *
197
	 * @return $this
198
	 */
199 9
	public function fetch_tracking_info()
200
	{
201 9
		if ($this->user->data['is_registered'] && $this->config['load_db_lastread'])
202 9
		{
203 8
			$this->cache_time = 0;
204
205 8
			$this->store['sql_array']['SELECT'][] = 'tt.mark_time, ft.mark_time as forum_mark_time';
206 8
			$this->store['sql_array']['LEFT_JOIN'][] = array(
207 8
				'FROM'	=> array(TOPICS_TRACK_TABLE => 'tt'),
208 8
				'ON'	=> 'tt.user_id = ' . (int) $this->user->data['user_id'] . ' AND t.topic_id = tt.topic_id'
209 8
			);
210
211 8
			$this->store['sql_array']['LEFT_JOIN'][] = array(
212 8
				'FROM'	=> array(FORUMS_TRACK_TABLE => 'ft'),
213 8
				'ON'	=> 'ft.user_id = ' . (int) $this->user->data['user_id'] . ' AND t.forum_id = ft.forum_id'
214 8
			);
215 8
		}
216
217 9
		return $this;
218
	}
219
220
	/**
221
	 * Fetch by Date Range
222
	 *
223
	 * @param int $unix_start_time
224
	 * @param int $unix_stop_time
225
	 * @param string $mode topic|post
226
	 * @return $this
227
	 */
228 14
	public function fetch_date_range($unix_start_time, $unix_stop_time, $mode = 'topic')
229
	{
230 14
		if ($unix_start_time && $unix_stop_time)
231 14
		{
232 2
			$this->store['sql_array']['WHERE'][] = (($mode == 'topic') ? 't.topic_time' : 'p.post_time') . " BETWEEN $unix_start_time AND $unix_stop_time";
233 2
		}
234
235 14
		return $this;
236
	}
237
238
	/**
239
	 * Fetch by Custom Query
240
	 *
241
	 * @param array	$sql_array			Array of elements to merge into query
242
	 * 										array(
243
	 * 											'SELECT'	=> array('p.*'),
244
	 * 											'WHERE'		=> array('p.post_id = 2'),
245
	 * 										)
246
	 * @param array $overwrite_keys		Array of query keys to overwrite with yours instead of merging
247
	 *									e.g array('SELECT') will overwrite the 'SELECT' key with whatever is provided in $sql_array
248
	 * @return $this
249
	 */
250 11
	public function fetch_custom(array $sql_array, $overwrite_keys = array())
251
	{
252 11
		$this->store['sql_array'] = array_merge_recursive($this->store['sql_array'], $sql_array);
253
254 11
		foreach ($overwrite_keys as $key)
255
		{
256 1
			$this->store['sql_array'][$key] = $sql_array[$key];
257 11
		}
258
259 11
		return $this;
260
	}
261
262
	/**
263
	 * Set Sorting Order
264
	 *
265
	 * @param string $sort_key		The sorting key e.g. t.topic_time
266
	 * @param string $sort_dir		Sort direction: ASC/DESC
267
	 * @return $this
268
	 */
269 13
	public function set_sorting($sort_key, $sort_dir = 'DESC')
270
	{
271 13
		$this->store['sql_array']['ORDER_BY'] = $sort_key . ' ' . $sort_dir;
272
273 13
		return $this;
274
	}
275
276
	/**
277
	 * Build the query
278
	 *
279
	 * @param bool|true $check_visibility		Should we only return data from forums the user is allowed to see?
280
	 * @param bool|true $enable_caching			Should the query be cached where possible?
281
	 * @param bool|true $exclude_hidden_forums	Leave out hidden forums?
282
	 * @return $this
283
	 */
284 33
	public function build($check_visibility = true, $enable_caching = true, $exclude_hidden_forums = true)
285
	{
286 33
		$this->_set_cache_time($enable_caching);
287 33
		$this->_set_topic_visibility($check_visibility);
288 33
		$this->_set_forum_table($exclude_hidden_forums);
289
290
		// Topics table need to be the last in the chain
291 33
		$this->store['sql_array']['FROM'][TOPICS_TABLE] = 't';
292 33
		$this->store['sql_array']['WHERE'][] = 't.topic_moved_id = 0';
293
294 33
		$this->store['sql_array']['SELECT'] = join(', ', array_filter($this->store['sql_array']['SELECT']));
295 33
		$this->store['sql_array']['WHERE'] = join(' AND ', array_filter($this->store['sql_array']['WHERE']));
296
297 33
		return $this;
298
	}
299
300
	/**
301
	 * Get the query array
302
	 *
303
	 * @return array	The sql array that can be used with sql_build_query
304
	 */
305 19
	public function get_sql_array()
306
	{
307 19
		return $this->store['sql_array'];
308
	}
309
310
	/**
311
	 * @return int
312
	 */
313 22
	public function time()
314
	{
315 22
		return time();
316
	}
317
318
	/**
319
	 * @param bool $enable_caching
320
	 * @return void
321
	 */
322 33
	protected function _set_cache_time($enable_caching)
323
	{
324 33
		if ($enable_caching === false)
325 33
		{
326 5
			$this->cache_time = 0;
327 5
		}
328 33
	}
329
330
	/**
331
	 * @param int $column_id
332
	 * @param string $column
333
	 * @return void
334
	 */
335 21
	private function _fetch($column_id, $column)
336
	{
337 21
		if (!empty($column_id))
338 21
		{
339 12
			$this->store['sql_array']['WHERE'][] = (is_array($column_id)) ? $this->db->sql_in_set($column, $column_id) : $column . ' = ' . (int) $column_id;
340 12
		}
341 21
	}
342
343
	/**
344
	 * @param bool $check_visibility
345
	 * @return void
346
	 */
347 33
	private function _set_topic_visibility($check_visibility)
348
	{
349
		if ($check_visibility)
350 33
		{
351 33
			$this->store['sql_array']['WHERE'][] = 't.topic_time <= ' . $this->time();
352 33
			$this->store['sql_array']['WHERE'][] = $this->content_visibility->get_global_visibility_sql('topic', $this->ex_fid_ary, 't.');
353 33
		}
354 33
	}
355
356
	/**
357
	 * @param bool $exclude_hidden_forums
358
	 * @return void
359
	 */
360 33
	private function _set_forum_table($exclude_hidden_forums)
361
	{
362
		if ($exclude_hidden_forums)
363 33
		{
364 22
			$this->store['sql_array']['FROM'][FORUMS_TABLE] = 'f';
365 22
			$this->store['sql_array']['WHERE'][] = 'f.hidden_forum = 0';
366 22
		}
367
368 33
		if (isset($this->store['sql_array']['FROM'][FORUMS_TABLE]))
369 33
		{
370 33
			$this->store['sql_array']['WHERE'][] = 'f.forum_id = t.forum_id';
371 33
		}
372 33
	}
373
374
	/**
375
	 * Reset data
376
	 * @return void
377
	 */
378 33
	private function _reset()
379
	{
380 33
		$this->store = array(
381 33
			'attachments'	=> array(),
382 33
			'post_ids'		=> array(),
383 33
			'poster_ids'	=> array(),
384 33
			'sql_array'		=> array(),
385 33
			'topic'			=> array(),
386 33
			'tracking'		=> array(),
387
		);
388 33
	}
389
}
390