Version 4.3.0
This commit is contained in:
1 parent
96997ddd8e
commit
fe1acf984a
1349 files changed
+116159
-67711
No files matched your search
@@ -130,16 +130,6 @@ class _Folder extends \IPS\Node\Model
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Node titles can contain HTML. Apparently.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get__stripTagsTitle()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sortable name
|
||||
*
|
||||
|
||||
@@ -245,14 +245,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public static function resetPath( $folderId )
|
||||
{
|
||||
try
|
||||
{
|
||||
$path = \IPS\cms\Pages\Folder::load( $folderId )->path;
|
||||
}
|
||||
catch ( \OutOfRangeException $ex )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
$path = $folderId ? \IPS\cms\Pages\Folder::load( $folderId )->path : '';
|
||||
|
||||
$children = static::getChildren( $folderId );
|
||||
|
||||
@@ -502,10 +495,13 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/**
|
||||
* Removes all include objects from all pages
|
||||
*
|
||||
* @param boolean $url The URL to find and remove
|
||||
* @param boolean $url The URL to find and remove
|
||||
* @param NULL|int $storageConfiguration Delete the cached includes from an alternate storage configuration
|
||||
* @note This method is called by \IPS\cms\extensions\core\FileStorage\Pages.php during a move, and in that process we want to remove resources
|
||||
from the old storage configuration, not the new one (which is what happens when the configuration id is not passed in to \IPS\File and a move is in progress)
|
||||
* @return void
|
||||
*/
|
||||
static public function deleteCachedIncludes( $url=NULL )
|
||||
static public function deleteCachedIncludes( $url=NULL, $storageConfiguration=NULL )
|
||||
{
|
||||
/* Remove them all */
|
||||
if ( $url === NULL )
|
||||
@@ -516,7 +512,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
\IPS\Db::i()->update( 'cms_pages', array( 'page_js_css_objects' => NULL ) );
|
||||
}
|
||||
/* Remove from file system */
|
||||
\IPS\File::getClass( 'cms_Pages')->deleteContainer('page_objects');
|
||||
\IPS\File::getClass( $storageConfiguration ?: 'cms_Pages' )->deleteContainer('page_objects');
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -708,8 +704,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
$jsincludes[ $obj->key ] = \IPS\cms\Templates::readableGroupName( $obj->group ) . '/' . \IPS\cms\Templates::readableGroupName( $obj->title );
|
||||
}
|
||||
ksort( $jsincludes );
|
||||
|
||||
$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' );
|
||||
$return['page_includes_js'] = new \IPS\Helpers\Form\CheckboxSet( 'page_includes_js', $item ? $item->js_includes : FALSE, FALSE, array( 'options' => $jsincludes, 'multiple' => true ), NULL, NULL, NULL, 'page_includes_js' );
|
||||
}
|
||||
|
||||
if ( count( $css ) )
|
||||
@@ -719,8 +716,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
$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' );
|
||||
ksort( $cssincludes );
|
||||
|
||||
$return['page_includes_css'] = new \IPS\Helpers\Form\CheckboxSet( 'page_includes_css', $item ? $item->css_includes : FALSE, FALSE, array( 'options' => $cssincludes, 'multiple' => true ), NULL, NULL, NULL, 'page_includes_css' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,7 +752,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$tags['cms_tag_pages']['{pageurl="' . $page['page_full_path'] . '"}' ] = \IPS\Member::loggedIn()->language()->addToStack( static::$titleLangPrefix . $page['page_id'] );
|
||||
}
|
||||
|
||||
$return['page_content'] = new \IPS\Helpers\Form\Codemirror( 'page_content', $item ? htmlentities( $item->content, \IPS\HTMLENTITIES, 'UTF-8', TRUE ) : NULL, FALSE, array( 'tags' => $tags, 'height' => 600 ), function( $val )
|
||||
$return['page_content'] = new \IPS\Helpers\Form\Codemirror( 'page_content', $item ? htmlentities( $item->content, ENT_DISALLOWED, 'UTF-8', TRUE ) : NULL, FALSE, array( 'tags' => $tags, 'height' => 600 ), function( $val )
|
||||
{
|
||||
/* Test */
|
||||
try
|
||||
@@ -1063,6 +1061,14 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/* Empty? Lets take a look and see if we need to compile anything */
|
||||
if ( empty( $this->_data['js_css_objects'] ) )
|
||||
{
|
||||
/* Lock it up to prevent a race condition */
|
||||
if ( \IPS\Theme::checkLock( "page_object_build" . $this->id ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
\IPS\Theme::lock( "page_object_build" . $this->id );
|
||||
|
||||
if ( count( $this->js_includes ) )
|
||||
{
|
||||
/* Build a file object for each JS */
|
||||
@@ -1107,6 +1113,8 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$this->js_css_objects = json_encode( $return );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
\IPS\Theme::unlock( "page_object_build" . $this->id );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1187,7 +1195,15 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
$contents = @file_get_contents( \IPS\ROOT_PATH . '/themes/cms/pages/' . $this->full_path );
|
||||
$contents = preg_replace( '#^<ips:pages.+?/>(\r\n?|\n)#', '', $contents );
|
||||
\IPS\Theme::runProcessFunction( \IPS\Theme::compileTemplate( $contents, $functionName, null, true ), $functionName );
|
||||
try
|
||||
{
|
||||
\IPS\Theme::runProcessFunction( \IPS\Theme::compileTemplate( $contents, $functionName, null, true ), $functionName );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'pages_error' );
|
||||
return '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1634,6 +1650,8 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
throw new \InvalidArgumentException( \IPS\Member::loggedIn()->language()->addToStack('content_err_page_save_exception', FALSE, array( 'sprintf' => \IPS\Member::loggedIn()->language()->addToStack( $ex->getMessage() ) ) ) );
|
||||
}
|
||||
|
||||
\IPS\Content\Search\Index::i()->index( $this->item() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1760,7 +1778,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
preg_match_all( '/(.+?)='.$array[2].'(.+?)'.$array[2].'\s?/', $array[1], $submatches );
|
||||
|
||||
$plugin = array_shift( $submatches[1] );
|
||||
$pluginClass = 'IPS\\Output\\Plugin\\' . ucfirst( $plugin );
|
||||
$pluginClass = 'IPS\\Output\\Plugin\\' . mb_ucfirst( $plugin );
|
||||
|
||||
$value = array_shift( $submatches[2] );
|
||||
$options = array();
|
||||
@@ -1777,9 +1795,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
foreach ( \IPS\Application::applications() as $app )
|
||||
{
|
||||
if ( file_exists( \IPS\ROOT_PATH . "/applications/{$app->directory}/extensions/core/OutputPlugins/" . ucfirst( $plugin ) . ".php" ) )
|
||||
if ( file_exists( \IPS\ROOT_PATH . "/applications/{$app->directory}/extensions/core/OutputPlugins/" . mb_ucfirst( $plugin ) . ".php" ) )
|
||||
{
|
||||
$pluginClass = 'IPS\\' . $app->directory . '\\extensions\\core\\OutputPlugins\\' . ucfirst( $plugin );
|
||||
$pluginClass = 'IPS\\' . $app->directory . '\\extensions\\core\\OutputPlugins\\' . mb_ucfirst( $plugin );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2009,6 +2027,8 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
static::cleanUpDesignersModeFiles();
|
||||
}
|
||||
|
||||
\IPS\Content\Search\Index::i()->removeFromSearchIndex( $this->item() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2063,6 +2083,8 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
|
||||
\IPS\Content\Search\Index::i()->index( $this->item() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2084,7 +2106,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
if ( $this->full_path and \IPS\Theme::designersModeEnabled() )
|
||||
{
|
||||
static::exportDesignersMode( $this->id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2493,4 +2515,20 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item
|
||||
*
|
||||
* @return \IPS\nexus\Package\Item
|
||||
*/
|
||||
public function item()
|
||||
{
|
||||
$data = array();
|
||||
foreach ( $this->_data as $k => $v )
|
||||
{
|
||||
$data[ 'page_' . $k ] = $v;
|
||||
}
|
||||
|
||||
return \IPS\cms\Pages\PageItem::constructFromData( $data );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Pages Page Item Model
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @subpackage Nexus
|
||||
* @since 15 Dec 2017
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Package Item Model
|
||||
*/
|
||||
class _PageItem extends \IPS\Content\Item implements \IPS\Content\Searchable
|
||||
{
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'cms';
|
||||
|
||||
/**
|
||||
* @brief Module
|
||||
*/
|
||||
public static $module = 'pages';
|
||||
|
||||
/**
|
||||
* @brief Database Table
|
||||
*/
|
||||
public static $databaseTable = 'cms_pages';
|
||||
|
||||
/**
|
||||
* @brief Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'page_';
|
||||
|
||||
/**
|
||||
* @brief Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief Database Column Map
|
||||
*/
|
||||
public static $databaseColumnMap = array(
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'cms_page';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'files-o';
|
||||
|
||||
/**
|
||||
* @brief Include In Sitemap
|
||||
*/
|
||||
public static $includeInSitemap = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Can this content be moderated normally from the front-end (will be FALSE for things like Pages and Commerce Products)
|
||||
*/
|
||||
public static $canBeModeratedFromFrontend = FALSE;
|
||||
|
||||
/**
|
||||
* Columns needed to query for search result / stream view
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function basicDataColumns()
|
||||
{
|
||||
return array( 'page_id', 'page_folder_id', 'page_full_path', 'page_default' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL from index data
|
||||
*
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public static function urlFromIndexData( $indexData, $itemData )
|
||||
{
|
||||
if ( ( \IPS\Application::load('cms')->default OR \IPS\Settings::i()->cms_use_different_gateway ) AND $itemData['page_default'] AND !$itemData['page_folder_id'] )
|
||||
{
|
||||
/* Are we using the gateway file? */
|
||||
if ( \IPS\Settings::i()->cms_use_different_gateway )
|
||||
{
|
||||
/* Yes, work out the proper URL. */
|
||||
return \IPS\Http\Url::createFromString( \IPS\Settings::i()->cms_root_page_url, TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No - that's easy */
|
||||
return \IPS\Http\Url::internal( '', 'front' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Http\Url::internal( 'app=cms&module=pages&controller=page&path=' . $itemData['page_full_path'], 'front', 'content_page_path', array( $itemData['page_full_path'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML for search result display
|
||||
*
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
|
||||
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
|
||||
* @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
|
||||
* @param array $reputationData Array of people who have given reputation and the reputation they gave
|
||||
* @param int|NULL $reviewRating If this is a review, the rating
|
||||
* @param bool $iPostedIn If the user has posted in the item
|
||||
* @param string $view 'expanded' or 'condensed'
|
||||
* @param bool $asItem Displaying results as items?
|
||||
* @param bool $canIgnoreComments Can ignore comments in the result stream? Activity stream can, but search results cannot.
|
||||
* @param array $template Optional custom template
|
||||
* @param array $reactions Reaction Data
|
||||
* @return string
|
||||
*/
|
||||
public static function searchResult( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $iPostedIn, $view, $asItem, $canIgnoreComments=FALSE, $template=NULL, $reactions=array() )
|
||||
{
|
||||
$indexData['index_title'] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_page_' . $indexData['index_item_id'] );
|
||||
return parent::searchResult( $indexData, $authorData, $itemData, $containerData, $reputationData, $reviewRating, $iPostedIn, $view, $asItem, $canIgnoreComments, $template, $reactions );
|
||||
}
|
||||
|
||||
/**
|
||||
* Title for search index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function searchIndexTitle()
|
||||
{
|
||||
$titles = array();
|
||||
foreach ( \IPS\Lang::languages() as $lang )
|
||||
{
|
||||
$titles[] = $lang->get("cms_page_{$this->id}");
|
||||
}
|
||||
return implode( ' ', $titles );
|
||||
}
|
||||
|
||||
/**
|
||||
* Content for search index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function searchIndexContent()
|
||||
{
|
||||
if ( $this->type == 'builder' )
|
||||
{
|
||||
$content = array();
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_page_widget_areas', array( 'area_page_id=?', $this->id ) ) as $widgetArea )
|
||||
{
|
||||
foreach ( json_decode( $widgetArea['area_widgets'], TRUE ) as $widget )
|
||||
{
|
||||
if ( $widget['app'] == 'cms' and $widget['key'] == 'Wysiwyg' )
|
||||
{
|
||||
$content[] = trim( $widget['configuration']['content'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
return implode( ' ', $content );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search Index Permissions
|
||||
*
|
||||
* @return string Comma-delimited values or '*'
|
||||
* @li Number indicates a group
|
||||
* @li Number prepended by "m" indicates a member
|
||||
* @li Number prepended by "s" indicates a social group
|
||||
*/
|
||||
public function searchIndexPermissions()
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\Db::i()->select( 'perm_view', 'core_permission_index', array( "app='cms' AND perm_type='pages' AND perm_type_id=?", $this->id ) )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user