Version 4.0.13.1
This commit is contained in:
1 parent
f9e857d255
commit
c6a86f0d9b
7517 files changed
+597400
-668041
No files matched your search
@@ -0,0 +1,381 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Admin CP Dispatcher
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 18 Feb 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Dispatcher;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin CP Dispatcher
|
||||
*/
|
||||
class _Admin extends \IPS\Dispatcher\Standard
|
||||
{
|
||||
/**
|
||||
* Controller Location
|
||||
*/
|
||||
public $controllerLocation = 'admin';
|
||||
|
||||
/**
|
||||
* @brief Cached Menu
|
||||
*/
|
||||
protected $menu = NULL;
|
||||
|
||||
/**
|
||||
* @brief Search Keywords
|
||||
*/
|
||||
public $searchKeywords = array();
|
||||
|
||||
/**
|
||||
* @brief ACP Restrictions (for search keyword editing)
|
||||
*/
|
||||
public $moduleRestrictions = array();
|
||||
|
||||
/**
|
||||
* @brief ACP Restriction for the current menu item (for search keyword editing)
|
||||
*/
|
||||
public $menuRestriction = NULL;
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
\IPS\Output::i()->sidebar['appmenu'] = '';
|
||||
|
||||
/* Sync stuff when in developer mode */
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
\IPS\Developer::sync();
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
/* Build the menu */
|
||||
$menu = $this->buildMenu();
|
||||
|
||||
/* Do we need to figure out the default? */
|
||||
if ( !isset( \IPS\Request::i()->app ) )
|
||||
{
|
||||
foreach ( $menu['tabs'] as $app => $appData )
|
||||
{
|
||||
if ( isset( $menu['defaults'][ $app ] ) )
|
||||
{
|
||||
parse_str( $menu['defaults'][ $app ], $defaultQueryString );
|
||||
foreach ( $defaultQueryString as $k => $v )
|
||||
{
|
||||
\IPS\Request::i()->$k = $v;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Call parent */
|
||||
static::baseCss();
|
||||
static::baseJs();
|
||||
|
||||
/* Stuff needed for output */
|
||||
if ( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
/* Special grouped CSS files */
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'core.css', 'core', 'admin' ) );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'responsive.css', 'core', 'front' ) );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'responsive.css', 'core', 'admin' ) );
|
||||
|
||||
/* JS */
|
||||
\IPS\Output::i()->globalControllers[] = 'core.admin.core.app';
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin.js' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'jquery/jquery-ui.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'jquery/jquery-touchpunch.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'jquery/jquery.menuaim.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'jquery/jquery.nestedSortable.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_core.js', 'core', 'front' ) );
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
/* These are just defaults in case we hit an immediate error, e.g. app or controller doesn't exist */
|
||||
\IPS\Output::i()->sidebar['sidebar'] = \IPS\Theme::i()->getTemplate( 'global', 'core' )->sidebar( array(), 'core_overview' );
|
||||
\IPS\Output::i()->sidebar['appmenu'] = \IPS\Theme::i()->getTemplate( 'global', 'core' )->appmenu( $menu, 'core' );
|
||||
\IPS\Output::i()->sidebar['mobilenav'] = \IPS\Theme::i()->getTemplate( 'global', 'core' )->mobileNavigation( $menu, 'core' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
parent::init();
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '2S100/' . $e->getCode(), $e->getCode() === 4 ? 403 : 404, '' );
|
||||
}
|
||||
|
||||
/* Check we're logged in and we have ACP access */
|
||||
if( ( !\IPS\Member::loggedIn()->member_id or !\IPS\Member::loggedIn()->isAdmin() )
|
||||
and ( $this->module->key !== 'system' or $this->controller !== 'login' )
|
||||
and ( !\IPS\ENFORCE_ACCESS )
|
||||
)
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'admin', NULL, array(), \IPS\Settings::i()->logins_over_https );
|
||||
|
||||
if ( \IPS\Session::i()->error )
|
||||
{
|
||||
$url = $url->setQueryString( 'error', \IPS\Session::i()->error->getMessage() );
|
||||
}
|
||||
|
||||
if( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
$url = $url->setQueryString( 'ref', preg_replace( '!adsess=((\w){32}|&)!', "", $_SERVER['QUERY_STRING'] ) );
|
||||
}
|
||||
else if( isset( $_SERVER['HTTP_REFERER'] ) )
|
||||
{
|
||||
$previous = preg_replace( "/^(.+?)\/\?/", "", $_SERVER['HTTP_REFERER'] );
|
||||
$url = $url->setQueryString( 'ref', preg_replace( '!adsess=.*?(&|$)!', "", $previous ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $url );
|
||||
}
|
||||
|
||||
/* Permission Check */
|
||||
if ( ( $this->module->key !== 'system' or !in_array( $this->controller, array( 'login', 'language', 'theme', 'livesearch' ) ) ) and !\IPS\Member::loggedIn()->hasAcpRestriction( $this->application, $this->module ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2S107/1', 403, '' );
|
||||
}
|
||||
|
||||
/* ACP search keywords */
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_acp_search_index' ) as $word )
|
||||
{
|
||||
$this->searchKeywords[ $word['url'] ]['lang_key'] = $word['lang_key'];
|
||||
$this->searchKeywords[ $word['url'] ]['restriction'] = $word['restriction'];
|
||||
$this->searchKeywords[ $word['url'] ]['keywords'][] = $word['keyword'];
|
||||
}
|
||||
|
||||
$restrictions = array();
|
||||
|
||||
$file = \IPS\ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json";
|
||||
if ( file_exists( $file ) )
|
||||
{
|
||||
$restrictions = json_decode( file_get_contents( $file ), TRUE );
|
||||
}
|
||||
|
||||
$this->moduleRestrictions[''] = 'acpmenu_norestriction';
|
||||
if ( isset( $restrictions[ $this->module->key ] ) )
|
||||
{
|
||||
foreach ( $restrictions[ $this->module->key ] as $key => $values )
|
||||
{
|
||||
$this->moduleRestrictions[ $key ] = array_combine( $values, $values );
|
||||
}
|
||||
}
|
||||
|
||||
$appMenu = $this->application->acpMenu();
|
||||
if ( isset( $appMenu[ $this->module->key ] ) )
|
||||
{
|
||||
foreach ( $appMenu[ $this->module->key ] as $menuItem )
|
||||
{
|
||||
if ( $menuItem['restriction'] and $menuItem['controller'] == $this->controller and ( !$menuItem['do'] or ( isset( \IPS\Request::i()->do ) and $menuItem['do'] == \IPS\Request::i()->do ) ) )
|
||||
{
|
||||
$this->menuRestriction = $menuItem['restriction'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* More stuff needed for output */
|
||||
if ( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
/* Menu and base navigation */
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
/* Work out what tab we're on */
|
||||
$currentTab = NULL;
|
||||
foreach ( $this->application->acpMenu() as $moduleKey => $items )
|
||||
{
|
||||
if ( $moduleKey === $this->module->key )
|
||||
{
|
||||
foreach ( $items as $itemKey => $item )
|
||||
{
|
||||
if ( !$currentTab )
|
||||
{
|
||||
$currentTab = $item['tab'];
|
||||
}
|
||||
if ( $item['controller'] === $this->controller )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !$currentTab )
|
||||
{
|
||||
$currentTab = $this->application->directory;
|
||||
}
|
||||
|
||||
/* Display */
|
||||
if( $this->controller !== 'login' )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['sidebar'] = \IPS\Theme::i()->getTemplate( 'global', 'core' )->sidebar( $menu['tabs'][ $currentTab ], $this->application->directory . '_' . $this->module->key );
|
||||
\IPS\Output::i()->sidebar['appmenu'] = \IPS\Theme::i()->getTemplate( 'global', 'core' )->appmenu( $menu, $currentTab );
|
||||
\IPS\Output::i()->sidebar['mobilenav'] = \IPS\Theme::i()->getTemplate( 'global', 'core' )->mobileNavigation( $menu, $currentTab );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Menu
|
||||
*
|
||||
* @param bool If TRUE, will rebuild
|
||||
* @return array
|
||||
*/
|
||||
public function buildMenu( $rebuild=FALSE )
|
||||
{
|
||||
if ( $this->menu === NULL or $rebuild === TRUE )
|
||||
{
|
||||
$this->menu = array( 'tabs' => array(), 'defaults' => array() );
|
||||
|
||||
foreach ( \IPS\Application::applications() as $app )
|
||||
{
|
||||
if ( \IPS\Application::appIsEnabled( $app->directory ) and \IPS\Application::load( $app->directory )->canAccess() )
|
||||
{
|
||||
foreach ( $app->acpMenu() as $moduleKey => $items )
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( $app, $moduleKey ) )
|
||||
{
|
||||
foreach ( $items as $itemKey => $item )
|
||||
{
|
||||
if ( !$item['restriction'] or \IPS\Member::loggedIn()->hasAcpRestriction( $app, $moduleKey, $item['restriction'] ) )
|
||||
{
|
||||
if ( !isset( $this->menu['defaults'][ $item['tab'] ] ) )
|
||||
{
|
||||
$this->menu['defaults'][ $item['tab'] ] = "app={$app->directory}&module={$moduleKey}&controller={$item['controller']}";
|
||||
}
|
||||
|
||||
$this->menu['tabs'][ $item['tab'] ][ "{$app->directory}_{$moduleKey}" ][ $itemKey ] = "app={$app->directory}&module={$moduleKey}&controller={$item['controller']}" . ( $item['do'] ? "&do={$item['do']}" : '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$acpTabOrder = $this->_getAcpTabOrder();
|
||||
|
||||
if ( $acpTabOrder !== NULL )
|
||||
{
|
||||
$_apps = array_keys( $acpTabOrder );
|
||||
uksort( $this->menu['tabs'], function($a, $b) use ( $_apps )
|
||||
{
|
||||
return array_search( $a, $_apps ) - array_search( $b, $_apps );
|
||||
} );
|
||||
|
||||
foreach( $acpTabOrder as $app => $submenu )
|
||||
{
|
||||
if ( !empty( $submenu ) )
|
||||
{
|
||||
if( isset( $this->menu['tabs'][ $app ] ) )
|
||||
{
|
||||
uksort( $this->menu['tabs'][ $app ], function($a, $b) use ( $submenu )
|
||||
{
|
||||
return array_search( $a, $submenu ) - array_search( $b, $submenu );
|
||||
} );
|
||||
}
|
||||
|
||||
if ( isset( $this->menu['defaults'] ) )
|
||||
{
|
||||
uksort( $this->menu['defaults'], function($a, $b) use ( $acpTabOrder )
|
||||
{
|
||||
return array_search( $a, $acpTabOrder );
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached ACP tab order
|
||||
*/
|
||||
protected $acpTabOrder = NULL;
|
||||
|
||||
/**
|
||||
* Figure out the ACP tab order
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getAcpTabOrder()
|
||||
{
|
||||
if( $this->acpTabOrder !== NULL )
|
||||
{
|
||||
return $this->acpTabOrder;
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->cookie['acpTabs'] ) )
|
||||
{
|
||||
$this->acpTabOrder = json_decode( \IPS\Request::i()->cookie['acpTabs'], TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->acpTabOrder = json_decode( \IPS\Db::i()->select( 'data', 'core_acp_tab_order', array( 'id=?', \IPS\Member::loggedIn()->member_id ) )->first(), TRUE );
|
||||
}
|
||||
catch( \UnderflowException $ex )
|
||||
{
|
||||
$this->acpTabOrder = array( 'core' => array(), 'community' => array(), 'members' => array(), 'nexus' => array(), 'content' => array(), 'stats' => array(), 'customization' => array() );
|
||||
}
|
||||
|
||||
\IPS\Request::i()->setCookie( 'acpTabs', json_encode( $this->acpTabOrder ) );
|
||||
}
|
||||
|
||||
return $this->acpTabOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do we have permission to use this module?
|
||||
*
|
||||
* @param \IPS\Application $app Application
|
||||
* @param \IPS\Module|string $module Module
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPermission( $app, $module )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->hasAcpRestriction( $app, $module );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check ACP Permission
|
||||
*
|
||||
* @param string $key Permission Key
|
||||
* @param \IPS\Application|null $app Application (NULL will default to current)
|
||||
* @param \IPS\Module|string|null $module Module (NULL will default to current)
|
||||
* @return void
|
||||
*/
|
||||
public function checkAcpPermission( $key, $app=NULL, $module=NULL )
|
||||
{
|
||||
if ( !\IPS\Member::loggedIn()->hasAcpRestriction( ( $app ?: $this->application ), ( $module ?: $this->module ), $key ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2S107/1', 403, '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Build/Tools Dispatcher
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 2 Apr 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Dispatcher;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build/Tools Dispatcher
|
||||
*/
|
||||
class _Build extends \IPS\Dispatcher
|
||||
{
|
||||
/**
|
||||
* @brief Controller Location
|
||||
*/
|
||||
public $controllerLocation = 'front';
|
||||
public $application = 'core';
|
||||
public $module = 'system';
|
||||
|
||||
/**
|
||||
* @brief Step
|
||||
*/
|
||||
public $step = 1;
|
||||
|
||||
/**
|
||||
* Initiator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$modules = \IPS\Application\Module::modules();
|
||||
$this->application = \IPS\Application::load('core');
|
||||
$this->module = $modules['core']['front']['system'];
|
||||
$this->controller = 'build';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->force ) )
|
||||
{
|
||||
if ( isset( \IPS\Data\Store::i()->builder_building ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->builder_building );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( \IPS\Data\Store::i()->builder_building ) and ! empty( \IPS\Data\Store::i()->builder_building ) )
|
||||
{
|
||||
/* We're currently rebuilding */
|
||||
if ( time() - \IPS\Data\Store::i()->builder_building < 180 )
|
||||
{
|
||||
print "Builder is already running. To force a rebuild anyway, add &force=1 on the end of your URL";
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Data\Store::i()->builder_building = time();
|
||||
}
|
||||
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( 'conf_key=?', 'site_online' ) );
|
||||
\IPS\Settings::i()->site_online = 0;
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Done
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function buildDone()
|
||||
{
|
||||
if ( isset( \IPS\Data\Store::i()->builder_building ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->builder_building );
|
||||
}
|
||||
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 1 ), array( 'conf_key=?', 'site_online' ) );
|
||||
\IPS\Settings::i()->site_online = 1;
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Abstract class that Controllers should extend
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 18 Feb 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Dispatcher;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class that Controllers should extend
|
||||
*/
|
||||
abstract class _Controller
|
||||
{
|
||||
/**
|
||||
* @brief Base URL
|
||||
*/
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Http\Url|NULL $url The base URL for this controller or NULL to calculate automatically
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $url=NULL )
|
||||
{
|
||||
if ( $url === NULL )
|
||||
{
|
||||
$class = get_called_class();
|
||||
$exploded = explode( '\\', $class );
|
||||
$this->url = \IPS\Http\Url::internal( "app={$exploded[1]}&module={$exploded[4]}&controller={$exploded[5]}", \IPS\Dispatcher::i()->controllerLocation );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->url = $url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a specific method within a controller to execute. Useful for unit testing.
|
||||
*
|
||||
* @param null|string $method The specific method to call
|
||||
* @return mixed
|
||||
*/
|
||||
public function forceExecute( $method=NULL )
|
||||
{
|
||||
if( \IPS\ENFORCE_ACCESS === true and $method !== null )
|
||||
{
|
||||
if ( method_exists( $this, $method ) )
|
||||
{
|
||||
return call_user_func( array( $this, $method ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->execute();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
if( \IPS\Request::i()->do and preg_match( '/^[a-zA-Z\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', \IPS\Request::i()->do ) )
|
||||
{
|
||||
if ( method_exists( $this, \IPS\Request::i()->do ) or method_exists( $this, '__call' ) )
|
||||
{
|
||||
call_user_func( array( $this, \IPS\Request::i()->do ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( 'page_not_found', '2S106/1', 404, '' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->manage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Embed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function embed()
|
||||
{
|
||||
$title = \IPS\Member::loggedIn()->language()->addToStack('error_title');
|
||||
|
||||
if( !isset( static::$contentModel ) )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedUnavailable();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
$class = static::$contentModel;
|
||||
$params = array();
|
||||
|
||||
if( \IPS\Request::i()->embedComment )
|
||||
{
|
||||
$commentClass = $class::$commentClass;
|
||||
if ( isset( $class::$archiveClass ) )
|
||||
{
|
||||
$item = call_user_func( array( $class, 'loadAndCheckPerms' ), \IPS\Request::i()->id );
|
||||
if ( $item->isArchived() )
|
||||
{
|
||||
$commentClass = $class::$archiveClass;
|
||||
}
|
||||
}
|
||||
|
||||
$content = call_user_func( array( $commentClass, 'loadAndCheckPerms' ), \IPS\Request::i()->embedComment );
|
||||
$title = $content->item()->mapped('title');
|
||||
}
|
||||
elseif( \IPS\Request::i()->embedReview )
|
||||
{
|
||||
$content = call_user_func( array( $class::$reviewClass, 'loadAndCheckPerms' ), \IPS\Request::i()->embedReview );
|
||||
$title = $content->item()->mapped('title');
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->page ) and \IPS\Request::i()->page > 1 )
|
||||
{
|
||||
$params['page'] = intval( \IPS\Request::i()->page );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->embedDo ) )
|
||||
{
|
||||
$params['do'] = \IPS\Request::i()->embedDo;
|
||||
}
|
||||
|
||||
$content = call_user_func( array( $class, 'loadAndCheckPerms' ), \IPS\Request::i()->id );
|
||||
$title = $content instanceof \IPS\Node\Model ? $content->_title : $content->mapped('title');
|
||||
}
|
||||
|
||||
if ( !( $content instanceof \IPS\Content\Embeddable ) )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedUnavailable();
|
||||
}
|
||||
else
|
||||
{
|
||||
$output = $content->embedContent( $params );
|
||||
}
|
||||
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedNoPermission();
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->base = '_parent';
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'embed.css' ) );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $output, $title ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Dispatcher
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 18 Feb 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatcher
|
||||
*/
|
||||
abstract class _Dispatcher
|
||||
{
|
||||
/**
|
||||
* @brief Singleton Instance
|
||||
*/
|
||||
protected static $instance = NULL;
|
||||
|
||||
/**
|
||||
* Check if a dispatcher instance is available
|
||||
*
|
||||
* @return static
|
||||
* @note This should be used sparingly, primarily for gateway scripts that do not need a dispatcher but still use the framework
|
||||
*/
|
||||
public static function hasInstance()
|
||||
{
|
||||
return ( static::$instance !== NULL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get instance
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function i()
|
||||
{
|
||||
if( static::$instance === NULL )
|
||||
{
|
||||
$class = get_called_class();
|
||||
|
||||
if( $class == 'IPS\\Dispatcher' )
|
||||
{
|
||||
throw new \RuntimeException( "Only subclasses of Dispatcher can be instantiated" );
|
||||
}
|
||||
|
||||
static::$instance = new $class;
|
||||
|
||||
if( static::$instance->controllerLocation != 'setup' )
|
||||
{
|
||||
$_redirect = FALSE;
|
||||
|
||||
if ( !file_exists( \IPS\ROOT_PATH . '/conf_global.php' ) )
|
||||
{
|
||||
$_redirect = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
require \IPS\ROOT_PATH . '/conf_global.php';
|
||||
|
||||
if( !isset( $INFO['sql_database'] ) )
|
||||
{
|
||||
$_redirect = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if( $_redirect === TRUE )
|
||||
{
|
||||
/* conf_global.php does not exist, forward to installer */
|
||||
$url = ( \IPS\Request::i()->isSecure() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . rtrim( dirname( $_SERVER['SCRIPT_NAME'] ), '/' );
|
||||
\IPS\Output::i()->redirect( "{$url}/" . \IPS\CP_DIRECTORY . "/install/" );
|
||||
}
|
||||
}
|
||||
|
||||
static::$instance->init();
|
||||
}
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller Classname
|
||||
*/
|
||||
protected $classname;
|
||||
|
||||
/**
|
||||
* Controller instance
|
||||
*/
|
||||
public $dispatcherController;
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
* @throws \DomainException
|
||||
*/
|
||||
abstract public function init();
|
||||
|
||||
/**
|
||||
* Run
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
/* Init class */
|
||||
if( !class_exists( $this->classname ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'page_doesnt_exist', '2S100/1', 404 );
|
||||
}
|
||||
$this->dispatcherController = new $this->classname;
|
||||
if( !( $this->dispatcherController instanceof \IPS\Dispatcher\Controller ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'page_not_found', '5S100/3', 500, '' );
|
||||
}
|
||||
|
||||
/* Execute */
|
||||
$this->dispatcherController->execute();
|
||||
|
||||
$this->finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
/* If we're still here - output */
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Output::i()->output ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just prefetch this to save a query later */
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Output::i()->title, \IPS\Output::i()->output, array( 'app' => \IPS\Dispatcher::i()->application->directory, 'module' => \IPS\Dispatcher::i()->module->key, 'controller' => \IPS\Dispatcher::i()->controller ) ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Front-end Dispatcher
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 18 Feb 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Dispatcher;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front-end Dispatcher
|
||||
*/
|
||||
class _Front extends \IPS\Dispatcher\Standard
|
||||
{
|
||||
/**
|
||||
* Controller Location
|
||||
*/
|
||||
public $controllerLocation = 'front';
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
/* Set up in progress? */
|
||||
if ( isset( \IPS\Settings::i()->setup_in_progress ) AND \IPS\Settings::i()->setup_in_progress )
|
||||
{
|
||||
if( isset( $_SERVER['SERVER_PROTOCOL'] ) and \strstr( $_SERVER['SERVER_PROTOCOL'], '/1.0' ) !== false )
|
||||
{
|
||||
header( "HTTP/1.0 503 Service Unavailable" );
|
||||
}
|
||||
else
|
||||
{
|
||||
header( "HTTP/1.1 503 Service Unavailable" );
|
||||
}
|
||||
|
||||
require \IPS\ROOT_PATH . '/' . \IPS\UPGRADING_PAGE;
|
||||
exit;
|
||||
}
|
||||
|
||||
/* Get cached page if available */
|
||||
$this->checkCached();
|
||||
|
||||
/* Perform some legacy URL conversions*/
|
||||
static::convertLegacyParameters();
|
||||
|
||||
/* Sync stuff when in developer mode */
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
\IPS\Developer::sync();
|
||||
}
|
||||
|
||||
/* Base CSS */
|
||||
static::baseCss();
|
||||
|
||||
/* Base JS */
|
||||
static::baseJs();
|
||||
|
||||
/* FURLs only apply when calling to index.php */
|
||||
$_calledScript = str_replace( '\\', '/', $_SERVER['SCRIPT_FILENAME'] );
|
||||
$_scriptParts = explode( '/', $_calledScript );
|
||||
array_pop( $_scriptParts );
|
||||
$_calledScript = implode( '/', $_scriptParts );
|
||||
|
||||
/* If script_filename was /index.php then calledscript will be empty */
|
||||
if( $_calledScript === '' )
|
||||
{
|
||||
$_calledScript = '/';
|
||||
}
|
||||
|
||||
/* Handle friendly URLs */
|
||||
if ( \IPS\Settings::i()->use_friendly_urls and $_calledScript == str_replace( '\\', '/', \IPS\ROOT_PATH ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach ( \IPS\Request::i()->url()->getFriendlyUrlData( \IPS\Settings::i()->seo_r_on and !\IPS\Request::i()->isAjax() and mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' and !\IPS\ENFORCE_ACCESS ) as $k => $v )
|
||||
{
|
||||
if( $k == 'module' )
|
||||
{
|
||||
$this->_module = NULL;
|
||||
}
|
||||
else if( $k == 'controller' )
|
||||
{
|
||||
$this->_controller = NULL;
|
||||
}
|
||||
|
||||
\IPS\Request::i()->$k = $v;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
if( \IPS\Settings::i()->seo_r_on and !\IPS\Request::i()->isAjax() and mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' and !\IPS\ENFORCE_ACCESS )
|
||||
{
|
||||
$defaultApplication = \IPS\Db::i()->select( 'app_directory', 'core_applications', 'app_default=1' )->first();
|
||||
$furlDefinitionFile = \IPS\ROOT_PATH . "/applications/{$defaultApplication}/data/furl.json";
|
||||
if ( file_exists( $furlDefinitionFile ) )
|
||||
{
|
||||
$furlDefinition = json_decode( preg_replace( '/\/\*.+?\*\//s', '', file_get_contents( $furlDefinitionFile ) ), TRUE );
|
||||
if ( isset( $furlDefinition['topLevel'] ) and $furlDefinition['topLevel'] )
|
||||
{
|
||||
$baseUrl = parse_url( \IPS\Settings::i()->base_url );
|
||||
$url = \IPS\Request::i()->url();
|
||||
$query = \IPS\Settings::i()->htaccess_mod_rewrite ? ( isset( $url->data['path'] ) ? $url->data['path'] : '' ) : ( isset( $url->data['query'] ) ? ltrim( $url->data['query'], '/' ) : '' );
|
||||
$query = preg_replace( '#^(' . preg_quote( rtrim( $baseUrl['path'], '/' ), '#' ) . ')/(index.php)?(?:(?:\?/|\?))?(.+?)?$#', '$3', $query );
|
||||
|
||||
if ( mb_substr( $query, 0, mb_strlen( $furlDefinition['topLevel'] ) ) === $furlDefinition['topLevel'] )
|
||||
{
|
||||
$target = preg_replace( '/(' . preg_quote( \IPS\Settings::i()->base_url, '/' ) . '(index.php\?\/)?)(' . preg_quote( $furlDefinition['topLevel'], '/' ) . ')\/?/', '$1', (string) $url );
|
||||
|
||||
\IPS\Output::i()->redirect( new \IPS\Http\Url( $target ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
$this->application = \IPS\Application::load('core');
|
||||
$this->setDefaultModule();
|
||||
|
||||
if ( \IPS\Member::loggedIn()->isBanned() )
|
||||
{
|
||||
\IPS\Output::i()->sidebar = FALSE;
|
||||
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
|
||||
}
|
||||
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'app.js' ) );
|
||||
|
||||
\IPS\Output::i()->error( 'requested_route_404', '1S160/2', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Run global init */
|
||||
try
|
||||
{
|
||||
parent::init();
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
{
|
||||
// If this is a "no permission", and they're validating - show the validating screen instead
|
||||
if( $e->getCode() === 6 and \IPS\Member::loggedIn()->member_id and \IPS\Member::loggedIn()->members_bitoptions['validating'] )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=validating', 'front', 'register' ) );
|
||||
}
|
||||
// Otherwise show the error
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '2S100/' . $e->getCode(), $e->getCode() === 4 ? 403 : 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable sidebar by default (controllers can turn it off if needed) */
|
||||
\IPS\Output::i()->sidebar['enabled'] = ( \IPS\Request::i()->isAjax() ) ? FALSE : TRUE;
|
||||
|
||||
/* Are we online? */
|
||||
if ( !( $this->application->directory == 'core' and $this->module->key == 'system' and ( $this->controller == 'login' /* Because you can login when offline */ or $this->controller == 'embed' /* Because the offline message can contain embedded media */ or $this->controller == 'lostpass' or $this->controller == 'register' ) ) AND !\IPS\Settings::i()->site_online AND $this->controllerLocation == 'front' AND !\IPS\Member::loggedIn()->group['g_access_offline'] )
|
||||
{
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( \IPS\Member::loggedIn()->language()->addToStack( 'offline_unavailable', FALSE, array( 'sprintf' => array( \IPS\Settings::i()->board_name ) ) ), 503 );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->showOffline();
|
||||
}
|
||||
|
||||
/* Member Ban? */
|
||||
$ipBanned = \IPS\Request::i()->ipAddressIsBanned();
|
||||
if ( $ipBanned or $banEnd = \IPS\Member::loggedIn()->isBanned() )
|
||||
{
|
||||
if ( !$ipBanned and !\IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
if ( $this->notAllowedBannedPage() )
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( 'app=core&module=system&controller=login', 'front', 'login' );
|
||||
if ( \IPS\Request::i()->url() != \IPS\Settings::i()->base_url )
|
||||
{
|
||||
$url = $url->setQueryString( 'ref', base64_encode( \IPS\Request::i()->url() ) );
|
||||
}
|
||||
\IPS\Output::i()->redirect( $url );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
\IPS\Output::i()->sidebar = FALSE;
|
||||
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
|
||||
if( $this->controller !== 'contact' )
|
||||
{
|
||||
$message = 'member_banned';
|
||||
if ( !$ipBanned and $banEnd instanceof \IPS\DateTime )
|
||||
{
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack( 'member_banned_temp', FALSE, array( 'htmlsprintf' => array( $banEnd->html() ) ) );
|
||||
}
|
||||
\IPS\Output::i()->error( $message, '2S160/4', 403, '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do we need more info from the member or do they need to validate? */
|
||||
if( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
if( ( !\IPS\Member::loggedIn()->real_name or !\IPS\Member::loggedIn()->email ) and $this->controller !== 'register' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=complete' ) );
|
||||
}
|
||||
elseif( \IPS\Member::loggedIn()->members_bitoptions['validating'] and $this->controller !== 'register' and $this->controller !== 'login' and $this->controller != 'redirect' and $this->controller !== 'contact' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=validating', 'front', 'register' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Permission Check */
|
||||
if ( !\IPS\Member::loggedIn()->canAccessModule( $this->module ) )
|
||||
{
|
||||
\IPS\Output::i()->error( ( \IPS\Member::loggedIn()->member_id ? 'no_module_permission' : 'no_module_permission_guest' ), '2S100/2', 403, 'no_module_permission_admin' );
|
||||
}
|
||||
|
||||
/* Stuff for output */
|
||||
if ( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
/* Base Navigation. We only add the module not the app as most apps don't have a global base (for example, in Nexus, you want "Store" or "Client Area" to be the base). Apps can override themselves in their controllers. */
|
||||
foreach( \IPS\Application::applications() as $directory => $application )
|
||||
{
|
||||
if( $application->default )
|
||||
{
|
||||
$defaultApplication = $directory;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !isset( $defaultApplication ) )
|
||||
{
|
||||
$defaultApplication = 'core';
|
||||
}
|
||||
|
||||
if ( $this->module->key != 'system' AND $this->application->directory != $defaultApplication )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb['module'] = array( \IPS\Http\Url::internal( 'app=' . $this->application->directory . '&module=' . $this->module->key . '&controller=' . $this->module->default_controller, 'front', $this->module->key ), $this->module->_title );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define that the page should load even if the user is banned and not logged in
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function notAllowedBannedPage()
|
||||
{
|
||||
return ( !\IPS\Member::loggedIn()->group['g_view_board'] and !( $this->application->directory == 'core' and ( ( $this->module->key == 'system' and in_array( $this->controller, array( 'login', 'register', 'lostpass', 'terms', 'ajax', 'privacy', 'editor', 'language', 'theme' ) ) ) or ( $this->module->key == 'contact' AND $this->controller == 'contact' ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check cache for this page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function checkCached()
|
||||
{
|
||||
/* If this is a guest and there's a full cached page, we can serve that */
|
||||
if( mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' and !\IPS\Session\Front::loggedIn() and !isset( \IPS\Request::i()->cookie['noCache'] ) and !\IPS\Request::i()->ipAddressIsBanned() )
|
||||
{
|
||||
/* Which language? */
|
||||
if ( isset( \IPS\Request::i()->cookie['language'] ) )
|
||||
{
|
||||
$language = \IPS\Request::i()->cookie['language'];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HTTP_ACCEPT_LANGUAGE is only available via http, thus trying to enable FURLs fails as we send out a socket request to test .htaccess */
|
||||
$language = ( isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) ? \IPS\Lang::autoDetectLanguage( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) : NULL;
|
||||
|
||||
if ( $language === NULL )
|
||||
{
|
||||
$language = \IPS\Lang::defaultLanguage();
|
||||
}
|
||||
}
|
||||
|
||||
/* Which theme? */
|
||||
$theme = isset( \IPS\Request::i()->cookie['theme'] ) ? \IPS\Request::i()->cookie['theme'] : \IPS\Theme::defaultTheme();
|
||||
|
||||
/* Get cache */
|
||||
try
|
||||
{
|
||||
$cache = \IPS\Data\Cache::i()->getWithExpire( 'page_' . md5( $_SERVER['REQUEST_URI'] ) . "_{$language}_{$theme}", TRUE );
|
||||
|
||||
$sessionId = isset( \IPS\Request::i()->cookie['IPSSessionFront'] ) ? \IPS\Request::i()->cookie['IPSSessionFront'] : \IPS\Session::i()->id;
|
||||
|
||||
\IPS\Output::i()->sendOutput( str_replace( '{{csrfKey}}', md5( '&& 0&' . $sessionId ), $cache['output'] ), $cache['code'], $cache['contentType'], $cache['httpHeaders'], FALSE, TRUE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform some legacy URL parameter conversions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function convertLegacyParameters()
|
||||
{
|
||||
/* Convert §ion= to &controller= */
|
||||
if ( isset( \IPS\Request::i()->section ) AND !isset( \IPS\Request::i()->controller ) )
|
||||
{
|
||||
\IPS\Request::i()->controller = \IPS\Request::i()->section;
|
||||
}
|
||||
|
||||
/* Convert &showtopic= */
|
||||
if ( isset( \IPS\Request::i()->showtopic ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=forums&module=forums&controller=topic&id=' . \IPS\Request::i()->showtopic ) );
|
||||
}
|
||||
|
||||
/* Convert &showforum= */
|
||||
if ( isset( \IPS\Request::i()->showforum ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=forums&module=forums&controller=forums&id=' . \IPS\Request::i()->showforum ) );
|
||||
}
|
||||
|
||||
/* Convert &showuser= */
|
||||
if ( isset( \IPS\Request::i()->showuser ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=members&controller=profile&id=' . \IPS\Request::i()->showuser ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
/* Sidebar Widgets */
|
||||
if( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
$widgets = array();
|
||||
|
||||
if ( ! isset( \IPS\Output::i()->sidebar['widgets'] ) OR ! is_array( \IPS\Output::i()->sidebar['widgets'] ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['widgets'] = array();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$widgetConfig = \IPS\Db::i()->select( '*', 'core_widget_areas', array( 'app=? AND module=? AND controller=?', $this->application->directory, $this->module->key, $this->controller ) );
|
||||
foreach( $widgetConfig as $area )
|
||||
{
|
||||
$widgets[ $area['area'] ] = json_decode( $area['widgets'], TRUE );
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e ) {}
|
||||
|
||||
if ( \IPS\Output::i()->allowDefaultWidgets )
|
||||
{
|
||||
foreach( \IPS\Widget::appDefaults( $this->application ) as $widget )
|
||||
{
|
||||
/* If another app has already defined this area, don't overwrite it */
|
||||
if ( isset( $widgets[ $widget['default_area'] ] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$widget['unique'] = $widget['key'];
|
||||
|
||||
$widgets[ $widget['default_area'] ][] = $widget;
|
||||
}
|
||||
}
|
||||
|
||||
if( count( $widgets ) )
|
||||
{
|
||||
$templateLoad = array();
|
||||
foreach ( $widgets as $areaKey => $area )
|
||||
{
|
||||
foreach ( $area as $widget )
|
||||
{
|
||||
if ( isset( $widget['app'] ) and $widget['app'] )
|
||||
{
|
||||
$templateLoad[] = array( $widget['app'], 'front', 'widgets' );
|
||||
$templateLoad[] = 'template_' . \IPS\Theme::i()->id . '_' . \IPS\Theme::makeBuiltTemplateLookupHash( $widget['app'], 'front', 'widgets' ) . '_widgets';
|
||||
}
|
||||
}
|
||||
}
|
||||
\IPS\Data\Store::i()->loadIntoMemory( $templateLoad );
|
||||
|
||||
$widgetObjects = array();
|
||||
$storeLoad = array();
|
||||
foreach ( $widgets as $areaKey => $area )
|
||||
{
|
||||
foreach ( $area as $widget )
|
||||
{
|
||||
try
|
||||
{
|
||||
$appOrPlugin = isset( $widget['plugin'] ) ? \IPS\Plugin::load( $widget['plugin'] ) : \IPS\Application::load( $widget['app'] );
|
||||
|
||||
if( isset( $widget['plugin'] ) and !$appOrPlugin->enabled )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$_widget = \IPS\Widget::load( $appOrPlugin, $widget['key'], ( ! empty($widget['unique'] ) ? $widget['unique'] : uniqid() ), ( isset( $widget['configuration'] ) ) ? $widget['configuration'] : array(), ( isset( $widget['restrict'] ) ? $widget['restrict'] : null ), ( $areaKey == 'sidebar' ) ? 'vertical' : 'horizontal' );
|
||||
if ( isset( $_widget->cacheKey ) )
|
||||
{
|
||||
$storeLoad[] = $_widget->cacheKey;
|
||||
}
|
||||
$widgetObjects[ $areaKey ][] = $_widget;
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Log::i( LOG_ERR )->write( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
\IPS\Data\Store::i()->loadIntoMemory( $storeLoad );
|
||||
|
||||
foreach ( $widgetObjects as $areaKey => $_widgets )
|
||||
{
|
||||
foreach ( $_widgets as $_widget )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['widgets'][ $areaKey ][] = $_widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Meta tags */
|
||||
\IPS\Output::i()->buildMetaTags();
|
||||
|
||||
/* Finish */
|
||||
parent::finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the basic javascript files every page needs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function baseJs()
|
||||
{
|
||||
parent::baseJs();
|
||||
|
||||
/* Stuff for output */
|
||||
if ( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->globalControllers[] = 'core.front.core.app';
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front.js' ) );
|
||||
|
||||
if ( \IPS\Member::loggedIn()->members_bitoptions['bw_using_skin_gen'] AND ( isset( \IPS\Request::i()->cookie['vseThemeId'] ) AND \IPS\Request::i()->cookie['vseThemeId'] ) and \IPS\Member::loggedIn()->isAdmin() and \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'customization', 'theme_easy_editor' ) )
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_vse.js', 'core', 'front' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'vse/vsedata.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->globalControllers[] = 'core.front.vse.window';
|
||||
}
|
||||
|
||||
/* Can we edit widget layouts? */
|
||||
if( \IPS\Member::loggedIn()->modPermission('can_manage_sidebar') )
|
||||
{
|
||||
\IPS\Output::i()->globalControllers[] = 'core.front.widgets.manager';
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_widgets.js', 'core', 'front' ) );
|
||||
}
|
||||
|
||||
/* Are we editing meta tags? */
|
||||
if( isset( $_SESSION['live_meta_tags'] ) and $_SESSION['live_meta_tags'] and \IPS\Member::loggedIn()->isAdmin() )
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_system.js', 'core', 'front' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Base CSS
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function baseCss()
|
||||
{
|
||||
parent::baseCss();
|
||||
|
||||
/* Stuff for output */
|
||||
if ( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'core.css', 'core', 'front' ) );
|
||||
if ( \IPS\Theme::i()->settings['responsive'] )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'core_responsive.css', 'core', 'front' ) );
|
||||
}
|
||||
if ( count( \IPS\Lang::languages() ) > 1 )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'flags.css', 'core', 'global' ) );
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->members_bitoptions['bw_using_skin_gen'] AND ( isset( \IPS\Request::i()->cookie['vseThemeId'] ) AND \IPS\Request::i()->cookie['vseThemeId'] ) and \IPS\Member::loggedIn()->isAdmin() and \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'customization', 'theme_easy_editor' ) )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/vse.css', 'core', 'front' ) );
|
||||
}
|
||||
|
||||
/* Are we editing meta tags? */
|
||||
if( isset( $_SESSION['live_meta_tags'] ) and $_SESSION['live_meta_tags'] and \IPS\Member::loggedIn()->isAdmin() )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/meta_tags.css', 'core', 'front' ) );
|
||||
}
|
||||
|
||||
/* Query log? */
|
||||
if ( \IPS\QUERY_LOG )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/query_log.css', 'core', 'front' ) );
|
||||
}
|
||||
if ( \IPS\CACHING_LOG )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/caching_log.css', 'core', 'front' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Installer/Upgrader Dispatcher
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 2 Apr 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Dispatcher;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Installer/Upgrader Dispatcher
|
||||
*/
|
||||
class _Setup extends \IPS\Dispatcher
|
||||
{
|
||||
/**
|
||||
* @brief Controller Location
|
||||
*/
|
||||
public $controllerLocation = 'setup';
|
||||
|
||||
/**
|
||||
* @brief Install or upgrade
|
||||
*/
|
||||
public $setupLocation = 'install';
|
||||
|
||||
/**
|
||||
* @brief Step
|
||||
*/
|
||||
public $step = 1;
|
||||
|
||||
/**
|
||||
* Initiator
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return valid steps
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function returnSteps()
|
||||
{
|
||||
if( $this->setupLocation == 'upgrade' )
|
||||
{
|
||||
return array(
|
||||
1 => 'login',
|
||||
2 => 'systemcheck',
|
||||
3 => 'license',
|
||||
4 => 'applications',
|
||||
5 => 'customoptions',
|
||||
6 => 'confirm',
|
||||
7 => 'upgrade',
|
||||
8 => 'done',
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array(
|
||||
1 => 'systemcheck',
|
||||
2 => 'license',
|
||||
3 => 'applications',
|
||||
4 => 'serverdetails',
|
||||
5 => 'admin',
|
||||
6 => 'install',
|
||||
7 => 'done',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set location (install or upgrade)
|
||||
*
|
||||
* @param string $location 'install' or 'upgrade'
|
||||
* @return \IPS\Dispatcher\Setup
|
||||
*/
|
||||
public function setLocation( $location )
|
||||
{
|
||||
$this->setupLocation = $location;
|
||||
$steps = $this->returnSteps();
|
||||
$this->classname = 'IPS\core\modules\setup\\' . $location . '\\' . ( isset( \IPS\Request::i()->controller ) ? \IPS\Request::i()->controller : $steps[1] );
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
/* Installer checks */
|
||||
if( $this->setupLocation == 'install' )
|
||||
{
|
||||
if ( !file_exists( \IPS\ROOT_PATH . '/conf_global.php' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
@rename( \IPS\ROOT_PATH . '/conf_global.dist.php', \IPS\ROOT_PATH . '/conf_global.php' );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
|
||||
if ( !file_exists( \IPS\ROOT_PATH . '/conf_global.php' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
@file_put_contents( \IPS\ROOT_PATH . '/conf_global.php', '' );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
if ( !file_exists( \IPS\ROOT_PATH . '/conf_global.php' ) )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( "Installation Error", '', true, \IPS\ROOT_PATH ) );
|
||||
}
|
||||
}
|
||||
|
||||
require \IPS\ROOT_PATH . '/conf_global.php';
|
||||
if ( isset( $INFO ) and isset( $INFO['installed'] ) )
|
||||
{
|
||||
echo "Installer Locked.";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
/* Upgrader Checks */
|
||||
else
|
||||
{
|
||||
if ( !file_exists( \IPS\ROOT_PATH . '/conf_global.php' ) )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( "Upgrade Error", '', "Could not locate your conf_global.php file.", \IPS\ROOT_PATH ), 200, 'text/html', array(), FALSE );
|
||||
}
|
||||
|
||||
if ( \IPS\STORE_METHOD === 'FileSystem' )
|
||||
{
|
||||
$config = json_decode( \IPS\STORE_CONFIG, TRUE );
|
||||
$path = str_replace( '{root}', \IPS\ROOT_PATH, $config['path'] );
|
||||
if ( !is_dir( $path ) or !is_writable( $path ) )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( "Upgrade Error", '', "Please create a {$path} directory and make it writeable. If you are not sure how to do this, contact your hosting provider.", \IPS\ROOT_PATH ), 200, 'text/html', array(), FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
require \IPS\ROOT_PATH . '/conf_global.php';
|
||||
if ( !isset( $INFO ) )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( "Upgrade Error", '', "Your conf_global.php file is invalid", \IPS\ROOT_PATH ), 200, 'text/html', array(), FALSE );
|
||||
}
|
||||
|
||||
/* Fix languages if necessary */
|
||||
if( \IPS\Db::i()->checkForTable( 'core_sys_lang' ) AND !\IPS\Db::i()->checkForColumn( 'core_sys_lang', 'lang_order' ) )
|
||||
{
|
||||
\IPS\Lang::languages( \IPS\Db::i()->select( '*', 'core_sys_lang' ) );
|
||||
}
|
||||
|
||||
/* Fix members if necessary */
|
||||
if( !\IPS\Db::i()->checkForTable( 'core_members' ) )
|
||||
{
|
||||
\IPS\Member::$databaseTable = 'members';
|
||||
|
||||
if ( !\IPS\Db::i()->checkForTable( 'core_groups' ) )
|
||||
{
|
||||
\IPS\Member\Group::$databaseTable = 'groups';
|
||||
}
|
||||
|
||||
/* re-arrange 3.x mapping to 4.x code */
|
||||
$bits = \IPS\Member::$bitOptions;
|
||||
unset( $bits['members_bitoptions']['members_bitoptions2'] );
|
||||
\IPS\Member::$bitOptions = $bits;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Settings::i()->base_url = ( \IPS\Request::i()->isSecure() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . mb_substr( $_SERVER['SCRIPT_NAME'], 0, -mb_strlen( \IPS\CP_DIRECTORY . '/' . $this->setupLocation . '/index.php' ) );
|
||||
|
||||
$this->step = array_search( \IPS\Request::i()->controller, $this->returnSteps() );
|
||||
|
||||
session_name( ( \IPS\COOKIE_PREFIX !== NULL ) ? \IPS\COOKIE_PREFIX . 'IPSSessionSetup' : 'IPSSessionSetup' );
|
||||
$currentCookieParams = session_get_cookie_params();
|
||||
session_set_cookie_params(
|
||||
86400 * 14,
|
||||
( \IPS\COOKIE_PATH !== NULL ) ? \IPS\COOKIE_PATH : $currentCookieParams['path'],
|
||||
( \IPS\COOKIE_DOMAIN !== NULL ) ? \IPS\COOKIE_DOMAIN : $currentCookieParams['domain'],
|
||||
( \IPS\COOKIE_BYPASS_SSLONLY !== NULL ) ? ( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) == 'https' ) : $currentCookieParams['secure'],
|
||||
TRUE
|
||||
);
|
||||
|
||||
if( !session_start() )
|
||||
{
|
||||
\IPS\Output::i()->error( "We were unable to start a PHP session. You will need to contact your host to adjust your PHP configuration before you can continue.", '4S109/5', 500, '' );
|
||||
}
|
||||
|
||||
if( $this->classname != 'IPS\core\modules\setup\upgrade\done' and $this->setupLocation != 'install' and $this->step > 1 AND ( !isset( $_SESSION['uniqueKey'] ) OR $_SESSION['uniqueKey'] != \IPS\Request::i()->key ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'upgrade_session_error', '3S109/4', 403, '' );
|
||||
}
|
||||
|
||||
/* Init class */
|
||||
if( !class_exists( $this->classname ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'page_doesnt_exist', '2S100/1', 404 );
|
||||
}
|
||||
$controller = new $this->classname;
|
||||
if( !( $controller instanceof \IPS\Dispatcher\Controller ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'page_not_found', '5S100/3', 500, '' );
|
||||
}
|
||||
|
||||
/* Execute */
|
||||
$controller->execute();
|
||||
|
||||
/* If we're still here - output */
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Output::i()->output ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Output::i()->title, \IPS\Output::i()->output ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Standard Dispatcher (For Front-End and ACP)
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 21 Nov 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Dispatcher;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Dispatcher
|
||||
*/
|
||||
abstract class _Standard extends \IPS\Dispatcher
|
||||
{
|
||||
/**
|
||||
* Application
|
||||
*/
|
||||
public $application;
|
||||
|
||||
/**
|
||||
* Module
|
||||
*/
|
||||
public $module;
|
||||
|
||||
/**
|
||||
* Controller
|
||||
*/
|
||||
public $controller;
|
||||
|
||||
/**
|
||||
* Base CSS
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function baseCss()
|
||||
{
|
||||
if ( !\IPS\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 the basic javascript files every page needs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function baseJs()
|
||||
{
|
||||
/* Stuff for output */
|
||||
if ( !\IPS\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'] = \IPS\Member::loggedIn()->language()->preferredDateFormat();
|
||||
\IPS\Output::i()->jsVars['date_first_day'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function finish()
|
||||
{
|
||||
/* If we're still here - output */
|
||||
if ( ! \IPS\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 ) );
|
||||
/* 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' ) );
|
||||
}
|
||||
|
||||
parent::finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
* @throws \DomainException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
/* Force HTTPs? */
|
||||
if ( mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' )
|
||||
{
|
||||
$baseUrl = new \IPS\Http\Url( \IPS\Settings::i()->base_url );
|
||||
|
||||
if( $baseUrl->data['scheme'] === 'https://' and \IPS\Request::i()->url()->data['scheme'] !== 'https' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( new \IPS\Http\Url( preg_replace( '/^http:/', 'https:', \IPS\Request::i()->url() ) ) );
|
||||
}
|
||||
|
||||
if( $baseUrl->data['host'] !== \IPS\Request::i()->url()->data['host'] )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::createFromArray( array_merge( \IPS\Request::i()->url()->data, array( 'host' => $baseUrl->data['host'] ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Check domain - www. vs no www. is particularly common */
|
||||
if ( mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' and mb_substr( \IPS\Settings::i()->base_url, 0, 8 ) === 'https://' and \IPS\Request::i()->url()->data['scheme'] !== 'https' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( new \IPS\Http\Url( preg_replace( '/^http:/', 'https:', \IPS\Request::i()->url() ) ) );
|
||||
}
|
||||
|
||||
/* Set locale */
|
||||
\IPS\Member::loggedIn()->language()->setLocale();
|
||||
|
||||
/* Set Application */
|
||||
if ( isset( \IPS\Request::i()->app ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->application = \IPS\Application::load( \IPS\Request::i()->app );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$applications = \IPS\Application::applications();
|
||||
|
||||
foreach( $applications as $application )
|
||||
{
|
||||
if( $application->default )
|
||||
{
|
||||
$this->application = $application;
|
||||
}
|
||||
}
|
||||
|
||||
if( !isset( $this->application ) )
|
||||
{
|
||||
$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 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$applications = \IPS\Application::applications();
|
||||
|
||||
foreach( $applications as $application )
|
||||
{
|
||||
if( $application->default )
|
||||
{
|
||||
$this->application = $application;
|
||||
}
|
||||
}
|
||||
|
||||
if( !isset( $this->application ) )
|
||||
{
|
||||
$this->application = array_shift( $applications );
|
||||
}
|
||||
}
|
||||
|
||||
/* Init Application */
|
||||
if( !$this->application->canAccess( \IPS\Member::loggedIn() ) AND $this->controllerLocation != 'admin' )
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'app.js' ) );
|
||||
$message = $this->application->disabled_message ?: 'generic_offline_message';
|
||||
throw new \DomainException( $message, 4 );
|
||||
}
|
||||
if ( method_exists( $this->application, 'init' ) )
|
||||
{
|
||||
$this->application->init();
|
||||
}
|
||||
|
||||
/* Set Module */
|
||||
if ( isset( \IPS\Request::i()->module ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->module = \IPS\Application\Module::get( $this->application->directory, \IPS\Request::i()->module, static::i()->controllerLocation );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->setDefaultModule();
|
||||
}
|
||||
|
||||
/* Set controller */
|
||||
$this->controller = isset( \IPS\Request::i()->controller ) ? \IPS\Request::i()->controller : $this->module->default_controller;
|
||||
|
||||
if( is_array( $this->controller ) )
|
||||
{
|
||||
$this->controller = NULL;
|
||||
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() )
|
||||
{
|
||||
/* Templates */
|
||||
\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' );
|
||||
$templateLoad = array();
|
||||
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 );
|
||||
|
||||
/* App JS */
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\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 ) );
|
||||
}
|
||||
|
||||
/* VLE */
|
||||
if ( isset( \IPS\Request::i()->cookie['vle_editor'] ) and \IPS\Request::i()->cookie['vle_editor'] )
|
||||
{
|
||||
\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';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default module
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setDefaultModule()
|
||||
{
|
||||
$modules = $this->application->modules( static::i()->controllerLocation );
|
||||
foreach( $modules as $module )
|
||||
{
|
||||
if( $module->default )
|
||||
{
|
||||
$this->module = $module;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( $this->module === NULL )
|
||||
{
|
||||
$this->module = array_shift( $modules );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* Runs tasks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
/* If you visit and you are redirected to installer, this code should not run */
|
||||
if( !file_exists( \IPS\ROOT_PATH . '/conf_global.php' ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( \IPS\Session\Front::loggedIn() and !\IPS\Settings::i()->task_use_cron )
|
||||
{
|
||||
$task = \IPS\Task::queued();
|
||||
if ( $task )
|
||||
{
|
||||
$task->runAndLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
Reference in new issue
Block a user