Board_News_Block::setup()   F
last analyzed

Complexity

Conditions 35
Paths > 20000

Size

Total Lines 187
Code Lines 96

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 1
Metric Value
cc 35
eloc 96
c 6
b 1
f 1
nc 31854016
nop 2
dl 0
loc 187
rs 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @package SimplePortal
5
 *
6
 * @author SimplePortal Team
7
 * @copyright 2015-2021 SimplePortal Team
8
 * @license BSD 3-clause
9
 * @version 1.0.0
10
 */
11
12
use BBC\ParserWrapper;
13
14
/**
15
 * Board Block, Displays a list of posts from selected board(s)
16
 *
17
 * @param mixed[] $parameters
18
 * 			'board' => Board(s) to select posts from
19
 * 			'limit' => max number of posts to show
20
 * 			'start' => id of post to start from
21
 *			'length' => preview length of the post
22
 *			'avatar' => show the poster avatar
23
 *			'per_page' => number of posts per page to show
24
 *			'attachment' => Show the first attachment as "blog" image
25
 * @param int $id - not used in this block
26
 * @param boolean $return_parameters if true returns the configuration options for the block
27
 */
28
class Board_News_Block extends SP_Abstract_Block
29
{
30
	/** @var array */
31
	protected $attachments = array();
32
33
	/** @var array */
34
	protected $color_ids = array();
35
36
	/** @var array */
37
	protected $icon_sources = array();
38
39
	/**
40
	 * Constructor, used to define block parameters
41
	 *
42
	 * @param Database|null $db
43
	 */
44
	public function __construct($db = null)
45
	{
46
		$this->block_parameters = array(
47
			'board' => 'boards',
48
			'limit' => 'int',
49
			'start' => 'int',
50
			'length' => 'int',
51
			'avatar' => 'check',
52
			'attachment' => 'check',
53
			'per_page' => 'int',
54
		);
55
56
		parent::__construct($db);
57
	}
58
59
	/**
60
	 * Initializes a block for use.
61
	 *
62
	 * - Called from portal.subs as part of the sportal_load_blocks process
63
	 *
64
	 * @param mixed[] $parameters
65
	 * @param int $id
66
	 */
67
	public function setup($parameters, $id)
68
	{
69
		global $scripturl, $txt, $settings, $context;
70
71
		// Break out / sanitize all the parameters
72
		$board = !empty($parameters['board']) ? explode('|', $parameters['board']) : null;
73
		$limit = !empty($parameters['limit']) ? (int) $parameters['limit'] : 5;
74
		$start = !empty($parameters['start']) ? (int) $parameters['start'] : 0;
75
		$length = isset($parameters['length']) ? (int) $parameters['length'] : 250;
76
		$avatars = !empty($parameters['avatar']);
77
		$attachments = !empty($parameters['attachment']);
78
		$per_page = !empty($parameters['per_page']) ? (int) $parameters['per_page'] : 0;
79
80
		$limit = max(0, $limit);
81
		$start = max(0, $start);
82
83
		loadLanguage('Stats');
84
85
		// Common message icons
86
		$this->_stable_icons();
87
88
		// Load the topics they can see
89
		$request = $this->_db->query('', '
90
			SELECT
91
				t.id_first_msg
92
			FROM {db_prefix}topics AS t
93
				INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
94
				INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
95
			WHERE {query_see_board}
96
				AND ' . (empty($board) ? 't.id_first_msg >= {int:min_msg_id}' : 't.id_board IN ({array_int:current_board})') . ($this->_modSettings['postmod_active'] ? '
97
				AND t.approved = {int:is_approved}' : '') . '
98
				AND (t.locked != {int:locked} OR m.icon != {string:icon})
99
			ORDER BY t.id_first_msg DESC
100
			LIMIT {int:limit}',
101
			array(
102
				'current_board' => $board,
103
				'min_msg_id' => $this->_modSettings['maxMsgID'] - 45 * min($limit, 5),
104
				'is_approved' => 1,
105
				'locked' => 1,
106
				'icon' => 'moved',
107
				'limit' => $limit,
108
			)
109
		);
110
		$posts = array();
111
		while ($row = $this->_db->fetch_assoc($request))
112
		{
113
			$posts[] = $row['id_first_msg'];
114
		}
115
		$this->_db->free_result($request);
116
117
		// No posts, basic error message it is
118
		$current_url = '';
119
		if (empty($posts))
120
		{
121
			$this->setTemplate('template_sp_boardNews_error');
122
			$this->data['error_msg'] = $txt['error_sp_no_posts_found'];
123
124
			return;
125
		}
126
		// Posts and page limits?
127
		elseif (!empty($per_page))
128
		{
129
			$limit = count($posts);
130
			$start = !empty($_REQUEST['news' . $id]) ? (int) $_REQUEST['news' . $id] : 0;
131
132
			$clean_url = str_replace('%', '%%', preg_replace('~news' . $id . '=[^;]+;?~', '', $_SERVER['REQUEST_URL']));
133
			$current_url = $clean_url . (strpos($clean_url, '?') !== false ? (in_array(substr($clean_url, -1), array(';', '?')) ? '' : ';') : '?');
134
		}
135
136
		// Load the actual post details for the topics
137
		$request = $this->_db->query('', '
138
			SELECT
139
				m.icon, m.subject, m.body, IFNULL(mem.real_name, m.poster_name) AS poster_name, m.poster_time,
140
				t.num_replies, t.id_topic, m.id_member, m.smileys_enabled, m.id_msg, t.locked, mem.avatar, mem.email_address,
141
				a.id_attach, a.attachment_type, a.filename, t.num_views
142
			FROM {db_prefix}topics AS t
143
				INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
144
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
145
				LEFT JOIN {db_prefix}attachments AS a ON (a.id_member = mem.id_member)
146
			WHERE t.id_first_msg IN ({array_int:post_list})
147
			ORDER BY t.id_first_msg DESC
148
			LIMIT ' . (!empty($per_page) ? '{int:start}, ' : '') . '{int:limit}',
149
			array(
150
				'post_list' => $posts,
151
				'start' => $start,
152
				'limit' => !empty($per_page) ? $per_page : $limit,
153
			)
154
		);
155
156
		// Get the first attachment for each post for this group
157
		if (!empty($attachments))
158
		{
159
			$this->loadAttachments($posts);
160
		}
161
162
		$this->data['news'] = array();
163
164
		while ($row = $this->_db->fetch_assoc($request))
165
		{
166
			// Good time to do this is ... now
167
			censor($row['subject']);
168
			censor($row['body']);
169
170
			$attach = !empty($attachments) ? $this->getMessageAttach($row['id_msg'], $row['id_topic'], $row['body']) : '';
171
			$limited = sportal_parse_cutoff_content($row['body'], 'bbc', $length);
172
173
			// Link the ellipsis if the body has been shortened.
174
			if ($limited)
175
			{
176
				$row['body'] .= '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0" title="' . $row['subject'] . '">&hellip;</a>';
177
			}
178
179
			if (empty($this->_modSettings['messageIconChecks_disable']) && !isset($this->icon_sources[$row['icon']]))
180
			{
181
				$this->icon_sources[$row['icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['icon'] . '.png') ? 'images_url' : 'default_images_url';
182
			}
183
184
			if ($this->_modSettings['sp_resize_images'])
185
			{
186
				$row['body'] = str_ireplace('class="bbc_img', 'class="bbc_img sp_article', $row['body']);
187
			}
188
189
			if (!empty($row['id_member']))
190
			{
191
				$this->color_ids[$row['id_member']] = $row['id_member'];
192
			}
193
194
			// If ILA is enable and what we rendered has ILA tags, assume they don't need any further attachment help
195
			if (!empty($this->_modSettings['attachment_inline_enabled']))
196
			{
197
				if (strpos($row['body'], '<img src="' . $scripturl . '?action=dlattach;attach=') !== false)
198
				{
199
					$attach = array();
200
				}
201
			}
202
203
			// Build an array of message information for output
204
			$this->data['news'][] = array(
205
				'id' => $row['id_topic'],
206
				'message_id' => $row['id_msg'],
207
				'icon' => '<img src="' . $settings[$this->icon_sources[$row['icon']]] . '/post/' . $row['icon'] . '.png" class="icon" alt="' . $row['icon'] . '" />',
208
				'icon_name' => $row['icon'],
209
				'subject' => $row['subject'],
210
				'time' => standardTime($row['poster_time']),
211
				'views' => $row['num_views'],
212
				'body' => $row['body'],
213
				'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0',
214
				'link' => '<a class="linkbutton" href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $txt['sp_read_more'] . '</a>',
215
				'replies' => $row['num_replies'],
216
				'comment_href' => !empty($row['locked']) ? '' : $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';num_replies=' . $row['num_replies'],
217
				'comment_link' => !empty($row['locked']) ? '' : '<a class="linkbutton" href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . ';num_replies=' . $row['num_replies'] . '">' . $txt['reply'] . '</a>',
218
				'new_comment' => !empty($row['locked']) ? '' : '<a class="linkbutton" href="' . $scripturl . '?action=post;topic=' . $row['id_topic'] . '.' . $row['num_replies'] . '">' . $txt['reply'] . '</a>',
219
				'poster' => array(
220
					'id' => $row['id_member'],
221
					'name' => $row['poster_name'],
222
					'href' => !empty($row['id_member']) ? $scripturl . '?action=profile;u=' . $row['id_member'] : '',
223
					'link' => !empty($row['id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['poster_name'] . '</a>' : $row['poster_name']
224
				),
225
				'locked' => !empty($row['locked']),
226
				'is_last' => false,
227
				'avatar' => $avatars ? determineAvatar($row) : array(),
228
				'attachment' => $attach,
229
			);
230
		}
231
		$this->_db->free_result($request);
232
233
		// Nothing found, set the message and return
234
		if (empty($this->data['news']))
235
		{
236
			$this->setTemplate('template_sp_boardNews_error');
237
			$this->data['error_msg'] = $txt['error_sp_no_posts_found'];
238
239
			return;
240
		}
241
242
		$this->data['news'][count($this->data['news']) - 1]['is_last'] = true;
243
		$this->setTemplate('template_sp_boardNews');
244
245
		// If we want color id's then lets add them in
246
		$this->_color_ids();
247
248
		// Account for embedded videos
249
		$this->data['embed_videos'] = !empty($this->_modSettings['enableVideoEmbeding']);
250
251
		if (!empty($per_page))
252
		{
253
			$context['sp_boardNews_page_index'] = constructPageIndex($current_url . 'news' . $id . '=%1$d', $start, $limit, $per_page, true);
254
		}
255
	}
256
257
	/**
258
	 * Load the first available attachments in a message (if any) for a group of messages
259
	 *
260
	 * @param array $posts
261
	 */
262
	protected function loadAttachments($posts)
263
	{
264
		global $attachments;
265
266
		require_once(SUBSDIR . '/Attachments.subs.php');
267
268
		// We will show attachments in the block, regardless, so save and restore
269
		$attachmentShowImages = $this->_modSettings['attachmentShowImages'];
270
		$this->_modSettings['attachmentShowImages'] = 1;
271
		$this->attachments = getAttachments($posts);
272
		$this->_modSettings['attachmentShowImages'] = $attachmentShowImages;
273
274
		if (!isset($attachments))
275
		{
276
			$attachments = array();
277
		}
278
279
		// For each message, use the first attachment in that message and no more
280
		foreach ($this->attachments as $id_msg => $attachs)
281
		{
282
			if (!isset($attachments[$id_msg]))
283
			{
284
				foreach ($attachs as $key => $val)
285
				{
286
					$attachments[$id_msg][$key] = $val;
287
					break;
288
				}
289
			}
290
		}
291
	}
292
293
	/**
294
	 * Load the attachment details into context
295
	 *
296
	 * - If the message was found to have attachments (via loadAttachments) then
297
	 * it will load that attachment data into context.
298
	 * - If the message did not have attachments, it is then searched for the first
299
	 * bbc IMG tag, and that image is used.
300
	 *
301
	 * @param int $id_msg
302
	 * @param int $id_topic
303
	 * @param string $body
304
	 *
305
	 * @return array|string
306
	 */
307
	protected function getMessageAttach($id_msg, $id_topic, &$body)
308
	{
309
		global $topic;
310
311
		if (!empty($this->attachments[$id_msg]))
312
		{
313
			// A little razzle dazzle since loadAttachment is dependant on this
314
			// poor behavior
315
			$o_topic = $topic ?? null;
316
			$topic = $id_topic;
317
			$this_attachs = loadAttachmentContext($id_msg);
318
			$topic = $o_topic;
319
320
			// Just one, and it must be an image
321
			$attachment = array_shift($this_attachs);
322
			if (!$attachment['is_image'])
323
			{
324
				return array();
325
			}
326
327
			return array(
328
				'id' => $attachment['id'],
329
				'href' => $attachment['href'] . ';image',
330
				'name' => $attachment['name'],
331
			);
332
		}
333
		// No attachments, perhaps an IMG tag then?
334
		else
335
		{
336
			$pos = strpos($body, '[img');
337
			if ($pos === false)
338
			{
339
				return '';
340
			}
341
342
			$img_tag = substr($body, $pos, strpos($body, '[/img]', $pos) + 6);
343
			$parser = ParserWrapper::instance();
344
			$img_html = $parser->parseMessage($img_tag, true);
345
			$body = str_replace($img_tag, '<div class="sp_attachment_thumb">' . $img_html . '</div>', $body);
346
347
			return array();
348
		}
349
	}
350
351
	/**
352
	 * Provide the color profile id's
353
	 */
354
	private function _color_ids()
355
	{
356
		global $color_profile;
357
358
		if (sp_loadColors($this->color_ids) !== false)
0 ignored issues
show
introduced by
The condition sp_loadColors($this->color_ids) !== false is always true.
Loading history...
359
		{
360
			foreach ($this->data['news'] as $k => $p)
361
			{
362
				if (!empty($color_profile[$p['poster']['id']]['link']))
363
				{
364
					$this->data['news'][$k]['poster']['link'] = $color_profile[$p['poster']['id']]['link'];
365
				}
366
			}
367
		}
368
	}
369
370
	/**
371
	 * Standard message icons
372
	 */
373
	private function _stable_icons()
374
	{
375
		$stable_icons = array('xx', 'thumbup', 'thumbdown', 'exclamation', 'question', 'lamp', 'smiley', 'angry', 'cheesy', 'grin', 'sad', 'wink', 'moved', 'recycled', 'wireless');
376
377
		foreach ($stable_icons as $icon)
378
		{
379
			$this->icon_sources[$icon] = 'images_url';
380
		}
381
	}
382
}
383
384
/**
385
 * Error template for this block
386
 *
387
 * @param mixed[] $data
388
 */
389
function template_sp_boardNews_error($data)
390
{
391
	echo $data['error_msg'];
392
}
393
394
/**
395
 * Main template for this block
396
 *
397
 * @param mixed[] $data
398
 */
399
function template_sp_boardNews($data)
400
{
401
	global $context, $scripturl, $txt, $modSettings;
402
403
	// Auto video embedding enabled?
404
	if ($data['embed_videos'])
405
	{
406
		addInlineJavascript('
407
		$(document).ready(function() {
408
			$().linkifyvideo(oEmbedtext);
409
		});', true);
410
	}
411
412
	// Output all the details we have found
413
	foreach ($data['news'] as $news)
414
	{
415
		$attachment = $news['attachment'];
416
417
		echo '
418
			<h3 class="category_header">' . (empty($modSettings['messageIcons_enable'])
419
				? '<span class="icon i-' . $news['icon_name'] . '"></span>'
420
				: '<span class="floatleft sp_article_icon">' . $news['icon'] . '</span>') . '
421
				<a href="', $news['href'], '" >', $news['subject'], '</a>
422
			</h3>
423
			<div id="msg_', $news['message_id'], '" class="sp_article_content">
424
				<div class="sp_content_padding">';
425
426
		if (!empty($news['avatar']['href']))
427
		{
428
			echo '
429
					<a href="', $scripturl, '?action=profile;u=', $news['poster']['id'], '">
430
						<img src="', $news['avatar']['href'], '" alt="', $news['poster']['name'], '" style="max-width:40px" class="floatright" />
431
					</a>
432
					<div>', $news['time'], ' ', $txt['by'], ' ', $news['poster']['link'], '<br />', $txt['sp-articlesViews'], ': ', $news['views'], ' | ', $txt['sp-articlesComments'], ': ', $news['replies'], '</div>';
433
		}
434
		else
435
		{
436
			echo '
437
					<div>', $news['time'], ' ', $txt['by'], ' ', $news['poster']['link'], ' | ', $txt['sp-articlesViews'], ': ', $news['views'], ' | ', $txt['sp-articlesComments'], ': ', $news['replies'], '</div>';
438
		}
439
440
		echo '
441
					<div class="post">
442
						<hr />';
443
444
		if (!empty($attachment))
445
		{
446
			echo '
447
						<div class="sp_attachment_thumb">';
448
449
			// If you want Fancybox to tag this, remove nfb_ from the id
450
			echo '
451
							<a href="', $news['href'], '" id="nfb_link_', $attachment['id'], '"><img src="', $attachment['href'], '" alt="" title="', $attachment['name'], '" id="thumb_', $attachment['id'], '" /></a>';
452
453
			echo '
454
						</div>';
455
		}
456
457
		echo $news['body'], '
458
					</div>
459
				<div class="submitbutton">', $news['link'], ' ', $news['new_comment'], '</div>
460
			</div>
461
		</div>';
462
	}
463
464
	// Pagination is a good thing
465
	if (!empty($context['sp_boardNews_page_index']))
466
	{
467
		echo '
468
		<div class="sp_page_index">',
469
			template_pagesection(false, '', array('page_index' => 'sp_boardNews_page_index')), '
470
		</div>';
471
	}
472
}
473