Completed
Push — develop ( b18c7a...273208 )
by Daniel
11:54 queued 09:05
created

query_builder   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 346
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 98.13%

Importance

Changes 8
Bugs 1 Features 0
Metric Value
wmc 29
c 8
b 1
f 0
lcom 1
cbo 0
dl 0
loc 346
ccs 105
cts 107
cp 0.9813
rs 10

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A _set_cache_time() 0 7 2
B query() 0 24 2
A fetch_forum() 0 6 1
A fetch_topic() 0 6 1
A fetch_topic_poster() 0 6 1
A fetch_topic_type() 0 14 3
A fetch_tracking_info() 0 20 3
A fetch_custom() 0 6 1
A set_sorting() 0 6 1
A get_sql_array() 0 4 1
A _fetch() 0 7 3
A _set_topic_visibility() 0 8 2
A _reset() 0 11 1
A fetch_date_range() 0 9 4
A build() 0 18 2
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 29
	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 = 10800)
49
	{
50 29
		$this->auth = $auth;
51 29
		$this->config = $config;
52 29
		$this->content_visibility = $content_visibility;
53 29
		$this->db = $db;
54 29
		$this->user = $user;
55 29
		$this->cache_time = $cache_time;
56
57 29
		$this->ex_fid_ary = array_unique(array_keys($this->auth->acl_getf('!f_read', true)));
58 29
	}
59
60
	/**
61
	 * Begin query
62
	 *
63
	 * @param bool $track_topics
64
	 * @return $this
65
	 */
66 20
	public function query($track_topics = true)
67
	{
68 20
		$this->_reset();
69
70 20
		$this->store['sql_array'] = array(
71 20
			'SELECT'	=> array('t.*, f.*'),
72
73 20
			'FROM'		=> array(FORUMS_TABLE => 'f'),
74
75 20
			'LEFT_JOIN'	=> array(),
76
77 20
			'WHERE'		=> array(),
78
		);
79
80
		// Topics table need to be the last in the chain
81 20
		$this->store['sql_array']['FROM'][TOPICS_TABLE] = 't';
82
83
		if ($track_topics)
84 20
		{
85 16
			$this->fetch_tracking_info();
86 16
		}
87
88 20
		return $this;
89
	}
90
91
	/**
92
	 * Fetch Forum by id(s)
93
	 *
94
	 * @param $forum_id
95
	 * @return $this
96
	 */
97 15
	public function fetch_forum($forum_id)
98
	{
99 15
		$this->_fetch($forum_id, 'f.forum_id');
100
101 15
		return $this;
102
	}
103
104
	/**
105
	 * Fetch Topic by id(s)
106
	 *
107
	 * @param mixed $topic_id	Limit by topic id: single id or array of topic ids
108
	 * @return $this
109
	 */
110 3
	public function fetch_topic($topic_id)
111
	{
112 3
		$this->_fetch($topic_id, 't.topic_id');
113
114 3
		return $this;
115
	}
116
117
	/**
118
	 * Fetch Topic by Poster id(s)
119
	 *
120
	 * @param mixed $user_id	User id of topic poster: single id or array of user ids
121
	 * @return $this
122
	 */
123 3
	public function fetch_topic_poster($user_id)
124
	{
125 3
		$this->_fetch($user_id, 't.topic_poster');
126
127 3
		return $this;
128
	}
129
130
	/**
131
	 * Fetch by Topic Type
132
	 *
133
	 * @param array $topic_type
134
	 * @return $this
135
	 */
136 15
	public function fetch_topic_type(array $topic_type)
137
	{
138 15
		if (sizeof($topic_type))
139 15
		{
140 4
			$this->store['sql_array']['WHERE'][] = $this->db->sql_in_set('t.topic_type', $topic_type);
141 4
		}
142
143 15
		if (in_array($topic_type, array(POST_STICKY, POST_ANNOUNCE)))
144 15
		{
145
			$this->store['sql_array']['WHERE'][] = '(t.topic_time_limit > 0 AND (t.topic_time + t.topic_time_limit) < ' . time() . ')';
146
		}
147
148 15
		return $this;
149
	}
150
151
	/**
152
	 * Fetch Topic Watch info
153
	 *
154
	 * @return $this
155
	 *
156
	public function fetch_watch_status()
157
	{
158
		if ($this->user->data['is_registered'])
159
		{
160
			$this->store['sql_array']['SELECT'][] = 'tw.notify_status';
161
			$this->store['sql_array']['LEFT_JOIN'][] = array(
162
				'FROM'	=> array(TOPICS_WATCH_TABLE => 'tw'),
163
				'ON'	=> 'tw.user_id = ' . $this->user->data['user_id'] . ' AND t.topic_id = tw.topic_id'
164
			);
165
166
			$this->store['sql_array']['SELECT'][] = 'fw.notify_status';
167
			$this->store['sql_array']['LEFT JOIN'][] = array(
168
				'FROM'	=> array(FORUMS_WATCH_TABLE => 'fw'),
169
				'ON'	=> '(fw.forum_id = f.forum_id AND fw.user_id = ' . $this->user->data['user_id'] . ')',
170
			);
171
		}
172
173
		return $this;
174
	}
175
176
	/**
177
	 * Fetch Topic Bookmark Info
178
	 *
179
	 * @return $this
180
	 *
181
	public function fetch_bookmark_status()
182
	{
183
		if ($this->user->data['is_registered'] && $this->config['allow_bookmarks'])
184
		{
185
			$this->store['sql_array']['SELECT'][] = 'bm.topic_id as bookmarked';
186
			$this->store['sql_array']['LEFT_JOIN'][] = array(
187
				'FROM'	=> array(BOOKMARKS_TABLE => 'bm'),
188
				'ON'	=> 'bm.user_id = ' . $this->user->data['user_id'] . ' AND t.topic_id = bm.topic_id'
189
			);
190
		}
191
192
		return $this;
193
	}
194
	*/
195
196
	/**
197
	 * Fetch Topic Tracking Info
198
	 *
199
	 * @return $this
200
	 */
201 16
	public function fetch_tracking_info()
202
	{
203 16
		if ($this->user->data['is_registered'] && $this->config['load_db_lastread'])
204 16
		{
205 5
			$this->cache_time = 0;
206
207 5
			$this->store['sql_array']['SELECT'][] = 'tt.mark_time, ft.mark_time as forum_mark_time';
208 5
			$this->store['sql_array']['LEFT_JOIN'][] = array(
209 5
				'FROM'	=> array(TOPICS_TRACK_TABLE => 'tt'),
210 5
				'ON'	=> 'tt.user_id = ' . $this->user->data['user_id'] . ' AND t.topic_id = tt.topic_id'
211 5
			);
212
213 5
			$this->store['sql_array']['LEFT_JOIN'][] = array(
214 5
				'FROM'	=> array(FORUMS_TRACK_TABLE => 'ft'),
215 5
				'ON'	=> 'ft.user_id = ' . $this->user->data['user_id'] . ' AND t.forum_id = ft.forum_id'
216 5
			);
217 5
		}
218
219 16
		return $this;
220
	}
221
222
	/**
223
	 * Fetch by Date Range
224
	 *
225
	 * @param int $unix_start_time
226
	 * @param int $unix_stop_time
227
	 * @param string $mode
228
	 * @return $this
229
	 */
230 12
	public function fetch_date_range($unix_start_time, $unix_stop_time, $mode = 'topic')
231
	{
232 12
		if ($unix_start_time && $unix_stop_time)
233 12
		{
234 2
			$this->store['sql_array']['WHERE'][] = (($mode == 'topic') ? 't.topic_time' : 'p.post_time') . " BETWEEN $unix_start_time AND $unix_stop_time";
235 2
		}
236
237 12
		return $this;
238
	}
239
240
	/**
241
	 * Fetch by Custom Query
242
	 *
243
	 * @param array	$sql_array		Array of elements to merge into query
244
	 * 										array(
245
	 * 											'SELECT'	=> array('p.*'),
246
	 * 											'WHERE'		=> array('p.post_id = 2'),
247
	 * 										)
248
	 * @return $this
249
	 */
250 8
	public function fetch_custom(array $sql_array)
251
	{
252 8
		$this->store['sql_array'] = array_merge_recursive($this->store['sql_array'], $sql_array);
253
254 8
		return $this;
255
	}
256
257
	/**
258
	 * Set Sorting Order
259
	 *
260
	 * @param string $sort_key		The sorting key e.g. t.topic_time
261
	 * @param string $sort_dir		Sort direction: ASC/DESC
262
	 * @return $this
263
	 */
264 12
	public function set_sorting($sort_key, $sort_dir = 'DESC')
265
	{
266 12
		$this->store['sql_array']['ORDER_BY'] = $sort_key . ' ' . $sort_dir;
267
268 12
		return $this;
269
	}
270
271
	/**
272
	 * Build the query
273
	 *
274
	 * @param bool|true $check_visibility		Should we only return data from forums the user is allowed to see?
275
	 * @param bool|true $enable_caching			Should the query be cached where possible?
276
	 * @param bool|true $exclude_hidden_forums	Leave out hidden forums?
277
	 * @return $this
278
	 */
279 20
	public function build($check_visibility = true, $enable_caching = true, $exclude_hidden_forums = true)
280
	{
281 20
		$this->_set_cache_time($enable_caching);
282 20
		$this->_set_topic_visibility($check_visibility);
283
284
		if ($exclude_hidden_forums)
285 20
		{
286 20
			$this->store['sql_array']['WHERE'][] = 'f.hidden_forum = 0';
287 20
		}
288
289 20
		$this->store['sql_array']['WHERE'][] = 'f.forum_id = t.forum_id';
290 20
		$this->store['sql_array']['WHERE'][] = 't.topic_moved_id = 0';
291
292 20
		$this->store['sql_array']['SELECT'] = join(', ', array_filter($this->store['sql_array']['SELECT']));
293 20
		$this->store['sql_array']['WHERE'] = join(' AND ', array_filter($this->store['sql_array']['WHERE']));
294
295 20
		return $this;
296
	}
297
298
	/**
299
	 * Get the query array
300
	 *
301
	 * @return array	The sql array that can be used with sql_build_query
302
	 */
303 7
	public function get_sql_array()
304
	{
305 7
		return $this->store['sql_array'];
306
	}
307
308
	/**
309
	 * @param bool $enable_caching
310
	 */
311 20
	protected function _set_cache_time($enable_caching)
312
	{
313 20
		if ($enable_caching === false)
314 20
		{
315 5
			$this->cache_time = 0;
316 5
		}
317 20
	}
318
319
	/**
320
	 * @param int $column_id
321
	 * @param string $column
322
	 */
323 15
	private function _fetch($column_id, $column)
324
	{
325 15
		if (!empty($column_id))
326 15
		{
327 10
			$this->store['sql_array']['WHERE'][] = (is_array($column_id)) ? $this->db->sql_in_set($column, $column_id) : $column . ' = ' . (int) $column_id;
328 10
		}
329 15
	}
330
331
	/**
332
	 * @param bool $check_visibility
333
	 */
334 20
	private function _set_topic_visibility($check_visibility)
335
	{
336
		if ($check_visibility)
337 20
		{
338 20
			$this->store['sql_array']['WHERE'][] = 't.topic_time <= ' . time();
339 20
			$this->store['sql_array']['WHERE'][] = $this->content_visibility->get_global_visibility_sql('topic', $this->ex_fid_ary, 't.');
340 20
		}
341 20
	}
342
343
	/**
344
	 * Reset data
345
	 */
346 20
	private function _reset()
347
	{
348 20
		$this->store = array(
349 20
			'attachments'	=> array(),
350 20
			'post_ids'		=> array(),
351 20
			'poster_ids'	=> array(),
352 20
			'sql_array'		=> array(),
353 20
			'topic'			=> array(),
354 20
			'tracking'		=> array(),
355
		);
356 20
	}
357
}
358