Passed
Push — myDevel ( 6b67fa...0991c9 )
by Spuds
04:10
created

sp_integrate_boardindex()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 13
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 5
nc 4
nop 0
dl 0
loc 13
rs 9.2222
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * @package SimplePortal ElkArte
5
 *
6
 * @author SimplePortal Team
7
 * @copyright 2015-2017 SimplePortal Team
8
 * @license BSD 3-clause
9
 * @version 1.0.0 RC1
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
			'settings' => array(
49
				'disable_sp' => 1,
50
			),
51
			'setting_callback' => function ($value) {
52
				// Enabling
53
				if ($value)
54
				{
55
					Hooks::instance()->enableIntegration('Portal_Integrate');
56
				}
57
				// Disabling
58
				else
59
				{
60
					Hooks::instance()->disableIntegration('Portal_Integrate');
61
				}
62
			},
63
		);
64
	}
65
66
	/******************************INTEGRATION HOOKS*******************************************/
67
68
	/**
69
	 * Adds [spattach] BBC code tags for use with article images.  Mostly the same as ILA [attach]
70
	 *
71
	 * @param mixed[] $additional_bbc
72
	 */
73
	public static function sp_integrate_additional_bbc(&$additional_bbc)
74
	{
75
		global $scripturl;
76
77
		// Generally we don't want to render inside of these tags ...
78
		$disallow = array(
79
			'quote' => 1,
80
			'code' => 1,
81
			'nobbc' => 1,
82
			'html' => 1,
83
			'php' => 1,
84
		);
85
86
		// Add simplePortal ILA codes
87
		$additional_bbc = array_merge($additional_bbc, array(
88
			// Require a width with optional height/align to allow use of full image and/or ;thumb
89
			array(
90
				Codes::ATTR_TAG => 'spattach',
91
				Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT,
92
				Codes::ATTR_PARAM => array(
93
					'width' => array(
94
						Codes::PARAM_ATTR_VALIDATE => self::validate_width(),
95
						Codes::PARAM_ATTR_MATCH => '(\d+)',
96
					),
97
					'height' => array(
98
						Codes::PARAM_ATTR_OPTIONAL => true,
99
						Codes::PARAM_ATTR_VALUE => 'max-height:$1px;',
100
						Codes::PARAM_ATTR_MATCH => '(\d+)',
101
					),
102
					'align' => array(
103
						Codes::PARAM_ATTR_OPTIONAL => true,
104
						Codes::PARAM_ATTR_VALUE => 'float$1',
105
						Codes::PARAM_ATTR_MATCH => '(right|left|center)',
106
					),
107
				),
108
				Codes::ATTR_CONTENT => '<a id="link_$1" 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>',
109
				Codes::ATTR_VALIDATE => self::validate_options(),
110
				Codes::ATTR_DISALLOW_PARENTS => $disallow,
111
				Codes::ATTR_BLOCK_LEVEL => false,
112
				Codes::ATTR_AUTOLINK => false,
113
				Codes::ATTR_LENGTH => 8,
114
			),
115
			// Require a height with optional width/align to allow removal of ;thumb
116
			array(
117
				Codes::ATTR_TAG => 'spattach',
118
				Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT,
119
				Codes::ATTR_PARAM => array(
120
					'height' => array(
121
						Codes::PARAM_ATTR_VALIDATE => self::validate_height(),
122
						Codes::PARAM_ATTR_MATCH => '(\d+)',
123
					),
124
					'width' => array(
125
						Codes::PARAM_ATTR_OPTIONAL => true,
126
						Codes::PARAM_ATTR_VALUE => 'width:100%;max-width:$1px;',
127
						Codes::PARAM_ATTR_MATCH => '(\d+)',
128
					),
129
					'align' => array(
130
						Codes::PARAM_ATTR_OPTIONAL => true,
131
						Codes::PARAM_ATTR_VALUE => 'float$1',
132
						Codes::PARAM_ATTR_MATCH => '(right|left|center)',
133
					),
134
				),
135
				Codes::ATTR_CONTENT => '<a id="link_$1" 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>',
136
				Codes::ATTR_VALIDATE => self::validate_options(),
137
				Codes::ATTR_DISALLOW_PARENTS => $disallow,
138
				Codes::ATTR_BLOCK_LEVEL => false,
139
				Codes::ATTR_AUTOLINK => false,
140
				Codes::ATTR_LENGTH => 8,
141
			),
142
			// Just a simple attach
143
			array(
144
				Codes::ATTR_TAG => 'spattach',
145
				Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT,
146
				Codes::ATTR_CONTENT => '$1',
147
				Codes::ATTR_VALIDATE => self::validate_plain(),
148
				Codes::ATTR_DISALLOW_PARENTS => $disallow,
149
				Codes::ATTR_BLOCK_LEVEL => false,
150
				Codes::ATTR_AUTOLINK => false,
151
				Codes::ATTR_LENGTH => 8,
152
			),
153
			// Just an align ?
154
			array(
155
				Codes::ATTR_TAG => 'spattach',
156
				Codes::ATTR_TYPE => Codes::TYPE_UNPARSED_CONTENT,
157
				Codes::ATTR_PARAM => array(
158
					'type' => array(
159
						Codes::PARAM_ATTR_OPTIONAL => true,
160
						Codes::PARAM_ATTR_VALUE => ';$1',
161
						Codes::PARAM_ATTR_MATCH => '(thumb|image)',
162
					),
163
					'align' => array(
164
						Codes::PARAM_ATTR_OPTIONAL => true,
165
						Codes::PARAM_ATTR_VALUE => 'float$1',
166
						Codes::PARAM_ATTR_MATCH => '(right|left|center)',
167
					),
168
				),
169
				Codes::ATTR_CONTENT => '<a id="link_$1" 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>',
170
				Codes::ATTR_VALIDATE => self::validate_options(),
171
				Codes::ATTR_DISALLOW_PARENTS => $disallow,
172
				Codes::ATTR_BLOCK_LEVEL => false,
173
				Codes::ATTR_AUTOLINK => false,
174
				Codes::ATTR_LENGTH => 8,
175
			),
176
		));
177
	}
178
179
	/**
180
	 * Used when the optional width parameter is set
181
	 *
182
	 * - Determines the best image, full or thumbnail, based on ILA width desired
183
	 * - Used as PARAM_ATTR_VALIDATE function
184
	 *
185
	 * @return Closure
186
	 */
187
	public static function validate_width()
188
	{
189
		global $modSettings;
190
191
		return function ($data) use ($modSettings) {
192
			if (!empty($modSettings['attachmentThumbWidth']) && $data <= $modSettings['attachmentThumbWidth'])
193
			{
194
				return ';thumb" style="width:100%;max-width:' . $data . 'px;';
195
			}
196
			else
197
			{
198
				return '" style="width:100%;max-width:' . $data . 'px;';
199
			}
200
		};
201
	}
202
203
	/**
204
	 * Used when the optional height parameter is set and no width is set
205
	 *
206
	 * - Determines the best image, full or thumbnail, based on desired ILA height
207
	 * - Used as PARAM_ATTR_VALIDATE function
208
	 *
209
	 * @return Closure
210
	 */
211
	public static function validate_height()
212
	{
213
		global $modSettings;
214
215
		return function ($data) use ($modSettings) {
216
			if (!empty($modSettings['attachmentThumbHeight']) && $data <= $modSettings['attachmentThumbHeight'])
217
			{
218
				return ';thumb" style="max-height:' . $data . 'px;';
219
			}
220
			else
221
			{
222
				return '" style="max-height:' . $data . 'px;';
223
			}
224
		};
225
	}
226
227
	/**
228
	 * This provides for some control for "plain" tags
229
	 *
230
	 * - Determines if the ILA is an image or not
231
	 * - Sets the lightbox attributes if an image is identified
232
	 * - Keeps track of attachment usage to prevent displaying below the post
233
	 *
234
	 * @return Closure
235
	 */
236
	public static function validate_plain()
237
	{
238
		global $user_info, $scripturl, $context, $modSettings;
239
240
		return function (&$tag, &$data) use ($user_info, $scripturl, &$context, $modSettings) {
241
			$num = $data;
242
			$is_image = array();
243
			$preview = strpos($data, 'post_tmp_' . $user_info['id'] . '_');
244
			$article = $context['article']['id'] ?? 0;
245
246
			// Not a preview, then sanitize the attach id and determine the actual type
247
			if ($preview === false)
248
			{
249
				$num = (int) $data;
250
				$is_image = isArticleAttachmentImage($num);
251
			}
252
253
			// An image will get the light box treatment
254
			if (!empty($is_image['is_image']) || $preview !== false)
255
			{
256
				$type = !empty($modSettings['attachmentThumbnails']) ? ';thumb' : '';
257
				$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>';
258
			}
259
			else
260
			{
261
				// Not an image, determine a mime or use a default thumbnail
262
				require_once(SUBSDIR . '/Attachments.subs.php');
263
				$check = returnMimeThumb(($is_image['fileext'] ?? ''), true);
264
265
				if ($is_image === false)
266
				{
267
					$data = '<img src="' . $check . '" alt="" class="bbc_img" />';
268
				}
269
				else
270
				{
271
					$data = '<a href="' . $scripturl . '?action=portal;sa=spattach;article=' . $article . ';attach=' . $num . '"><img src="' . $check . '" alt="' . $is_image['filename'] . '" class="bbc_img" /></a>';
272
				}
273
			}
274
275
			$context['ila_dont_show_attach_below'][] = $num;
276
			$context['ila_dont_show_attach_below'] = array_unique($context['ila_dont_show_attach_below']);
277
		};
278
	}
279
280
	/**
281
	 * For tags with options (width / height / align)
282
	 *
283
	 * - Keeps track of attachment usage to prevent displaying below the post
284
	 *
285
	 * @return Closure
286
	 */
287
	public static function validate_options()
288
	{
289
		global $context, $scripturl;
290
291
		return function (&$tag, &$data) use (&$context, $scripturl) {
0 ignored issues
show
Unused Code introduced by
The import $scripturl is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
292
			$article = $context['article']['id'] ?? 0;
293
294
			// Not a preview, then sanitize the attach id
295
			if (strpos($data, 'post_tmp_') === false)
296
			{
297
				$data = (int) $data;
298
			}
299
300
			$tag[Codes::ATTR_CONTENT] = str_replace('{article}', $article, $tag[Codes::ATTR_CONTENT]);
301
302
			$context['ila_dont_show_attach_below'][] = $data;
303
			$context['ila_dont_show_attach_below'] = array_unique($context['ila_dont_show_attach_below']);
304
		};
305
	}
306
307
	/**
308
	 * Integration hook integrate_setup_allow
309
	 *
310
	 * Called from Theme.php setupMenuContext(), used to determine if the admin button is visible for a given
311
	 * member as its needed to access certain sub menus
312
	 */
313
	public static function sp_integrate_setup_allow()
314
	{
315
		global $context;
316
317
		$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'));
318
	}
319
320
	/**
321
	 * integration hook integrate_actions
322
	 * Called from dispatcher.class, used to add in custom actions
323
	 *
324
	 * @param array $actions
325
	 */
326
	public static function sp_integrate_actions(&$actions)
327
	{
328
		global $context;
329
330
		if (!empty($context['disable_sp']))
331
		{
332
			return;
333
		}
334
335
		$actions['forum'] = array('BoardIndex.controller.php', 'BoardIndex_Controller', 'action_boardindex');
336
		$actions['portal'] = array('PortalMain.controller.php', 'PortalMain_Controller', 'action_index');
337
		$actions['shoutbox'] = array('PortalShoutbox.controller.php', 'Shoutbox_Controller', 'action_sportal_shoutbox');
338
	}
339
340
	/**
341
	 * Admin hook, integrate_admin_areas, called from Menu.subs
342
	 * adds the admin menu
343
	 *
344
	 * @param array $admin_areas
345
	 */
346
	public static function sp_integrate_admin_areas(&$admin_areas)
347
	{
348
		global $txt, $context;
349
350
		require_once(SUBSDIR . '/Portal.subs.php');
351
		loadLanguage('SPortalAdmin');
352
		loadLanguage('SPortal');
353
354
		$temp = $admin_areas;
355
		$admin_areas = array();
356
357
		foreach ($temp as $area => $data)
358
		{
359
			$admin_areas[$area] = $data;
360
361
			// Add in our admin menu option after layout aka forum
362
			if ($area === 'layout')
363
			{
364
				$admin_areas['portal'] = array(
365
					'enabled' => in_array('pt', $context['admin_features']),
366
					'title' => $txt['sp-adminCatTitle'],
367
					'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'),
368
					'areas' => array(
369
						'portalconfig' => array(
370
							'label' => $txt['sp-adminConfiguration'],
371
							'file' => 'PortalAdminMain.controller.php',
372
							'controller' => 'ManagePortalConfig_Controller',
373
							'function' => 'action_index',
374
							'icon' => 'transparent.png',
375
							'class' => 'admin_img_corefeatures',
376
							'permission' => array('sp_admin', 'sp_manage_settings'),
377
							'subsections' => array(
378
								'information' => array($txt['sp-info_title']),
379
								'generalsettings' => array($txt['sp-adminGeneralSettingsName']),
380
								'blocksettings' => array($txt['sp-adminBlockSettingsName']),
381
								'articlesettings' => array($txt['sp-adminArticleSettingsName']),
382
							),
383
						),
384
						'portalblocks' => array(
385
							'label' => $txt['sp-blocksBlocks'],
386
							'file' => 'PortalAdminBlocks.controller.php',
387
							'controller' => 'ManagePortalBlocks_Controller',
388
							'function' => 'action_index',
389
							'icon' => 'blocks.png',
390
							'permission' => array('sp_admin', 'sp_manage_blocks'),
391
							'subsections' => array(
392
								'list' => array($txt['sp-adminBlockListName']),
393
								'add' => array($txt['sp-adminBlockAddName']),
394
								'header' => array($txt['sp-positionHeader']),
395
								'left' => array($txt['sp-positionLeft']),
396
								'top' => array($txt['sp-positionTop']),
397
								'bottom' => array($txt['sp-positionBottom']),
398
								'right' => array($txt['sp-positionRight']),
399
								'footer' => array($txt['sp-positionFooter']),
400
							),
401
						),
402
						'portalarticles' => array(
403
							'label' => $txt['sp_admin_articles_title'],
404
							'file' => 'PortalAdminArticles.controller.php',
405
							'controller' => 'ManagePortalArticles_Controller',
406
							'function' => 'action_index',
407
							'icon' => 'transparent.png',
408
							'class' => 'admin_img_news',
409
							'permission' => array('sp_admin', 'sp_manage_articles'),
410
							'subsections' => array(
411
								'list' => array($txt['sp_admin_articles_list']),
412
								'add' => array($txt['sp_admin_articles_add']),
413
							),
414
						),
415
						'portalcategories' => array(
416
							'label' => $txt['sp_admin_categories_title'],
417
							'file' => 'PortalAdminCategories.controller.php',
418
							'controller' => 'ManagePortalCategories_Controller',
419
							'function' => 'action_index',
420
							'icon' => 'transparent.png',
421
							'class' => 'admin_img_server',
422
							'permission' => array('sp_admin', 'sp_manage_categories'),
423
							'subsections' => array(
424
								'list' => array($txt['sp_admin_categories_list']),
425
								'add' => array($txt['sp_admin_categories_add']),
426
							),
427
						),
428
						'portalpages' => array(
429
							'label' => $txt['sp_admin_pages_title'],
430
							'file' => 'PortalAdminPages.controller.php',
431
							'controller' => 'ManagePortalPages_Controller',
432
							'function' => 'action_index',
433
							'icon' => 'transparent.png',
434
							'class' => 'admin_img_posts',
435
							'permission' => array('sp_admin', 'sp_manage_pages'),
436
							'subsections' => array(
437
								'list' => array($txt['sp_admin_pages_list']),
438
								'add' => array($txt['sp_admin_pages_add']),
439
							),
440
						),
441
						'portalshoutbox' => array(
442
							'label' => $txt['sp_admin_shoutbox_title'],
443
							'file' => 'PortalAdminShoutbox.controller.php',
444
							'controller' => 'ManagePortalShoutbox_Controller',
445
							'function' => 'action_index',
446
							'icon' => 'transparent.png',
447
							'class' => 'admin_img_smiley',
448
							'permission' => array('sp_admin', 'sp_manage_shoutbox'),
449
							'subsections' => array(
450
								'list' => array($txt['sp_admin_shoutbox_list']),
451
								'add' => array($txt['sp_admin_shoutbox_add']),
452
							),
453
						),
454
						/* Shhh its a secret for now, not done yet ;)
455
						'portalmenus' => array(
456
							'label' => $txt['sp_admin_menus_title'],
457
							'file' => 'PortalAdminMenus.controller.php',
458
							'controller' => 'ManagePortalMenus_Controller',
459
							'function' => 'action_index',
460
							'icon' => 'menus.png',
461
							'permission' => array('sp_admin', 'sp_manage_menus'),
462
							'subsections' => array(
463
								'listmainitem' => array($txt['sp_admin_menus_main_item_list']),
464
								'addmainitem' => array($txt['sp_admin_menus_main_item_add']),
465
								'listcustommenu' => array($txt['sp_admin_menus_custom_menu_list']),
466
								'addcustommenu' => array($txt['sp_admin_menus_custom_menu_add']),
467
								'addcustomitem' => array($txt['sp_admin_menus_custom_item_add'], 'enabled' => !empty($_REQUEST['sa']) && $_REQUEST['sa'] === 'listcustomitem'),
468
							),
469
						),
470
						*/
471
						'portalprofiles' => array(
472
							'label' => $txt['sp_admin_profiles_title'],
473
							'file' => 'PortalAdminProfiles.controller.php',
474
							'controller' => 'ManagePortalProfile_Controller',
475
							'function' => 'action_index',
476
							'icon' => 'transparent.png',
477
							'class' => 'admin_img_permissions',
478
							'permission' => array('sp_admin', 'sp_manage_profiles'),
479
							'subsections' => array(
480
								'listpermission' => array($txt['sp_admin_permission_profiles_list']),
481
								'liststyle' => array($txt['sp_admin_style_profiles_list']),
482
								'listvisibility' => array($txt['sp_admin_visibility_profiles_list']),
483
							),
484
						),
485
					),
486
				);
487
			}
488
		}
489
	}
490
491
	/**
492
	 * Permissions hook, integrate_load_permissions, called from ManagePermissions.php
493
	 * used to add new permissions
494
	 *
495
	 * @param array $permissionGroups
496
	 * @param array $permissionList
497
	 * @param array $leftPermissionGroups
498
	 * @param array $hiddenPermissions
499
	 * @param array $relabelPermissions
500
	 */
501
	public static function sp_integrate_load_permissions(&$permissionGroups, &$permissionList, &$leftPermissionGroups, &$hiddenPermissions, &$relabelPermissions)
502
	{
503
		$permissionList['membergroup'] = array_merge($permissionList['membergroup'], array(
504
			'sp_admin' => array(false, 'sp', 'sp'),
505
			'sp_manage_settings' => array(false, 'sp', 'sp'),
506
			'sp_manage_blocks' => array(false, 'sp', 'sp'),
507
			'sp_manage_articles' => array(false, 'sp', 'sp'),
508
			'sp_manage_pages' => array(false, 'sp', 'sp'),
509
			'sp_manage_shoutbox' => array(false, 'sp', 'sp'),
510
			'sp_manage_menus' => array(false, 'sp', 'sp'),
511
			'sp_manage_profiles' => array(false, 'sp', 'sp'),
512
		));
513
514
		$permissionGroups['membergroup'][] = 'sp';
515
516
		$leftPermissionGroups[] = 'sp';
517
	}
518
519
	/**
520
	 * Whos online hook, integrate_whos_online, called from who.subs
521
	 * translates custom actions to allow us to show what area a user is in
522
	 *
523
	 * @param string $actions
524
	 *
525
	 * @return string|array
526
	 */
527
	public static function sp_integrate_whos_online($actions)
528
	{
529
		global $scripturl, $modSettings, $txt;
530
531
		$data = null;
532
533
		require_once(SUBSDIR . '/Portal.subs.php');
534
		loadLanguage('SPortal');
535
536
		// This may miss if its needed for the first action ... need to improve the hook or
537
		// find another location
538
		if ($modSettings['sp_portal_mode'] == 1)
539
		{
540
			$txt['who_index'] = sprintf($txt['sp_who_index'], $scripturl);
541
			$txt['whoall_forum'] = sprintf($txt['sp_who_forum'], $scripturl);
542
		}
543
		elseif ($modSettings['sp_portal_mode'] == 3)
544
		{
545
			$txt['whoall_portal'] = sprintf($txt['sp_who_index'], $scripturl);
546
		}
547
548
		// If its a portal action, lets check it out.
549
		if (isset($actions['page']))
550
		{
551
			$data = self::sp_whos_online_page($actions['page']);
552
		}
553
		elseif (isset($actions['article']))
554
		{
555
			$data = self::sp_whos_online_article($actions['article']);
556
		}
557
558
		return $data;
559
	}
560
561
	/**
562
	 * Page online hook, helper function to determine the page a user is viewing
563
	 *
564
	 * @param string $page_id
565
	 *
566
	 * @return string
567
	 */
568
	public static function sp_whos_online_page($page_id)
569
	{
570
		global $scripturl, $txt, $context;
571
572
		$db = database();
573
574
		$data = $txt['who_hidden'];
575
		$numeric_ids = '';
576
		$string_ids = '';
577
		$page_where = '';
578
579
		if (is_numeric($page_id))
580
		{
581
			$numeric_ids = (int) $page_id;
582
		}
583
		else
584
		{
585
			$string_ids = $page_id;
586
		}
587
588
		if (!empty($numeric_ids))
589
		{
590
			$page_where = 'id_page IN ({int:numeric_ids})';
591
		}
592
593
		if (!empty($string_ids))
594
		{
595
			$page_where = 'namespace IN ({string:string_ids})';
596
		}
597
598
		$query = sprintf($context['SPortal']['permissions']['query'], 'permissions');
599
600
		$result = $db->query('', '
601
		SELECT
602
			id_page, namespace, title, permissions
603
		FROM {db_prefix}sp_pages
604
		WHERE ' . $page_where . ' AND ' . $query . '
605
		LIMIT {int:limit}',
606
			array(
607
				'numeric_ids' => $numeric_ids,
608
				'string_ids' => $string_ids,
609
				'limit' => 1,
610
			)
611
		);
612
		$page_data = '';
613
		while ($row = $db->fetch_assoc($result))
614
		{
615
			$page_data = array(
616
				'id' => $row['id_page'],
617
				'namespace' => $row['namespace'],
618
				'title' => $row['title'],
619
			);
620
		}
621
		$db->free_result($result);
622
623
		if (!empty($page_data))
624
		{
625
			if (isset($page_data['id']))
626
			{
627
				$data = sprintf($txt['sp_who_page'], $page_data['id'], censor($page_data['title']), $scripturl);
628
			}
629
630
			if (isset($page_data['namespace']))
631
			{
632
				$data = sprintf($txt['sp_who_page'], $page_data['namespace'], censor($page_data['title']), $scripturl);
633
			}
634
		}
635
636
		return $data;
637
	}
638
639
	/**
640
	 * Article online hook, helper function to determine the page a user is viewing
641
	 *
642
	 * @param string $article_id
643
	 *
644
	 * @return string
645
	 */
646
	public static function sp_whos_online_article($article_id)
647
	{
648
		global $scripturl, $txt, $context;
649
650
		$db = database();
651
652
		$data = $txt['who_hidden'];
653
		$numeric_ids = '';
654
		$string_ids = '';
655
		$article_where = '';
656
657
		if (is_numeric($article_id))
658
		{
659
			$numeric_ids = (int) $article_id;
660
		}
661
		else
662
		{
663
			$string_ids = $article_id;
664
		}
665
666
		if (!empty($numeric_ids))
667
		{
668
			$article_where = 'id_article IN ({int:numeric_ids})';
669
		}
670
671
		if (!empty($string_ids))
672
		{
673
			$article_where = 'namespace IN ({string:string_ids})';
674
		}
675
676
		$query = sprintf($context['SPortal']['permissions']['query'], 'permissions');
677
678
		$result = $db->query('', '
679
		SELECT
680
			id_article, namespace, title, permissions
681
		FROM {db_prefix}sp_articles
682
		WHERE ' . $article_where . ' AND ' . $query . '
683
		LIMIT {int:limit}',
684
			array(
685
				'numeric_ids' => $numeric_ids,
686
				'string_ids' => $string_ids,
687
				'limit' => 1,
688
			)
689
		);
690
		$article_data = '';
691
		while ($row = $db->fetch_assoc($result))
692
		{
693
			$article_data = array(
694
				'id' => $row['id_article'],
695
				'namespace' => $row['namespace'],
696
				'title' => $row['title'],
697
			);
698
		}
699
		$db->free_result($result);
700
701
		if (!empty($article_data))
702
		{
703
			if (isset($article_data['id']))
704
			{
705
				$data = sprintf($txt['sp_who_article'], $article_data['id'], censor($article_data['title']), $scripturl);
706
			}
707
708
			if (isset($article_data['namespace']))
709
			{
710
				$data = sprintf($txt['sp_who_article'], $article_data['namespace'], censor($article_data['title']), $scripturl);
711
			}
712
		}
713
714
		return $data;
715
	}
716
717
	/**
718
	 * Theme hook, integrate_init_theme, called from load.php
719
	 * Used to initialize main portal functions as soon as the theme is started
720
	 */
721
	public static function sp_integrate_init_theme()
722
	{
723
		// Need to run init to determine if we are even active
724
		require_once(SUBSDIR . '/Portal.subs.php');
725
		sportal_init();
726
	}
727
728
	/**
729
	 * Help hook, integrate_quickhelp, called from help.controller.php
730
	 * Used to add in additional help languages for use in the admin quickhelp
731
	 */
732
	public static function sp_integrate_quickhelp()
733
	{
734
		require_once(SUBSDIR . '/Portal.subs.php');
735
736
		// Load the Simple Portal Help file.
737
		loadLanguage('SPortalHelp');
738
		loadLanguage('SPortalAdmin');
739
	}
740
741
	/**
742
	 * Integration hook integrate_buffer, called from ob_exit via call_integration_buffer
743
	 * Used to modify the output buffer before its sent, here we add in our copyright
744
	 *
745
	 * @param string $tourniquet
746
	 *
747
	 * @return string
748
	 */
749
	public static function sp_integrate_buffer($tourniquet)
750
	{
751
		global $sportal_version, $context, $modSettings, $forum_copyright;
752
753
		$fix = str_replace('{version}', $sportal_version, '<a href="https://simpleportal.net/" target="_blank" class="new_win">SimplePortal {version} &copy; 2008-' . strftime('%Y') . '</a>');
754
755
		if ((ELK === 'SSI' && empty($context['standalone']))
756
			|| !Template_Layers::instance()->hasLayers()
757
			|| empty($modSettings['sp_portal_mode'])
758
			|| strpos($tourniquet, $fix) !== false)
759
		{
760
			return $tourniquet;
761
		}
762
763
		// Don't display copyright for things like SSI.
764
		if (!defined('FORUM_VERSION'))
765
		{
766
			return $tourniquet;
767
		}
768
769
		// Append our cp notice at the end of the line
770
		$finds = array(
771
			$forum_copyright,
772
		);
773
		$replaces = array(
774
			sprintf($forum_copyright, FORUM_VERSION) . ' | ' . $fix,
775
		);
776
777
		$tourniquet = str_replace($finds, $replaces, $tourniquet);
778
779
		// Can't find it for some reason so we add it at the end
780
		if (strpos($tourniquet, $fix) === false)
781
		{
782
			$fix = '<div style="text-align: center; width: 100%; font-size: x-small; margin-bottom: 5px;">' . $fix . '</div></body></html>';
783
			$tourniquet = preg_replace('~</body>\s*</html>~', $fix, $tourniquet);
784
		}
785
786
		return $tourniquet;
787
	}
788
789
	/**
790
	 * Menu Button hook, integrate_menu_buttons, called from subs.php
791
	 * used to add top menu buttons
792
	 *
793
	 * @param array $buttons
794
	 */
795
	public static function sp_integrate_menu_buttons(&$buttons)
796
	{
797
		global $txt, $scripturl, $modSettings, $context;
798
799
		require_once(SUBSDIR . '/Portal.subs.php');
800
		loadLanguage('SPortal');
801
802
		// Set the right portalurl based on what integration mode the portal is using
803
		if ($modSettings['sp_portal_mode'] == 1 && empty($context['disable_sp']))
804
		{
805
			$sportal_url = $scripturl . '?action=forum';
806
		}
807
		elseif ($modSettings['sp_portal_mode'] == 3 && empty($context['disable_sp']))
808
		{
809
			$buttons['home']['href'] = $modSettings['sp_standalone_url'];
810
			$sportal_url = $modSettings['sp_standalone_url'];
811
		}
812
		else
813
		{
814
			return;
815
		}
816
817
		theme()->addCSSRules("
818
	.i-spgroup::before {
819
		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\");
820
	}");
821
822
		// Define the new menu item(s), show it for modes 1 and 3 only
823
		$buttons = elk_array_insert($buttons, 'home', array(
824
			'forum' => array(
825
				'title' => empty($txt['sp-forum']) ? 'Forum' : $txt['sp-forum'],
826
				'data-icon' => 'i-spgroup',
827
				'href' => $sportal_url,
828
				'show' => in_array($modSettings['sp_portal_mode'], array(1, 3)) && empty($context['disable_sp']),
829
				'sub_buttons' => array(),
830
			),
831
		), 'after');
832
	}
833
834
	/**
835
	 * Redirection hook, integrate_redirect, called from subs.php redirectexit()
836
	 *
837
	 * @param string $setLocation
838
	 *
839
	 * @uses redirectexit_callback in subs.php
840
	 */
841
	public static function sp_integrate_redirect(&$setLocation)
842
	{
843
		global $modSettings, $context, $scripturl;
844
845
		// Set the default redirect location as the forum or the portal.
846
		if ($scripturl == $setLocation && ($modSettings['sp_portal_mode'] == 1 || $modSettings['sp_portal_mode'] == 3))
847
		{
848
			// Redirect the user to the forum.
849
			if (!empty($modSettings['sp_disableForumRedirect']))
850
			{
851
				$setLocation = '?action=forum';
852
			}
853
			// Redirect the user to the SSI.php standalone portal.
854
			elseif ($modSettings['sp_portal_mode'] == 3)
855
			{
856
				$setLocation = $context['portal_url'];
857
			}
858
		}
859
		// If we are using Search engine friendly URLs then lets do the same for page links
860
		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'])))
861
		{
862
			if (defined('SID') && SID != '')
863
			{
864
				$setLocation = preg_replace_callback('~^' . preg_quote($scripturl, '/') . '\?(?:' . SID . '(?:;|&|&amp;))((?:page)=[^#]+?)(#[^"]*?)?$~', 'redirectexit_callback', $setLocation);
865
			}
866
			else
867
			{
868
				$setLocation = preg_replace_callback('~^' . preg_quote($scripturl, '/') . '\?((?:page)=[^#"]+?)(#[^"]*?)?$~', 'redirectexit_callback', $setLocation);
869
			}
870
		}
871
	}
872
873
	/**
874
	 * A single check for the sake of remove yet another code edit. :P
875
	 * integrate_action_boardindex_after
876
	 */
877
	public static function sp_integrate_boardindex()
878
	{
879
		global $context, $modSettings, $scripturl;
880
881
		if (!empty($_GET) && $_GET !== array('action' => 'forum'))
882
		{
883
			$context['robot_no_index'] = true;
884
		}
885
886
		// Set the board index canonical URL correctly when portal mode is set to front page
887
		if (!empty($modSettings['sp_portal_mode']) && $modSettings['sp_portal_mode'] == 1 && empty($context['disable_sp']))
888
		{
889
			$context['canonical_url'] = $scripturl . '?action=forum';
890
		}
891
	}
892
893
	/**
894
	 * Dealing with the current action?
895
	 *
896
	 * @param string $current_action
897
	 */
898
	public static function sp_integrate_current_action(&$current_action)
899
	{
900
		global $modSettings, $context;
901
902
		// If it is home, it may be something else
903
		if ($current_action === 'home')
904
		{
905
			$current_action = $modSettings['sp_portal_mode'] == 3 && empty($context['standalone']) && empty($context['disable_sp'])
906
				? 'forum' : 'home';
907
		}
908
909
		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))))
910
		{
911
			$current_action = 'forum';
912
		}
913
	}
914
915
	/**
916
	 * Add in to the xml array our sortable action
917
	 * integrate_sa_xmlhttp
918
	 *
919
	 * @param array $subActions
920
	 */
921
	public static function sp_integrate_xmlhttp(&$subActions)
922
	{
923
		$subActions['blockorder'] = array('controller' => 'ManagePortalBlocks_Controller', 'file' => 'PortalAdminBlocks.controller.php', 'function' => 'action_blockorder', 'permission' => 'admin_forum');
924
		$subActions['userblockorder'] = array('controller' => 'PortalMain_Controller', 'dir' => CONTROLLERDIR, 'file' => 'PortalMain.controller.php', 'function' => 'action_userblockorder');
925
	}
926
927
	/**
928
	 * Add permissions that guest should never be able to have
929
	 * integrate_load_illegal_guest_permissions called from Permission.subs.php
930
	 */
931
	public static function sp_integrate_load_illegal_guest_permissions()
932
	{
933
		global $context;
934
935
		// Guests shouldn't be able to have any portal specific permissions.
936
		$context['non_guest_permissions'] = array_merge($context['non_guest_permissions'], array(
937
			'sp_admin',
938
			'sp_manage_settings',
939
			'sp_manage_blocks',
940
			'sp_manage_articles',
941
			'sp_manage_pages',
942
			'sp_manage_shoutbox',
943
			'sp_manage_profiles',
944
			'sp_manage_menus',
945
			'sp_manage_categories'
946
		));
947
	}
948
949
	/**
950
	 * Subs hook, integrate_pre_parsebbc
951
	 *
952
	 * - Allow addons access before entering the main parse_bbc loop
953
	 * - Prevents cutoff tag from bleeding into the message
954
	 *
955
	 * @param string $message
956
	 * @param string[]|null $bbc_tags
957
	 */
958
	public static function sp_integrate_pre_parsebbc(&$message)
959
	{
960
		if (strpos($message, '[cutoff]') !== false)
961
		{
962
			$message = str_replace('[cutoff]', '', $message);
963
		}
964
	}
965
}