| Total Complexity | 99 |
| Total Lines | 941 |
| Duplicated Lines | 0 % |
| Changes | 2 | ||
| Bugs | 0 | Features | 1 |
Complex classes like ManageSPortalModule_Controller often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ManageSPortalModule_Controller, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 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() |
||
| 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() |
||
| 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} © 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 . '(?:;|&|&))((?: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) |
||
| 962 | } |
||
| 963 | } |
||
| 964 | } |