sp_integrate_additional_bbc()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 102
Code Lines 77

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
eloc 77
c 2
b 0
f 1
nc 1
nop 1
dl 0
loc 102
rs 8.5018

How to fix   Long Method   

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 ElkArte
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\Codes;
13
14
/**
15
 * Portal "management" controller.
16
 *
17
 * This class holds all of SimplePortals integration hooks.
18
 *
19
 * @package SimplePortal
20
 */
21
class ManageSPortalModule_Controller extends Action_Controller
22
{
23
	/**
24
	 * Default method.
25
	 * Requires admin_forum permissions
26
	 * Required by Action_Controller
27
	 *
28
	 * @uses SPortal language file
29
	 */
30
	public function action_index()
31
	{
32
		isAllowedTo('admin_forum');
33
		loadLanguage('SPortal');
34
	}
35
36
	/**
37
	 * Used to add the Portal entry to the Core Features list.
38
	 *
39
	 * @param mixed[] $core_features The core features array
40
	 */
41
	public static function addCoreFeature(&$core_features)
42
	{
43
		isAllowedTo('admin_forum');
44
		loadLanguage('SPortalAdmin');
45
46
		$core_features['pt'] = array(
47
			'url' => 'action=admin;area=portalconfig',
48
			'setting_callback' => function ($value) {
49
				// Enabling
50
				if ($value)
51
				{
52
					Hooks::instance()->enableIntegration('Portal_Integrate');
53
					return array('disable_sp' => '');
54
				}
55
				// Disabling
56
				else
57
				{
58
					Hooks::instance()->disableIntegration('Portal_Integrate');
59
					return array('disable_sp' => 1);
60
				}
61
			},
62
		);
63
	}
64
65
	/******************************INTEGRATION HOOKS*******************************************/
66
67
	/**
68
	 * Adds [spattach] BBC code tags for use with article images.  Mostly the same as ILA [attach]
69
	 *
70
	 * @param mixed[] $additional_bbc
71
	 */
72
	public static function sp_integrate_additional_bbc(&$additional_bbc)
73
	{
74
		global $scripturl;
75
76
		// Generally we don't want to render inside of these tags ...
77
		$disallow = array(
78
			'quote' => 1,
79
			'code' => 1,
80
			'nobbc' => 1,
81
			'html' => 1,
82
			'php' => 1,
83
		);
84
85
		// Add simplePortal ILA codes
86
		$additional_bbc = array_merge($additional_bbc, array(
87
			// Require a width with optional height/align to allow use of full image and/or ;thumb
88
			array(
89
				Codes::ATTR_TAG => 'spattach',
90
				Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT,
91
				Codes::ATTR_PARAM => array(
92
					'width' => array(
93
						Codes::PARAM_ATTR_VALIDATE => self::validate_width(),
94
						Codes::PARAM_ATTR_MATCH => '(\d+)',
95
					),
96
					'height' => array(
97
						Codes::PARAM_ATTR_OPTIONAL => true,
98
						Codes::PARAM_ATTR_VALUE => 'max-height:$1px;',
99
						Codes::PARAM_ATTR_MATCH => '(\d+)',
100
					),
101
					'align' => array(
102
						Codes::PARAM_ATTR_OPTIONAL => true,
103
						Codes::PARAM_ATTR_VALUE => 'float$1',
104
						Codes::PARAM_ATTR_MATCH => '(right|left|center)',
105
					),
106
				),
107
				Codes::ATTR_CONTENT => '<a id="link_$1" class="sp_attach" data-lightboximage="$1" data-lightboxmessage="0" href="' . $scripturl . '?action=portal;sa=spattach;article={article};attach=$1;image"><img src="' . $scripturl . '?action=portal;sa=spattach;article={article};attach=$1{width}{height}" alt="" class="bbc_img {align}" /></a>',
108
				Codes::ATTR_VALIDATE => self::validate_options(),
109
				Codes::ATTR_DISALLOW_PARENTS => $disallow,
110
				Codes::ATTR_BLOCK_LEVEL => false,
111
				Codes::ATTR_AUTOLINK => false,
112
				Codes::ATTR_LENGTH => 8,
113
			),
114
			// Require a height with optional width/align to allow removal of ;thumb
115
			array(
116
				Codes::ATTR_TAG => 'spattach',
117
				Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT,
118
				Codes::ATTR_PARAM => array(
119
					'height' => array(
120
						Codes::PARAM_ATTR_VALIDATE => self::validate_height(),
121
						Codes::PARAM_ATTR_MATCH => '(\d+)',
122
					),
123
					'width' => array(
124
						Codes::PARAM_ATTR_OPTIONAL => true,
125
						Codes::PARAM_ATTR_VALUE => 'width:100%;max-width:$1px;',
126
						Codes::PARAM_ATTR_MATCH => '(\d+)',
127
					),
128
					'align' => array(
129
						Codes::PARAM_ATTR_OPTIONAL => true,
130
						Codes::PARAM_ATTR_VALUE => 'float$1',
131
						Codes::PARAM_ATTR_MATCH => '(right|left|center)',
132
					),
133
				),
134
				Codes::ATTR_CONTENT => '<a id="link_$1" class="sp_attach" data-lightboximage="$1" data-lightboxmessage="{article}" href="' . $scripturl . '?action=portal;sa=spattach;article={article};attach=$1;image"><img src="' . $scripturl . '?action=portal;sa=spattach;article={article};attach=$1{height}{width}" alt="" class="bbc_img {align}" /></a>',
135
				Codes::ATTR_VALIDATE => self::validate_options(),
136
				Codes::ATTR_DISALLOW_PARENTS => $disallow,
137
				Codes::ATTR_BLOCK_LEVEL => false,
138
				Codes::ATTR_AUTOLINK => false,
139
				Codes::ATTR_LENGTH => 8,
140
			),
141
			// Just a simple attach
142
			array(
143
				Codes::ATTR_TAG => 'spattach',
144
				Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT,
145
				Codes::ATTR_CONTENT => '$1',
146
				Codes::ATTR_VALIDATE => self::validate_plain(),
147
				Codes::ATTR_DISALLOW_PARENTS => $disallow,
148
				Codes::ATTR_BLOCK_LEVEL => false,
149
				Codes::ATTR_AUTOLINK => false,
150
				Codes::ATTR_LENGTH => 8,
151
			),
152
			// Just an align ?
153
			array(
154
				Codes::ATTR_TAG => 'spattach',
155
				Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT,
156
				Codes::ATTR_PARAM => array(
157
					'type' => array(
158
						Codes::PARAM_ATTR_OPTIONAL => true,
159
						Codes::PARAM_ATTR_VALUE => ';$1',
160
						Codes::PARAM_ATTR_MATCH => '(thumb|image)',
161
					),
162
					'align' => array(
163
						Codes::PARAM_ATTR_OPTIONAL => true,
164
						Codes::PARAM_ATTR_VALUE => 'float$1',
165
						Codes::PARAM_ATTR_MATCH => '(right|left|center)',
166
					),
167
				),
168
				Codes::ATTR_CONTENT => '<a id="link_$1" class="sp_attach" data-lightboximage="$1" data-lightboxmessage="{article}" href="' . $scripturl . '?action=portal;sa=spattach;article={article};attach=$1;image"><img src="' . $scripturl . '?action=portal;sa=spattach;article={article};attach=$1{type}" alt="" class="bbc_img {align}" /></a>',
169
				Codes::ATTR_VALIDATE => self::validate_options(),
170
				Codes::ATTR_DISALLOW_PARENTS => $disallow,
171
				Codes::ATTR_BLOCK_LEVEL => false,
172
				Codes::ATTR_AUTOLINK => false,
173
				Codes::ATTR_LENGTH => 8,
174
			),
175
		));
176
	}
177
178
	/**
179
	 * Used when the optional width parameter is set
180
	 *
181
	 * - Determines the best image, full or thumbnail, based on ILA width desired
182
	 * - Used as PARAM_ATTR_VALIDATE function
183
	 *
184
	 * @return Closure
185
	 */
186
	public static function validate_width()
187
	{
188
		global $modSettings;
189
190
		return function ($data) use ($modSettings) {
191
			if (!empty($modSettings['attachmentThumbWidth']) && $data <= $modSettings['attachmentThumbWidth'])
192
			{
193
				return ';thumb" style="width:100%;max-width:' . $data . 'px;';
194
			}
195
			else
196
			{
197
				return '" style="width:100%;max-width:' . $data . 'px;';
198
			}
199
		};
200
	}
201
202
	/**
203
	 * Used when the optional height parameter is set and no width is set
204
	 *
205
	 * - Determines the best image, full or thumbnail, based on desired ILA height
206
	 * - Used as PARAM_ATTR_VALIDATE function
207
	 *
208
	 * @return Closure
209
	 */
210
	public static function validate_height()
211
	{
212
		global $modSettings;
213
214
		return function ($data) use ($modSettings) {
215
			if (!empty($modSettings['attachmentThumbHeight']) && $data <= $modSettings['attachmentThumbHeight'])
216
			{
217
				return ';thumb" style="max-height:' . $data . 'px;';
218
			}
219
			else
220
			{
221
				return '" style="max-height:' . $data . 'px;';
222
			}
223
		};
224
	}
225
226
	/**
227
	 * This provides for some control for "plain" tags
228
	 *
229
	 * - Determines if the ILA is an image or not
230
	 * - Sets the lightbox attributes if an image is identified
231
	 * - Keeps track of attachment usage to prevent displaying below the post
232
	 *
233
	 * @return Closure
234
	 */
235
	public static function validate_plain()
236
	{
237
		global $user_info, $scripturl, $context, $modSettings;
238
239
		return function (&$tag, &$data) use ($user_info, $scripturl, &$context, $modSettings) {
240
			$num = $data;
241
			$is_image = array();
242
			$preview = strpos($data, 'post_tmp_' . $user_info['id'] . '_');
243
			$article = $context['article']['id'] ?? 0;
244
245
			// Not a preview, then sanitize the attach id and determine the actual type
246
			if ($preview === false)
247
			{
248
				$num = (int) $data;
249
				$is_image = isArticleAttachmentImage($num);
250
			}
251
252
			// An image will get the light box treatment
253
			if (!empty($is_image['is_image']) || $preview !== false)
254
			{
255
				$type = !empty($modSettings['attachmentThumbnails']) ? ';thumb' : '';
256
				$data = '<a id="link_' . $num . '" data-lightboximage="' . $num . '" data-lightboxmessage="{article}" href="' . $scripturl . '?action=portal;sa=spattach;article=' . $article . ';attach=' . $num . ';image' . '"><img src="' . $scripturl . '?action=portal;sa=spattach;article=' . $article . ';attach=' . $num . $type . '" alt="" class="bbc_img" /></a>';
257
			}
258
			else
259
			{
260
				// Not an image, determine a mime or use a default thumbnail
261
				require_once(SUBSDIR . '/Attachments.subs.php');
262
				$check = returnMimeThumb(($is_image['fileext'] ?? ''), true);
263
264
				if ($is_image === false)
265
				{
266
					$data = '<img src="' . $check . '" alt="" class="bbc_img" />';
267
				}
268
				else
269
				{
270
					$data = '<a class="sp_attach" href="' . $scripturl . '?action=portal;sa=spattach;article=' . $article . ';attach=' . $num . '"><img src="' . $check . '" alt="' . $is_image['filename'] . '" class="bbc_img" /></a>';
271
				}
272
			}
273
274
			$context['ila_dont_show_attach_below'][] = $num;
275
			$context['ila_dont_show_attach_below'] = array_unique($context['ila_dont_show_attach_below']);
276
		};
277
	}
278
279
	/**
280
	 * For tags with options (width / height / align)
281
	 *
282
	 * - Keeps track of attachment usage to prevent displaying below the post
283
	 *
284
	 * @return Closure
285
	 */
286
	public static function validate_options()
287
	{
288
		global $context;
289
290
		return function (&$tag, &$data) use (&$context) {
291
			$article = $context['article']['id'] ?? 0;
292
293
			// Not a preview, then sanitize the attach id
294
			if (strpos($data, 'post_tmp_') === false)
295
			{
296
				$data = (int) $data;
297
			}
298
299
			$tag[Codes::ATTR_CONTENT] = str_replace('{article}', $article, $tag[Codes::ATTR_CONTENT]);
300
301
			$context['ila_dont_show_attach_below'][] = $data;
302
			$context['ila_dont_show_attach_below'] = array_unique($context['ila_dont_show_attach_below']);
303
		};
304
	}
305
306
	/**
307
	 * Integration hook integrate_setup_allow
308
	 *
309
	 * Called from Theme.php setupMenuContext(), used to determine if the admin button is visible for a given
310
	 * member as its needed to access certain sub menus
311
	 */
312
	public static function sp_integrate_setup_allow()
313
	{
314
		global $context;
315
316
		$context['allow_admin'] = $context['allow_admin'] || allowedTo(array('sp_admin', 'sp_manage_settings', 'sp_manage_blocks', 'sp_manage_articles', 'sp_manage_pages', 'sp_manage_shoutbox', 'sp_manage_profiles', 'sp_manage_categories'));
317
	}
318
319
	/**
320
	 * integration hook integrate_actions
321
	 * Called from dispatcher.class, used to add in custom actions
322
	 *
323
	 * @param array $actions
324
	 */
325
	public static function sp_integrate_actions(&$actions)
326
	{
327
		global $context;
328
329
		if (!empty($context['disable_sp']))
330
		{
331
			return;
332
		}
333
334
		$actions['forum'] = array('BoardIndex.controller.php', 'BoardIndex_Controller', 'action_boardindex');
335
		$actions['portal'] = array('PortalMain.controller.php', 'PortalMain_Controller', 'action_index');
336
		$actions['shoutbox'] = array('PortalShoutbox.controller.php', 'Shoutbox_Controller', 'action_sportal_shoutbox');
337
	}
338
339
	/**
340
	 * Admin hook, integrate_admin_areas, called from Menu.subs
341
	 * adds the admin menu
342
	 *
343
	 * @param array $admin_areas
344
	 */
345
	public static function sp_integrate_admin_areas(&$admin_areas)
346
	{
347
		global $txt, $context;
348
349
		require_once(SUBSDIR . '/Portal.subs.php');
350
		loadLanguage('SPortalAdmin');
351
		loadLanguage('SPortal');
352
353
		$temp = $admin_areas;
354
		$admin_areas = array();
355
356
		foreach ($temp as $area => $data)
357
		{
358
			$admin_areas[$area] = $data;
359
360
			// Add in our admin menu option after layout aka forum
361
			if ($area === 'layout')
362
			{
363
				$admin_areas['portal'] = array(
364
					'enabled' => in_array('pt', $context['admin_features']),
365
					'title' => $txt['sp-adminCatTitle'],
366
					'permission' => array('sp_admin', 'sp_manage_settings', 'sp_manage_blocks', 'sp_manage_articles', 'sp_manage_pages', 'sp_manage_shoutbox', 'sp_manage_profiles', 'sp_manage_categories'),
367
					'areas' => array(
368
						'portalconfig' => array(
369
							'label' => $txt['sp-adminConfiguration'],
370
							'file' => 'PortalAdminMain.controller.php',
371
							'controller' => 'ManagePortalConfig_Controller',
372
							'function' => 'action_index',
373
							'icon' => 'transparent.png',
374
							'class' => 'admin_img_corefeatures',
375
							'permission' => array('sp_admin', 'sp_manage_settings'),
376
							'subsections' => array(
377
								'information' => array($txt['sp-info_title']),
378
								'generalsettings' => array($txt['sp-adminGeneralSettingsName']),
379
								'blocksettings' => array($txt['sp-adminBlockSettingsName']),
380
								'articlesettings' => array($txt['sp-adminArticleSettingsName']),
381
							),
382
						),
383
						'portalblocks' => array(
384
							'label' => $txt['sp-blocksBlocks'],
385
							'file' => 'PortalAdminBlocks.controller.php',
386
							'controller' => 'ManagePortalBlocks_Controller',
387
							'function' => 'action_index',
388
							'icon' => 'blocks.png',
389
							'permission' => array('sp_admin', 'sp_manage_blocks'),
390
							'subsections' => array(
391
								'list' => array($txt['sp-adminBlockListName']),
392
								'add' => array($txt['sp-adminBlockAddName']),
393
								'header' => array($txt['sp-positionHeader']),
394
								'left' => array($txt['sp-positionLeft']),
395
								'top' => array($txt['sp-positionTop']),
396
								'bottom' => array($txt['sp-positionBottom']),
397
								'right' => array($txt['sp-positionRight']),
398
								'footer' => array($txt['sp-positionFooter']),
399
							),
400
						),
401
						'portalarticles' => array(
402
							'label' => $txt['sp_admin_articles_title'],
403
							'file' => 'PortalAdminArticles.controller.php',
404
							'controller' => 'ManagePortalArticles_Controller',
405
							'function' => 'action_index',
406
							'icon' => 'transparent.png',
407
							'class' => 'admin_img_news',
408
							'permission' => array('sp_admin', 'sp_manage_articles'),
409
							'subsections' => array(
410
								'list' => array($txt['sp_admin_articles_list']),
411
								'add' => array($txt['sp_admin_articles_add']),
412
							),
413
						),
414
						'portalcategories' => array(
415
							'label' => $txt['sp_admin_categories_title'],
416
							'file' => 'PortalAdminCategories.controller.php',
417
							'controller' => 'ManagePortalCategories_Controller',
418
							'function' => 'action_index',
419
							'icon' => 'transparent.png',
420
							'class' => 'admin_img_server',
421
							'permission' => array('sp_admin', 'sp_manage_categories'),
422
							'subsections' => array(
423
								'list' => array($txt['sp_admin_categories_list']),
424
								'add' => array($txt['sp_admin_categories_add']),
425
							),
426
						),
427
						'portalpages' => array(
428
							'label' => $txt['sp_admin_pages_title'],
429
							'file' => 'PortalAdminPages.controller.php',
430
							'controller' => 'ManagePortalPages_Controller',
431
							'function' => 'action_index',
432
							'icon' => 'transparent.png',
433
							'class' => 'admin_img_posts',
434
							'permission' => array('sp_admin', 'sp_manage_pages'),
435
							'subsections' => array(
436
								'list' => array($txt['sp_admin_pages_list']),
437
								'add' => array($txt['sp_admin_pages_add']),
438
							),
439
						),
440
						'portalshoutbox' => array(
441
							'label' => $txt['sp_admin_shoutbox_title'],
442
							'file' => 'PortalAdminShoutbox.controller.php',
443
							'controller' => 'ManagePortalShoutbox_Controller',
444
							'function' => 'action_index',
445
							'icon' => 'transparent.png',
446
							'class' => 'admin_img_smiley',
447
							'permission' => array('sp_admin', 'sp_manage_shoutbox'),
448
							'subsections' => array(
449
								'list' => array($txt['sp_admin_shoutbox_list']),
450
								'add' => array($txt['sp_admin_shoutbox_add']),
451
							),
452
						),
453
						/* Shhh its a secret for now, not done yet ;)
454
						'portalmenus' => array(
455
							'label' => $txt['sp_admin_menus_title'],
456
							'file' => 'PortalAdminMenus.controller.php',
457
							'controller' => 'ManagePortalMenus_Controller',
458
							'function' => 'action_index',
459
							'icon' => 'menus.png',
460
							'permission' => array('sp_admin', 'sp_manage_menus'),
461
							'subsections' => array(
462
								'listmainitem' => array($txt['sp_admin_menus_main_item_list']),
463
								'addmainitem' => array($txt['sp_admin_menus_main_item_add']),
464
								'listcustommenu' => array($txt['sp_admin_menus_custom_menu_list']),
465
								'addcustommenu' => array($txt['sp_admin_menus_custom_menu_add']),
466
								'addcustomitem' => array($txt['sp_admin_menus_custom_item_add'], 'enabled' => !empty($_REQUEST['sa']) && $_REQUEST['sa'] === 'listcustomitem'),
467
							),
468
						),
469
						*/
470
						'portalprofiles' => array(
471
							'label' => $txt['sp_admin_profiles_title'],
472
							'file' => 'PortalAdminProfiles.controller.php',
473
							'controller' => 'ManagePortalProfile_Controller',
474
							'function' => 'action_index',
475
							'icon' => 'transparent.png',
476
							'class' => 'admin_img_permissions',
477
							'permission' => array('sp_admin', 'sp_manage_profiles'),
478
							'subsections' => array(
479
								'listpermission' => array($txt['sp_admin_permission_profiles_list']),
480
								'liststyle' => array($txt['sp_admin_style_profiles_list']),
481
								'listvisibility' => array($txt['sp_admin_visibility_profiles_list']),
482
							),
483
						),
484
					),
485
				);
486
			}
487
		}
488
	}
489
490
	/**
491
	 * Permissions hook, integrate_load_permissions, called from ManagePermissions.php
492
	 * used to add new permissions
493
	 *
494
	 * @param array $permissionGroups
495
	 * @param array $permissionList
496
	 * @param array $leftPermissionGroups
497
	 * @param array $hiddenPermissions
498
	 * @param array $relabelPermissions
499
	 */
500
	public static function sp_integrate_load_permissions(&$permissionGroups, &$permissionList, &$leftPermissionGroups, &$hiddenPermissions, &$relabelPermissions)
501
	{
502
		$permissionList['membergroup'] = array_merge($permissionList['membergroup'], array(
503
			'sp_admin' => array(false, 'sp', 'sp'),
504
			'sp_manage_settings' => array(false, 'sp', 'sp'),
505
			'sp_manage_blocks' => array(false, 'sp', 'sp'),
506
			'sp_manage_articles' => array(false, 'sp', 'sp'),
507
			'sp_manage_pages' => array(false, 'sp', 'sp'),
508
			'sp_manage_shoutbox' => array(false, 'sp', 'sp'),
509
			'sp_manage_menus' => array(false, 'sp', 'sp'),
510
			'sp_manage_profiles' => array(false, 'sp', 'sp'),
511
		));
512
513
		$permissionGroups['membergroup'][] = 'sp';
514
515
		$leftPermissionGroups[] = 'sp';
516
	}
517
518
	/**
519
	 * Whos online hook, integrate_whos_online, called from who.subs
520
	 * translates custom actions to allow us to show what area a user is in
521
	 *
522
	 * @param string $actions
523
	 *
524
	 * @return string|array
525
	 */
526
	public static function sp_integrate_whos_online($actions)
527
	{
528
		global $scripturl, $modSettings, $txt;
529
530
		$data = null;
531
532
		require_once(SUBSDIR . '/Portal.subs.php');
533
		loadLanguage('SPortal');
534
535
		// This may miss if its needed for the first action ... need to improve the hook or
536
		// find another location
537
		if ($modSettings['sp_portal_mode'] == 1)
538
		{
539
			$txt['who_index'] = sprintf($txt['sp_who_index'], $scripturl);
540
			$txt['whoall_forum'] = sprintf($txt['sp_who_forum'], $scripturl);
541
		}
542
		elseif ($modSettings['sp_portal_mode'] == 3)
543
		{
544
			$txt['whoall_portal'] = sprintf($txt['sp_who_index'], $scripturl);
545
		}
546
547
		// If its a portal action, lets check it out.
548
		if (isset($actions['page']))
549
		{
550
			$data = self::sp_whos_online_page($actions['page']);
551
		}
552
		elseif (isset($actions['article']))
553
		{
554
			$data = self::sp_whos_online_article($actions['article']);
555
		}
556
557
		return $data;
558
	}
559
560
	/**
561
	 * Page online hook, helper function to determine the page a user is viewing
562
	 *
563
	 * @param string $page_id
564
	 *
565
	 * @return string
566
	 */
567
	public static function sp_whos_online_page($page_id)
568
	{
569
		global $scripturl, $txt, $context;
570
571
		$db = database();
572
573
		$data = $txt['who_hidden'];
574
		$numeric_ids = '';
575
		$string_ids = '';
576
		$page_where = '';
577
578
		if (is_numeric($page_id))
579
		{
580
			$numeric_ids = (int) $page_id;
581
		}
582
		else
583
		{
584
			$string_ids = $page_id;
585
		}
586
587
		if (!empty($numeric_ids))
588
		{
589
			$page_where = 'id_page IN ({int:numeric_ids})';
590
		}
591
592
		if (!empty($string_ids))
593
		{
594
			$page_where = 'namespace IN ({string:string_ids})';
595
		}
596
597
		$query = sprintf($context['SPortal']['permissions']['query'], 'permissions');
598
599
		$result = $db->query('', '
600
		SELECT
601
			id_page, namespace, title, permissions
602
		FROM {db_prefix}sp_pages
603
		WHERE ' . $page_where . ' AND ' . $query . '
604
		LIMIT {int:limit}',
605
			array(
606
				'numeric_ids' => $numeric_ids,
607
				'string_ids' => $string_ids,
608
				'limit' => 1,
609
			)
610
		);
611
		$page_data = '';
612
		while ($row = $db->fetch_assoc($result))
613
		{
614
			$page_data = array(
615
				'id' => $row['id_page'],
616
				'namespace' => $row['namespace'],
617
				'title' => $row['title'],
618
			);
619
		}
620
		$db->free_result($result);
621
622
		if (!empty($page_data))
623
		{
624
			if (isset($page_data['id']))
625
			{
626
				$data = sprintf($txt['sp_who_page'], $page_data['id'], censor($page_data['title']), $scripturl);
627
			}
628
629
			if (isset($page_data['namespace']))
630
			{
631
				$data = sprintf($txt['sp_who_page'], $page_data['namespace'], censor($page_data['title']), $scripturl);
632
			}
633
		}
634
635
		return $data;
636
	}
637
638
	/**
639
	 * Article online hook, helper function to determine the page a user is viewing
640
	 *
641
	 * @param string $article_id
642
	 *
643
	 * @return string
644
	 */
645
	public static function sp_whos_online_article($article_id)
646
	{
647
		global $scripturl, $txt, $context;
648
649
		$db = database();
650
651
		$data = $txt['who_hidden'];
652
		$numeric_ids = '';
653
		$string_ids = '';
654
		$article_where = '';
655
656
		if (is_numeric($article_id))
657
		{
658
			$numeric_ids = (int) $article_id;
659
		}
660
		else
661
		{
662
			$string_ids = $article_id;
663
		}
664
665
		if (!empty($numeric_ids))
666
		{
667
			$article_where = 'id_article IN ({int:numeric_ids})';
668
		}
669
670
		if (!empty($string_ids))
671
		{
672
			$article_where = 'namespace IN ({string:string_ids})';
673
		}
674
675
		$query = sprintf($context['SPortal']['permissions']['query'], 'permissions');
676
677
		$result = $db->query('', '
678
		SELECT
679
			id_article, namespace, title, permissions
680
		FROM {db_prefix}sp_articles
681
		WHERE ' . $article_where . ' AND ' . $query . '
682
		LIMIT {int:limit}',
683
			array(
684
				'numeric_ids' => $numeric_ids,
685
				'string_ids' => $string_ids,
686
				'limit' => 1,
687
			)
688
		);
689
		$article_data = '';
690
		while ($row = $db->fetch_assoc($result))
691
		{
692
			$article_data = array(
693
				'id' => $row['id_article'],
694
				'namespace' => $row['namespace'],
695
				'title' => $row['title'],
696
			);
697
		}
698
		$db->free_result($result);
699
700
		if (!empty($article_data))
701
		{
702
			if (isset($article_data['id']))
703
			{
704
				$data = sprintf($txt['sp_who_article'], $article_data['id'], censor($article_data['title']), $scripturl);
705
			}
706
707
			if (isset($article_data['namespace']))
708
			{
709
				$data = sprintf($txt['sp_who_article'], $article_data['namespace'], censor($article_data['title']), $scripturl);
710
			}
711
		}
712
713
		return $data;
714
	}
715
716
	/**
717
	 * Theme hook, integrate_init_theme, called from load.php
718
	 * Used to initialize main portal functions as soon as the theme is started
719
	 */
720
	public static function sp_integrate_init_theme()
721
	{
722
		// Need to run init to determine if we are even active
723
		require_once(SUBSDIR . '/Portal.subs.php');
724
		sportal_init();
725
	}
726
727
	/**
728
	 * Help hook, integrate_quickhelp, called from help.controller.php
729
	 * Used to add in additional help languages for use in the admin quickhelp
730
	 */
731
	public static function sp_integrate_quickhelp()
732
	{
733
		require_once(SUBSDIR . '/Portal.subs.php');
734
735
		// Load the Simple Portal Help file.
736
		loadLanguage('SPortalHelp');
737
		loadLanguage('SPortalAdmin');
738
	}
739
740
	/**
741
	 * Integration hook integrate_buffer, called from ob_exit via call_integration_buffer
742
	 * Used to modify the output buffer before its sent, here we add in our copyright
743
	 *
744
	 * @param string $tourniquet
745
	 *
746
	 * @return string
747
	 */
748
	public static function sp_integrate_buffer($tourniquet)
749
	{
750
		global $context, $modSettings, $forum_copyright;
751
752
		$fix = str_replace('{version}', SPORTAL_VERSION, '<a href="https://simpleportal.net/" target="_blank" class="new_win">SimplePortal {version} &copy; 2008-' . strftime('%Y') . '</a>');
753
754
		if ((ELK === 'SSI' && empty($context['standalone']))
755
			|| !Template_Layers::instance()->hasLayers()
756
			|| empty($modSettings['sp_portal_mode'])
757
			|| strpos($tourniquet, $fix) !== false)
758
		{
759
			return $tourniquet;
760
		}
761
762
		// Don't display copyright for things like SSI.
763
		if (!defined('FORUM_VERSION'))
764
		{
765
			return $tourniquet;
766
		}
767
768
		// Append our cp notice at the end of the line
769
		$finds = array(
770
			$forum_copyright,
771
		);
772
		$replaces = array(
773
			sprintf($forum_copyright, FORUM_VERSION) . ' | ' . $fix,
774
		);
775
776
		$tourniquet = str_replace($finds, $replaces, $tourniquet);
777
778
		// Can't find it for some reason so we add it at the end
779
		if (strpos($tourniquet, $fix) === false)
780
		{
781
			$fix = '<div style="text-align: center; width: 100%; font-size: x-small; margin-bottom: 5px;">' . $fix . '</div></body></html>';
782
			$tourniquet = preg_replace('~</body>\s*</html>~', $fix, $tourniquet);
783
		}
784
785
		return $tourniquet;
786
	}
787
788
	/**
789
	 * Menu Button hook, integrate_menu_buttons, called from subs.php
790
	 * used to add top menu buttons
791
	 *
792
	 * @param array $buttons
793
	 */
794
	public static function sp_integrate_menu_buttons(&$buttons)
795
	{
796
		global $txt, $scripturl, $modSettings, $context;
797
798
		require_once(SUBSDIR . '/Portal.subs.php');
799
		loadLanguage('SPortal');
800
801
		// Set the right portalurl based on what integration mode the portal is using
802
		if ($modSettings['sp_portal_mode'] == 1 && empty($context['disable_sp']))
803
		{
804
			$sportal_url = $scripturl . '?action=forum';
805
		}
806
		elseif ($modSettings['sp_portal_mode'] == 3 && empty($context['disable_sp']))
807
		{
808
			$buttons['home']['href'] = $modSettings['sp_standalone_url'];
809
			$sportal_url = $modSettings['sp_standalone_url'];
810
		}
811
		else
812
		{
813
			return;
814
		}
815
816
		theme()->addCSSRules("
817
	.i-spgroup::before {
818
		content: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23555555' viewBox='0 0 36 32'%3E%3Cpath d='M24 24v-1.6a9 9 0 0 0 4-7.4c0-5 0-9-6-9s-6 4-6 9a9 9 0 0 0 4 7.4v1.7C13.2 24.6 8 28 8 32h28c0-4-5.2-7.4-12-8z'/%3E%3Cpath d='M10.2 24.9a19 19 0 0 1 6.3-2.6 11.3 11.3 0 0 1-2.8-7.3c0-2.7 0-5.2 1-7.3 1-2 2.6-3.3 5-3.7-.5-2.4-2-4-5.7-4-6 0-6 4-6 9a9 9 0 0 0 4 7.4v1.7C5.2 18.6 0 22 0 26h8.7l1.5-1.1z'/%3E%3C/svg%3E\");
819
	}");
820
821
		// Define the new menu item(s), show it for modes 1 and 3 only
822
		$buttons = elk_array_insert($buttons, 'home', array(
823
			'forum' => array(
824
				'title' => empty($txt['sp-forum']) ? 'Forum' : $txt['sp-forum'],
825
				'data-icon' => 'i-spgroup',
826
				'href' => $sportal_url,
827
				'show' => in_array($modSettings['sp_portal_mode'], array(1, 3)) && empty($context['disable_sp']),
828
				'sub_buttons' => array(),
829
			),
830
		), 'after');
831
	}
832
833
	/**
834
	 * Redirection hook, integrate_redirect, called from subs.php redirectexit()
835
	 *
836
	 * @param string $setLocation
837
	 *
838
	 * @uses redirectexit_callback in subs.php
839
	 */
840
	public static function sp_integrate_redirect(&$setLocation)
841
	{
842
		global $modSettings, $context, $scripturl;
843
844
		// Set the default redirect location as the forum or the portal.
845
		if ($scripturl == $setLocation && ($modSettings['sp_portal_mode'] == 1 || $modSettings['sp_portal_mode'] == 3))
846
		{
847
			// Redirect the user to the forum.
848
			if (!empty($modSettings['sp_disableForumRedirect']))
849
			{
850
				$setLocation = '?action=forum';
851
			}
852
			// Redirect the user to the SSI.php standalone portal.
853
			elseif ($modSettings['sp_portal_mode'] == 3)
854
			{
855
				$setLocation = $context['portal_url'];
856
			}
857
		}
858
		// If we are using Search engine friendly URLs then lets do the same for page links
859
		elseif (!empty($modSettings['queryless_urls']) && (empty($context['server']['is_cgi']) || ini_get('cgi.fix_pathinfo') == 1 || @get_cfg_var('cgi.fix_pathinfo') == 1) && (!empty($context['server']['is_apache']) || !empty($context['server']['is_lighttpd']) || !empty($context['server']['is_litespeed'])))
860
		{
861
			if (defined('SID') && SID != '')
862
			{
863
				$setLocation = preg_replace_callback('~^' . preg_quote($scripturl, '/') . '\?(?:' . SID . '(?:;|&|&amp;))((?:page)=[^#]+?)(#[^"]*?)?$~', 'redirectexit_callback', $setLocation);
864
			}
865
			else
866
			{
867
				$setLocation = preg_replace_callback('~^' . preg_quote($scripturl, '/') . '\?((?:page)=[^#"]+?)(#[^"]*?)?$~', 'redirectexit_callback', $setLocation);
868
			}
869
		}
870
	}
871
872
	/**
873
	 * A single check for the sake of remove yet another code edit. :P
874
	 * integrate_action_boardindex_after
875
	 */
876
	public static function sp_integrate_boardindex()
877
	{
878
		global $context, $modSettings, $scripturl;
879
880
		if (!empty($_GET) && $_GET !== array('action' => 'forum'))
881
		{
882
			$context['robot_no_index'] = true;
883
		}
884
885
		// Set the board index canonical URL correctly when portal mode is set to front page
886
		if (!empty($modSettings['sp_portal_mode']) && $modSettings['sp_portal_mode'] == 1 && empty($context['disable_sp']))
887
		{
888
			$context['canonical_url'] = $scripturl . '?action=forum';
889
		}
890
	}
891
892
	/**
893
	 * Dealing with the current action?
894
	 *
895
	 * @param string $current_action
896
	 */
897
	public static function sp_integrate_current_action(&$current_action)
898
	{
899
		global $modSettings, $context;
900
901
		// If it is home, it may be something else
902
		if ($current_action === 'home')
903
		{
904
			$current_action = $modSettings['sp_portal_mode'] == 3 && empty($context['standalone']) && empty($context['disable_sp'])
905
				? 'forum' : 'home';
906
		}
907
908
		if (empty($context['disable_sp']) && ((isset($_GET['board']) || isset($_GET['topic']) || in_array($context['current_action'], array('unread', 'unreadreplies', 'collapse', 'recent', 'stats', 'who'))) && in_array($modSettings['sp_portal_mode'], array(1, 3))))
909
		{
910
			$current_action = 'forum';
911
		}
912
	}
913
914
	/**
915
	 * Add in to the xml array our sortable action
916
	 * integrate_sa_xmlhttp
917
	 *
918
	 * @param array $subActions
919
	 */
920
	public static function sp_integrate_xmlhttp(&$subActions)
921
	{
922
		$subActions['blockorder'] = array('controller' => 'ManagePortalBlocks_Controller', 'file' => 'PortalAdminBlocks.controller.php', 'function' => 'action_blockorder', 'permission' => 'admin_forum');
923
		$subActions['userblockorder'] = array('controller' => 'PortalMain_Controller', 'dir' => CONTROLLERDIR, 'file' => 'PortalMain.controller.php', 'function' => 'action_userblockorder');
924
	}
925
926
	/**
927
	 * Add permissions that guest should never be able to have
928
	 * integrate_load_illegal_guest_permissions called from Permission.subs.php
929
	 */
930
	public static function sp_integrate_load_illegal_guest_permissions()
931
	{
932
		global $context;
933
934
		// Guests shouldn't be able to have any portal specific permissions.
935
		$context['non_guest_permissions'] = array_merge($context['non_guest_permissions'], array(
936
			'sp_admin',
937
			'sp_manage_settings',
938
			'sp_manage_blocks',
939
			'sp_manage_articles',
940
			'sp_manage_pages',
941
			'sp_manage_shoutbox',
942
			'sp_manage_profiles',
943
			'sp_manage_menus',
944
			'sp_manage_categories'
945
		));
946
	}
947
948
	/**
949
	 * Subs hook, integrate_pre_parsebbc
950
	 *
951
	 * - Allow addons access before entering the main parse_bbc loop
952
	 * - Prevents cutoff tag from bleeding into the message
953
	 *
954
	 * @param string $message
955
	 * @param string[]|null $bbc_tags
956
	 */
957
	public static function sp_integrate_pre_parsebbc(&$message)
958
	{
959
		if (strpos($message, '[cutoff]') !== false)
960
		{
961
			$message = str_replace('[cutoff]', '', $message);
962
		}
963
	}
964
}