Invision Power Services, Inc. * @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc. * @license http://www.invisionpower.com/legal/standards/ * @package IPS Social Suite * @since 15 Jan 2014 * @version SVN_VERSION_NUMBER */ namespace IPS\cms\Pages; /* 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 Page Model */ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions { /** * @brief [ActiveRecord] Multiton Store */ protected static $multitons; /** * @brief [ActiveRecord] Database Table */ public static $databaseTable = 'cms_pages'; /** * @brief [ActiveRecord] Database Prefix */ public static $databasePrefix = 'page_'; /** * @brief [ActiveRecord] ID Database Column */ public static $databaseColumnId = 'id'; /** * @brief [ActiveRecord] Database ID Fields */ protected static $databaseIdFields = array('page_seo_name', 'page_full_path'); /** * @brief [Node] Parent ID Database Column */ public static $databaseColumnParent = null; /** * @brief [Node] Parent Node ID Database Column */ public static $parentNodeColumnId = 'folder_id'; /** * @brief [Node] Parent Node Class */ public static $parentNodeClass = 'IPS\cms\Pages\Folder'; /** * @brief [Node] Parent ID Database Column */ public static $databaseColumnOrder = 'seo_name'; /** * @brief [Node] Show forms modally? */ public static $modalForms = TRUE; /** * @brief [Node] Title */ public static $nodeTitle = 'page'; /** * @brief [Node] ACP Restrictions * @code array( 'app' => 'core', // The application key which holds the restrictrions 'module' => 'foo', // The module key which holds the restrictions 'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix" 'add' => 'foo_add', 'edit' => 'foo_edit', 'permissions' => 'foo_perms', 'delete' => 'foo_delete' ), 'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4) 'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete" * @endcode */ protected static $restrictions = array( 'app' => 'cms', 'module' => 'pages', 'prefix' => 'page_' ); /** * @brief [Node] App for permission index */ public static $permApp = 'cms'; /** * @brief [Node] Type for permission index */ public static $permType = 'pages'; /** * @brief The map of permission columns */ public static $permissionMap = array( 'view' => 'view' ); /** * @brief [Node] Prefix string that is automatically prepended to permission matrix language strings */ public static $permissionLangPrefix = 'perm_content_page_'; /** * @brief [Page] Loaded pages from paths */ protected static $loadedPagesFromPath = array(); /** * @brief [Page] Currently loaded page */ public static $currentPage = NULL; /** * @brief [Page] Default page */ public static $defaultPage = array(); /** * */ /** * @brief Pre save flag */ const PRE_SAVE = 1; /** * @brief Post save flag */ const POST_SAVE = 2; /** * Set Default Values * * @return void */ public function setDefaultValues() { $this->js_css_ids = ''; $this->content = ''; $this->meta_keywords = ''; $this->meta_description = ''; $this->template = ''; $this->full_path = ''; $this->js_css_objects = ''; } /** * @brief [Node] Title prefix. If specified, will look for a language key with "{$titleLangPrefix}_{$id}" as the key */ public static $titleLangPrefix = 'cms_page_'; /** * Load record based on a URL * * @param \IPS\Http\Url $url URL to load from * @return \IPS\cms\Pages\Page * @throws \InvalidArgumentException * @throws \OutOfRangeException */ public static function loadFromUrl( \IPS\Http\Url $url ) { $qs = array_merge( $url->queryString, $url->getFriendlyUrlData() ); if ( isset( $qs['id'] ) ) { if ( method_exists( get_called_class(), 'loadAndCheckPerms' ) ) { return static::loadAndCheckPerms( $qs['id'] ); } else { return static::load( $qs['id'] ); } } else if ( isset( $qs['path'] ) ) { if ( method_exists( get_called_class(), 'loadAndCheckPerms' ) ) { return static::loadAndCheckPerms( $qs['path'], 'page_full_path' ); } else { return static::load( $qs['path'], 'page_full_path' ); } } throw new \InvalidArgumentException; } /** * Get the page based on the database ID * * @param int $databaseId * @return \IPS\cms\Pages\Page object * @throws \OutOfRangeException */ public static function loadByDatabaseId( $databaseId ) { return static::load( \IPS\cms\Databases::load( $databaseId )->page_id ); } /** * Resets a page path * * @param int $folderId Folder ID to reset * @return void */ public static function resetPath( $folderId ) { try { $path = \IPS\cms\Pages\Folder::load( $folderId )->path; } catch ( \OutOfRangeException $ex ) { throw new \OutOfRangeException; } $children = static::getChildren( $folderId ); foreach( $children as $id => $obj ) { $obj->setFullPath( $path ); } } /** * Get all children of a specific folder. * * @param INT $folderId Folder ID to fetch children from * @return array */ public static function getChildren( $folderId=0 ) { $children = array(); foreach( \IPS\Db::i()->select( '*', static::$databaseTable, array( 'page_folder_id=?', intval( $folderId ) ), 'page_seo_name ASC' ) as $child ) { $children[ $child[ static::$databasePrefix . static::$databaseColumnId ] ] = static::load( $child[ static::$databasePrefix . static::$databaseColumnId ] ); } return $children; } /** * Returns a page object (or NULL) based on the path * * @param string $path Path /like/this/ok.html * @return NULL|\IPS\cms\Pages\Page object */ public static function loadFromPath( $path ) { $path = trim( $path, '/' ); if ( ! array_key_exists( $path, static::$loadedPagesFromPath ) ) { static::$loadedPagesFromPath[ $path ] = NULL; /* Try the simplest option */ try { static::$loadedPagesFromPath[ $path ] = static::load( $path, 'page_full_path' ); } catch ( \OutOfRangeException $e ) { /* Nope - try a folder */ try { $class = static::$parentNodeClass; $folder = $class::load( $path, 'folder_path' ); static::$loadedPagesFromPath[ $path ] = static::getDefaultPage( $folder->id ); } catch ( \OutOfRangeException $e ) { /* May contain a database path */ if ( \strstr( $path, '/' ) ) { $bits = explode( '/', $path ); $pathsToTry = array(); while( count( $bits ) ) { $pathsToTry[] = implode( '/', $bits ); array_pop($bits); } try { static::$loadedPagesFromPath[ $path ] = static::constructFromData( \IPS\Db::i()->select( '*', 'cms_pages', \IPS\Db::i()->in( 'page_full_path', $pathsToTry ), 'page_full_path DESC' )->first() ); } catch( \UnderFlowException $e ) { /* Last chance saloon */ foreach( \IPS\Db::i()->select( '*', 'cms_pages', array( '? LIKE CONCAT( page_full_path, \'%\')', $path ), 'page_full_path DESC' ) as $page ) { if ( mb_stristr( $page['page_content'], '{database' ) ) { static::$loadedPagesFromPath[ $path ] = static::constructFromData( $page ); break; } } } } } } } if ( static::$loadedPagesFromPath[ $path ] === NULL ) { throw new \OutOfRangeException; } return static::$loadedPagesFromPath[ $path ]; } /** * Load from path history so we can 301 to the correct record. * * @param string $slug Thing that lives in the garden and eats your plants * @param string|NULL $queryString Any query string to add to the end * @return \IPS\cms\Pages\Page */ public static function getUrlFromHistory( $slug, $queryString=NULL ) { $slug = trim( $slug, '/' ); try { $row = \IPS\Db::i()->select( '*', 'cms_url_store', array( 'store_type=? and store_path=?', 'page', $slug ) )->first(); return static::load( $row['store_current_id'] )->url(); } catch( \UnderflowException $ex ) { /* Ok, perhaps this is a full URL with the page name at the beginning */ foreach( \IPS\Db::i()->select( '*', 'cms_url_store', array( 'store_type=? and ? LIKE CONCAT( store_path, \'%\') OR store_path=?', 'page', $slug, $slug ) ) as $item ) { $url = static::load( $item['store_current_id'] )->url(); $url->data['path'] = '/' . trim( str_replace( $item['store_path'], trim( $url->data['path'], '/' ), $slug ), '/' ); if ( $queryString !== NULL ) { $url->data['query'] = $queryString; } return \IPS\Http\Url::createFromArray( $url->data ); } /* Still here? Ok, now we may have changed the folder name at some point, so lets look for that */ foreach( \IPS\Db::i()->select( '*', 'cms_url_store', array( 'store_type=? and ? LIKE CONCAT( store_path, \'%\') OR store_path=?', 'folder', $slug, $slug ) ) as $item ) { try { $folder = \IPS\cms\Pages\Folder::load( $item['store_current_id'] ); /* Attempt to build the new path */ $newPath = str_replace( $item['store_path'], $folder->path, $slug ); /* Do we have a page with this path? */ try { return static::load( $newPath, 'page_full_path' )->url(); } catch( \OutOfRangeException $ex ) { /* This is not the path you are looking for */ } } catch( \OutOfRangeException $ex ) { /* This also is not the path you are looking for */ } } } /* Still here? Consistent with AR pattern */ throw new \OutOfRangeException(); } /** * Return the default page for this folder * * @param INT $folderId Folder ID to fetch children from * @return \IPS\cms\Pages\Page */ public static function getDefaultPage( $folderId=0 ) { if ( ! isset( static::$defaultPage[ $folderId ] ) ) { /* Try the easiest method first */ try { static::$defaultPage[ $folderId ] = \IPS\cms\Pages\Page::load( \IPS\Db::i()->select( 'page_id', static::$databaseTable, array( 'page_default=? AND page_folder_id=?', 1, intval( $folderId ) ) )->first() ); } catch( \Exception $ex ) { throw new \OutOfRangeException; } /* Got a page called index? */ if ( ! isset( static::$defaultPage[ $folderId ] ) ) { foreach( static::getChildren( $folderId ) as $id => $obj ) { if ( \mb_substr( $obj->seo_name, 0, 5 ) === 'index' ) { return $obj; } } reset( $children ); /* Just return the first, then */ static::$defaultPage[ $folderId ] = array_shift( $children ); } } return ( isset( static::$defaultPage[ $folderId ] ) ) ? static::$defaultPage[ $folderId ] : NULL; } /** * Delete compiled versions * * @param int|array $ids Integer ID or Array IDs to remove * @return void */ public static function deleteCompiled( $ids ) { if ( is_numeric( $ids ) ) { $ids = array( $ids ); } foreach( $ids as $id ) { $functionName = 'content_pages_' . $id; if ( isset( \IPS\Data\Store::i()->$functionName ) ) { unset( \IPS\Data\Store::i()->$functionName ); } } } /** * Removes all include objects from all pages * * @param boolean $url The URL to find and remove * @return void */ static public function deleteCachedIncludes( $url=NULL ) { /* Remove them all */ if ( $url === NULL ) { /* Remove from DB */ if ( \IPS\Db::i()->checkForTable( 'cms_pages' ) ) { \IPS\Db::i()->update( 'cms_pages', array( 'page_js_css_objects' => NULL ) ); } /* Remove from file system */ \IPS\File::getClass( 'cms_Pages')->deleteContainer('page_objects'); } else { $bits = explode( '/', (string ) $url ); $name = array_pop( $bits ); /* Remove selectively */ foreach( \IPS\Db::i()->select( '*', 'cms_pages', array( "page_js_css_objects LIKE '%" . \IPS\Db::i()->escape_string( $name ) . "%'" ) ) as $row ) { \IPS\Db::i()->update( 'cms_pages', array( 'page_js_css_objects' => NULL ), array( 'page_id=?', $row['page_id'] ) ); } } } /** * Form elements * * @param object|null $item Page object or NULL * @return array */ static public function formElements( $item=NULL ) { $return = array(); $pageType = isset( \IPS\Request::i()->page_type ) ? \IPS\Request::i()->page_type : ( $item ? $item->type : 'html' ); $return['tab_details'] = array( 'content_page_form_tab__details' ); $return['page_name'] = new \IPS\Helpers\Form\Translatable( 'page_name', NULL, TRUE, array( 'app' => 'cms', 'key' => ( $item and $item->id ) ? "cms_page_" . $item->id : NULL, 'maxLength' => 64 ), function( $val ) { if ( empty( $val ) ) { throw new \DomainException('form_required'); } }, NULL, NULL, 'page_name' ); $return['page_seo_name'] = new \IPS\Helpers\Form\Text( 'page_seo_name', $item ? $item->seo_name : '', FALSE, array( 'maxLength' => 255 ), function( $val ) { if ( empty( $val ) ) { $val = \IPS\Http\Url::seoTitle( $val ); } try { $test = \IPS\cms\Pages\Page::load( $val, 'page_seo_name' ); if ( isset( \IPS\Request::i()->id ) ) { if ( $test->id == \IPS\Request::i()->id ) { /* Just us.. */ return TRUE; } } /* Not us */ if ( intval( \IPS\Request::i()->page_folder_id ) == $test->folder_id ) { throw new \InvalidArgumentException( 'content_page_file_name_in_use' ); } } catch ( \OutOfRangeException $e ) { /* If we hit here, we don't have an existing name so that's good */ if ( ! \IPS\Request::i()->page_folder_id and \IPS\cms\Pages\Page::isFurlCollision( $val ) ) { throw new \InvalidArgumentException('content_folder_name_furl_collision'); } } }, NULL, NULL, 'page_seo_name' ); $return['page_folder_id'] = new \IPS\Helpers\Form\Node( 'page_folder_id', ( $item ? intval( $item->folder_id ) : ( ( isset( \IPS\Request::i()->parent ) and \IPS\Request::i()->parent ) ? \IPS\Request::i()->parent : 0 ) ), FALSE, array( 'class' => '\IPS\cms\Pages\Folder', 'zeroVal' => 'node_no_parent', 'subnodes' => false ), NULL, NULL, NULL, 'page_folder_id' ); if ( $pageType === 'html' ) { $return['page_ipb_wrapper'] = new \IPS\Helpers\Form\YesNo( 'page_ipb_wrapper', $item AND $item->id ? $item->ipb_wrapper : 1, TRUE, array( 'togglesOn' => array( 'page_show_sidebar' ), 'togglesOff' => array( 'page_wrapper_template' ) ), NULL, NULL, NULL, 'page_ipb_wrapper' ); $return['page_show_sidebar'] = new \IPS\Helpers\Form\YesNo( 'page_show_sidebar', $item ? $item->show_sidebar : TRUE, FALSE, array(), NULL, NULL, NULL, 'page_show_sidebar' ); $wrapperTemplates = array( '_none_' => \IPS\Member::loggedIn()->language()->addToStack('cms_page_wrapper_template_none') ); foreach( \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_PAGE + \IPS\cms\Templates::RETURN_DATABASE_AND_IN_DEV ) as $id => $obj ) { if ( $obj->isSuitableForCustomWrapper() ) { $wrapperTemplates[ \IPS\cms\Templates::readableGroupName( $obj->group ) ][ $obj->group . '__' . $obj->title . '__' . $obj->key ] = \IPS\cms\Templates::readableGroupName( $obj->title ); } } /* List of templates */ $return['page_wrapper_template'] = new \IPS\Helpers\Form\Select( 'page_wrapper_template', ( $item ? $item->wrapper_template : NULL ), FALSE, array( 'options' => $wrapperTemplates ), NULL, NULL, \IPS\Theme::i()->getTemplate( 'pages', 'cms', 'admin' )->previewTemplateLink(), 'page_wrapper_template' ); } else { if ( count( \IPS\Theme::themes() ) > 1 ) { $themes = array( 0 => 'cms_page_theme_id_default' ); foreach ( \IPS\Theme::themes() as $theme ) { $themes[ $theme->id ] = $theme->_title; } $return['page_theme'] = new \IPS\Helpers\Form\Select( 'page_theme', $item ? $item->theme : 0, FALSE, array( 'options' => $themes ), NULL, NULL, NULL, 'page_theme' ); } $builderTemplates = array(); foreach( \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_PAGE + \IPS\cms\Templates::RETURN_DATABASE_AND_IN_DEV ) as $id => $obj ) { if ( $obj->isSuitableForBuilderWrapper() ) { $builderTemplates[ \IPS\cms\Templates::readableGroupName( $obj->group ) ][ $obj->group . '__' . $obj->title . '__' . $obj->key ] = \IPS\cms\Templates::readableGroupName( $obj->title ); } } $return['page_template'] = new \IPS\Helpers\Form\Select( 'page_template', $item->template ? $item->template : FALSE, FALSE, array( 'options' => $builderTemplates ), NULL, NULL, NULL, 'page_template' ); } /* Page CSS and JS */ $js = \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_ONLY_JS + \IPS\cms\Templates::RETURN_DATABASE_ONLY ); $css = \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_ONLY_CSS + \IPS\cms\Templates::RETURN_DATABASE_ONLY ); if ( count( $js ) OR count( $css ) ) { $return['tab_js_css'] = array( 'content_page_form_tab__includes' ); $return['msg_js_css'] = array( 'cms_page_includes_message', 'ipsMessage ipsMessage_info ipsCmsIncludesMessage' ); if ( count( $js ) ) { $jsincludes = array(); foreach( $js as $obj ) { $jsincludes[ $obj->key ] = \IPS\cms\Templates::readableGroupName( $obj->group ) . '/' . \IPS\cms\Templates::readableGroupName( $obj->title ); } $return['page_includes_js'] = new \IPS\Helpers\Form\Select( 'page_includes_js', $item ? $item->js_includes : FALSE, FALSE, array( 'options' => $jsincludes, 'multiple' => true ), NULL, NULL, NULL, 'page_includes_js' ); } if ( count( $css ) ) { $cssincludes = array(); foreach( $css as $obj ) { $cssincludes[ $obj->key ] = \IPS\cms\Templates::readableGroupName( $obj->group ) . '/' . \IPS\cms\Templates::readableGroupName( $obj->title ); } $return['page_includes_css'] = new \IPS\Helpers\Form\Select( 'page_includes_css', $item ? $item->css_includes : FALSE, FALSE, array( 'options' => $cssincludes, 'multiple' => true ), NULL, NULL, NULL, 'page_includes_css' ); } } if ( $pageType === 'html' ) { $return['tab_content'] = array( 'content_page_form_tab__content', NULL, NULL, 'ipsForm_vertical' ); $tags = array(); foreach( \IPS\cms\Databases::roots( NULL, NULL ) as $id => $db ) { if ( ! $db->page_id ) { $tags['{database="' . $db->_id . '" title="' . $db->_title . '"}'] = $db->_title; } } foreach( \IPS\cms\Blocks\Block::roots( NULL, NULL ) as $id => $block ) { $tags['{block="' . $block->_id . '" title="' . $block->_title . '"}'] = $block->_title; } $return['page_content'] = new \IPS\Helpers\Form\Codemirror( 'page_content', $item ? $item->content : NULL, FALSE, array( 'tags' => $tags ), function( $val ) { /* Test */ try { \IPS\Theme::checkTemplateSyntax( $val ); } catch( \LogicException $e ) { throw new \LogicException('cms_page_error_bad_syntax'); } }, NULL, NULL, 'page_content' ); } $return['tab_meta'] = array( 'content_page_form_tab__meta' ); $return['page_title'] = new \IPS\Helpers\Form\Text( 'page_title', $item ? $item->title : '', FALSE, array( 'maxLength' => 64 ), NULL, NULL, NULL, 'page_title' ); $return['page_meta_keywords'] = new \IPS\Helpers\Form\TextArea( 'page_meta_keywords', $item ? $item->meta_keywords : '', FALSE, array(), NULL, NULL, NULL, 'page_meta_keywords' ); $return['page_meta_description'] = new \IPS\Helpers\Form\TextArea( 'page_meta_description', $item ? $item->meta_description : '', FALSE, array(), NULL, NULL, NULL, 'page_meta_description' ); \IPS\Output::i()->globalControllers[] = 'cms.admin.pages.form'; \IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_pages.js', 'cms' ) ); return $return; } /** * Create a new page from a form. Pretty much what the function says. * * @param array $values Array of form values * @param string $pageType Type of page. 'html', 'builder' or 'editor' * @return \IPS\cms\Pages\Page object */ static public function createFromForm( $values, $pageType=NULL ) { $page = new self; $page->type = $pageType; $page->save(); $page->saveForm( $page->formatFormValues( $values ), $pageType ); /* Set permissions */ \IPS\Db::i()->insert( 'core_permission_index', array( 'app' => 'cms', 'perm_type' => 'pages', 'perm_type_id' => $page->id, 'perm_view' => '*' ) ); return $page; } /** * Ensure there aren't any collision issues when the CMS is the default app and folders such as "forums" are created when * the forums app is installed. * * @param string $path Path to check * @return boolean */ static public function isFurlCollision( $path ) { $path = trim( $path , '/'); $bits = explode( '/', $path ); $folder = $bits[0]; $defaultApplication = \IPS\Db::i()->select( 'app_directory', 'core_applications', 'app_default=1' )->first(); foreach( \IPS\Application::applications() as $key => $app ) { if ( $app->directory === 'cms' ) { continue; } $furlDefinitionFile = \IPS\ROOT_PATH . "/applications/{$app->directory}/data/furl.json"; if ( file_exists( $furlDefinitionFile ) ) { $furlDefinition = json_decode( preg_replace( '/\/\*.+?\*\//s', '', file_get_contents( $furlDefinitionFile ) ), TRUE ); if ( isset( $furlDefinition['topLevel'] ) ) { if ( $furlDefinition['topLevel'] == $folder ) { return TRUE; } if ( isset( $furlDefinition['pages'] ) ) { foreach( $furlDefinition['pages'] as $name => $data ) { if ( isset( $data['friendly'] ) ) { $furlBits = explode( '/', $data['friendly'] ); if ( $furlBits[0] == $folder ) { return TRUE; } } } } } } } return FALSE; } /** * Delete all stored includes so they can be rebuilt on demand. * * @return void */ public static function deleteCompiledIncludes() { \IPS\Db::i()->update( 'cms_pages', array( 'page_js_css_objects' => NULL ) ); \IPS\cms\Templates::deleteCompiledFiles(); } /** * Set JS/CSS include keys * * @param string|array $value * @return void */ public function set__js_css_ids( $value ) { $this->_data['js_css_ids'] = ( is_array( $value ) ? json_encode( $value ) : $value ); } /** * Get JS/CSS include keys * * @return array|null */ protected function get__js_css_ids() { if ( ! is_array( $this->_data['js_css_ids'] ) ) { $this->_data['js_css_ids'] = json_decode( $this->_data['js_css_ids'], true ); } return ( is_array( $this->_data['js_css_ids'] ) ) ? $this->_data['js_css_ids'] : array(); } /** * Get JS include keys * * @return array */ protected function get_js_includes() { /* Makes sure js_css_ids is unpacked if required */ $this->_js_css_ids; if ( isset( $this->_data['js_css_ids']['js'] ) ) { return $this->_data['js_css_ids']['js']; } return array(); } /** * Get CSS include keys * * @return array */ protected function get_css_includes() { /* Makes sure js_css_ids is unpacked if required */ $this->_js_css_ids; if ( isset( $this->_data['js_css_ids']['css'] ) ) { return $this->_data['js_css_ids']['css']; } return array(); } /** * Get JS/CSS Objects * * @return array */ public function getIncludes() { $return = array( 'css' => NULL, 'js' => NULL ); /* Empty? Lets take a look and see if we need to compile anything */ if ( empty( $this->_data['js_css_objects'] ) ) { if ( count( $this->js_includes ) ) { /* Build a file object for each JS */ foreach( $this->js_includes as $key ) { try { $template = \IPS\cms\Templates::load( $key ); $object = $template->_file_object; $return['js'][ $key ] = $object; } catch( \OutOfRangeException $e ) { continue; } } } if ( count( $this->css_includes ) ) { /* Build a file object for each JS */ foreach( $this->css_includes as $key ) { try { $template = \IPS\cms\Templates::load( $key ); $object = $template->_file_object; $return['css'][ $key ] = $object; } catch( \Exception $e ) { continue; } } } /* Save this to prevent it looking for includes on every page refresh */ $this->js_css_objects = json_encode( $return ); $this->save(); } else { $return = json_decode( $this->_data['js_css_objects'], TRUE ); } foreach( $return as $type => $data ) { if ( is_array( $data ) ) { foreach( $data as $key => $object ) { $return[ $type ][ $key ] = (string) \IPS\File::get( 'cms_Pages', $object )->url; } } } return $return; } /** * Get the content type of this page. Calculates based on page extension * * @return string */ public function getContentType() { $map = array( 'js' => 'text/javascript', 'css' => 'text/css', 'txt' => 'text/plain', 'xml' => 'text/xml', 'rss' => 'text/xml', 'html' => 'text/html', 'json' => 'application/json' ); $extension = mb_substr( $this->seo_name, ( mb_strrpos( $this->seo_name, '.' ) + 1 ) ); if ( in_array( $extension, array_keys( $map ) ) ) { return $map[ $extension ]; } return 'text/html'; } /** * Return the title for the publicly viewable HTML page * * @return string Title to use between