Completed
Push — develop ( fd19b8...660ae6 )
by Daniel
11:13
created

query_builder::time()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
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 31
	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 31
		$this->auth = $auth;
51 31
		$this->config = $config;
52 31
		$this->content_visibility = $content_visibility;
53 31
		$this->db = $db;
54 31
		$this->user = $user;
55 31
		$this->cache_time = $cache_time;
56
57 31
		$this->ex_fid_ary = array_unique(array_keys($this->auth->acl_getf('!f_read', true)));
58 31
	}
59
60
	/**
61
	 * Begin query
62
	 *
63
	 * @param bool $track_topics
64
	 * @param bool $get_forum_data
65
	 * @return $this
66
	 */
67 22
	public function query($track_topics = true, $get_forum_data = true)
68
	{
69 22
		$this->_reset();
70
71 22
		$this->store['sql_array'] = array_fill_keys(array('SELECT', 'FROM', 'LEFT_JOIN', 'WHERE'), array());
72
73
		if ($get_forum_data)
74 22
		{
75 21
			$this->store['sql_array']['SELECT'][] = 'f.*';
76 21
			$this->store['sql_array']['FROM'][FORUMS_TABLE] = 'f';
77 21
		}
78
79 22
		$this->store['sql_array']['SELECT'][] = 't.*';
80
81
		if ($track_topics)
82 22
		{
83 7
			$this->fetch_tracking_info();
84 7
		}
85
86 22
		return $this;
87
	}
88
89
	/**
90
	 * Fetch Forum by id(s)
91
	 *
92
	 * @param int|array $forum_id
93
	 * @return $this
94
	 */
95 17
	public function fetch_forum($forum_id)
96
	{
97 17
		$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 17
		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 11
	public function fetch_topic($topic_id)
109
	{
110 11
		$this->_fetch($topic_id, 't.topic_id');
111
112 11
		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 3
	public function fetch_topic_poster($user_id)
122
	{
123 3
		$this->_fetch($user_id, 't.topic_poster');
124
125 3
		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
	public function fetch_watch_status($type = 'topic')
151
	{
152
		if ($this->user->data['is_registered'])
153
		{
154
			$keys = array(
155
				'forum'	=> array(
156
					'table'	=> FORUMS_WATCH_TABLE,
157
					'cond'	=> 'ws.forum_id = f.forum_id',
158
				),
159
				'topic'	=> array(
160
					'table'	=> TOPICS_WATCH_TABLE,
161
					'cond'	=> 'ws.topic_id = t.topic_id',
162
				),
163
			);
164
165
			$this->store['sql_array']['SELECT'][] = 'ws.notify_status';
166
			$this->store['sql_array']['LEFT_JOIN'][] = array(
167
				'FROM'	=> array($keys[$type]['table'] => 'ws'),
168
				'ON'	=> $keys[$type]['cond'] . ' AND ws.user_id = ' . (int) $this->user->data['user_id'],
169
			);
170
		}
171
172
		return $this;
173
	}
174
175
	/**
176
	 * Fetch Topic Bookmark Info
177
	 *
178
	 * @return $this
179
	 */
180
	public function fetch_bookmark_status()
181
	{
182
		if ($this->user->data['is_registered'] && $this->config['allow_bookmarks'])
183
		{
184
			$this->store['sql_array']['SELECT'][] = 'bm.topic_id as bookmarked';
185
			$this->store['sql_array']['LEFT_JOIN'][] = array(
186
				'FROM'	=> array(BOOKMARKS_TABLE => 'bm'),
187
				'ON'	=> 'bm.user_id = ' . (int) $this->user->data['user_id'] . ' AND t.topic_id = bm.topic_id'
188
			);
189
		}
190
191
		return $this;
192
	}
193
194
	/**
195
	 * Fetch Topic Tracking Info
196
	 *
197
	 * @return $this
198
	 */
199 7
	public function fetch_tracking_info()
200
	{
201 7
		if ($this->user->data['is_registered'] && $this->config['load_db_lastread'])
202 7
		{
203 6
			$this->cache_time = 0;
204
205 6
			$this->store['sql_array']['SELECT'][] = 'tt.mark_time, ft.mark_time as forum_mark_time';
206 6
			$this->store['sql_array']['LEFT_JOIN'][] = array(
207 6
				'FROM'	=> array(TOPICS_TRACK_TABLE => 'tt'),
208 6
				'ON'	=> 'tt.user_id = ' . (int) $this->user->data['user_id'] . ' AND t.topic_id = tt.topic_id'
209 6
			);
210
211 6
			$this->store['sql_array']['LEFT_JOIN'][] = array(
212 6
				'FROM'	=> array(FORUMS_TRACK_TABLE => 'ft'),
213 6
				'ON'	=> 'ft.user_id = ' . (int) $this->user->data['user_id'] . ' AND t.forum_id = ft.forum_id'
214 6
			);
215 6
		}
216
217 7
		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 8
	public function fetch_custom(array $sql_array, $overwrite_keys = array())
251
	{
252 8
		$this->store['sql_array'] = array_merge_recursive($this->store['sql_array'], $sql_array);
253
254 8
		foreach ($overwrite_keys as $key)
255
		{
256
			$this->store['sql_array'][$key] = $sql_array[$key];
257 8
		}
258
259 8
		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 22
	public function build($check_visibility = true, $enable_caching = true, $exclude_hidden_forums = true)
285
	{
286 22
		$this->_set_cache_time($enable_caching);
287 22
		$this->_set_topic_visibility($check_visibility);
288 22
		$this->_set_forum_table($exclude_hidden_forums);
289
290
		// Topics table need to be the last in the chain
291 22
		$this->store['sql_array']['FROM'][TOPICS_TABLE] = 't';
292 22
		$this->store['sql_array']['WHERE'][] = 't.topic_moved_id = 0';
293
294 22
		$this->store['sql_array']['SELECT'] = join(', ', array_filter($this->store['sql_array']['SELECT']));
295 22
		$this->store['sql_array']['WHERE'] = join(' AND ', array_filter($this->store['sql_array']['WHERE']));
296
297 22
		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 8
	public function get_sql_array()
306
	{
307 8
		return $this->store['sql_array'];
308
	}
309
310
	/**
311
	 * @return int
312
	 */
313
	public function time()
314 22
	{
315
		return time();
316 22
	}
317 22
318 5
	/**
319 5
	 * @param bool $enable_caching
320 22
	 * @return void
321
	 */
322
	protected function _set_cache_time($enable_caching)
323
	{
324
		if ($enable_caching === false)
325
		{
326
			$this->cache_time = 0;
327 17
		}
328
	}
329 17
330 17
	/**
331 11
	 * @param int $column_id
332 11
	 * @param string $column
333 17
	 * @return void
334
	 */
335
	private function _fetch($column_id, $column)
336
	{
337
		if (!empty($column_id))
338
		{
339 22
			$this->store['sql_array']['WHERE'][] = (is_array($column_id)) ? $this->db->sql_in_set($column, $column_id) : $column . ' = ' . (int) $column_id;
340
		}
341
	}
342 22
343 22
	/**
344 22
	 * @param bool $check_visibility
345 22
	 * @return void
346 22
	 */
347
	private function _set_topic_visibility($check_visibility)
348
	{
349
		if ($check_visibility)
350
		{
351
			$this->store['sql_array']['WHERE'][] = 't.topic_time <= ' . $this->time();
352 22
			$this->store['sql_array']['WHERE'][] = $this->content_visibility->get_global_visibility_sql('topic', $this->ex_fid_ary, 't.');
353
		}
354
	}
355 22
356 11
	/**
357 11
	 * @param bool $exclude_hidden_forums
358 11
	 * @return void
359
	 */
360 22
	private function _set_forum_table($exclude_hidden_forums)
361 22
	{
362 22
		if ($exclude_hidden_forums)
363 22
		{
364 22
			$this->store['sql_array']['FROM'][FORUMS_TABLE] = 'f';
365
			$this->store['sql_array']['WHERE'][] = 'f.hidden_forum = 0';
366
		}
367
368
		if (isset($this->store['sql_array']['FROM'][FORUMS_TABLE]))
369
		{
370 22
			$this->store['sql_array']['WHERE'][] = 'f.forum_id = t.forum_id';
371
		}
372 22
	}
373 22
374 22
	/**
375 22
	 * Reset data
376 22
	 * @return void
377 22
	 */
378 22
	private function _reset()
379
	{
380 22
		$this->store = array(
381
			'attachments'	=> array(),
382
			'post_ids'		=> array(),
383
			'poster_ids'	=> array(),
384
			'sql_array'		=> array(),
385
			'topic'			=> array(),
386
			'tracking'		=> array(),
387
		);
388
	}
389
}
390