Version 4.1.19
This commit is contained in:
1 parent
28bd025b35
commit
2bd5025018
2674 files changed
+233518
-77766
No files matched your search
+68
-38
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @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.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @since 18 Feb 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
@@ -116,7 +116,45 @@ class _Admin extends \IPS\Dispatcher\Standard
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Check we're logged in and we have ACP access */
|
||||
if( ( !\IPS\Member::loggedIn()->member_id or !\IPS\Member::loggedIn()->isAdmin() )
|
||||
and ( \IPS\Request::i()->module !== 'system' or \IPS\Request::i()->controller !== 'login' )
|
||||
and ( !\IPS\ENFORCE_ACCESS )
|
||||
)
|
||||
{
|
||||
/* Make sure the right protocol is used. IIS, for example, does not like protocol relative URL's in redirects. (Ref: 970629) */
|
||||
$protocol = \IPS\Http\Url::PROTOCOL_HTTP;
|
||||
if ( \IPS\Settings::i()->logins_over_https OR \substr( \IPS\Settings::i()->base_url, 0, 5 ) == 'https' )
|
||||
{
|
||||
$protocol = \IPS\Http\Url::PROTOCOL_HTTPS;
|
||||
}
|
||||
|
||||
$url = \IPS\Http\Url::internal( "app=core&module=system&controller=login", 'admin', NULL, array(), $protocol );
|
||||
|
||||
if ( \IPS\Session::i()->error )
|
||||
{
|
||||
$url = $url->setQueryString( 'error', \IPS\Session::i()->error->getMessage() );
|
||||
}
|
||||
|
||||
if( !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
/* If someone calls this from command line, while it wouldn't work, the key won't be set */
|
||||
if( isset( $_SERVER['QUERY_STRING'] ) )
|
||||
{
|
||||
$url = $url->setQueryString( 'ref', base64_encode( preg_replace( '!adsess=((\w){32}|&)!', "", $_SERVER['QUERY_STRING'] ) ) );
|
||||
}
|
||||
}
|
||||
else if( isset( $_SERVER['HTTP_REFERER'] ) )
|
||||
{
|
||||
$previous = preg_replace( "/^(.+?)\/\?/", "", $_SERVER['HTTP_REFERER'] );
|
||||
$url = $url->setQueryString( 'ref', base64_encode( preg_replace( '!adsess=.*?(&|$)!', "", $previous ) ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $url );
|
||||
}
|
||||
|
||||
/* Init */
|
||||
try
|
||||
{
|
||||
parent::init();
|
||||
@@ -126,30 +164,10 @@ class _Admin extends \IPS\Dispatcher\Standard
|
||||
\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 )
|
||||
)
|
||||
/* If we are in recovery mode, but not actually doing the recovery process, or logging in, then we need them to remove the constant */
|
||||
if ( \IPS\RECOVERY_MODE === TRUE AND !in_array( $this->controller, array( 'recovery', 'login' ) ) )
|
||||
{
|
||||
$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', base64_encode( preg_replace( '!adsess=((\w){32}|&)!', "", $_SERVER['QUERY_STRING'] ) ) );
|
||||
}
|
||||
else if( isset( $_SERVER['HTTP_REFERER'] ) )
|
||||
{
|
||||
$previous = preg_replace( "/^(.+?)\/\?/", "", $_SERVER['HTTP_REFERER'] );
|
||||
$url = $url->setQueryString( 'ref', base64_encode( preg_replace( '!adsess=.*?(&|$)!', "", $previous ) ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $url );
|
||||
\IPS\Output::i()->error( 'recovery_mode_remove_constant', '1S107/3', 403, '' );
|
||||
}
|
||||
|
||||
/* Permission Check */
|
||||
@@ -227,7 +245,7 @@ class _Admin extends \IPS\Dispatcher\Standard
|
||||
{
|
||||
$currentTab = $this->application->directory;
|
||||
}
|
||||
|
||||
|
||||
/* Display */
|
||||
if( $this->controller !== 'login' )
|
||||
{
|
||||
@@ -250,6 +268,8 @@ class _Admin extends \IPS\Dispatcher\Standard
|
||||
*/
|
||||
public function buildMenu( $rebuild=FALSE )
|
||||
{
|
||||
$acpTabOrder = $this->_getAcpTabOrder();
|
||||
|
||||
if ( $this->menu === NULL or $rebuild === TRUE )
|
||||
{
|
||||
$this->menu = array( 'tabs' => array(), 'defaults' => array() );
|
||||
@@ -258,13 +278,25 @@ class _Admin extends \IPS\Dispatcher\Standard
|
||||
{
|
||||
if ( \IPS\Application::appIsEnabled( $app->directory ) and \IPS\Application::load( $app->directory )->canAccess() )
|
||||
{
|
||||
foreach ( $app->acpMenu() as $moduleKey => $items )
|
||||
$appMenu = $app->acpMenu();
|
||||
|
||||
if ( $acpTabOrder !== NULL and isset( $acpTabOrder[ $app->directory ] ) and $app->directory == 'nexus' )
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( $app, $moduleKey ) )
|
||||
{
|
||||
foreach ( $items as $itemKey => $item )
|
||||
{
|
||||
if ( !$item['restriction'] or \IPS\Member::loggedIn()->hasAcpRestriction( $app, $moduleKey, $item['restriction'] ) )
|
||||
uksort( $appMenu, function( $a, $b ) use ( $acpTabOrder, $app )
|
||||
{
|
||||
return array_search( "{$app->directory}_{$a}", $acpTabOrder[ $app->directory ] ) - array_search( "{$app->directory}_{$b}", $acpTabOrder[ $app->directory ] );
|
||||
} );
|
||||
}
|
||||
|
||||
foreach ( $appMenu as $moduleKey => $items )
|
||||
{
|
||||
foreach ( $items as $itemKey => $item )
|
||||
{
|
||||
$moduleToCheck = ( isset( $item['restriction_module'] ) ) ? $item['restriction_module'] : $moduleKey;
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( $app, $moduleToCheck ) )
|
||||
{
|
||||
if ( !$item['restriction'] or \IPS\Member::loggedIn()->hasAcpRestriction( $app, $moduleToCheck, $item['restriction'] ) )
|
||||
{
|
||||
if ( !isset( $this->menu['defaults'][ $item['tab'] ] ) )
|
||||
{
|
||||
@@ -278,9 +310,7 @@ class _Admin extends \IPS\Dispatcher\Standard
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$acpTabOrder = $this->_getAcpTabOrder();
|
||||
}
|
||||
|
||||
if ( $acpTabOrder !== NULL )
|
||||
{
|
||||
@@ -344,8 +374,8 @@ class _Admin extends \IPS\Dispatcher\Standard
|
||||
$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() );
|
||||
{
|
||||
$this->acpTabOrder = array( 'core' => array(), 'community' => array(), 'members' => array(), 'nexus' => array(), 'cms' => array(), 'stats' => array(), 'customization' => array() );
|
||||
}
|
||||
|
||||
\IPS\Request::i()->setCookie( 'acpTabs', json_encode( $this->acpTabOrder ) );
|
||||
@@ -378,7 +408,7 @@ class _Admin extends \IPS\Dispatcher\Standard
|
||||
{
|
||||
if ( !\IPS\Member::loggedIn()->hasAcpRestriction( ( $app ?: $this->application ), ( $module ?: $this->module ), $key ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2S107/1', 403, '' );
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2S107/2', 403, '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief API Dispatcher
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 3 Dec 2015
|
||||
* @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 API Dispatcher
|
||||
*/
|
||||
class _Api extends \IPS\Dispatcher
|
||||
{
|
||||
/**
|
||||
* @brief Controller Location
|
||||
*/
|
||||
public $controllerLocation = 'api';
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
* @throws \DomainException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Run
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
/* Init */
|
||||
$shouldLog = FALSE;
|
||||
$isBadKey = FALSE;
|
||||
$output = NULL;
|
||||
$httpResponseCode = 500;
|
||||
|
||||
/* Decode URL */
|
||||
if ( \IPS\Settings::i()->use_friendly_urls and \IPS\Settings::i()->htaccess_mod_rewrite )
|
||||
{
|
||||
/* We are using Mod Rewrite URL's, so look in the path */
|
||||
$path = mb_substr( \IPS\Request::i()->url()->data[ \IPS\Http\Url::COMPONENT_PATH ], mb_strpos( \IPS\Request::i()->url()->data[ \IPS\Http\Url::COMPONENT_PATH ], '/api/' ) + 5 );
|
||||
|
||||
/* nginx won't convert the 'fake' query string to $_GET params, so do this now */
|
||||
if ( ! empty( \IPS\Request::i()->url()->data[ \IPS\Http\Url::COMPONENT_QUERY ] ) )
|
||||
{
|
||||
parse_str( \IPS\Request::i()->url()->data[ \IPS\Http\Url::COMPONENT_QUERY ], $params );
|
||||
foreach ( $params as $k => $v )
|
||||
{
|
||||
if ( ! isset( \IPS\Request::i()->$k ) )
|
||||
{
|
||||
\IPS\Request::i()->$k = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise we are not, so we need the query string instead, which is actually easier */
|
||||
$path = \IPS\Request::i()->url()->data[ \IPS\Http\Url::COMPONENT_QUERY ];
|
||||
|
||||
/* However, if we passed any actual query string arguments, we need to strip those */
|
||||
if( mb_strpos( $path, '&' ) )
|
||||
{
|
||||
$path = mb_substr( $path, 0, mb_strpos( $path, '&' ) );
|
||||
}
|
||||
}
|
||||
$pathBits = array_filter( explode( '/', $path ) );
|
||||
|
||||
/* Run */
|
||||
try
|
||||
{
|
||||
/* IP is banned? */
|
||||
if ( \IPS\Request::i()->ipAddressIsBanned() )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'IP_ADDRESS_BANNED', '1S290/A', 403 );
|
||||
}
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'core_api_logs', array( 'ip_address=? AND is_bad_key=1', \IPS\Request::i()->ipAddress() ) )->first() > 10 )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_banfilters', array(
|
||||
'ban_type' => 'ip',
|
||||
'ban_content' => \IPS\Request::i()->ipAddress(),
|
||||
'ban_date' => time(),
|
||||
'ban_reason' => 'API',
|
||||
) );
|
||||
unset( \IPS\Data\Store::i()->bannedIpAddresses );
|
||||
throw new \IPS\Api\Exception( 'IP_ADDRESS_BANNED', '1S290/A', 403 );
|
||||
}
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'core_api_logs', array( 'ip_address=? AND is_bad_key=1 AND date>?', \IPS\Request::i()->ipAddress(), \IPS\DateTime::create()->sub( new \DateInterval( 'PT5M' ) )->getTimestamp() ) )->first() > 1 )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'TOO_MANY_REQUESTS_WITH_BAD_KEY', '1S290/A', 429 );
|
||||
}
|
||||
|
||||
/* Work out API key */
|
||||
$rawApiKey = NULL;
|
||||
if ( \IPS\Request::i()->isCgi() and isset( \IPS\Request::i()->key ) )
|
||||
{
|
||||
$rawApiKey = \IPS\Request::i()->key;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( $_SERVER['PHP_AUTH_USER'] ) )
|
||||
{
|
||||
$rawApiKey = $_SERVER['PHP_AUTH_USER'];
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( $_SERVER as $k => $v )
|
||||
{
|
||||
if ( mb_substr( $k, -18 ) == 'HTTP_AUTHORIZATION' )
|
||||
{
|
||||
$exploded = explode( ':', base64_decode( mb_substr( $v, 6 ) ) );
|
||||
if ( isset( $exploded[0] ) )
|
||||
{
|
||||
$rawApiKey = $exploded[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get API key */
|
||||
if ( !isset( $rawApiKey ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_API_KEY', '2S290/6', 401 );
|
||||
}
|
||||
try
|
||||
{
|
||||
$apiKey = \IPS\Api\Key::load( $rawApiKey );
|
||||
|
||||
if ( $rawApiKey != 'test' and $apiKey->allowed_ips and !in_array( \IPS\Request::i()->ipAddress(), explode( ',', $apiKey->allowed_ips ) ) )
|
||||
{
|
||||
$shouldLog = TRUE;
|
||||
throw new \IPS\Api\Exception( 'IP_ADDRESS_NOT_ALLOWED', '2S290/8', 403 );
|
||||
}
|
||||
|
||||
if ( $rawApiKey != 'test' and ! \IPS\Request::i()->isCgi() and isset( \IPS\Request::i()->key ) )
|
||||
{
|
||||
$shouldLog = TRUE;
|
||||
throw new \IPS\Api\Exception( 'CANNOT_USE_KEY_AS_URL_PARAM', '2S290/B', 403 );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
if ( $rawApiKey != 'test' )
|
||||
{
|
||||
$shouldLog = TRUE;
|
||||
$isBadKey = TRUE;
|
||||
}
|
||||
throw new \IPS\Api\Exception( 'INVALID_API_KEY', '3S290/7', 401 );
|
||||
}
|
||||
|
||||
/* Get language */
|
||||
try
|
||||
{
|
||||
if ( isset( $_SERVER['HTTP_X_IPS_LANGUAGE'] ) )
|
||||
{
|
||||
$language = \IPS\Lang::load( intval( $_SERVER['HTTP_X_IPS_LANGUAGE'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$language = \IPS\Lang::load( \IPS\Lang::defaultLanguage() );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_LANGUAGE', '2S290/9', 400 );
|
||||
}
|
||||
|
||||
/* Work out the app and controller. Both can only be alphanumeric - prevents include injections */
|
||||
$app = array_shift( $pathBits );
|
||||
if ( !preg_match( '/^[a-z0-9]+$/', $app ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_APP', '3S290/3', 400 );
|
||||
}
|
||||
$controller = array_shift( $pathBits );
|
||||
if ( !preg_match( '/^[a-z0-9]+$/', $controller ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_CONTROLLER', '3S290/4', 400 );
|
||||
}
|
||||
|
||||
/* Load the app */
|
||||
try
|
||||
{
|
||||
$app = \IPS\Application::load( $app );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_APP', '2S290/1', 404 );
|
||||
}
|
||||
|
||||
/* Check it's enabled */
|
||||
if ( !$app->enabled )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'APP_DISABLED', '1S290/2', 503 );
|
||||
}
|
||||
|
||||
/* Get the controller */
|
||||
$class = 'IPS\\' . $app->directory . '\\api\\' . $controller;
|
||||
if ( !class_exists( $class ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_CONTROLLER', '2S290/5', 404 );
|
||||
}
|
||||
|
||||
/* Run it */
|
||||
$controller = new $class( $apiKey );
|
||||
$response = $controller->execute( $pathBits, $shouldLog );
|
||||
|
||||
/* Output */
|
||||
$output = json_encode( $response->getOutput(), JSON_PRETTY_PRINT );
|
||||
$language->parseOutputForDisplay( $output );
|
||||
$httpResponseCode = $response->httpCode;
|
||||
|
||||
}
|
||||
catch ( \IPS\Api\Exception $e )
|
||||
{
|
||||
if ( $shouldLog )
|
||||
{
|
||||
\IPS\Log::log( $e, 'api' );
|
||||
}
|
||||
|
||||
$output = json_encode( array( 'errorCode' => $e->exceptionCode, 'errorMessage' => $e->getMessage() ), JSON_PRETTY_PRINT );
|
||||
$httpResponseCode = $e->getCode();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
if ( $shouldLog )
|
||||
{
|
||||
\IPS\Log::log( $e, 'api' );
|
||||
}
|
||||
|
||||
$output = json_encode( array( 'errorCode' => 'EX' . $e->getCode(), 'errorMessage' => \IPS\IN_DEV ? $e->getMessage() : 'UNKNOWN_ERROR' ), JSON_PRETTY_PRINT );
|
||||
$httpResponseCode = 500;
|
||||
}
|
||||
|
||||
/* Log? */
|
||||
if ( $shouldLog )
|
||||
{
|
||||
/* Database logging errors should not prevent the output being sent */
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_api_logs', array(
|
||||
'endpoint' => $path,
|
||||
'method' => $_SERVER['REQUEST_METHOD'],
|
||||
'api_key' => $rawApiKey,
|
||||
'ip_address' => \IPS\Request::i()->ipAddress(),
|
||||
'request_data' => json_encode( $_REQUEST, JSON_PRETTY_PRINT ),
|
||||
'response_code' => $httpResponseCode,
|
||||
'response_output' => $output,
|
||||
'date' => time(),
|
||||
'is_bad_key' => $isBadKey
|
||||
) );
|
||||
}
|
||||
catch ( \IPS\Db\Exception $e ) {}
|
||||
}
|
||||
|
||||
/* Output */
|
||||
\IPS\Output::i()->sendOutput( $output, $httpResponseCode, 'application/json' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @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.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @since 2 Apr 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @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.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @since 18 Feb 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
@@ -60,7 +60,7 @@ abstract class _Controller
|
||||
{
|
||||
if ( method_exists( $this, $method ) )
|
||||
{
|
||||
return call_user_func( array( $this, $method ) );
|
||||
return $this->$method();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -82,7 +82,8 @@ abstract class _Controller
|
||||
{
|
||||
if ( method_exists( $this, \IPS\Request::i()->do ) or method_exists( $this, '__call' ) )
|
||||
{
|
||||
call_user_func( array( $this, \IPS\Request::i()->do ) );
|
||||
$method = \IPS\Request::i()->do;
|
||||
$this->$method();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -91,7 +92,14 @@ abstract class _Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->manage();
|
||||
if ( method_exists( $this, 'manage' ) or method_exists( $this, '__call' ) )
|
||||
{
|
||||
$this->manage();
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( 'page_not_found', '2S106/2', 404, '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,19 +128,20 @@ abstract class _Controller
|
||||
$commentClass = $class::$commentClass;
|
||||
if ( isset( $class::$archiveClass ) )
|
||||
{
|
||||
$item = call_user_func( array( $class, 'loadAndCheckPerms' ), \IPS\Request::i()->id );
|
||||
$item = $class::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
if ( $item->isArchived() )
|
||||
{
|
||||
$commentClass = $class::$archiveClass;
|
||||
}
|
||||
}
|
||||
|
||||
$content = call_user_func( array( $commentClass, 'loadAndCheckPerms' ), \IPS\Request::i()->embedComment );
|
||||
$content = $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 );
|
||||
$reviewClass = $class::$reviewClass;
|
||||
$content = $reviewClass::loadAndCheckPerms( \IPS\Request::i()->embedReview );
|
||||
$title = $content->item()->mapped('title');
|
||||
}
|
||||
else
|
||||
@@ -146,7 +155,7 @@ abstract class _Controller
|
||||
$params['do'] = \IPS\Request::i()->embedDo;
|
||||
}
|
||||
|
||||
$content = call_user_func( array( $class, 'loadAndCheckPerms' ), \IPS\Request::i()->id );
|
||||
$content = $class::loadAndCheckPerms( \IPS\Request::i()->id );
|
||||
$title = $content instanceof \IPS\Node\Model ? $content->_title : $content->mapped('title');
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @brief Dispatcher
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @since 18 Feb 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Front-end Dispatcher
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatcher that doesn't really dispatch but sets things up for external scripts calling IPS4 stuff, like Pages external blocks
|
||||
*/
|
||||
class _External extends \IPS\Dispatcher\Standard
|
||||
{
|
||||
/**
|
||||
* Controller Location
|
||||
*/
|
||||
public $controllerLocation = 'front';
|
||||
|
||||
/**
|
||||
* Init
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
/* Base CSS */
|
||||
static::baseCss();
|
||||
|
||||
/* Base JS */
|
||||
static::baseJs();
|
||||
|
||||
/* Run global init */
|
||||
try
|
||||
{
|
||||
parent::init();
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '2S100/' . $e->getCode(), $e->getCode() === 4 ? 403 : 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+179
-149
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @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.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @since 18 Feb 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
@@ -53,10 +53,7 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
|
||||
/* Get cached page if available */
|
||||
$this->checkCached();
|
||||
|
||||
/* Perform some legacy URL conversions*/
|
||||
static::convertLegacyParameters();
|
||||
|
||||
|
||||
/* Sync stuff when in developer mode */
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
@@ -69,91 +66,27 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
/* 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 === '' )
|
||||
/* Check friendly URL and whether it is correct */
|
||||
try
|
||||
{
|
||||
$_calledScript = '/';
|
||||
$this->checkUrl();
|
||||
}
|
||||
|
||||
/* Handle friendly URLs */
|
||||
if ( \IPS\Settings::i()->use_friendly_urls and $_calledScript == str_replace( '\\', '/', \IPS\ROOT_PATH ) )
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
try
|
||||
/* Display a 404 */
|
||||
$this->application = \IPS\Application::load('core');
|
||||
$this->setDefaultModule();
|
||||
if ( \IPS\Member::loggedIn()->isBanned() )
|
||||
{
|
||||
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, '' );
|
||||
\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, '' );
|
||||
}
|
||||
|
||||
/* Perform some legacy URL conversions*/
|
||||
static::convertLegacyParameters();
|
||||
|
||||
/* Run global init */
|
||||
try
|
||||
@@ -177,8 +110,17 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
/* Enable sidebar by default (controllers can turn it off if needed) */
|
||||
\IPS\Output::i()->sidebar['enabled'] = ( \IPS\Request::i()->isAjax() ) ? FALSE : TRUE;
|
||||
|
||||
/* Add in RSS Feeds */
|
||||
foreach( \IPS\core\Rss::getAllFeeds() AS $feed_id => $feed )
|
||||
{
|
||||
if ( $feed->groups == '*' OR \IPS\Member::loggedIn()->inGroup( $feed->groups ) )
|
||||
{
|
||||
\IPS\Output::i()->rssFeeds[ $feed->_title ] = $feed->url();
|
||||
}
|
||||
}
|
||||
|
||||
/* 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\Settings::i()->site_online and !\IPS\Member::loggedIn()->group['g_access_offline'] and $this->controllerLocation == 'front' and !$this->application->allowOfflineAccess( $this->module, $this->controller, \IPS\Request::i()->do ) )
|
||||
{
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
@@ -206,41 +148,66 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
\IPS\Output::i()->sidebar = FALSE;
|
||||
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
|
||||
if( $this->controller !== 'contact' )
|
||||
if( !in_array( $this->controller, array( 'contact', 'warnings' ) ) )
|
||||
{
|
||||
$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, '' );
|
||||
\IPS\Output::i()->showBanned();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Do we need more info from the member or do they need to validate? */
|
||||
if( \IPS\Member::loggedIn()->member_id )
|
||||
if( \IPS\Member::loggedIn()->member_id and $this->controller !== 'language' and $this->controller !== 'theme' )
|
||||
{
|
||||
/* Need their name or email... */
|
||||
if( ( !\IPS\Member::loggedIn()->real_name or !\IPS\Member::loggedIn()->email ) and $this->controller !== 'register' )
|
||||
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' ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=complete' )->setQueryString( 'ref', base64_encode( \IPS\Request::i()->url() ) ) );
|
||||
}
|
||||
|
||||
/* Need them to validate... */
|
||||
elseif( \IPS\Member::loggedIn()->members_bitoptions['validating'] and $this->controller !== 'register' and $this->controller !== 'login' and $this->controller != 'redirect' and $this->controller !== 'contact' )
|
||||
elseif( \IPS\Member::loggedIn()->members_bitoptions['validating'] and $this->controller !== 'register' and $this->controller !== 'login' and $this->controller != 'redirect' and $this->controller !== 'contact' and $this->controller !== 'privacy' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=validating', 'front', 'register' ) );
|
||||
}
|
||||
|
||||
/* Need them to reconfirm terms/privacy policy */
|
||||
elseif ( ( \IPS\Member::loggedIn()->members_bitoptions['must_reaccept_privacy'] or \IPS\Member::loggedIn()->members_bitoptions['must_reaccept_terms'] ) and $this->controller !== 'register' )
|
||||
/* Need them to reconfirm terms/privacy policy... */
|
||||
elseif ( ( \IPS\Member::loggedIn()->members_bitoptions['must_reaccept_privacy'] or \IPS\Member::loggedIn()->members_bitoptions['must_reaccept_terms'] ) and $this->controller !== 'register' and $this->controller !== 'ajax' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=reconfirm', 'front', 'register' ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=register&do=reconfirm', 'front', 'register' )->setQueryString( 'ref', base64_encode( \IPS\Request::i()->url() ) ) );
|
||||
}
|
||||
/* Need to set up MFA... */
|
||||
elseif ( !in_array( $this->controller, array( 'register', 'login', 'redirect', 'contact', 'privacy', 'ajax', 'settings' ) ) )
|
||||
{
|
||||
$haveAcceptableHandlers = FALSE;
|
||||
$haveConfiguredHandler = FALSE;
|
||||
foreach ( \IPS\MFA\MFAHandler::handlers() as $key => $handler )
|
||||
{
|
||||
if ( $handler->isEnabled() and $handler->memberCanUseHandler( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
$haveAcceptableHandlers = TRUE;
|
||||
if ( $handler->memberHasConfiguredHandler( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
$haveConfiguredHandler = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$haveConfiguredHandler and $haveAcceptableHandlers )
|
||||
{
|
||||
if ( \IPS\Settings::i()->mfa_required_groups == '*' or \IPS\Member::loggedIn()->inGroup( explode( ',', \IPS\Settings::i()->mfa_required_groups ) ) )
|
||||
{
|
||||
if ( \IPS\Settings::i()->mfa_required_prompt === 'immediate' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&do=initialMfa', 'front', 'settings' )->setQueryString( 'ref', base64_encode( \IPS\Request::i()->url() ) ) );
|
||||
}
|
||||
}
|
||||
elseif ( \IPS\Settings::i()->mfa_optional_prompt === 'immediate' and !\IPS\Member::loggedIn()->members_bitoptions['security_questions_opt_out'] )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=system&controller=settings&do=initialMfa', 'front', 'settings' )->setQueryString( 'ref', base64_encode( \IPS\Request::i()->url() ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Permission Check */
|
||||
@@ -269,7 +236,7 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
|
||||
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 );
|
||||
\IPS\Output::i()->breadcrumb['module'] = array( \IPS\Http\Url::internal( 'app=' . $this->application->directory . '&module=' . $this->module->key . '&controller=' . $this->module->default_controller, 'front', array_key_exists( $this->module->key, \IPS\Http\Url::furlDefinition() ) ? $this->module->key : NULL ), $this->module->_title );
|
||||
}
|
||||
|
||||
/* Figure out what the global search is */
|
||||
@@ -282,7 +249,7 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
$classes = $object->classes;
|
||||
foreach ( $classes as $class )
|
||||
{
|
||||
if ( is_subclass_of( $class, 'IPS\Content\Searchable' ) and $class::$includeInSiteSearch )
|
||||
if ( is_subclass_of( $class, 'IPS\Content\Searchable' ) and $class::includeInSiteSearch() )
|
||||
{
|
||||
$type = mb_strtolower( str_replace( '\\', '_', mb_substr( array_pop( $classes ), 4 ) ) );
|
||||
\IPS\Output::i()->defaultSearchOption = array( $type, "{$type}_pl" );
|
||||
@@ -295,6 +262,78 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the URL we visited is correct and route appropriately
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function checkUrl()
|
||||
{
|
||||
/* Handle friendly URLs */
|
||||
if ( \IPS\Settings::i()->use_friendly_urls )
|
||||
{
|
||||
$url = \IPS\Request::i()->url();
|
||||
|
||||
/* Redirect to the "correct" friendly URL if there is one */
|
||||
if ( !\IPS\Request::i()->isAjax() and mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' and !\IPS\ENFORCE_ACCESS )
|
||||
{
|
||||
$correctUrl = NULL;
|
||||
|
||||
/* If it's already a friendly URL, we need to check the SEO title is valid. If it isn't, we redirect iof "Force Friendly URLs" is enabled */
|
||||
if ( $url instanceof \IPS\Http\Url\Friendly or ( $url instanceof \IPS\Http\Url\Internal and \IPS\Settings::i()->seo_r_on ) )
|
||||
{
|
||||
$correctUrl = $url->correctFriendlyUrl();
|
||||
}
|
||||
|
||||
/* If they are accessing "index.php/whatever", we want "index.php?/whatever */
|
||||
if ( !( $correctUrl instanceof \IPS\Http\Url ) and $url instanceof \IPS\Http\Url\Internal and mb_strpos( $url->data[ \IPS\Http\Url::COMPONENT_PATH ], '/index.php/' ) !== FALSE )
|
||||
{
|
||||
$pathFromBaseUrl = mb_substr( $url->data[ \IPS\Http\Url::COMPONENT_PATH ], mb_strlen( \IPS\Http\Url::internal('')->data[ \IPS\Http\Url::COMPONENT_PATH ] ) );
|
||||
if ( preg_match( '/index.php\//', $pathFromBaseUrl ) )
|
||||
{
|
||||
$correctUrl = \IPS\Http\Url\Friendly::friendlyUrlFromComponent( 0, trim( mb_substr( $pathFromBaseUrl, 10 ), '/' ), $url->queryString );
|
||||
}
|
||||
}
|
||||
|
||||
/* Redirect to the correct URL if we got one */
|
||||
if ( $correctUrl instanceof \IPS\Http\Url )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $correctUrl, NULL, 301 );
|
||||
}
|
||||
}
|
||||
|
||||
/* If the accessed URL is friendly, set the "real" query string properties */
|
||||
if ( $url instanceof \IPS\Http\Url\Friendly )
|
||||
{
|
||||
foreach ( ( $url->queryString + $url->hiddenQueryString ) as $k => $v )
|
||||
{
|
||||
if( $k == 'module' )
|
||||
{
|
||||
$this->_module = NULL;
|
||||
}
|
||||
else if( $k == 'controller' )
|
||||
{
|
||||
$this->_controller = NULL;
|
||||
}
|
||||
|
||||
\IPS\Request::i()->$k = $v;
|
||||
}
|
||||
}
|
||||
/* Otherwise if it's not a recognised URL, show a 404 */
|
||||
elseif ( !( $url instanceof \IPS\Http\Url\Internal ) or $url->base !== 'front' )
|
||||
{
|
||||
/* Call the parent first in case we need to redirect to https, and so the correct locale, etc. is set */
|
||||
try
|
||||
{
|
||||
parent::init();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define that the page should load even if the user is banned and not logged in
|
||||
*
|
||||
@@ -313,7 +352,7 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
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() )
|
||||
if( mb_strtolower( $_SERVER['REQUEST_METHOD'] ) == 'get' and !isset( \IPS\Request::i()->csrfKey ) and !isset( \IPS\Request::i()->_mfaLogin ) and !\IPS\Session\Front::loggedIn() and !isset( \IPS\Request::i()->cookie['noCache'] ) and !\IPS\Request::i()->ipAddressIsBanned() and \IPS\CACHE_PAGE_TIMEOUT )
|
||||
{
|
||||
/* Which language? */
|
||||
if ( isset( \IPS\Request::i()->cookie['language'] ) )
|
||||
@@ -337,7 +376,7 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
/* Get cache */
|
||||
try
|
||||
{
|
||||
$cache = \IPS\Data\Cache::i()->getWithExpire( 'page_' . md5( ( !empty( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'] ) . '/' . $_SERVER['REQUEST_URI'] ) . "_{$language}_{$theme}", TRUE );
|
||||
$cache = \IPS\Data\Cache::i()->getWithExpire( 'page_' . md5( (int) \IPS\Request::i()->isSecure() . ( !empty( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'] ) . '/' . $_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 );
|
||||
@@ -353,49 +392,12 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
*/
|
||||
public static function convertLegacyParameters()
|
||||
{
|
||||
/* Convert §ion= to &controller= */
|
||||
if ( isset( \IPS\Request::i()->section ) AND !isset( \IPS\Request::i()->controller ) )
|
||||
foreach( \IPS\Application::applications() as $directory => $application )
|
||||
{
|
||||
\IPS\Request::i()->controller = \IPS\Request::i()->section;
|
||||
}
|
||||
|
||||
/* Convert &showtopic= */
|
||||
if ( isset( \IPS\Request::i()->showtopic ) )
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( 'app=forums&module=forums&controller=topic&id=' . \IPS\Request::i()->showtopic );
|
||||
if ( isset( \IPS\Request::i()->p ) or isset( \IPS\Request::i()->findpost ) )
|
||||
if( method_exists( $application, 'convertLegacyParameters' ) )
|
||||
{
|
||||
$url = $url->setQueryString( array( 'do' => 'findComment', 'comment' => \IPS\Request::i()->p ?: \IPS\Request::i()->findpost ) );
|
||||
$application->convertLegacyParameters();
|
||||
}
|
||||
elseif ( isset( \IPS\Request::i()->page ) )
|
||||
{
|
||||
$url = $url->setQueryString( array( 'page' => \IPS\Request::i()->page ) );
|
||||
}
|
||||
\IPS\Output::i()->redirect( $url );
|
||||
}
|
||||
|
||||
/* 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 ) );
|
||||
}
|
||||
|
||||
/* Support legacy subscriptions */
|
||||
if( isset( \IPS\Request::i()->app ) AND \IPS\Request::i()->app == 'subscriptions' )
|
||||
{
|
||||
/* Redirecting isn't necessary, we just need to route the payment to the appropriate area.
|
||||
@see \IPS\nexus\Application */
|
||||
\IPS\Request::i()->app = 'nexus';
|
||||
\IPS\Request::i()->module = 'payments';
|
||||
\IPS\Request::i()->section = 'receive'; /* It actually looks for section=receive, so make sure we set that */
|
||||
\IPS\Request::i()->controller = 'receive'; /* We set this just to be complete in case anywhere else only looks at controller */
|
||||
\IPS\Request::i()->validate = 'paypal';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +477,7 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
{
|
||||
$appOrPlugin = isset( $widget['plugin'] ) ? \IPS\Plugin::load( $widget['plugin'] ) : \IPS\Application::load( $widget['app'] );
|
||||
|
||||
if( isset( $widget['plugin'] ) and !$appOrPlugin->enabled )
|
||||
if( !$appOrPlugin->enabled )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -489,7 +491,7 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Log::i( LOG_ERR )->write( $e->getMessage() );
|
||||
\IPS\Log::log( $e, 'dispatcher' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -512,10 +514,30 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
/* Meta tags */
|
||||
\IPS\Output::i()->buildMetaTags();
|
||||
|
||||
/* Check MFA */
|
||||
$this->checkMfa();
|
||||
|
||||
/* Finish */
|
||||
parent::finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check MFA to see if we need to supply a code
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function checkMfa()
|
||||
{
|
||||
/* MFA Login? */
|
||||
if ( isset( \IPS\Request::i()->_mfaLogin ) and isset( $_SESSION['processing2FA'] ) and $member = \IPS\Member::load( $_SESSION['processing2FA']['memberId'] ) and $member->member_id )
|
||||
{
|
||||
if ( $output = \IPS\MFA\MFAHandler::accessToArea( 'core', 'AuthenticateFront', \IPS\Http\Url::internal( 'app=core&module=system&controller=login&do=mfa', 'front', 'login' ), $member ) )
|
||||
{
|
||||
\IPS\Output::i()->output .= $output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the basic javascript files every page needs
|
||||
*
|
||||
@@ -593,4 +615,12 @@ class _Front extends \IPS\Dispatcher\Standard
|
||||
}
|
||||
}
|
||||
}
|
||||
function run() {
|
||||
/* отслеживаем переходы */
|
||||
if ( $_SERVER['HTTP_REFERER'] )
|
||||
{
|
||||
\IPS\core\modules\admin\promotion\seovisitors::track( $_SERVER['HTTP_REFERER'], htmlentities( $_SERVER['QUERY_STRING'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ), \IPS\Member::loggedIn()->member_id );
|
||||
}
|
||||
parent::run();
|
||||
}
|
||||
}
|
||||
+12
-12
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @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.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @since 2 Apr 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
@@ -109,7 +109,7 @@ class _Setup extends \IPS\Dispatcher
|
||||
{
|
||||
try
|
||||
{
|
||||
@rename( \IPS\ROOT_PATH . '/conf_global.dist.php', \IPS\ROOT_PATH . '/conf_global.php' );
|
||||
rename( \IPS\ROOT_PATH . '/conf_global.dist.php', \IPS\ROOT_PATH . '/conf_global.php' );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
|
||||
@@ -117,21 +117,21 @@ class _Setup extends \IPS\Dispatcher
|
||||
{
|
||||
try
|
||||
{
|
||||
@file_put_contents( \IPS\ROOT_PATH . '/conf_global.php', '' );
|
||||
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 ) );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Member::loggedIn()->language()->addToStack( 'installation_error' ), '', true, \IPS\ROOT_PATH ), 500, 'text/html', array(), FALSE, FALSE, FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
require \IPS\ROOT_PATH . '/conf_global.php';
|
||||
if ( isset( $INFO ) and isset( $INFO['installed'] ) )
|
||||
{
|
||||
echo "Installer Locked.";
|
||||
echo \IPS\Member::loggedIn()->language()->addToStack( 'installer_locked' );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -140,7 +140,7 @@ class _Setup extends \IPS\Dispatcher
|
||||
{
|
||||
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 );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Member::loggedIn()->language()->addToStack('upgrade_error'), '', \IPS\Member::loggedIn()->language()->addToStack('no_conf_global'), \IPS\ROOT_PATH ), 200, 'text/html', array(), FALSE );
|
||||
}
|
||||
|
||||
if ( \IPS\STORE_METHOD === 'FileSystem' )
|
||||
@@ -149,14 +149,14 @@ class _Setup extends \IPS\Dispatcher
|
||||
$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 );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Member::loggedIn()->language()->addToStack('upgrade_error'), '', \IPS\Member::loggedIn()->language()->addToStack( 'create_conf_global', FALSE, array( 'sprintf' => array( $path ) ) ), \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 );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Member::loggedIn()->language()->addToStack('upgrade_error'), '', \IPS\Member::loggedIn()->language()->addToStack('bad_conf_global'), \IPS\ROOT_PATH ), 200, 'text/html', array(), FALSE );
|
||||
}
|
||||
|
||||
/* Fix languages if necessary */
|
||||
@@ -192,14 +192,14 @@ class _Setup extends \IPS\Dispatcher
|
||||
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'],
|
||||
( \IPS\COOKIE_BYPASS_SSLONLY !== TRUE ) ? ( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) == 'https' ) : $currentCookieParams['secure'],
|
||||
TRUE
|
||||
);
|
||||
|
||||
if( !@session_start() )
|
||||
{
|
||||
$lastError = error_get_last();
|
||||
\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. The error reported was: " . $lastError['message'], '4S109/5', 500, '' );
|
||||
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'session_no_good', FALSE, array( 'sprintf' => array( $lastError['message'] ) ) ), '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 ) )
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* @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.
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @package IPS Community Suite
|
||||
* @since 21 Nov 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
@@ -76,9 +76,12 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
\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_format'] = mb_strtolower( \IPS\Member::loggedIn()->language()->preferredDateFormat() );
|
||||
\IPS\Output::i()->jsVars['date_first_day'] = 0;
|
||||
\IPS\Output::i()->jsVars['remote_image_proxy'] = intval( \IPS\Settings::i()->remote_image_proxy );
|
||||
\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'] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,27 +112,21 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
/* Force HTTPs? */
|
||||
/* 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 );
|
||||
|
||||
if( $baseUrl->data['scheme'] === 'https://' and \IPS\Request::i()->url()->data['scheme'] !== 'https' )
|
||||
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() ) ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->setScheme('https') );
|
||||
}
|
||||
|
||||
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'] ) ) ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->setHost( $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();
|
||||
@@ -232,11 +229,14 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
\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 )
|
||||
if ( ! \IPS\Theme::isUsingTemplateDiskCache() )
|
||||
{
|
||||
$templateLoad[] = 'template_' . \IPS\Theme::i()->id . '_' . \IPS\Theme::makeBuiltTemplateLookupHash( $data[0], $data[1], $data[2] ) . '_' . $data[2];
|
||||
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 );
|
||||
}
|
||||
\IPS\Data\Store::i()->loadIntoMemory( $templateLoad );
|
||||
}
|
||||
|
||||
/* App JS */
|
||||
@@ -296,13 +296,17 @@ abstract class _Standard extends \IPS\Dispatcher
|
||||
return;
|
||||
}
|
||||
|
||||
if ( \IPS\Session\Front::loggedIn() and !\IPS\Settings::i()->task_use_cron )
|
||||
if ( \IPS\Session\Front::loggedIn() and \IPS\Settings::i()->task_use_cron == 'normal' )
|
||||
{
|
||||
$task = \IPS\Task::queued();
|
||||
if ( $task )
|
||||
try
|
||||
{
|
||||
$task->runAndLog();
|
||||
$task = \IPS\Task::queued();
|
||||
if ( $task )
|
||||
{
|
||||
$task->runAndLog();
|
||||
}
|
||||
}
|
||||
catch( \IPS\Db\Exception $e ) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user