Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
+151
-102
@@ -11,56 +11,80 @@
|
||||
namespace IPS\Dispatcher;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DomainException;
|
||||
use IPS\Application;
|
||||
use IPS\Application\Module;
|
||||
use IPS\Data\Cache;
|
||||
use IPS\Data\Cache\None;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db\Exception;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Platform\Bridge;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function intval;
|
||||
use function is_array;
|
||||
use const IPS\CIC2;
|
||||
use const IPS\SITE_FILES_PATH;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Dispatcher
|
||||
*/
|
||||
abstract class _Standard extends \IPS\Dispatcher
|
||||
abstract class Standard extends Dispatcher
|
||||
{
|
||||
/**
|
||||
* Application
|
||||
*/
|
||||
public $application;
|
||||
public ?Application $application = NULL;
|
||||
|
||||
/**
|
||||
* Module
|
||||
*/
|
||||
public $module;
|
||||
public ?Module $module = NULL;
|
||||
|
||||
/**
|
||||
* Controller
|
||||
*/
|
||||
public $controller;
|
||||
public ?string $controller = NULL;
|
||||
|
||||
/**
|
||||
* @brief Check access permissions
|
||||
*/
|
||||
public $checkGenericPermissions = TRUE;
|
||||
public bool $checkGenericPermissions = TRUE;
|
||||
|
||||
public array $platformFeatureExpires = [];
|
||||
|
||||
/**
|
||||
* Base CSS
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function baseCss()
|
||||
public static function baseCss() : void
|
||||
{
|
||||
if ( !\IPS\Request::i()->isAjax() )
|
||||
if ( !Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'framework.css', 'core', 'global' ) );
|
||||
if ( \IPS\Theme::i()->settings['responsive'] )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'responsive.css', 'core', 'global' ) );
|
||||
}
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'framework/framework.css', 'core', 'global' ) );
|
||||
}
|
||||
|
||||
if ( \count( \IPS\Lang::languages() ) > 1 )
|
||||
if ( count( Lang::languages() ) > 1 )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'flags.css', 'core', 'global' ) );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'flags.css', 'core', 'global' ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,28 +93,26 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function baseJs()
|
||||
protected static function baseJs() : void
|
||||
{
|
||||
/* Stuff for output */
|
||||
if ( !\IPS\Request::i()->isAjax() )
|
||||
if ( !Request::i()->isAjax() )
|
||||
{
|
||||
/* JS */
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'library.js' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'js_lang_' . \IPS\Member::loggedIn()->language()->id . '.js' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'framework.js' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'global_core.js', 'core', 'global' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'plugins.js', 'core', 'plugins' ) );
|
||||
\IPS\Output::i()->jsVars['date_format'] = mb_strtolower( \IPS\Member::loggedIn()->language()->preferredDateFormat() );
|
||||
\IPS\Output::i()->jsVars['date_first_day'] = 0;
|
||||
\IPS\Output::i()->jsVars['ipb_url_filter_option'] = \IPS\Settings::i()->ipb_url_filter_option;
|
||||
\IPS\Output::i()->jsVars['url_filter_any_action'] = \IPS\Settings::i()->url_filter_any_action;
|
||||
\IPS\Output::i()->jsVars['bypass_profanity'] = \intval( \IPS\Member::loggedIn()->group['g_bypass_badwords'] );
|
||||
\IPS\Output::i()->jsVars['emoji_style'] = ( \IPS\Settings::i()->getFromConfGlobal('sql_utf8mb4') === TRUE ) ? \IPS\Settings::i()->emoji_style : 'disabled';
|
||||
\IPS\Output::i()->jsVars['emoji_shortcodes'] = (bool) \IPS\Settings::i()->emoji_shortcodes;
|
||||
\IPS\Output::i()->jsVars['emoji_ascii'] = (bool) \IPS\Settings::i()->emoji_ascii;
|
||||
\IPS\Output::i()->jsVars['emoji_cache'] = (int) \IPS\Settings::i()->emoji_cache;
|
||||
\IPS\Output::i()->jsVars['image_jpg_quality'] = (int) \IPS\Settings::i()->image_jpg_quality ?: 85;
|
||||
\IPS\Output::i()->jsVars['cloud2'] = (bool) \IPS\CIC2;
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'library.js' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, [ Output\Javascript::getLanguageUrl( Member::loggedIn()->language() ) ] );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'framework.js' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'global_core.js', 'core', 'global' ) );
|
||||
Output::i()->jsVars['date_format'] = mb_strtolower( Member::loggedIn()->language()->preferredDateFormat() );
|
||||
Output::i()->jsVars['date_first_day'] = 0;
|
||||
Output::i()->jsVars['ipb_url_filter_option'] = Settings::i()->ipb_url_filter_option;
|
||||
Output::i()->jsVars['url_filter_any_action'] = Settings::i()->url_filter_any_action;
|
||||
Output::i()->jsVars['bypass_profanity'] = intval( Member::loggedIn()->group['g_bypass_badwords'] );
|
||||
Output::i()->jsVars['emoji_style'] = ( Settings::i()->getFromConfGlobal('sql_utf8mb4') === TRUE ) ? Settings::i()->emoji_style : 'disabled';
|
||||
Output::i()->jsVars['emoji_shortcodes'] = (bool) Settings::i()->emoji_shortcodes;
|
||||
Output::i()->jsVars['emoji_cache'] = (int) Settings::i()->emoji_cache;
|
||||
Output::i()->jsVars['image_jpg_quality'] = (int) Settings::i()->image_jpg_quality ?: 85;
|
||||
Output::i()->jsVars['cloud2'] = (bool) CIC2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,15 +121,15 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function finish()
|
||||
public function finish() : void
|
||||
{
|
||||
/* If we're still here - output */
|
||||
if ( ! \IPS\Request::i()->isAjax() )
|
||||
if ( ! Request::i()->isAjax() )
|
||||
{
|
||||
/* Load all models for this app and location */
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'app.js', \IPS\Dispatcher::i()->application->directory ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'app.js', Dispatcher::i()->application->directory ) );
|
||||
/* Map.js must come last as it will always have the correct file names */
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'map.js' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'map.js' ) );
|
||||
}
|
||||
|
||||
parent::finish();
|
||||
@@ -116,53 +138,53 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
/**
|
||||
* @brief Initialize tasks
|
||||
*/
|
||||
protected $runTasks = FALSE;
|
||||
protected bool $runTasks = FALSE;
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
* @throws \DomainException
|
||||
* @throws DomainException
|
||||
*/
|
||||
public function init()
|
||||
public function init() : void
|
||||
{
|
||||
$this->runTasks = (bool) \IPS\Member::loggedIn()->member_id;
|
||||
$this->runTasks = (bool) Member::loggedIn()->member_id;
|
||||
|
||||
/* Force HTTPs and correct domain (e.g. not "www." if that's not in the base URL) */
|
||||
if ( mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' )
|
||||
{
|
||||
$baseUrl = new \IPS\Http\Url( \IPS\Settings::i()->base_url );
|
||||
$newUrl = \IPS\Request::i()->url();
|
||||
$baseUrl = new Url( Settings::i()->base_url );
|
||||
$newUrl = Request::i()->url();
|
||||
|
||||
if( $baseUrl->data['scheme'] === 'https' and \IPS\Request::i()->url()->data['scheme'] !== 'https' )
|
||||
if( $baseUrl->data['scheme'] === 'https' and Request::i()->url()->data['scheme'] !== 'https' )
|
||||
{
|
||||
$newUrl = $newUrl->setScheme('https');
|
||||
}
|
||||
|
||||
if( $baseUrl->data['host'] !== \IPS\Request::i()->url()->data['host'] )
|
||||
if( $baseUrl->data['host'] !== Request::i()->url()->data['host'] )
|
||||
{
|
||||
$newUrl = $newUrl->setHost( $baseUrl->data['host'] );
|
||||
}
|
||||
|
||||
if( $newUrl != \IPS\Request::i()->url() )
|
||||
if( $newUrl != Request::i()->url() )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $newUrl );
|
||||
Output::i()->redirect( $newUrl );
|
||||
}
|
||||
}
|
||||
|
||||
/* Set locale */
|
||||
\IPS\Member::loggedIn()->language()->setLocale();
|
||||
Member::loggedIn()->language()->setLocale();
|
||||
|
||||
/* Set Application */
|
||||
if ( isset( \IPS\Request::i()->app ) )
|
||||
if ( isset( Request::i()->app ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->application = \IPS\Application::load( \IPS\Request::i()->app );
|
||||
$this->application = Application::load( Request::i()->app );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
$applications = \IPS\Application::applications();
|
||||
$applications = Application::applications();
|
||||
|
||||
foreach( $applications as $application )
|
||||
{
|
||||
@@ -176,13 +198,13 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
{
|
||||
$this->application = array_shift( $applications );
|
||||
}
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'app.js' ) );
|
||||
throw new \DomainException( 'requested_route_404', 5 );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'app.js' ) );
|
||||
throw new DomainException( 'requested_route_404', 5 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$applications = \IPS\Application::applications();
|
||||
$applications = Application::applications();
|
||||
|
||||
foreach( $applications as $application )
|
||||
{
|
||||
@@ -199,11 +221,11 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
}
|
||||
|
||||
/* Init Application */
|
||||
if( $this->checkGenericPermissions === TRUE AND !$this->application->canAccess( \IPS\Member::loggedIn() ) AND $this->controllerLocation != 'admin' )
|
||||
if( $this->checkGenericPermissions === TRUE AND !$this->application->canAccess( Member::loggedIn() ) AND $this->controllerLocation != 'admin' )
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'app.js' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'app.js' ) );
|
||||
$message = $this->application->disabled_message ?: 'generic_offline_message';
|
||||
throw new \DomainException( $message, 4 );
|
||||
throw new DomainException( $message, 4 );
|
||||
}
|
||||
if ( method_exists( $this->application, 'init' ) )
|
||||
{
|
||||
@@ -211,16 +233,16 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
}
|
||||
|
||||
/* Set Module */
|
||||
if ( isset( \IPS\Request::i()->module ) )
|
||||
if ( isset( Request::i()->module ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->module = \IPS\Application\Module::get( $this->application->directory, \IPS\Request::i()->module, static::i()->controllerLocation );
|
||||
$this->module = Module::get( $this->application->directory, Request::i()->module, static::i()->controllerLocation );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'app.js' ) );
|
||||
throw new \DomainException( 'requested_route_404', 6 );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'app.js' ) );
|
||||
throw new DomainException( 'requested_route_404', 6 );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -229,54 +251,49 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
}
|
||||
|
||||
/* Set controller */
|
||||
$this->controller = isset( \IPS\Request::i()->controller ) ? \IPS\Request::i()->controller : $this->module->default_controller;
|
||||
$this->controller = isset( Request::i()->controller ) ? Request::i()->controller : $this->module->default_controller;
|
||||
|
||||
if( \is_array( $this->controller ) )
|
||||
if( is_array( $this->controller ) )
|
||||
{
|
||||
$this->controller = NULL;
|
||||
throw new \DomainException( 'requested_route_404', 7 );
|
||||
throw new DomainException( 'requested_route_404', 7 );
|
||||
}
|
||||
|
||||
/* Set classname */
|
||||
$this->classname = 'IPS\\' . $this->application->directory . '\\modules\\' . $this->controllerLocation . '\\' . $this->module->key . '\\' . $this->controller;
|
||||
|
||||
/* Base Templates, CSS and JS */
|
||||
if ( !\IPS\Request::i()->isAjax() )
|
||||
if ( !Request::i()->isAjax() )
|
||||
{
|
||||
/* Templates */
|
||||
if ( \IPS\Data\Cache::i() instanceof \IPS\Data\Cache\None )
|
||||
if ( Cache::i() instanceof None )
|
||||
{
|
||||
\IPS\Data\Store::i()->templateLoad[] = array( 'core', $this->controllerLocation, 'global' );
|
||||
\IPS\Data\Store::i()->templateLoad[] = array( 'core', 'global', 'global' );
|
||||
\IPS\Data\Store::i()->templateLoad[] = array( 'core', 'global', 'forms' );
|
||||
\IPS\Data\Store::i()->templateLoad[] = array( 'core', $this->controllerLocation, 'forms' );
|
||||
Store::i()->templateLoad[] = array( 'core', $this->controllerLocation, 'global' );
|
||||
Store::i()->templateLoad[] = array( 'core', 'global', 'global' );
|
||||
Store::i()->templateLoad[] = array( 'core', 'global', 'forms' );
|
||||
Store::i()->templateLoad[] = array( 'core', $this->controllerLocation, 'forms' );
|
||||
$templateLoad = array();
|
||||
if ( ! \IPS\Theme::isUsingTemplateDiskCache() )
|
||||
foreach ( Store::i()->templateLoad as $data )
|
||||
{
|
||||
foreach ( \IPS\Data\Store::i()->templateLoad as $data )
|
||||
{
|
||||
$templateLoad[] = 'template_' . \IPS\Theme::i()->id . '_' . \IPS\Theme::makeBuiltTemplateLookupHash( $data[0], $data[1], $data[2] ) . '_' . $data[2];
|
||||
}
|
||||
\IPS\Data\Store::i()->loadIntoMemory( $templateLoad );
|
||||
$templateLoad[] = 'template_' . Theme::i()->id . '_' . Theme::makeBuiltTemplateLookupHash( $data[0], $data[1], $data[2] ) . '_' . $data[2];
|
||||
}
|
||||
|
||||
Store::i()->loadIntoMemory( $templateLoad );
|
||||
}
|
||||
|
||||
/* App JS */
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'app.js' ) );
|
||||
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'app.js' ) );
|
||||
|
||||
/* App CSS */
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( $this->application->directory . '.css', $this->application->directory, $this->controllerLocation ) );
|
||||
if ( \IPS\Theme::i()->settings['responsive'] )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( $this->application->directory . '_responsive.css', $this->application->directory, $this->controllerLocation ) );
|
||||
}
|
||||
$currentApp = $this->application;
|
||||
$currentApp::outputCss();
|
||||
|
||||
/* VLE */
|
||||
if ( \IPS\Lang::vleActive() )
|
||||
if ( Lang::vleActive() )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'customization/visuallanguage.css', 'core', 'admin' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'global_customization.js', 'core', 'global' ) );
|
||||
\IPS\Output::i()->globalControllers[] = 'core.global.customization.visualLang';
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'customization/visuallanguage.css', 'core', 'admin' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'global_customization.js', 'core', 'global' ) );
|
||||
Output::i()->globalControllers[] = 'core.global.customization.visualLang';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -286,7 +303,7 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setDefaultModule()
|
||||
protected function setDefaultModule() : void
|
||||
{
|
||||
$modules = $this->application->modules( static::i()->controllerLocation );
|
||||
foreach( $modules as $module )
|
||||
@@ -308,13 +325,8 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
* @brief Enable destruct method
|
||||
* @note Disable to avoid an automatic database connection
|
||||
*/
|
||||
public $destruct = true;
|
||||
public bool $destruct = true;
|
||||
|
||||
/**
|
||||
* @brief Flag to check if we are in the destructor
|
||||
*/
|
||||
public bool $inDestructor = false;
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* Runs tasks
|
||||
@@ -324,23 +336,60 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
public function __destruct()
|
||||
{
|
||||
/* If you visit and you are redirected to installer, this code should not run */
|
||||
if( !file_exists( \IPS\SITE_FILES_PATH . '/conf_global.php' ) OR !$this->destruct )
|
||||
if( !file_exists( SITE_FILES_PATH . '/conf_global.php' ) OR !$this->destruct )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->runTasks and \IPS\Settings::i()->task_use_cron == 'normal' and !\IPS\Request::i()->isAjax() )
|
||||
if ( $this->runTasks and Settings::i()->task_use_cron == 'normal' and !Request::i()->isAjax() )
|
||||
{
|
||||
$this->inDestructor = true;
|
||||
try
|
||||
{
|
||||
$task = \IPS\Task::queued();
|
||||
$task = Task::queued();
|
||||
if ( $task )
|
||||
{
|
||||
$task->runAndLog();
|
||||
}
|
||||
}
|
||||
catch( \IPS\Db\Exception $e ) { }
|
||||
catch( Exception $e ) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check ACP Permission
|
||||
*
|
||||
* @param string $key Permission Key
|
||||
* @param string|Application|null $app Application (NULL will default to current)
|
||||
* @param string|Module|null $module Module (NULL will default to current)
|
||||
* @param boolean $return Return boolean (true/false) instead of throwing an error
|
||||
* @return int|bool|null
|
||||
*/
|
||||
public function checkAcpPermission( string $key, string|Application $app=NULL, Module|string $module=NULL, bool $return=FALSE ): int|bool|null
|
||||
{
|
||||
$result = Bridge::i()->checkPlatformPermission( $key, $app, $module, $return );
|
||||
|
||||
if ( is_int( $result ) )
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ( !Member::loggedIn()->hasAcpRestriction( ( $app ?: $this->application ), ( $module ?: $this->module ), $key ) )
|
||||
{
|
||||
if ( $return )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Output::i()->error( 'no_module_permission', '2S107/2', 403, '' );
|
||||
}
|
||||
|
||||
if ( $return )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user