Completed
Push — master ( c96b51...1deced )
by Daniel
08:48
created

query_builder::build()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

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