Completed
Push — develop ( 271dc0...7d62a3 )
by Daniel
08:48
created

query_builder::_set_cache_time()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

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