Invision Power Services, Inc. * @copyright (c) Invision Power Services, Inc. * @license https://www.invisioncommunity.com/legal/standards/ * @package Invision Community * @since 18 Feb 2013 */ 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 $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' ) ) { $method = \IPS\Request::i()->do; $this->$method(); } else { \IPS\Output::i()->error( 'page_not_found', '2S106/1', 404, '' ); } } else { if ( method_exists( $this, 'manage' ) or method_exists( $this, '__call' ) ) { $this->manage(); } else { \IPS\Output::i()->error( 'page_not_found', '2S106/2', 404, '' ); } } } /** * 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 = $class::loadAndCheckPerms( \IPS\Request::i()->id ); if ( $item->isArchived() ) { $commentClass = $class::$archiveClass; } } $content = $commentClass::loadAndCheckPerms( \IPS\Request::i()->embedComment ); $title = $content->item()->mapped('title'); } elseif( \IPS\Request::i()->embedReview ) { $reviewClass = $class::$reviewClass; $content = $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 = $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(); } } /* 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' ) ); \IPS\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 ) { 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' ) ); \IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->embedInternal( $output, $js ), 200, 'text/html', \IPS\Output::i()->httpHeaders ); } }