Version 5.0.13
This commit is contained in:
1 parent
b89858b2ff
commit
5efe744c5f
1407 files changed
+69690
-30177
No files matched your search
@@ -92,7 +92,7 @@ class Page extends Model implements Permissions
|
||||
* @brief [ActiveRecord] Caches
|
||||
* @note Defined cache keys will be cleared automatically as needed
|
||||
*/
|
||||
protected array $caches = array( 'frontNavigation' );
|
||||
protected array $caches = array( 'frontNavigation', 'pageDefaults' );
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
@@ -348,11 +348,11 @@ class Page extends Model implements Permissions
|
||||
/* @var $class Model */
|
||||
$folder = $class::load( $path, 'folder_path' );
|
||||
|
||||
static::$loadedPagesFromPath[ $path ] = static::getDefaultPage( $folder->id );
|
||||
static::$loadedPagesFromPath[ $path ] = static::getDefaultForMember( $folder->id );
|
||||
}
|
||||
else
|
||||
{
|
||||
static::$loadedPagesFromPath[ $path ] = static::getDefaultPage();
|
||||
static::$loadedPagesFromPath[ $path ] = static::getDefaultForMember();
|
||||
}
|
||||
}
|
||||
catch ( OutOfRangeException $e )
|
||||
@@ -474,6 +474,13 @@ class Page extends Model implements Permissions
|
||||
/* Still here? Consistent with AR pattern */
|
||||
throw new OutOfRangeException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constants for default page settings
|
||||
*/
|
||||
const PAGE_NODEFAULT = 0;
|
||||
const PAGE_DEFAULT = 1;
|
||||
const PAGE_DEFAULT_OVERRIDE = 2;
|
||||
|
||||
/**
|
||||
* Return the default page for this folder
|
||||
@@ -488,7 +495,7 @@ class Page extends Model implements Permissions
|
||||
/* Try the easiest method first */
|
||||
try
|
||||
{
|
||||
static::$defaultPage[ $folderId ] = Page::load( Db::i()->select( 'page_id', static::$databaseTable, array( 'page_default=? AND page_folder_id=?', 1, $folderId ) )->first() );
|
||||
static::$defaultPage[ $folderId ] = Page::load( Db::i()->select( 'page_id', static::$databaseTable, array( 'page_default=? AND page_folder_id=?', static::PAGE_DEFAULT, $folderId ) )->first() );
|
||||
}
|
||||
catch( Exception $ex )
|
||||
{
|
||||
@@ -510,6 +517,159 @@ class Page extends Model implements Permissions
|
||||
|
||||
return ( isset( static::$defaultPage[ $folderId ] ) ) ? static::$defaultPage[ $folderId ] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a list of default pages for each group
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function loadDefaultsPerGroup() : array
|
||||
{
|
||||
try
|
||||
{
|
||||
return Store::i()->pageDefaults;
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
|
||||
$folderRoots = iterator_to_array(
|
||||
Db::i()->select( 'folder_id', 'cms_folders' )
|
||||
);
|
||||
array_unshift( $folderRoots, 0 );
|
||||
|
||||
$defaults = [];
|
||||
|
||||
foreach( $folderRoots as $folderId )
|
||||
{
|
||||
$defaults[ $folderId ] = [];
|
||||
foreach( Db::i()->select( 'page_id,page_group_defaults', static::$databaseTable, [ 'page_default=? and page_folder_id=?', static::PAGE_DEFAULT_OVERRIDE, $folderId ] ) as $row )
|
||||
{
|
||||
foreach( explode( ",", $row['page_group_defaults'] ) as $groupId )
|
||||
{
|
||||
$defaults[ $folderId ][ $groupId ] = $row['page_id'];
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$primaryDefault = static::getDefaultPage( $folderId );
|
||||
foreach( Group::groups() as $group )
|
||||
{
|
||||
if( !isset( $defaults[ $folderId ][ $group->g_id ] ) )
|
||||
{
|
||||
$defaults[ $folderId ][ $group->g_id ] = $primaryDefault->_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
|
||||
Store::i()->pageDefaults = $defaults;
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the default application for this member
|
||||
*
|
||||
* @param int $folderId
|
||||
* @param Member|null $member
|
||||
* @return static
|
||||
*/
|
||||
public static function getDefaultForMember( int $folderId=0, ?Member $member=null ) : static
|
||||
{
|
||||
/* We're only going to use the primary group here */
|
||||
$member = $member ?? Member::loggedIn();
|
||||
|
||||
$pageId = static::loadDefaultsPerGroup()[ $folderId ][ $member->member_group_id ] ?? null;
|
||||
if( $pageId )
|
||||
{
|
||||
try
|
||||
{
|
||||
return static::load( $pageId );
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
|
||||
return static::getDefaultPage( $folderId );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the page as a default for specific groups
|
||||
*
|
||||
* @param array $groups
|
||||
* @return void
|
||||
*/
|
||||
public function setAsDefaultForGroups( array $groups ) : void
|
||||
{
|
||||
$currentDefaults = static::loadDefaultsPerGroup();
|
||||
$newGroups = [];
|
||||
$pagesToUpdate = [];
|
||||
foreach( $groups as $group )
|
||||
{
|
||||
$groupId = ( $group instanceof Group ) ? $group->g_id : $group;
|
||||
$currentPage = $currentDefaults[ $this->folder_id ][ $groupId ] ?? null;
|
||||
if( $currentPage !== null and $currentPage != $this->id )
|
||||
{
|
||||
$pagesToUpdate[ $currentPage ] = [];
|
||||
foreach( $currentDefaults[ $this->folder_id ] as $k => $v )
|
||||
{
|
||||
if( $v == $currentPage and $k != $groupId )
|
||||
{
|
||||
$pagesToUpdate[ $currentPage ][] = $k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$newGroups[] = $groupId;
|
||||
}
|
||||
|
||||
/* Did we make this the default for all the groups? */
|
||||
if( count( $newGroups ) == count( Group::groups() ) )
|
||||
{
|
||||
$this->setAsDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
if( empty( $newGroups ) )
|
||||
{
|
||||
$this->default = static::PAGE_NODEFAULT;
|
||||
$this->group_defaults = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->default = static::PAGE_DEFAULT_OVERRIDE;
|
||||
$this->group_defaults = implode( ",", $newGroups );
|
||||
}
|
||||
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/* Now update any pages that need to be changed */
|
||||
foreach( $pagesToUpdate as $pageId => $_values )
|
||||
{
|
||||
try
|
||||
{
|
||||
$page = static::load( $pageId );
|
||||
|
||||
/* If it's set as default 1, we can leave that alone */
|
||||
if( $page->default == static::PAGE_DEFAULT_OVERRIDE )
|
||||
{
|
||||
$groupsToUse = array_diff( $_values, $newGroups );
|
||||
if( empty( $groupsToUse ) )
|
||||
{
|
||||
$page->default = static::PAGE_NODEFAULT;
|
||||
$page->group_defaults = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$page->group_defaults = implode( ",", $groupsToUse );
|
||||
}
|
||||
|
||||
$page->save();
|
||||
}
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete compiled versions
|
||||
@@ -756,7 +916,7 @@ class Page extends Model implements Permissions
|
||||
|
||||
if ( $pageType == 'html' )
|
||||
{
|
||||
$return['tab_content'] = array( 'content_page_form_tab__content', NULL, NULL, 'ipsForm_vertical' );
|
||||
$return['tab_content'] = array( 'content_page_form_tab__content', NULL, NULL, 'ipsForm--vertical' );
|
||||
|
||||
$tagSource = Url::internal( "app=cms&module=pages&controller=ajax&do=loadTags" );
|
||||
if ( $item )
|
||||
@@ -809,7 +969,6 @@ class Page extends Model implements Permissions
|
||||
{
|
||||
$page = new self;
|
||||
$page->type = $pageType;
|
||||
$page->save();
|
||||
|
||||
$page->saveForm( $page->formatFormValues( $values ) );
|
||||
|
||||
@@ -1241,6 +1400,17 @@ class Page extends Model implements Permissions
|
||||
public function getAreasFromDatabase( ?string $area=null ) : array
|
||||
{
|
||||
$areas = array();
|
||||
|
||||
if( $this->_version !== null )
|
||||
{
|
||||
foreach( $this->_version->data['areas'] as $id => $tree )
|
||||
{
|
||||
$areas[ $id ] = new Area( $tree, $id );
|
||||
}
|
||||
|
||||
return $areas;
|
||||
}
|
||||
|
||||
$where = [ array( 'area_page_id=?', $this->id ) ];
|
||||
|
||||
if ( $area !== null )
|
||||
@@ -1267,10 +1437,23 @@ class Page extends Model implements Permissions
|
||||
* Save an area to the database and link it to the page
|
||||
*
|
||||
* @param Area $area
|
||||
* @param bool $backup Should we store a copy?
|
||||
* @return void
|
||||
*/
|
||||
public function saveArea( Area $area ) : void
|
||||
public function saveArea( Area $area, bool $backup=true ) : void
|
||||
{
|
||||
/* If we are viewing an old version, do nothing! These should be read-only */
|
||||
if( $this->_version !== null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create a backup before we do anything here */
|
||||
if( $backup )
|
||||
{
|
||||
Revision::store( $this );
|
||||
}
|
||||
|
||||
/* If we have no content, clear this out entirely */
|
||||
if( !$area->hasWidgets() )
|
||||
{
|
||||
@@ -1429,22 +1612,33 @@ class Page extends Model implements Permissions
|
||||
$return['edit'] = $buttons['edit'];
|
||||
}
|
||||
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'page_edit' ) and !$this->default )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'page_edit' ) )
|
||||
{
|
||||
$return['default'] = array(
|
||||
'icon' => $this->default ? 'star' : 'regular fa-star',
|
||||
'title' => 'content_default_page',
|
||||
'link' => $url->setQueryString( array( 'id' => $this->id, 'subnode' => 1, 'do' => 'setAsDefault' ) )->csrf()
|
||||
);
|
||||
}
|
||||
$return['default'] = array(
|
||||
'icon' => ( $this->default == static::PAGE_DEFAULT ) ? 'star' : 'regular fa-star',
|
||||
'title' => 'content_default_page',
|
||||
'link' => $url->setQueryString( array( 'id' => $this->id, 'subnode' => 1, 'do' => 'setAsDefault' ) ),
|
||||
'data' => [ 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'content_default_page' ) ]
|
||||
);
|
||||
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'page_edit' ) and $this->type !== 'builder' )
|
||||
{
|
||||
$return['default_error'] = array(
|
||||
'icon' => Settings::i()->cms_error_page == $this->id ? 'exclamation-circle' : 'exclamation',
|
||||
'title' => Settings::i()->cms_error_page == $this->id ? 'content_remove_error_page' : 'content_default_error_page',
|
||||
'link' => $url->setQueryString( array( 'id' => Settings::i()->cms_error_page ? 0 : $this->id, 'subnode' => 1, 'do' => 'toggleDefaultError' ) )->csrf()
|
||||
);
|
||||
if( $this->type !== 'builder' )
|
||||
{
|
||||
$return['default_error'] = array(
|
||||
'icon' => Settings::i()->cms_error_page == $this->id ? 'exclamation-circle' : 'exclamation',
|
||||
'title' => Settings::i()->cms_error_page == $this->id ? 'content_remove_error_page' : 'content_default_error_page',
|
||||
'link' => $url->setQueryString( array( 'id' => Settings::i()->cms_error_page ? 0 : $this->id, 'subnode' => 1, 'do' => 'toggleDefaultError' ) )->csrf()
|
||||
);
|
||||
}
|
||||
|
||||
/* Do we have at least one stored version? */
|
||||
if( $previous = Revision::previousVersion( $this ) )
|
||||
{
|
||||
$return['history'] = array(
|
||||
'icon' => 'history',
|
||||
'title' => 'content_page_history',
|
||||
'link' => $url->setQueryString( array( 'id' => $this->id, 'subnode' => 1, 'do' => 'history' ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$return['view'] = array(
|
||||
@@ -1587,6 +1781,12 @@ class Page extends Model implements Permissions
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/* If this is not a new page, store the current page in the history before we make any changes */
|
||||
if( !$isNew )
|
||||
{
|
||||
Revision::store( $this );
|
||||
}
|
||||
|
||||
if( isset( $values['page_name'] ) )
|
||||
{
|
||||
$_copied = $values['page_name'];
|
||||
@@ -1810,7 +2010,7 @@ class Page extends Model implements Permissions
|
||||
{
|
||||
if( $this->_url === NULL )
|
||||
{
|
||||
if ( Application::load('cms')->default AND $this->default AND ! $this->folder_id )
|
||||
if ( Application::load('cms')->default AND $this->default == static::PAGE_DEFAULT AND ! $this->folder_id )
|
||||
{
|
||||
/* No - that's easy */
|
||||
$this->_url = Url::internal( '', 'front' );
|
||||
@@ -1841,6 +2041,33 @@ class Page extends Model implements Permissions
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @var Revision|null
|
||||
*/
|
||||
protected ?Revision $_version = null;
|
||||
|
||||
/**
|
||||
* View as a specific version
|
||||
*
|
||||
* @param int|null $version
|
||||
* @return void
|
||||
*/
|
||||
public function setVersion( ?int $version=null ) : void
|
||||
{
|
||||
/* Clear it first */
|
||||
$this->_version = null;
|
||||
|
||||
try
|
||||
{
|
||||
$this->_version = Revision::load( $version );
|
||||
foreach( $this->_version->data['settings'] as $k => $v )
|
||||
{
|
||||
$this->_data[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map this database to a specific page
|
||||
*
|
||||
@@ -1951,6 +2178,9 @@ class Page extends Model implements Permissions
|
||||
|
||||
/* Remove any widgets for this page */
|
||||
Db::i()->delete( 'cms_page_widget_areas', array( 'area_page_id=?', $this->id ) );
|
||||
|
||||
/* Clear history */
|
||||
Db::i()->delete( 'cms_page_revisions', array( 'revision_page_id=?', $this->id ) );
|
||||
|
||||
parent::delete();
|
||||
|
||||
@@ -2020,10 +2250,22 @@ class Page extends Model implements Permissions
|
||||
*/
|
||||
public function save(): void
|
||||
{
|
||||
/* If we are viewing an older version, don't allow any changes */
|
||||
if( $this->_version !== null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->id )
|
||||
{
|
||||
static::deleteCompiled( $this->id );
|
||||
}
|
||||
|
||||
/* If this is not new and the folder changed, check defaults */
|
||||
if( !$this->_new and isset( $this->changed['folder_id'] ) )
|
||||
{
|
||||
$this->checkDefaultPage();
|
||||
}
|
||||
|
||||
parent::save();
|
||||
|
||||
@@ -2047,10 +2289,39 @@ class Page extends Model implements Permissions
|
||||
*/
|
||||
public function setAsDefault() : void
|
||||
{
|
||||
Db::i()->update( 'cms_pages', array( 'page_default' => 0 ), array( 'page_folder_id=?', $this->folder_id ) );
|
||||
Db::i()->update( 'cms_pages', array( 'page_default' => 1 ), array( 'page_id=?', $this->id ) );
|
||||
Db::i()->update( 'cms_pages', array( 'page_default' => static::PAGE_NODEFAULT, 'page_group_defaults' => null ), array( 'page_folder_id=? and page_default=?', $this->folder_id, static::PAGE_DEFAULT ) );
|
||||
Db::i()->update( 'cms_pages', array( 'page_default' => static::PAGE_DEFAULT, 'page_group_defaults' => null ), array( 'page_id=?', $this->id ) );
|
||||
|
||||
static::buildPageUrlStore();
|
||||
|
||||
unset( Store::i()->pageDefaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that we only have one default page per folder.
|
||||
* This is called only when the folder is changed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function checkDefaultPage() : void
|
||||
{
|
||||
if( $this->default == static::PAGE_DEFAULT )
|
||||
{
|
||||
try
|
||||
{
|
||||
$currentDefault = Db::i()->select( 'page_id', 'cms_pages', [ 'page_default=? and page_folder_id=? and page_id <> ?', static::PAGE_DEFAULT, $this->folder_id, (int) $this->_id ] )->first();
|
||||
|
||||
/* If we found a different default page, remove the default from this one */
|
||||
$this->default = static::PAGE_NODEFAULT;
|
||||
}
|
||||
catch( UnderflowException ){}
|
||||
}
|
||||
elseif( $this->default == static::PAGE_DEFAULT_OVERRIDE )
|
||||
{
|
||||
/* Group overrides are always removed when we move a page to another folder */
|
||||
$this->default = static::PAGE_NODEFAULT;
|
||||
$this->group_defaults = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2121,7 +2392,7 @@ class Page extends Model implements Permissions
|
||||
/* Make sure we initialize the main area */
|
||||
Output::i()->sidebar['widgets']['col1'] = [];
|
||||
|
||||
Output::i()->output = Theme::i()->getTemplate( 'pages' )->globalWrap( $nav, $this->getPageContent(), $this );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'pages', 'cms' )->globalWrap( $nav, $this->getPageContent(), $this );
|
||||
|
||||
if ( isset( Settings::i()->cms_error_page ) and Settings::i()->cms_error_page and Settings::i()->cms_error_page == $this->id )
|
||||
{
|
||||
@@ -2138,7 +2409,7 @@ class Page extends Model implements Permissions
|
||||
}
|
||||
catch ( OutOfRangeException | OutOfBoundsException )
|
||||
{
|
||||
if ( !( Application::load( 'cms' )->default and !$this->folder_id and $this->default ) )
|
||||
if ( !( Application::load( 'cms' )->default and !$this->folder_id and $this->default == static::PAGE_DEFAULT ) )
|
||||
{
|
||||
Output::i()->breadcrumb['module'] = array( $this->url(), $this->_title );
|
||||
}
|
||||
@@ -2156,10 +2427,6 @@ class Page extends Model implements Permissions
|
||||
/* Send straight to the output engine */
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( Output::i()->title, Output::i()->output, array( 'app' => Dispatcher::i()->application->directory, 'module' => Dispatcher::i()->module->key, 'controller' => Dispatcher::i()->controller ) ), ( $httpStatusCode ?: 200 ), 'text/html', ( $httpHeaders ?: array() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Output::i()->allowDefaultWidgets = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2200,9 +2467,15 @@ class Page extends Model implements Permissions
|
||||
*/
|
||||
protected function getPageContent() : string
|
||||
{
|
||||
$content = '';
|
||||
if( $this->_version !== null )
|
||||
{
|
||||
Output::i()->customHeader .= Theme::i()->getTemplate( 'pages', 'cms' )->revision( $this->_version );
|
||||
}
|
||||
|
||||
if( $this->type == 'html' )
|
||||
{
|
||||
return $this->getHtmlContent();
|
||||
return $content . $this->getHtmlContent();
|
||||
}
|
||||
|
||||
$widgets = [];
|
||||
@@ -2216,6 +2489,15 @@ class Page extends Model implements Permissions
|
||||
}
|
||||
|
||||
$tree = $item['area_tree'] ? json_decode( $item['area_tree'], true ) : [];
|
||||
if( $this->_version !== null )
|
||||
{
|
||||
if ( isset( $this->_version->data['areas'][ $item['area_area'] ] ) )
|
||||
{
|
||||
/* We have a previous version we want to show */
|
||||
$tree = $this->_version->data['areas'][ $item['area_area'] ];
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $tree ) )
|
||||
{
|
||||
/* If the tree is empty, generate one from the database rows */
|
||||
@@ -2242,7 +2524,7 @@ class Page extends Model implements Permissions
|
||||
$widgets['col1'] = new Area( [], 'col1' );
|
||||
}
|
||||
|
||||
return Theme::i()->getTemplate( 'pages', 'cms' )->mainArea( $this, $widgets );
|
||||
return $content . Theme::i()->getTemplate( 'pages', 'cms' )->mainArea( $this, $widgets );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user