Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -11,26 +11,45 @@
|
||||
namespace IPS\Dispatcher;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\core\DataLayer;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Log;
|
||||
use IPS\Member;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function get_called_class;
|
||||
use function intval;
|
||||
use function mb_stristr;
|
||||
use const IPS\ENFORCE_ACCESS;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class that Controllers should extend
|
||||
*/
|
||||
abstract class _Controller
|
||||
abstract class Controller
|
||||
{
|
||||
/**
|
||||
* @brief Base URL
|
||||
*/
|
||||
public $url;
|
||||
public mixed $url;
|
||||
|
||||
/**
|
||||
* @brief Is this for displaying "content"? Affects if advertisements may be shown
|
||||
*/
|
||||
public $isContentPage = TRUE;
|
||||
public bool $isContentPage = TRUE;
|
||||
|
||||
/**
|
||||
* @brief These properties are used to specify datalayer context properties.
|
||||
@@ -39,21 +58,21 @@ abstract class _Controller
|
||||
'community_area' => array( 'value' => 'search', 'odkUpdate' => 'true' )
|
||||
* )
|
||||
*/
|
||||
public static $dataLayerContext = array();
|
||||
public static array $dataLayerContext = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Http\Url|NULL $url The base URL for this controller or NULL to calculate automatically
|
||||
* @param Url|null $url The base URL for this controller or NULL to calculate automatically
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $url=NULL )
|
||||
public function __construct( mixed $url=NULL )
|
||||
{
|
||||
if ( $url === NULL )
|
||||
{
|
||||
$class = \get_called_class();
|
||||
$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 );
|
||||
$this->url = Url::internal( "app={$exploded[1]}&module={$exploded[4]}&controller={$exploded[5]}", Dispatcher::i()->controllerLocation );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -64,12 +83,12 @@ abstract class _Controller
|
||||
/**
|
||||
* Force a specific method within a controller to execute. Useful for unit testing.
|
||||
*
|
||||
* @param null|string $method The specific method to call
|
||||
* @param string|null $method The specific method to call
|
||||
* @return mixed
|
||||
*/
|
||||
public function forceExecute( $method=NULL )
|
||||
public function forceExecute( ?string $method=NULL ): mixed
|
||||
{
|
||||
if( \IPS\ENFORCE_ACCESS === true and $method !== null )
|
||||
if( ENFORCE_ACCESS and $method !== null )
|
||||
{
|
||||
if ( method_exists( $this, $method ) )
|
||||
{
|
||||
@@ -77,11 +96,13 @@ abstract class _Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->execute();
|
||||
$this->execute();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->execute();
|
||||
$this->execute();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,26 +110,26 @@ abstract class _Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
if ( !empty( static::$dataLayerContext ) AND \IPS\Settings::i()->core_datalayer_enabled AND !\IPS\Request::i()->isAjax() )
|
||||
if ( !empty( static::$dataLayerContext ) AND Settings::i()->core_datalayer_enabled AND !Request::i()->isAjax() )
|
||||
{
|
||||
foreach ( static::$dataLayerContext as $property => $data )
|
||||
{
|
||||
\IPS\core\DataLayer::i()->addContextProperty( $property, $data['value'], $data['odkUpdate'] ?? false );
|
||||
DataLayer::i()->addContextProperty( $property, $data['value'], $data['odkUpdate'] ?? false );
|
||||
}
|
||||
}
|
||||
|
||||
if( \IPS\Request::i()->do and preg_match( '/^[a-zA-Z\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', \IPS\Request::i()->do ) )
|
||||
if( Request::i()->do and preg_match( '/^[a-zA-Z\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', Request::i()->do ) )
|
||||
{
|
||||
if ( method_exists( $this, \IPS\Request::i()->do ) or method_exists( $this, '__call' ) )
|
||||
if ( method_exists( $this, Request::i()->do ) or method_exists( $this, '__call' ) )
|
||||
{
|
||||
$method = \IPS\Request::i()->do;
|
||||
$method = Request::i()->do;
|
||||
$this->$method();
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( 'page_not_found', '2S106/1', 404, '' );
|
||||
Output::i()->error( 'page_not_found', '2S106/1', 404, '' );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -119,7 +140,7 @@ abstract class _Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->error( 'page_not_found', '2S106/2', 404, '' );
|
||||
Output::i()->error( 'page_not_found', '2S106/2', 404, '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,14 +150,14 @@ abstract class _Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function embed()
|
||||
protected function embed() : void
|
||||
{
|
||||
$title = \IPS\Member::loggedIn()->language()->addToStack('error_title');
|
||||
$title = Member::loggedIn()->language()->addToStack('error_title');
|
||||
$content = null;
|
||||
|
||||
if( !isset( static::$contentModel ) )
|
||||
if( !isset( static::$contentModel ) OR !in_array( 'IPS\Content\Embeddable', class_implements( static::$contentModel ) ) )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedUnavailable();
|
||||
$output = Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedUnavailable();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -145,131 +166,131 @@ abstract class _Controller
|
||||
$class = static::$contentModel;
|
||||
$params = array();
|
||||
|
||||
if( \IPS\Request::i()->embedComment )
|
||||
if( Request::i()->embedComment )
|
||||
{
|
||||
|
||||
$commentClass = $class::$commentClass;
|
||||
if ( isset( $class::$archiveClass ) )
|
||||
$commentClass = $class::$commentClass;
|
||||
if ( isset( $class::$archiveClass ) )
|
||||
{
|
||||
$item = $class::load( Request::i()->id );
|
||||
if ( $item->isArchived() )
|
||||
{
|
||||
$item = $class::load( \IPS\Request::i()->id );
|
||||
if ( $item->isArchived() )
|
||||
{
|
||||
$commentClass = $class::$archiveClass;
|
||||
}
|
||||
$commentClass = $class::$archiveClass;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
$content = $commentClass::load( \IPS\Request::i()->embedComment );
|
||||
$content = $commentClass::load( Request::i()->embedComment );
|
||||
$title = $content->item()->mapped('title');
|
||||
}
|
||||
/* Comment wasn't found, but we can still link to the item */
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
$type = $commentClass::$title;
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedCommentUnavailable( $type, $item );
|
||||
$output = Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedCommentUnavailable( $type, $item );
|
||||
goto embedOutput;
|
||||
}
|
||||
}
|
||||
elseif( \IPS\Request::i()->embedReview )
|
||||
elseif( Request::i()->embedReview )
|
||||
{
|
||||
$reviewClass = $class::$reviewClass;
|
||||
$reviewClass = $class::$reviewClass;
|
||||
$item = $class::load( Request::i()->id );
|
||||
try
|
||||
{
|
||||
$content = $reviewClass::load( \IPS\Request::i()->embedReview );
|
||||
$title = $content->item()->mapped('title');
|
||||
$content = $reviewClass::load( Request::i()->embedReview );
|
||||
$title = $content->item()->mapped('title');
|
||||
}
|
||||
/* Review wasn't found, but we can still link to the item */
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
$type = $reviewClass::$title;
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedCommentUnavailable( $type, $item );
|
||||
$output = Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedCommentUnavailable( $type, $item );
|
||||
goto embedOutput;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->page ) and \IPS\Request::i()->page > 1 )
|
||||
if ( isset( Request::i()->page ) and Request::i()->page > 1 )
|
||||
{
|
||||
$params['page'] = \intval( \IPS\Request::i()->page );
|
||||
$params['page'] = intval( Request::i()->page );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->embedDo ) )
|
||||
if ( isset( Request::i()->embedDo ) )
|
||||
{
|
||||
$params['do'] = \IPS\Request::i()->embedDo;
|
||||
$params['do'] = Request::i()->embedDo;
|
||||
}
|
||||
|
||||
$content = $class::load( \IPS\Request::i()->id );
|
||||
$title = $content instanceof \IPS\Node\Model ? $content->_title : $content->mapped( 'title' );
|
||||
$content = $class::load( Request::i()->id );
|
||||
$title = $content instanceof Model ? $content->_title : $content->mapped( 'title' );
|
||||
}
|
||||
$output = $this->getEmbedOutput( $content, $params );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedUnavailable();
|
||||
$output = Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedUnavailable();
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'embed_error' );
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedNoPermission();
|
||||
Log::log( $e, 'embed_error' );
|
||||
$output = Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedNoPermission();
|
||||
}
|
||||
}
|
||||
embedOutput:
|
||||
|
||||
|
||||
/* Make sure our iframe contents get the necessary elements and JS */
|
||||
$js = array(
|
||||
\IPS\Output::i()->js( 'js/commonEmbedHandler.js', 'core', 'interface' ),
|
||||
\IPS\Output::i()->js( 'js/internalEmbedHandler.js', 'core', 'interface' )
|
||||
Output::i()->js( 'js/commonEmbedHandler.js', 'core', 'interface' ),
|
||||
Output::i()->js( 'js/internalEmbedHandler.js', 'core', 'interface' )
|
||||
);
|
||||
\IPS\Output::i()->base = '_parent';
|
||||
Output::i()->base = '_parent';
|
||||
|
||||
/* We need to keep any embed.css files that have been specified so that we can re-add them after we re-fetch the css framework */
|
||||
$embedCss = array();
|
||||
foreach( \IPS\Output::i()->cssFiles as $cssFile )
|
||||
foreach( Output::i()->cssFiles as $cssFile )
|
||||
{
|
||||
if( \mb_stristr( $cssFile, 'embed.css' ) )
|
||||
if( mb_stristr( $cssFile, 'embed.css' ) )
|
||||
{
|
||||
$embedCss[] = $cssFile;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to reset the included CSS files because by this point the responsive files are already in the output CSS array */
|
||||
\IPS\Output::i()->cssFiles = array();
|
||||
\IPS\Output::i()->responsive = FALSE;
|
||||
\IPS\Dispatcher\Front::baseCss();
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, $embedCss );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'styles/embeds.css', 'core', 'front' ) );
|
||||
Output::i()->cssFiles = array();
|
||||
Output::i()->responsive = FALSE;
|
||||
Front::baseCss();
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, $embedCss );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'styles/embeds.css', 'core', 'front' ) );
|
||||
|
||||
/* Seo Stuffs */
|
||||
\IPS\Output::i()->title = $title;
|
||||
Output::i()->title = $title;
|
||||
|
||||
if( $content !== NULL )
|
||||
{
|
||||
\IPS\Output::i()->linkTags['canonical'] = (string) $content->url();
|
||||
Output::i()->linkTags['canonical'] = (string) $content->url();
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->metaTags['robots'] = 'noindex';
|
||||
Output::i()->metaTags['robots'] = 'noindex';
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->embedInternal( $output, $js ), 200, 'text/html' );
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate( 'global', 'core', 'front' )->embedInternal( $output, $js ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content item or the proper error message
|
||||
*
|
||||
* @param \IPS\Content $content
|
||||
* @param object $content
|
||||
* @param array $params
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getEmbedOutput( $content, array $params = array() )
|
||||
protected function getEmbedOutput( object $content, array $params = array() ): string
|
||||
{
|
||||
if ( !$content->canView() )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedNoPermission();
|
||||
$output = Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedNoPermission();
|
||||
}
|
||||
else if ( !( $content instanceof \IPS\Content\Embeddable ) )
|
||||
else if ( !in_array( 'IPS\Content\Embeddable', class_implements( $content ) ) )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedUnavailable();
|
||||
$output = Theme::i()->getTemplate( 'embed', 'core', 'global' )->embedUnavailable();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user