mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
Merge pull request #1583 from open-sausages/pulls/4.0/namespace-admin
Namespace Admin module
This commit is contained in:
commit
ef46dee37f
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use SilverStripe\Admin\CMSMenu;
|
||||
|
||||
/**
|
||||
* - CMS_DIR: Path relative to webroot, e.g. "cms"
|
||||
* - CMS_PATH: Absolute filepath, e.g. "/var/www/my-webroot/cms"
|
||||
@ -23,5 +25,3 @@ CMSMenu::remove_menu_class('SilverStripe\\CMS\\Controllers\\CMSPageEditControlle
|
||||
CMSMenu::remove_menu_class('SilverStripe\\CMS\\Controllers\\CMSPageSettingsController');
|
||||
CMSMenu::remove_menu_class('SilverStripe\\CMS\\Controllers\\CMSPageHistoryController');
|
||||
CMSMenu::remove_menu_class('SilverStripe\\CMS\\Controllers\\CMSPageAddController');
|
||||
|
||||
CMSMenu::remove_menu_item("SiteConfigLeftAndMain");
|
||||
|
@ -1,2 +1,2 @@
|
||||
AdminRootController:
|
||||
SilverStripe\Admin\AdminRootController:
|
||||
default_panel: 'SilverStripe\CMS\Controllers\CMSPagesController'
|
||||
|
@ -1,4 +1,4 @@
|
||||
LeftAndMain:
|
||||
SilverStripe\Admin\LeftAndMain:
|
||||
extensions:
|
||||
- SilverStripe\CMS\Controllers\LeftAndMainPageIconsExtension
|
||||
Controller:
|
||||
|
@ -3,4 +3,4 @@ Name: cmslegacy
|
||||
---
|
||||
SilverStripe\ORM\DatabaseAdmin:
|
||||
classname_value_remapping:
|
||||
SiteTree: 'SilverStripe\CMS\Model\SiteTree'
|
||||
SiteTree: 'SilverStripe\CMS\Model\SiteTree'
|
||||
|
34
code/BatchActions/CMSBatchAction_Archive.php
Normal file
34
code/BatchActions/CMSBatchAction_Archive.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\BatchActions;
|
||||
|
||||
use SilverStripe\Admin\CMSBatchAction;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
|
||||
/**
|
||||
* Archives a page, removing it from both live and stage
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Archive extends CMSBatchAction
|
||||
{
|
||||
|
||||
public function getActionTitle()
|
||||
{
|
||||
return _t('CMSBatchActions.ARCHIVE', 'Archive');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages)
|
||||
{
|
||||
return $this->batchaction($pages, 'doArchive',
|
||||
_t('CMSBatchActions.ARCHIVED_PAGES', 'Archived %d pages')
|
||||
);
|
||||
}
|
||||
|
||||
public function applicablePages($ids)
|
||||
{
|
||||
return $this->applicablePagesHelper($ids, 'canArchive', true, true);
|
||||
}
|
||||
|
||||
}
|
55
code/BatchActions/CMSBatchAction_Delete.php
Normal file
55
code/BatchActions/CMSBatchAction_Delete.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\BatchActions;
|
||||
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
use SilverStripe\Admin\CMSBatchAction;
|
||||
|
||||
/**
|
||||
* Delete items batch action.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Delete extends CMSBatchAction {
|
||||
public function getActionTitle() {
|
||||
return _t('CMSBatchActions.DELETE_DRAFT_PAGES', 'Delete from draft site');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
$status = array(
|
||||
'modified'=>array(),
|
||||
'deleted'=>array(),
|
||||
'error'=>array()
|
||||
);
|
||||
|
||||
foreach($pages as $page) {
|
||||
$id = $page->ID;
|
||||
|
||||
// Perform the action
|
||||
if($page->canDelete()) $page->delete();
|
||||
else $status['error'][$page->ID] = true;
|
||||
|
||||
// check to see if the record exists on the live site,
|
||||
// if it doesn't remove the tree node
|
||||
$liveRecord = Versioned::get_one_by_stage( 'SilverStripe\\CMS\\Model\\SiteTree', 'Live', array(
|
||||
'"SiteTree"."ID"' => $id
|
||||
));
|
||||
if($liveRecord) {
|
||||
$status['modified'][$liveRecord->ID] = array(
|
||||
'TreeTitle' => $liveRecord->TreeTitle,
|
||||
);
|
||||
} else {
|
||||
$status['deleted'][$id] = array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->response(_t('CMSBatchActions.DELETED_DRAFT_PAGES', 'Deleted %d pages from draft site, %d failures'), $status);
|
||||
}
|
||||
|
||||
public function applicablePages($ids) {
|
||||
return $this->applicablePagesHelper($ids, 'canDelete', true, false);
|
||||
}
|
||||
}
|
32
code/BatchActions/CMSBatchAction_Publish.php
Normal file
32
code/BatchActions/CMSBatchAction_Publish.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\BatchActions;
|
||||
|
||||
use SilverStripe\Admin\CMSBatchAction;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
|
||||
/**
|
||||
* Publish items batch action.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Publish extends CMSBatchAction
|
||||
{
|
||||
public function getActionTitle()
|
||||
{
|
||||
return _t('CMSBatchActions.PUBLISH_PAGES', 'Publish');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages)
|
||||
{
|
||||
return $this->batchaction($pages, 'publishRecursive',
|
||||
_t('CMSBatchActions.PUBLISHED_PAGES', 'Published %d pages, %d failures')
|
||||
);
|
||||
}
|
||||
|
||||
public function applicablePages($ids)
|
||||
{
|
||||
return $this->applicablePagesHelper($ids, 'canPublish', true, false);
|
||||
}
|
||||
}
|
62
code/BatchActions/CMSBatchAction_Restore.php
Normal file
62
code/BatchActions/CMSBatchAction_Restore.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\BatchActions;
|
||||
|
||||
use SilverStripe\Admin\CMSBatchAction;
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
use SilverStripe\Security\Permission;
|
||||
|
||||
/**
|
||||
* Batch restore of pages
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Restore extends CMSBatchAction
|
||||
{
|
||||
|
||||
public function getActionTitle()
|
||||
{
|
||||
return _t('CMSBatchActions.RESTORE', 'Restore');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages)
|
||||
{
|
||||
// Sort pages by depth
|
||||
$pageArray = $pages->toArray();
|
||||
// because of https://bugs.php.net/bug.php?id=50688
|
||||
/** @var SiteTree $page */
|
||||
foreach ($pageArray as $page) {
|
||||
$page->getPageLevel();
|
||||
}
|
||||
usort($pageArray, function (SiteTree $a, SiteTree $b) {
|
||||
return $a->getPageLevel() - $b->getPageLevel();
|
||||
});
|
||||
$pages = new ArrayList($pageArray);
|
||||
|
||||
// Restore
|
||||
return $this->batchaction($pages, 'doRestoreToStage',
|
||||
_t('CMSBatchActions.RESTORED_PAGES', 'Restored %d pages')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@see SiteTree::canEdit()}
|
||||
*
|
||||
* @param array $ids
|
||||
* @return array
|
||||
*/
|
||||
public function applicablePages($ids)
|
||||
{
|
||||
// Basic permission check based on SiteTree::canEdit
|
||||
if (!Permission::check(array("ADMIN", "SITETREE_EDIT_ALL"))) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Get pages that exist in stage and remove them from the restore-able set
|
||||
$stageIDs = Versioned::get_by_stage($this->managedClass, 'Stage')->column('ID');
|
||||
return array_values(array_diff($ids, $stageIDs));
|
||||
}
|
||||
}
|
32
code/BatchActions/CMSBatchAction_Unpublish.php
Normal file
32
code/BatchActions/CMSBatchAction_Unpublish.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\BatchActions;
|
||||
|
||||
use SilverStripe\Admin\CMSBatchAction;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
|
||||
/**
|
||||
* Unpublish items batch action.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Unpublish extends CMSBatchAction
|
||||
{
|
||||
public function getActionTitle()
|
||||
{
|
||||
return _t('CMSBatchActions.UNPUBLISH_PAGES', 'Unpublish');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages)
|
||||
{
|
||||
return $this->batchaction($pages, 'doUnpublish',
|
||||
_t('CMSBatchActions.UNPUBLISHED_PAGES', 'Unpublished %d pages')
|
||||
);
|
||||
}
|
||||
|
||||
public function applicablePages($ids)
|
||||
{
|
||||
return $this->applicablePagesHelper($ids, 'canUnpublish', false, true);
|
||||
}
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\BatchActions;
|
||||
|
||||
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
use SilverStripe\Security\Permission;
|
||||
use CMSBatchAction;
|
||||
|
||||
|
||||
/**
|
||||
* Publish items batch action.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Publish extends CMSBatchAction {
|
||||
public function getActionTitle() {
|
||||
return _t('CMSBatchActions.PUBLISH_PAGES', 'Publish');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
return $this->batchaction($pages, 'publishRecursive',
|
||||
_t('CMSBatchActions.PUBLISHED_PAGES', 'Published %d pages, %d failures')
|
||||
);
|
||||
}
|
||||
|
||||
public function applicablePages($ids) {
|
||||
return $this->applicablePagesHelper($ids, 'canPublish', true, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpublish items batch action.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Unpublish extends CMSBatchAction {
|
||||
public function getActionTitle() {
|
||||
return _t('CMSBatchActions.UNPUBLISH_PAGES', 'Unpublish');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
return $this->batchaction($pages, 'doUnpublish',
|
||||
_t('CMSBatchActions.UNPUBLISHED_PAGES', 'Unpublished %d pages')
|
||||
);
|
||||
}
|
||||
|
||||
public function applicablePages($ids) {
|
||||
return $this->applicablePagesHelper($ids, 'canUnpublish', false, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Archives a page, removing it from both live and stage
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Archive extends CMSBatchAction {
|
||||
|
||||
public function getActionTitle() {
|
||||
return _t('CMSBatchActions.ARCHIVE', 'Archive');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
return $this->batchaction($pages, 'doArchive',
|
||||
_t('CMSBatchActions.ARCHIVED_PAGES', 'Archived %d pages')
|
||||
);
|
||||
}
|
||||
|
||||
public function applicablePages($ids) {
|
||||
return $this->applicablePagesHelper($ids, 'canArchive', true, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch restore of pages
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Restore extends CMSBatchAction {
|
||||
|
||||
public function getActionTitle() {
|
||||
return _t('CMSBatchActions.RESTORE', 'Restore');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
// Sort pages by depth
|
||||
$pageArray = $pages->toArray();
|
||||
// because of https://bugs.php.net/bug.php?id=50688
|
||||
foreach($pageArray as $page) {
|
||||
$page->getPageLevel();
|
||||
}
|
||||
usort($pageArray, function($a, $b) {
|
||||
return $a->getPageLevel() - $b->getPageLevel();
|
||||
});
|
||||
$pages = new ArrayList($pageArray);
|
||||
|
||||
// Restore
|
||||
return $this->batchaction($pages, 'doRestoreToStage',
|
||||
_t('CMSBatchActions.RESTORED_PAGES', 'Restored %d pages')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@see SiteTree::canEdit()}
|
||||
*
|
||||
* @param array $ids
|
||||
* @return bool
|
||||
*/
|
||||
public function applicablePages($ids) {
|
||||
// Basic permission check based on SiteTree::canEdit
|
||||
if(!Permission::check(array("ADMIN", "SITETREE_EDIT_ALL"))) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Get pages that exist in stage and remove them from the restore-able set
|
||||
$stageIDs = Versioned::get_by_stage($this->managedClass, 'Stage')->column('ID');
|
||||
return array_values(array_diff($ids, $stageIDs));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete items batch action.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchaction
|
||||
*/
|
||||
class CMSBatchAction_Delete extends CMSBatchAction {
|
||||
public function getActionTitle() {
|
||||
return _t('CMSBatchActions.DELETE_DRAFT_PAGES', 'Delete from draft site');
|
||||
}
|
||||
|
||||
public function run(SS_List $pages) {
|
||||
$status = array(
|
||||
'modified'=>array(),
|
||||
'deleted'=>array(),
|
||||
'error'=>array()
|
||||
);
|
||||
|
||||
foreach($pages as $page) {
|
||||
$id = $page->ID;
|
||||
|
||||
// Perform the action
|
||||
if($page->canDelete()) $page->delete();
|
||||
else $status['error'][$page->ID] = true;
|
||||
|
||||
// check to see if the record exists on the live site,
|
||||
// if it doesn't remove the tree node
|
||||
$liveRecord = Versioned::get_one_by_stage( 'SilverStripe\\CMS\\Model\\SiteTree', 'Live', array(
|
||||
'"SiteTree"."ID"' => $id
|
||||
));
|
||||
if($liveRecord) {
|
||||
$status['modified'][$liveRecord->ID] = array(
|
||||
'TreeTitle' => $liveRecord->TreeTitle,
|
||||
);
|
||||
} else {
|
||||
$status['deleted'][$id] = array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->response(_t('CMSBatchActions.DELETED_DRAFT_PAGES', 'Deleted %d pages from draft site, %d failures'), $status);
|
||||
}
|
||||
|
||||
public function applicablePages($ids) {
|
||||
return $this->applicablePagesHelper($ids, 'canDelete', true, false);
|
||||
}
|
||||
}
|
@ -2,17 +2,22 @@
|
||||
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SearchContext;
|
||||
use SearchFilter;
|
||||
use SilverStripe\Filesystem\Storage\AssetNameGenerator;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\ORM\DataList;
|
||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\Security\Security;
|
||||
use SilverStripe\Security\PermissionProvider;
|
||||
use LeftAndMain;
|
||||
use SilverStripe\Admin\CMSBatchAction;
|
||||
use SilverStripe\Admin\CMSBatchActionHandler;
|
||||
use SilverStripe\Admin\LeftAndMain;
|
||||
use Session;
|
||||
use Requirements;
|
||||
use CMSBatchActionHandler;
|
||||
use File;
|
||||
use DateField;
|
||||
use HiddenField;
|
||||
@ -29,6 +34,7 @@ use GridFieldLevelup;
|
||||
use GridField;
|
||||
use Controller;
|
||||
use LiteralField;
|
||||
use SS_HTTPRequest;
|
||||
use TabSet;
|
||||
use Tab;
|
||||
use CompositeField;
|
||||
@ -50,7 +56,7 @@ use Folder;
|
||||
use Injector;
|
||||
use Director;
|
||||
use ArrayData;
|
||||
use CMSBatchAction;
|
||||
|
||||
|
||||
|
||||
|
||||
@ -94,6 +100,8 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
'getsubtree'
|
||||
);
|
||||
|
||||
private static $required_permission_codes = 'CMS_ACCESS_AssetAdmin';
|
||||
|
||||
/**
|
||||
* Return fake-ID "root" if no ID is found (needed to upload files into the root-folder)
|
||||
*/
|
||||
@ -136,6 +144,7 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
// Overwrite name filter to search both Name and Title attributes
|
||||
$context->removeFilterByName('Name');
|
||||
$params = $this->getRequest()->requestVar('q');
|
||||
/** @var DataList $list */
|
||||
$list = $context->getResults($params);
|
||||
|
||||
// Don't filter list when a detail view is requested,
|
||||
@ -216,6 +225,7 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
);
|
||||
|
||||
$gridField = GridField::create('File', $title, $this->getList(), $gridFieldConfig);
|
||||
/** @var GridFieldDataColumns $columns */
|
||||
$columns = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
|
||||
$columns->setDisplayFields(array(
|
||||
'StripThumbnail' => '',
|
||||
@ -253,14 +263,14 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
// Move existing fields to a "details" tab, unless they've already been tabbed out through extensions.
|
||||
// Required to keep Folder->getCMSFields() simple and reuseable,
|
||||
// without any dependencies into AssetAdmin (e.g. useful for "add folder" views).
|
||||
if(!$fields->hasTabset()) {
|
||||
if(!$fields->hasTabSet()) {
|
||||
$tabs = new TabSet('Root',
|
||||
$tabList = new Tab('ListView', _t('AssetAdmin.ListView', 'List View')),
|
||||
$tabTree = new Tab('TreeView', _t('AssetAdmin.TreeView', 'Tree View'))
|
||||
);
|
||||
$tabList->addExtraClass("content-listview cms-tabset-icon list");
|
||||
$tabTree->addExtraClass("content-treeview cms-tabset-icon tree");
|
||||
if($fields->Count() && $folder && $folder->isInDB()) {
|
||||
if($fields->count() && $folder && $folder->isInDB()) {
|
||||
$tabs->push($tabDetails = new Tab('DetailsView', _t('AssetAdmin.DetailsView', 'Details')));
|
||||
$tabDetails->addExtraClass("content-galleryview cms-tabset-icon edit");
|
||||
foreach($fields as $field) {
|
||||
@ -370,6 +380,10 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param SS_HTTPRequest $request
|
||||
* @return DBHTMLText
|
||||
*/
|
||||
public function addfolder($request) {
|
||||
$obj = $this->customise(array(
|
||||
'EditForm' => $this->AddForm()
|
||||
@ -410,12 +424,14 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
* @return SearchContext
|
||||
*/
|
||||
public function getSearchContext() {
|
||||
$context = singleton('File')->getDefaultSearchContext();
|
||||
$context = File::singleton()->getDefaultSearchContext();
|
||||
|
||||
// Namespace fields, for easier detection if a search is present
|
||||
/** @var FormField $field */
|
||||
foreach($context->getFields() as $field) {
|
||||
$field->setName(sprintf('q[%s]', $field->getName()));
|
||||
}
|
||||
/** @var SearchFilter $filter */
|
||||
foreach($context->getFilters() as $filter) {
|
||||
$filter->setFullName(sprintf('q[%s]', $filter->getFullName()));
|
||||
}
|
||||
@ -526,6 +542,10 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
* Add a new group and return its details suitable for ajax.
|
||||
*
|
||||
* @todo Move logic into Folder class, and use LeftAndMain->doAdd() default implementation.
|
||||
*
|
||||
* @param array $data
|
||||
* @param Form $form
|
||||
* @return SS_HTTPResponse|string
|
||||
*/
|
||||
public function doAdd($data, $form) {
|
||||
$class = $this->stat('tree_class');
|
||||
@ -536,6 +556,7 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
}
|
||||
|
||||
// check addchildren permissions
|
||||
/** @var File $parentRecord */
|
||||
if(
|
||||
singleton($class)->hasExtension('SilverStripe\ORM\Hierarchy\Hierarchy')
|
||||
&& isset($data['ParentID'])
|
||||
@ -676,37 +697,3 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Delete multiple {@link Folder} records (and the associated filesystem nodes).
|
||||
* Usually used through the {@link AssetAdmin} interface.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchactions
|
||||
*/
|
||||
class AssetAdmin_DeleteBatchAction extends CMSBatchAction {
|
||||
public function getActionTitle() {
|
||||
// _t('AssetAdmin_left_ss.SELECTTODEL','Select the folders that you want to delete and then click the button below')
|
||||
return _t('AssetAdmin_DeleteBatchAction.TITLE', 'Delete folders');
|
||||
}
|
||||
|
||||
public function run(SS_List $records) {
|
||||
$status = array(
|
||||
'modified'=>array(),
|
||||
'deleted'=>array()
|
||||
);
|
||||
|
||||
foreach($records as $record) {
|
||||
$id = $record->ID;
|
||||
|
||||
// Perform the action
|
||||
if($record->canDelete()) $record->delete();
|
||||
|
||||
$status['deleted'][$id] = array();
|
||||
|
||||
$record->destroy();
|
||||
unset($record);
|
||||
}
|
||||
|
||||
return Convert::raw2json($status);
|
||||
}
|
||||
}
|
||||
|
47
code/Controllers/AssetAdmin_DeleteBatchAction.php
Normal file
47
code/Controllers/AssetAdmin_DeleteBatchAction.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use Convert;
|
||||
use SilverStripe\Admin\CMSBatchAction;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
|
||||
/**
|
||||
* Delete multiple {@link Folder} records (and the associated filesystem nodes).
|
||||
* Usually used through the {@link AssetAdmin} interface.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage batchactions
|
||||
*/
|
||||
class AssetAdmin_DeleteBatchAction extends CMSBatchAction
|
||||
{
|
||||
public function getActionTitle()
|
||||
{
|
||||
// _t('AssetAdmin_left_ss.SELECTTODEL','Select the folders that you want to delete and then click the button below')
|
||||
return _t('AssetAdmin_DeleteBatchAction.TITLE', 'Delete folders');
|
||||
}
|
||||
|
||||
public function run(SS_List $records)
|
||||
{
|
||||
$status = array(
|
||||
'modified' => array(),
|
||||
'deleted' => array()
|
||||
);
|
||||
|
||||
foreach ($records as $record) {
|
||||
$id = $record->ID;
|
||||
|
||||
// Perform the action
|
||||
if ($record->canDelete()) {
|
||||
$record->delete();
|
||||
}
|
||||
|
||||
$status['deleted'][$id] = array();
|
||||
|
||||
$record->destroy();
|
||||
unset($record);
|
||||
}
|
||||
|
||||
return Convert::raw2json($status);
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use FormField;
|
||||
use Injector;
|
||||
use ResetFormAction;
|
||||
use SilverStripe\ORM\FieldType\DBHTMLText;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
@ -16,33 +18,33 @@ use SilverStripe\Security\Security;
|
||||
use SilverStripe\Security\SecurityToken;
|
||||
use SilverStripe\Security\Permission;
|
||||
use SilverStripe\Security\PermissionProvider;
|
||||
use LeftAndMain;
|
||||
|
||||
|
||||
use SilverStripe\Admin\AdminRootController;
|
||||
use SilverStripe\Admin\LeftAndMain;
|
||||
use SilverStripe\Admin\CMSBatchActionHandler;
|
||||
use SilverStripe\Admin\CMSPreviewable;
|
||||
use SilverStripe\Admin\AddToCampaignHandler;
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\CMS\Model\RedirectorPage;
|
||||
use SilverStripe\CMS\Model\CurrentPageIdentifier;
|
||||
use SS_HTTPRequest;
|
||||
use TabSet;
|
||||
use Translatable;
|
||||
use Requirements;
|
||||
use CMSBatchActionHandler;
|
||||
use Controller;
|
||||
use AdminRootController;
|
||||
use Director;
|
||||
use Page;
|
||||
|
||||
use TextField;
|
||||
use HeaderField;
|
||||
use DateField;
|
||||
use DropdownField;
|
||||
use FieldGroup;
|
||||
use FieldList;
|
||||
use FormAction;
|
||||
use Object;
|
||||
use Form;
|
||||
use SS_Cache;
|
||||
use Zend_Cache;
|
||||
use Convert;
|
||||
use ArrayData;
|
||||
use HiddenField;
|
||||
use CMSPreviewable;
|
||||
use LiteralField;
|
||||
use RequiredFields;
|
||||
use LabelField;
|
||||
@ -55,16 +57,7 @@ use GridFieldLevelup;
|
||||
use GridField;
|
||||
use SS_HTTPResponse_Exception;
|
||||
use Session;
|
||||
use AddToCampaignHandler;
|
||||
use HTMLEditorField;
|
||||
use SS_HTTPResponse;
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\CMS\Model\RedirectorPage;
|
||||
use SilverStripe\CMS\Model\CurrentPageIdentifier;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The main "content" area of the CMS.
|
||||
@ -75,6 +68,8 @@ use SilverStripe\CMS\Model\CurrentPageIdentifier;
|
||||
* @package cms
|
||||
* @subpackage controller
|
||||
* @todo Create some base classes to contain the generic functionality that will be replicated.
|
||||
*
|
||||
* @mixin LeftAndMainPageIconsExtension
|
||||
*/
|
||||
class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionProvider {
|
||||
|
||||
@ -96,6 +91,8 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
|
||||
private static $session_namespace = 'SilverStripe\\CMS\\Controllers\\CMSMain';
|
||||
|
||||
private static $required_permission_codes = 'CMS_ACCESS_CMSMain';
|
||||
|
||||
/**
|
||||
* Amount of results showing on a single page.
|
||||
*
|
||||
@ -172,7 +169,9 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
public function index($request) {
|
||||
// In case we're not showing a specific record, explicitly remove any session state,
|
||||
// to avoid it being highlighted in the tree, and causing an edit form to show.
|
||||
if(!$request->param('Action')) $this->setCurrentPageId(null);
|
||||
if(!$request->param('Action')) {
|
||||
$this->setCurrentPageID(null);
|
||||
}
|
||||
|
||||
return parent::index($request);
|
||||
}
|
||||
@ -199,6 +198,9 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
/**
|
||||
* Overloads the LeftAndMain::ShowView. Allows to pass a page as a parameter, so we are able
|
||||
* to switch view also for archived versions.
|
||||
*
|
||||
* @param SiteTree $page
|
||||
* @return array
|
||||
*/
|
||||
public function SwitchView($page = null) {
|
||||
if(!$page) {
|
||||
@ -226,7 +228,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
public function Link($action = null) {
|
||||
$link = Controller::join_links(
|
||||
AdminRootController::admin_url(),
|
||||
$this->stat('url_segment', true), // in case we want to change the segment
|
||||
$this->stat('url_segment'), // in case we want to change the segment
|
||||
'/', // trailing slash needed if $action is null!
|
||||
"$action"
|
||||
);
|
||||
@ -400,7 +402,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
$dateFrom,
|
||||
$dateTo
|
||||
);
|
||||
$dateGroup->setTitle('Last Edited', _t('CMSSearch.PAGEFILTERDATEHEADING', 'Last edited'));
|
||||
$dateGroup->setTitle(_t('CMSSearch.PAGEFILTERDATEHEADING', 'Last edited'));
|
||||
|
||||
// Create the Field list
|
||||
$fields = new FieldList(
|
||||
@ -418,6 +420,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
);
|
||||
|
||||
// Use <button> to allow full jQuery UI styling on the all of the Actions
|
||||
/** @var FormAction $action */
|
||||
foreach($actions->dataFields() as $action) {
|
||||
/** @var FormAction $action */
|
||||
$action->setUseButtonTag(true);
|
||||
@ -482,17 +485,18 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
* @return string Serialized JSON
|
||||
*/
|
||||
public function SiteTreeHints() {
|
||||
$json = '';
|
||||
$classes = SiteTree::page_type_classes();
|
||||
|
||||
$cacheCanCreate = array();
|
||||
foreach($classes as $class) $cacheCanCreate[$class] = singleton($class)->canCreate();
|
||||
$cacheCanCreate = array();
|
||||
foreach($classes as $class) $cacheCanCreate[$class] = singleton($class)->canCreate();
|
||||
|
||||
// Generate basic cache key. Too complex to encompass all variations
|
||||
$cache = SS_Cache::factory('CMSMain_SiteTreeHints');
|
||||
$cacheKey = md5(implode('_', array(Member::currentUserID(), implode(',', $cacheCanCreate), implode(',', $classes))));
|
||||
if($this->getRequest()->getVar('flush')) $cache->clean(Zend_Cache::CLEANING_MODE_ALL);
|
||||
$json = $cache->load($cacheKey);
|
||||
// Generate basic cache key. Too complex to encompass all variations
|
||||
$cache = SS_Cache::factory('CMSMain_SiteTreeHints');
|
||||
$cacheKey = md5(implode('_', array(Member::currentUserID(), implode(',', $cacheCanCreate), implode(',', $classes))));
|
||||
if($this->getRequest()->getVar('flush')) {
|
||||
$cache->clean(Zend_Cache::CLEANING_MODE_ALL);
|
||||
}
|
||||
$json = $cache->load($cacheKey);
|
||||
if(!$json) {
|
||||
$def['Root'] = array();
|
||||
$def['Root']['disallowedChildren'] = array();
|
||||
@ -706,7 +710,8 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
$actions = $record->getCMSActions();
|
||||
|
||||
// Find and remove action menus that have no actions.
|
||||
if ($actions && $actions->Count()) {
|
||||
if ($actions && $actions->count()) {
|
||||
/** @var TabSet $tabset */
|
||||
$tabset = $actions->fieldByName('ActionMenus');
|
||||
if ($tabset) {
|
||||
foreach ($tabset->getChildren() as $tab) {
|
||||
@ -720,7 +725,12 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
|
||||
// Use <button> to allow full jQuery UI styling
|
||||
$actionsFlattened = $actions->dataFields();
|
||||
if($actionsFlattened) foreach($actionsFlattened as $action) $action->setUseButtonTag(true);
|
||||
if($actionsFlattened) {
|
||||
/** @var FormAction $action */
|
||||
foreach($actionsFlattened as $action) {
|
||||
$action->setUseButtonTag(true);
|
||||
}
|
||||
}
|
||||
|
||||
if($record->hasMethod('getCMSValidator')) {
|
||||
$validator = $record->getCMSValidator();
|
||||
@ -734,7 +744,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
$form->setValidationExemptActions(array('restore', 'revert', 'deletefromlive', 'delete', 'unpublish', 'rollback', 'doRollback'));
|
||||
|
||||
// Announce the capability so the frontend can decide whether to allow preview or not.
|
||||
if(in_array('CMSPreviewable', class_implements($record))) {
|
||||
if ($record instanceof CMSPreviewable) {
|
||||
$form->addExtraClass('cms-previewable');
|
||||
}
|
||||
|
||||
@ -840,6 +850,9 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Form
|
||||
*/
|
||||
public function ListViewForm() {
|
||||
$params = $this->getRequest()->requestVar('q');
|
||||
$list = $this->getList($params, $parentID = $this->getRequest()->requestVar('ParentID'));
|
||||
@ -856,6 +869,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
);
|
||||
}
|
||||
$gridField = new GridField('Page','Pages', $list, $gridFieldConfig);
|
||||
/** @var GridFieldDataColumns $columns */
|
||||
$columns = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
|
||||
|
||||
// Don't allow navigating into children nodes on filtered lists
|
||||
@ -864,7 +878,9 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
'singular_name' => _t('SiteTree.PAGETYPE'),
|
||||
'LastEdited' => _t('SiteTree.LASTUPDATED', 'Last Updated'),
|
||||
);
|
||||
$gridField->getConfig()->getComponentByType('GridFieldSortableHeader')->setFieldSorting(array('getTreeTitle' => 'Title'));
|
||||
/** @var GridFieldSortableHeader $sortableHeader */
|
||||
$sortableHeader = $gridField->getConfig()->getComponentByType('GridFieldSortableHeader');
|
||||
$sortableHeader->setFieldSorting(array('getTreeTitle' => 'Title'));
|
||||
$gridField->getState()->ParentID = $parentID;
|
||||
|
||||
if(!$params) {
|
||||
@ -881,6 +897,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
$controller = $this;
|
||||
$columns->setFieldFormatting(array(
|
||||
'listChildrenLink' => function($value, &$item) use($controller) {
|
||||
/** @var SiteTree $item */
|
||||
$num = $item ? $item->numChildren() : null;
|
||||
if($num) {
|
||||
return sprintf(
|
||||
@ -1025,12 +1042,17 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
|
||||
/**
|
||||
* @uses LeftAndMainExtension->augmentNewSiteTreeItem()
|
||||
*
|
||||
* @param int|string $id
|
||||
* @param bool $setID
|
||||
* @return mixed|DataObject
|
||||
* @throws SS_HTTPResponse_Exception
|
||||
*/
|
||||
public function getNewItem($id, $setID = true) {
|
||||
$parentClass = $this->stat('tree_class');
|
||||
list($dummy, $className, $parentID, $suffix) = array_pad(explode('-',$id),4,null);
|
||||
|
||||
if(!is_subclass_of($className, $parentClass) && strcasecmp($className, $parentClass) != 0) {
|
||||
if (!is_a($className, $parentClass, true)) {
|
||||
$response = Security::permissionFailure($this);
|
||||
if (!$response) {
|
||||
$response = $this->getResponse();
|
||||
@ -1038,8 +1060,8 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
throw new SS_HTTPResponse_Exception($response);
|
||||
}
|
||||
|
||||
$newItem = new $className();
|
||||
|
||||
/** @var SiteTree $newItem */
|
||||
$newItem = Injector::inst()->create($className);
|
||||
if( !$suffix ) {
|
||||
$sessionTag = "NewItems." . $parentID . "." . $className;
|
||||
if(Session::get($sessionTag)) {
|
||||
@ -1232,7 +1254,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @return SS_HTTPResponse
|
||||
*/
|
||||
public function rollback() {
|
||||
return $this->doRollback(array(
|
||||
@ -1314,6 +1336,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
$SNG_action = singleton($batchAction);
|
||||
if ($SNG_action->canView() && $fieldset = $SNG_action->getParameterFields()) {
|
||||
$formHtml = '';
|
||||
/** @var FormField $field */
|
||||
foreach($fieldset as $field) {
|
||||
$formHtml .= $field->Field();
|
||||
}
|
||||
@ -1349,6 +1372,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
$pages = SiteTree::get()->limit("$start,30");
|
||||
$count = 0;
|
||||
while($pages) {
|
||||
/** @var SiteTree $page */
|
||||
foreach($pages as $page) {
|
||||
if($page && !$page->canPublish()) {
|
||||
return Security::permissionFailure($this);
|
||||
@ -1373,7 +1397,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
$token = SecurityToken::inst();
|
||||
$fields = new FieldList();
|
||||
$token->updateFieldSet($fields);
|
||||
$tokenField = $fields->First();
|
||||
$tokenField = $fields->first();
|
||||
$tokenHtml = ($tokenField) ? $tokenField->FieldHolder() : '';
|
||||
$response .= '<h1>' . _t('CMSMain.PUBALLFUN','"Publish All" functionality') . '</h1>
|
||||
<p>' . _t('CMSMain.PUBALLFUN2', 'Pressing this button will do the equivalent of going to every page and pressing "publish". It\'s
|
||||
@ -1391,6 +1415,10 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
|
||||
/**
|
||||
* Restore a completely deleted page from the SiteTree_versions table.
|
||||
*
|
||||
* @param array $data
|
||||
* @param Form $form
|
||||
* @return SS_HTTPResponse
|
||||
*/
|
||||
public function restore($data, $form) {
|
||||
if(!isset($data['ID']) || !is_numeric($data['ID'])) {
|
||||
@ -1398,8 +1426,11 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
}
|
||||
|
||||
$id = (int)$data['ID'];
|
||||
/** @var SiteTree $restoredPage */
|
||||
$restoredPage = Versioned::get_latest_version("SilverStripe\\CMS\\Model\\SiteTree", $id);
|
||||
if(!$restoredPage) return new SS_HTTPResponse("SiteTree #$id not found", 400);
|
||||
if(!$restoredPage) {
|
||||
return new SS_HTTPResponse("SiteTree #$id not found", 400);
|
||||
}
|
||||
|
||||
$restoredPage = $restoredPage->doRestoreToStage();
|
||||
|
||||
@ -1420,6 +1451,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
if(!SecurityToken::inst()->checkRequest($request)) return $this->httpError(400);
|
||||
|
||||
if(($id = $this->urlParams['ID']) && is_numeric($id)) {
|
||||
/** @var SiteTree $page */
|
||||
$page = SiteTree::get()->byID($id);
|
||||
if($page && (!$page->canEdit() || !$page->canCreate(null, array('Parent' => $page->Parent())))) {
|
||||
return Security::permissionFailure($this);
|
||||
@ -1458,6 +1490,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
if(!SecurityToken::inst()->checkRequest($request)) return $this->httpError(400);
|
||||
increase_time_limit_to();
|
||||
if(($id = $this->urlParams['ID']) && is_numeric($id)) {
|
||||
/** @var SiteTree $page */
|
||||
$page = SiteTree::get()->byID($id);
|
||||
if($page && (!$page->canEdit() || !$page->canCreate(null, array('Parent' => $page->Parent())))) {
|
||||
return Security::permissionFailure($this);
|
||||
|
@ -11,11 +11,11 @@ use FieldList;
|
||||
use LiteralField;
|
||||
use SelectionGroup;
|
||||
use SelectionGroup_Item;
|
||||
use SS_HTTPResponse;
|
||||
use TreeDropdownField;
|
||||
use OptionsetField;
|
||||
use FormAction;
|
||||
use Form;
|
||||
|
||||
use Session;
|
||||
use Controller;
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
@ -151,8 +151,8 @@ class CMSPageAddController extends CMSPageEditController {
|
||||
$form->setValidationResponseCallback(function() use ($negotiator, $form) {
|
||||
$request = $this->getRequest();
|
||||
if($request->isAjax() && $negotiator) {
|
||||
$this->setupFormErrors();
|
||||
$result = $this->forTemplate();
|
||||
$form->setupFormErrors();
|
||||
$result = $form->forTemplate();
|
||||
|
||||
return $negotiator->respond($request, array(
|
||||
'CurrentForm' => function() use($result) {
|
||||
@ -167,6 +167,11 @@ class CMSPageAddController extends CMSPageEditController {
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param Form $form
|
||||
* @return SS_HTTPResponse
|
||||
*/
|
||||
public function doAdd($data, $form) {
|
||||
$className = isset($data['PageType']) ? $data['PageType'] : "Page";
|
||||
$parentID = isset($data['ParentID']) ? (int)$data['ParentID'] : 0;
|
||||
|
@ -403,6 +403,7 @@ class CMSPageHistoryController extends CMSMain {
|
||||
/** @var SiteTree $page */
|
||||
$page = SiteTree::get()->byID($id);
|
||||
|
||||
$record = null;
|
||||
if($page && $page->exists()) {
|
||||
if(!$page->canView()) {
|
||||
return Security::permissionFailure($this);
|
||||
|
@ -7,9 +7,10 @@ use SilverStripe\ORM\DataList;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
use Object;
|
||||
use LeftAndMain_SearchFilter;
|
||||
use ClassInfo;
|
||||
use DateField;
|
||||
use SilverStripe\Admin\LeftAndMain_SearchFilter;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for filtering the subtree for certain node statuses.
|
||||
@ -239,220 +240,3 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
|
||||
return $ids;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This filter will display the SiteTree as a site visitor might see the site, i.e only the
|
||||
* pages that is currently published.
|
||||
*
|
||||
* Note that this does not check canView permissions that might hide pages from certain visitors
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_PublishedPages extends CMSSiteTreeFilter {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function title() {
|
||||
return _t('CMSSIteTreeFilter_PublishedPages.Title', "Published pages");
|
||||
}
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $childrenMethod = "AllHistoricalChildren";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $numChildrenMethod = 'numHistoricalChildren';
|
||||
|
||||
/**
|
||||
* Filters out all pages who's status who's status that doesn't exist on live
|
||||
*
|
||||
* @see {@link SiteTree::getStatusFlags()}
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages() {
|
||||
$pages = Versioned::get_including_deleted('SilverStripe\\CMS\\Model\\SiteTree');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
$pages = $pages->filterByCallback(function(SiteTree $page) {
|
||||
return $page->getExistsOnLive();
|
||||
});
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Works a bit different than the other filters:
|
||||
* Shows all pages *including* those deleted from stage and live.
|
||||
* It does not filter out pages still existing in the different stages.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $childrenMethod = "AllHistoricalChildren";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $numChildrenMethod = 'numHistoricalChildren';
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_DeletedPages.Title', "All pages, including archived");
|
||||
}
|
||||
|
||||
public function getFilteredPages() {
|
||||
$pages = Versioned::get_including_deleted('SilverStripe\\CMS\\Model\\SiteTree');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all pages which have changed on stage.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_ChangedPages extends CMSSiteTreeFilter {
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_ChangedPages.Title', "Modified pages");
|
||||
}
|
||||
|
||||
public function getFilteredPages() {
|
||||
$pages = Versioned::get_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Stage');
|
||||
$pages = $this->applyDefaultFilters($pages)
|
||||
->leftJoin('SiteTree_Live', '"SiteTree_Live"."ID" = "SiteTree"."ID"')
|
||||
->where('"SiteTree"."Version" <> "SiteTree_Live"."Version"');
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters pages which have a status "Removed from Draft".
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_StatusRemovedFromDraftPages extends CMSSiteTreeFilter {
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_StatusRemovedFromDraftPages.Title', 'Live but removed from draft');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all pages who's status is set to "Removed from draft".
|
||||
*
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages() {
|
||||
$pages = Versioned::get_including_deleted('SilverStripe\\CMS\\Model\\SiteTree');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
$pages = $pages->filterByCallback(function(SiteTree $page) {
|
||||
// If page is removed from stage but not live
|
||||
return $page->getIsDeletedFromStage() && $page->getExistsOnLive();
|
||||
});
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters pages which have a status "Draft".
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_StatusDraftPages extends CMSSiteTreeFilter {
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_StatusDraftPages.Title', 'Draft pages');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all pages who's status is set to "Draft".
|
||||
*
|
||||
* @see {@link SiteTree::getStatusFlags()}
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages() {
|
||||
$pages = Versioned::get_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Stage');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
$pages = $pages->filterByCallback(function(SiteTree $page) {
|
||||
// If page exists on stage but not on live
|
||||
return (!$page->getIsDeletedFromStage() && $page->getIsAddedToStage());
|
||||
});
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters pages which have a status "Deleted".
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_StatusDeletedPages extends CMSSiteTreeFilter {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $childrenMethod = "AllHistoricalChildren";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $numChildrenMethod = 'numHistoricalChildren';
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_StatusDeletedPages.Title', 'Archived pages');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all pages who's status is set to "Deleted".
|
||||
*
|
||||
* @see {@link SiteTree::getStatusFlags()}
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages() {
|
||||
$pages = Versioned::get_including_deleted('SilverStripe\\CMS\\Model\\SiteTree');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
|
||||
$pages = $pages->filterByCallback(function(SiteTree $page) {
|
||||
// Doesn't exist on either stage or live
|
||||
return $page->getIsDeletedFromStage() && !$page->getExistsOnLive();
|
||||
});
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_Search extends CMSSiteTreeFilter {
|
||||
|
||||
static public function title() {
|
||||
return _t('CMSSiteTreeFilter_Search.Title', "All pages");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retun an array of maps containing the keys, 'ID' and 'ParentID' for each page to be displayed
|
||||
* in the search.
|
||||
*
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages() {
|
||||
// Filter default records
|
||||
$pages = Versioned::get_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Stage');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
return $pages;
|
||||
}
|
||||
}
|
||||
|
29
code/Controllers/CMSSiteTreeFilter_ChangedPages.php
Normal file
29
code/Controllers/CMSSiteTreeFilter_ChangedPages.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
|
||||
/**
|
||||
* Gets all pages which have changed on stage.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_ChangedPages extends CMSSiteTreeFilter
|
||||
{
|
||||
|
||||
static public function title()
|
||||
{
|
||||
return _t('CMSSiteTreeFilter_ChangedPages.Title', "Modified pages");
|
||||
}
|
||||
|
||||
public function getFilteredPages()
|
||||
{
|
||||
$pages = Versioned::get_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Stage');
|
||||
$pages = $this->applyDefaultFilters($pages)
|
||||
->leftJoin('SiteTree_Live', '"SiteTree_Live"."ID" = "SiteTree"."ID"')
|
||||
->where('"SiteTree"."Version" <> "SiteTree_Live"."Version"');
|
||||
return $pages;
|
||||
}
|
||||
}
|
39
code/Controllers/CMSSiteTreeFilter_DeletedPages.php
Normal file
39
code/Controllers/CMSSiteTreeFilter_DeletedPages.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
|
||||
/**
|
||||
* Works a bit different than the other filters:
|
||||
* Shows all pages *including* those deleted from stage and live.
|
||||
* It does not filter out pages still existing in the different stages.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $childrenMethod = "AllHistoricalChildren";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $numChildrenMethod = 'numHistoricalChildren';
|
||||
|
||||
static public function title()
|
||||
{
|
||||
return _t('CMSSiteTreeFilter_DeletedPages.Title', "All pages, including archived");
|
||||
}
|
||||
|
||||
public function getFilteredPages()
|
||||
{
|
||||
$pages = Versioned::get_including_deleted('SilverStripe\\CMS\\Model\\SiteTree');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
return $pages;
|
||||
}
|
||||
}
|
54
code/Controllers/CMSSiteTreeFilter_PublishedPages.php
Normal file
54
code/Controllers/CMSSiteTreeFilter_PublishedPages.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
|
||||
/**
|
||||
* This filter will display the SiteTree as a site visitor might see the site, i.e only the
|
||||
* pages that is currently published.
|
||||
*
|
||||
* Note that this does not check canView permissions that might hide pages from certain visitors
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_PublishedPages extends CMSSiteTreeFilter
|
||||
{
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
static public function title()
|
||||
{
|
||||
return _t('CMSSIteTreeFilter_PublishedPages.Title', "Published pages");
|
||||
}
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $childrenMethod = "AllHistoricalChildren";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $numChildrenMethod = 'numHistoricalChildren';
|
||||
|
||||
/**
|
||||
* Filters out all pages who's status who's status that doesn't exist on live
|
||||
*
|
||||
* @see {@link SiteTree::getStatusFlags()}
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages()
|
||||
{
|
||||
$pages = Versioned::get_including_deleted('SilverStripe\\CMS\\Model\\SiteTree');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
$pages = $pages->filterByCallback(function (SiteTree $page) {
|
||||
return $page->getExistsOnLive();
|
||||
});
|
||||
return $pages;
|
||||
}
|
||||
}
|
32
code/Controllers/CMSSiteTreeFilter_Search.php
Normal file
32
code/Controllers/CMSSiteTreeFilter_Search.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_Search extends CMSSiteTreeFilter
|
||||
{
|
||||
|
||||
static public function title()
|
||||
{
|
||||
return _t('CMSSiteTreeFilter_Search.Title', "All pages");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retun an array of maps containing the keys, 'ID' and 'ParentID' for each page to be displayed
|
||||
* in the search.
|
||||
*
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages()
|
||||
{
|
||||
// Filter default records
|
||||
$pages = Versioned::get_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Stage');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
return $pages;
|
||||
}
|
||||
}
|
50
code/Controllers/CMSSiteTreeFilter_StatusDeletedPages.php
Normal file
50
code/Controllers/CMSSiteTreeFilter_StatusDeletedPages.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
|
||||
/**
|
||||
* Filters pages which have a status "Deleted".
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_StatusDeletedPages extends CMSSiteTreeFilter
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $childrenMethod = "AllHistoricalChildren";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $numChildrenMethod = 'numHistoricalChildren';
|
||||
|
||||
static public function title()
|
||||
{
|
||||
return _t('CMSSiteTreeFilter_StatusDeletedPages.Title', 'Archived pages');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all pages who's status is set to "Deleted".
|
||||
*
|
||||
* @see {@link SiteTree::getStatusFlags()}
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages()
|
||||
{
|
||||
$pages = Versioned::get_including_deleted('SilverStripe\\CMS\\Model\\SiteTree');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
|
||||
$pages = $pages->filterByCallback(function (SiteTree $page) {
|
||||
// Doesn't exist on either stage or live
|
||||
return $page->getIsDeletedFromStage() && !$page->getExistsOnLive();
|
||||
});
|
||||
return $pages;
|
||||
}
|
||||
}
|
39
code/Controllers/CMSSiteTreeFilter_StatusDraftPages.php
Normal file
39
code/Controllers/CMSSiteTreeFilter_StatusDraftPages.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
|
||||
/**
|
||||
* Filters pages which have a status "Draft".
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_StatusDraftPages extends CMSSiteTreeFilter
|
||||
{
|
||||
|
||||
static public function title()
|
||||
{
|
||||
return _t('CMSSiteTreeFilter_StatusDraftPages.Title', 'Draft pages');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all pages who's status is set to "Draft".
|
||||
*
|
||||
* @see {@link SiteTree::getStatusFlags()}
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages()
|
||||
{
|
||||
$pages = Versioned::get_by_stage('SilverStripe\\CMS\\Model\\SiteTree', 'Stage');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
$pages = $pages->filterByCallback(function (SiteTree $page) {
|
||||
// If page exists on stage but not on live
|
||||
return (!$page->getIsDeletedFromStage() && $page->getIsAddedToStage());
|
||||
});
|
||||
return $pages;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
|
||||
/**
|
||||
* Filters pages which have a status "Removed from Draft".
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class CMSSiteTreeFilter_StatusRemovedFromDraftPages extends CMSSiteTreeFilter
|
||||
{
|
||||
|
||||
static public function title()
|
||||
{
|
||||
return _t('CMSSiteTreeFilter_StatusRemovedFromDraftPages.Title', 'Live but removed from draft');
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out all pages who's status is set to "Removed from draft".
|
||||
*
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getFilteredPages()
|
||||
{
|
||||
$pages = Versioned::get_including_deleted('SilverStripe\\CMS\\Model\\SiteTree');
|
||||
$pages = $this->applyDefaultFilters($pages);
|
||||
$pages = $pages->filterByCallback(function (SiteTree $page) {
|
||||
// If page is removed from stage but not live
|
||||
return $page->getIsDeletedFromStage() && $page->getExistsOnLive();
|
||||
});
|
||||
return $pages;
|
||||
}
|
||||
}
|
@ -17,9 +17,7 @@ use SilverStripe\Security\Member;
|
||||
use SilverStripe\Security\Permission;
|
||||
use Controller;
|
||||
use Page;
|
||||
|
||||
use SiteConfig;
|
||||
use Config;
|
||||
use SS_HTTPRequest;
|
||||
use Translatable;
|
||||
use i18n;
|
||||
|
@ -4,10 +4,8 @@ namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\ORM\DataExtension;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
use SilverStripe\CMS\Model\ErrorPage;
|
||||
|
||||
|
||||
/**
|
||||
* Decorates {@see File} with ErrorPage support
|
||||
*/
|
||||
|
@ -7,7 +7,6 @@ use SilverStripe\ORM\DataModel;
|
||||
use SilverStripe\ORM\DB;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use Controller;
|
||||
|
||||
use ClassInfo;
|
||||
use Injector;
|
||||
use SS_HTTPRequest;
|
||||
|
@ -11,7 +11,6 @@ use SS_HTTPResponse;
|
||||
use Controller;
|
||||
use SS_HTTPResponse_Exception;
|
||||
|
||||
|
||||
class OldPageRedirector extends Extension {
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,6 @@ use SS_HTTPRequest;
|
||||
use ClassInfo;
|
||||
use Director;
|
||||
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage control
|
||||
|
@ -5,17 +5,10 @@ namespace SilverStripe\CMS\Controllers;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
use SilverStripe\Security\Member;
|
||||
use ViewableData;
|
||||
use CMSPreviewable;
|
||||
use ClassInfo;
|
||||
use LeftAndMain;
|
||||
use Controller;
|
||||
|
||||
use SilverStripe\Admin\CMSPreviewable;
|
||||
use SiteTreeFutureState;
|
||||
use SilverStripe\CMS\Model\RedirectorPage;
|
||||
|
||||
|
||||
/**
|
||||
@ -108,309 +101,3 @@ class SilverStripeNavigator extends ViewableData {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigator items are links that appear in the $SilverStripeNavigator bar.
|
||||
* To add an item, extend this class - it will be automatically picked up.
|
||||
* When instanciating items manually, please ensure to call {@link canView()}.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
abstract class SilverStripeNavigatorItem extends ViewableData {
|
||||
|
||||
/**
|
||||
* @param DataObject|CMSPreviewable
|
||||
*/
|
||||
protected $record;
|
||||
|
||||
/** @var string */
|
||||
protected $recordLink;
|
||||
|
||||
/**
|
||||
* @param DataObject|CMSPreviewable $record
|
||||
*/
|
||||
public function __construct(CMSPreviewable $record) {
|
||||
parent::__construct();
|
||||
$this->record = $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string HTML, mostly a link - but can be more complex as well.
|
||||
* For example, a "future state" item might show a date selector.
|
||||
*/
|
||||
abstract public function getHTML();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* Get the Title of an item
|
||||
*/
|
||||
abstract public function getTitle();
|
||||
|
||||
/**
|
||||
* Machine-friendly name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return substr(get_class($this), strpos(get_class($this), '_')+1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional link to a specific view of this record.
|
||||
* Not all items are simple links, please use {@link getHTML()}
|
||||
* to represent an item in markup unless you know what you're doing.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLink() {}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage() {}
|
||||
|
||||
/**
|
||||
* @return DataObject
|
||||
*/
|
||||
public function getRecord() {
|
||||
return $this->record;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPriority() {
|
||||
return $this->stat('priority');
|
||||
}
|
||||
|
||||
/**
|
||||
* As items might convey different record states like a "stage" or "live" table,
|
||||
* an item can be active (showing the record in this state).
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isActive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters items based on member permissions or other criteria,
|
||||
* such as if a state is generally available for the current record.
|
||||
*
|
||||
* @param Member $member
|
||||
* @return Boolean
|
||||
*/
|
||||
public function canView($member = null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts as "archived" if the current record is a different version from both live and draft.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isArchived() {
|
||||
if(!$this->record->hasExtension('SilverStripe\ORM\Versioning\Versioned')) return false;
|
||||
|
||||
if(!isset($this->record->_cached_isArchived)) {
|
||||
$baseClass = $this->record->baseClass();
|
||||
$currentDraft = Versioned::get_by_stage($baseClass, Versioned::DRAFT)->byID($this->record->ID);
|
||||
$currentLive = Versioned::get_by_stage($baseClass, Versioned::LIVE)->byID($this->record->ID);
|
||||
|
||||
$this->record->_cached_isArchived = (
|
||||
(!$currentDraft || ($currentDraft && $this->record->Version != $currentDraft->Version))
|
||||
&& (!$currentLive || ($currentLive && $this->record->Version != $currentLive->Version))
|
||||
);
|
||||
}
|
||||
|
||||
return $this->record->_cached_isArchived;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class SilverStripeNavigatorItem_CMSLink extends SilverStripeNavigatorItem {
|
||||
/** @config */
|
||||
private static $priority = 10;
|
||||
|
||||
public function getHTML() {
|
||||
return sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
$this->record->CMSEditLink(),
|
||||
_t('ContentController.CMS', 'CMS')
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return _t('ContentController.CMS', 'CMS', 'Used in navigation. Should be a short label');
|
||||
}
|
||||
|
||||
public function getLink() {
|
||||
return $this->record->CMSEditLink();
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
return (Controller::curr() instanceof LeftAndMain);
|
||||
}
|
||||
|
||||
public function canView($member = null) {
|
||||
return (
|
||||
// Don't show in CMS
|
||||
!(Controller::curr() instanceof LeftAndMain)
|
||||
// Don't follow redirects in preview, they break the CMS editing form
|
||||
&& !($this->record instanceof RedirectorPage)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class SilverStripeNavigatorItem_StageLink extends SilverStripeNavigatorItem {
|
||||
/** @config */
|
||||
private static $priority = 20;
|
||||
|
||||
public function getHTML() {
|
||||
$draftPage = $this->getDraftPage();
|
||||
if($draftPage) {
|
||||
$this->recordLink = Controller::join_links($draftPage->AbsoluteLink(), "?stage=Stage");
|
||||
return "<a ". ($this->isActive() ? 'class="current" ' : '') ."href=\"$this->recordLink\">". _t('ContentController.DRAFTSITE', 'Draft Site') ."</a>";
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return _t('ContentController.DRAFT', 'Draft', 'Used for the Switch between draft and published view mode. Needs to be a short label');
|
||||
}
|
||||
|
||||
public function getMessage() {
|
||||
return "<div id=\"SilverStripeNavigatorMessage\" title=\"". _t('ContentControl.NOTEWONTBESHOWN', 'Note: this message will not be shown to your visitors') ."\">". _t('ContentController.DRAFTSITE', 'Draft Site') ."</div>";
|
||||
}
|
||||
|
||||
public function getLink() {
|
||||
$date = Versioned::current_archived_date();
|
||||
return Controller::join_links(
|
||||
$this->record->PreviewLink(),
|
||||
'?stage=Stage',
|
||||
$date ? '?archiveDate=' . $date : null
|
||||
);
|
||||
}
|
||||
|
||||
public function canView($member = null) {
|
||||
return (
|
||||
$this->record->hasExtension('SilverStripe\ORM\Versioning\Versioned')
|
||||
&& $this->getDraftPage()
|
||||
// Don't follow redirects in preview, they break the CMS editing form
|
||||
&& !($this->record instanceof RedirectorPage)
|
||||
);
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
return (
|
||||
Versioned::get_stage() == 'Stage'
|
||||
&& !(ClassInfo::exists('SiteTreeFutureState') && SiteTreeFutureState::get_future_datetime())
|
||||
&& !$this->isArchived()
|
||||
);
|
||||
}
|
||||
|
||||
protected function getDraftPage() {
|
||||
$baseClass = $this->record->baseClass();
|
||||
return Versioned::get_by_stage($baseClass, Versioned::DRAFT)->byID($this->record->ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class SilverStripeNavigatorItem_LiveLink extends SilverStripeNavigatorItem {
|
||||
/** @config */
|
||||
private static $priority = 30;
|
||||
|
||||
public function getHTML() {
|
||||
$livePage = $this->getLivePage();
|
||||
if($livePage) {
|
||||
$this->recordLink = Controller::join_links($livePage->AbsoluteLink(), "?stage=Live");
|
||||
return "<a ". ($this->isActive() ? 'class="current" ' : '') ."href=\"$this->recordLink\">". _t('ContentController.PUBLISHEDSITE', 'Published Site') ."</a>";
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return _t('ContentController.PUBLISHED', 'Published', 'Used for the Switch between draft and published view mode. Needs to be a short label');
|
||||
}
|
||||
|
||||
public function getMessage() {
|
||||
return "<div id=\"SilverStripeNavigatorMessage\" title=\"". _t('ContentControl.NOTEWONTBESHOWN', 'Note: this message will not be shown to your visitors') ."\">". _t('ContentController.PUBLISHEDSITE', 'Published Site') ."</div>";
|
||||
}
|
||||
|
||||
public function getLink() {
|
||||
return Controller::join_links($this->record->PreviewLink(), '?stage=Live');
|
||||
}
|
||||
|
||||
public function canView($member = null) {
|
||||
return (
|
||||
$this->record->hasExtension('SilverStripe\ORM\Versioning\Versioned')
|
||||
&& $this->getLivePage()
|
||||
// Don't follow redirects in preview, they break the CMS editing form
|
||||
&& !($this->record instanceof RedirectorPage)
|
||||
);
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
return (
|
||||
(!Versioned::get_stage() || Versioned::get_stage() == 'Live')
|
||||
&& !$this->isArchived()
|
||||
);
|
||||
}
|
||||
|
||||
protected function getLivePage() {
|
||||
$baseClass = $this->record->baseClass();
|
||||
return Versioned::get_by_stage($baseClass, Versioned::LIVE)->byID($this->record->ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class SilverStripeNavigatorItem_ArchiveLink extends SilverStripeNavigatorItem {
|
||||
/** @config */
|
||||
private static $priority = 40;
|
||||
|
||||
public function getHTML() {
|
||||
$this->recordLink = $this->record->AbsoluteLink();
|
||||
return "<a class=\"ss-ui-button". ($this->isActive() ? ' current' : '') ."\" href=\"$this->recordLink?archiveDate={$this->record->LastEdited}\" target=\"_blank\">". _t('ContentController.ARCHIVEDSITE', 'Preview version') ."</a>";
|
||||
}
|
||||
|
||||
public function getTitle() {
|
||||
return _t('SilverStripeNavigator.ARCHIVED', 'Archived');
|
||||
}
|
||||
|
||||
public function getMessage() {
|
||||
if($date = Versioned::current_archived_date()) {
|
||||
$dateObj = DBField::create_field('Datetime', $date);
|
||||
return "<div id=\"SilverStripeNavigatorMessage\" title=\"". _t('ContentControl.NOTEWONTBESHOWN', 'Note: this message will not be shown to your visitors') ."\">". _t('ContentController.ARCHIVEDSITEFROM', 'Archived site from') ."<br>" . $dateObj->Nice() . "</div>";
|
||||
}
|
||||
}
|
||||
|
||||
public function getLink() {
|
||||
return $this->record->PreviewLink() . '?archiveDate=' . urlencode($this->record->LastEdited);
|
||||
}
|
||||
|
||||
public function canView($member = null) {
|
||||
return (
|
||||
$this->record->hasExtension('SilverStripe\ORM\Versioning\Versioned')
|
||||
&& $this->isArchived()
|
||||
// Don't follow redirects in preview, they break the CMS editing form
|
||||
&& !($this->record instanceof RedirectorPage)
|
||||
);
|
||||
}
|
||||
|
||||
public function isActive() {
|
||||
return $this->isArchived();
|
||||
}
|
||||
}
|
||||
|
141
code/Controllers/SilverStripeNavigatorItem.php
Normal file
141
code/Controllers/SilverStripeNavigatorItem.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\Admin\CMSPreviewable;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
use SilverStripe\Security\Member;
|
||||
use ViewableData;
|
||||
|
||||
/**
|
||||
* Navigator items are links that appear in the $SilverStripeNavigator bar.
|
||||
* To add an item, extend this class - it will be automatically picked up.
|
||||
* When instanciating items manually, please ensure to call {@link canView()}.
|
||||
*
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
abstract class SilverStripeNavigatorItem extends ViewableData
|
||||
{
|
||||
|
||||
/**
|
||||
* @param DataObject|CMSPreviewable
|
||||
*/
|
||||
protected $record;
|
||||
|
||||
/** @var string */
|
||||
protected $recordLink;
|
||||
|
||||
/**
|
||||
* @param DataObject|CMSPreviewable $record
|
||||
*/
|
||||
public function __construct(CMSPreviewable $record)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->record = $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string HTML, mostly a link - but can be more complex as well.
|
||||
* For example, a "future state" item might show a date selector.
|
||||
*/
|
||||
abstract public function getHTML();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* Get the Title of an item
|
||||
*/
|
||||
abstract public function getTitle();
|
||||
|
||||
/**
|
||||
* Machine-friendly name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return substr(get_class($this), strpos(get_class($this), '_') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional link to a specific view of this record.
|
||||
* Not all items are simple links, please use {@link getHTML()}
|
||||
* to represent an item in markup unless you know what you're doing.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLink()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DataObject
|
||||
*/
|
||||
public function getRecord()
|
||||
{
|
||||
return $this->record;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPriority()
|
||||
{
|
||||
return $this->stat('priority');
|
||||
}
|
||||
|
||||
/**
|
||||
* As items might convey different record states like a "stage" or "live" table,
|
||||
* an item can be active (showing the record in this state).
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isActive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters items based on member permissions or other criteria,
|
||||
* such as if a state is generally available for the current record.
|
||||
*
|
||||
* @param Member $member
|
||||
* @return Boolean
|
||||
*/
|
||||
public function canView($member = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts as "archived" if the current record is a different version from both live and draft.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isArchived()
|
||||
{
|
||||
if (!$this->record->hasExtension('SilverStripe\ORM\Versioning\Versioned')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($this->record->_cached_isArchived)) {
|
||||
$baseClass = $this->record->baseClass();
|
||||
$currentDraft = Versioned::get_by_stage($baseClass, Versioned::DRAFT)->byID($this->record->ID);
|
||||
$currentLive = Versioned::get_by_stage($baseClass, Versioned::LIVE)->byID($this->record->ID);
|
||||
|
||||
$this->record->_cached_isArchived = (
|
||||
(!$currentDraft || ($currentDraft && $this->record->Version != $currentDraft->Version))
|
||||
&& (!$currentLive || ($currentLive && $this->record->Version != $currentLive->Version))
|
||||
);
|
||||
}
|
||||
|
||||
return $this->record->_cached_isArchived;
|
||||
}
|
||||
}
|
60
code/Controllers/SilverStripeNavigatorItem_ArchiveLink.php
Normal file
60
code/Controllers/SilverStripeNavigatorItem_ArchiveLink.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use SilverStripe\CMS\Model\RedirectorPage;
|
||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class SilverStripeNavigatorItem_ArchiveLink extends SilverStripeNavigatorItem
|
||||
{
|
||||
/** @config */
|
||||
private static $priority = 40;
|
||||
|
||||
public function getHTML()
|
||||
{
|
||||
$this->recordLink = $this->record->AbsoluteLink();
|
||||
return "<a class=\"ss-ui-button" . ($this->isActive() ? ' current' : '') . "\" href=\"$this->recordLink?archiveDate={$this->record->LastEdited}\" target=\"_blank\">" . _t('ContentController.ARCHIVEDSITE',
|
||||
'Preview version') . "</a>";
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return _t('SilverStripeNavigator.ARCHIVED', 'Archived');
|
||||
}
|
||||
|
||||
public function getMessage()
|
||||
{
|
||||
if ($date = Versioned::current_archived_date()) {
|
||||
/** @var DBDatetime $dateObj */
|
||||
$dateObj = DBField::create_field('Datetime', $date);
|
||||
return "<div id=\"SilverStripeNavigatorMessage\" title=\"" . _t('ContentControl.NOTEWONTBESHOWN',
|
||||
'Note: this message will not be shown to your visitors') . "\">" . _t('ContentController.ARCHIVEDSITEFROM',
|
||||
'Archived site from') . "<br>" . $dateObj->Nice() . "</div>";
|
||||
}
|
||||
}
|
||||
|
||||
public function getLink()
|
||||
{
|
||||
return $this->record->PreviewLink() . '?archiveDate=' . urlencode($this->record->LastEdited);
|
||||
}
|
||||
|
||||
public function canView($member = null)
|
||||
{
|
||||
return (
|
||||
$this->record->hasExtension('SilverStripe\ORM\Versioning\Versioned')
|
||||
&& $this->isArchived()
|
||||
// Don't follow redirects in preview, they break the CMS editing form
|
||||
&& !($this->record instanceof RedirectorPage)
|
||||
);
|
||||
}
|
||||
|
||||
public function isActive()
|
||||
{
|
||||
return $this->isArchived();
|
||||
}
|
||||
}
|
51
code/Controllers/SilverStripeNavigatorItem_CMSLink.php
Normal file
51
code/Controllers/SilverStripeNavigatorItem_CMSLink.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use Controller;
|
||||
use SilverStripe\Admin\LeftAndMain;
|
||||
use SilverStripe\CMS\Model\RedirectorPage;
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class SilverStripeNavigatorItem_CMSLink extends SilverStripeNavigatorItem
|
||||
{
|
||||
/** @config */
|
||||
private static $priority = 10;
|
||||
|
||||
public function getHTML()
|
||||
{
|
||||
return sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
$this->record->CMSEditLink(),
|
||||
_t('ContentController.CMS', 'CMS')
|
||||
);
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return _t('ContentController.CMS', 'CMS', 'Used in navigation. Should be a short label');
|
||||
}
|
||||
|
||||
public function getLink()
|
||||
{
|
||||
return $this->record->CMSEditLink();
|
||||
}
|
||||
|
||||
public function isActive()
|
||||
{
|
||||
return (Controller::curr() instanceof LeftAndMain);
|
||||
}
|
||||
|
||||
public function canView($member = null)
|
||||
{
|
||||
return (
|
||||
// Don't show in CMS
|
||||
!(Controller::curr() instanceof LeftAndMain)
|
||||
// Don't follow redirects in preview, they break the CMS editing form
|
||||
&& !($this->record instanceof RedirectorPage)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
68
code/Controllers/SilverStripeNavigatorItem_LiveLink.php
Normal file
68
code/Controllers/SilverStripeNavigatorItem_LiveLink.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use Controller;
|
||||
use SilverStripe\CMS\Model\RedirectorPage;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class SilverStripeNavigatorItem_LiveLink extends SilverStripeNavigatorItem
|
||||
{
|
||||
/** @config */
|
||||
private static $priority = 30;
|
||||
|
||||
public function getHTML()
|
||||
{
|
||||
$livePage = $this->getLivePage();
|
||||
if ($livePage) {
|
||||
$this->recordLink = Controller::join_links($livePage->AbsoluteLink(), "?stage=Live");
|
||||
return "<a " . ($this->isActive() ? 'class="current" ' : '') . "href=\"$this->recordLink\">" . _t('ContentController.PUBLISHEDSITE',
|
||||
'Published Site') . "</a>";
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return _t('ContentController.PUBLISHED', 'Published',
|
||||
'Used for the Switch between draft and published view mode. Needs to be a short label');
|
||||
}
|
||||
|
||||
public function getMessage()
|
||||
{
|
||||
return "<div id=\"SilverStripeNavigatorMessage\" title=\"" . _t('ContentControl.NOTEWONTBESHOWN',
|
||||
'Note: this message will not be shown to your visitors') . "\">" . _t('ContentController.PUBLISHEDSITE',
|
||||
'Published Site') . "</div>";
|
||||
}
|
||||
|
||||
public function getLink()
|
||||
{
|
||||
return Controller::join_links($this->record->PreviewLink(), '?stage=Live');
|
||||
}
|
||||
|
||||
public function canView($member = null)
|
||||
{
|
||||
return (
|
||||
$this->record->hasExtension('SilverStripe\ORM\Versioning\Versioned')
|
||||
&& $this->getLivePage()
|
||||
// Don't follow redirects in preview, they break the CMS editing form
|
||||
&& !($this->record instanceof RedirectorPage)
|
||||
);
|
||||
}
|
||||
|
||||
public function isActive()
|
||||
{
|
||||
return (
|
||||
(!Versioned::get_stage() || Versioned::get_stage() == 'Live')
|
||||
&& !$this->isArchived()
|
||||
);
|
||||
}
|
||||
|
||||
protected function getLivePage()
|
||||
{
|
||||
$baseClass = $this->record->baseClass();
|
||||
return Versioned::get_by_stage($baseClass, Versioned::LIVE)->byID($this->record->ID);
|
||||
}
|
||||
}
|
76
code/Controllers/SilverStripeNavigatorItem_StageLink.php
Normal file
76
code/Controllers/SilverStripeNavigatorItem_StageLink.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Controllers;
|
||||
|
||||
use ClassInfo;
|
||||
use Controller;
|
||||
use SilverStripe\CMS\Model\RedirectorPage;
|
||||
use SilverStripe\ORM\Versioning\Versioned;
|
||||
use SiteTreeFutureState;
|
||||
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class SilverStripeNavigatorItem_StageLink extends SilverStripeNavigatorItem
|
||||
{
|
||||
/** @config */
|
||||
private static $priority = 20;
|
||||
|
||||
public function getHTML()
|
||||
{
|
||||
$draftPage = $this->getDraftPage();
|
||||
if ($draftPage) {
|
||||
$this->recordLink = Controller::join_links($draftPage->AbsoluteLink(), "?stage=Stage");
|
||||
return "<a " . ($this->isActive() ? 'class="current" ' : '') . "href=\"$this->recordLink\">" . _t('ContentController.DRAFTSITE',
|
||||
'Draft Site') . "</a>";
|
||||
}
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return _t('ContentController.DRAFT', 'Draft',
|
||||
'Used for the Switch between draft and published view mode. Needs to be a short label');
|
||||
}
|
||||
|
||||
public function getMessage()
|
||||
{
|
||||
return "<div id=\"SilverStripeNavigatorMessage\" title=\"" . _t('ContentControl.NOTEWONTBESHOWN',
|
||||
'Note: this message will not be shown to your visitors') . "\">" . _t('ContentController.DRAFTSITE',
|
||||
'Draft Site') . "</div>";
|
||||
}
|
||||
|
||||
public function getLink()
|
||||
{
|
||||
$date = Versioned::current_archived_date();
|
||||
return Controller::join_links(
|
||||
$this->record->PreviewLink(),
|
||||
'?stage=Stage',
|
||||
$date ? '?archiveDate=' . $date : null
|
||||
);
|
||||
}
|
||||
|
||||
public function canView($member = null)
|
||||
{
|
||||
return (
|
||||
$this->record->hasExtension('SilverStripe\ORM\Versioning\Versioned')
|
||||
&& $this->getDraftPage()
|
||||
// Don't follow redirects in preview, they break the CMS editing form
|
||||
&& !($this->record instanceof RedirectorPage)
|
||||
);
|
||||
}
|
||||
|
||||
public function isActive()
|
||||
{
|
||||
return (
|
||||
Versioned::get_stage() == 'Stage'
|
||||
&& !(ClassInfo::exists('SiteTreeFutureState') && SiteTreeFutureState::get_future_datetime())
|
||||
&& !$this->isArchived()
|
||||
);
|
||||
}
|
||||
|
||||
protected function getDraftPage()
|
||||
{
|
||||
$baseClass = $this->record->baseClass();
|
||||
return Versioned::get_by_stage($baseClass, Versioned::DRAFT)->byID($this->record->ID);
|
||||
}
|
||||
}
|
@ -158,18 +158,3 @@ class SiteTreeURLSegmentField extends TextField {
|
||||
return $newInst;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Readonly version of a site tree URL segment field
|
||||
*
|
||||
* @package forms
|
||||
* @subpackage fields-basic
|
||||
*/
|
||||
class SiteTreeURLSegmentField_Readonly extends SiteTreeURLSegmentField {
|
||||
protected $readonly = true;
|
||||
|
||||
public function performReadonlyTransformation() {
|
||||
return clone $this;
|
||||
}
|
||||
}
|
||||
|
18
code/Forms/SiteTreeURLSegmentField_Readonly.php
Normal file
18
code/Forms/SiteTreeURLSegmentField_Readonly.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Forms;
|
||||
|
||||
/**
|
||||
* Readonly version of a site tree URL segment field
|
||||
*
|
||||
* @package forms
|
||||
* @subpackage fields-basic
|
||||
*/
|
||||
class SiteTreeURLSegmentField_Readonly extends SiteTreeURLSegmentField
|
||||
{
|
||||
protected $readonly = true;
|
||||
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
return clone $this;
|
||||
}
|
||||
}
|
@ -383,27 +383,3 @@ class ErrorPage extends Page {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller for ErrorPages.
|
||||
*
|
||||
* @package cms
|
||||
*/
|
||||
class ErrorPage_Controller extends Page_Controller {
|
||||
|
||||
/**
|
||||
* Overload the provided {@link Controller::handleRequest()} to append the
|
||||
* correct status code post request since otherwise permission related error
|
||||
* pages such as 401 and 403 pages won't be rendered due to
|
||||
* {@link SS_HTTPResponse::isFinished() ignoring the response body.
|
||||
*
|
||||
* @param SS_HTTPRequest $request
|
||||
* @param DataModel $model
|
||||
* @return SS_HTTPResponse
|
||||
*/
|
||||
public function handleRequest(SS_HTTPRequest $request, DataModel $model = NULL) {
|
||||
$response = parent::handleRequest($request, $model);
|
||||
$response->setStatusCode($this->ErrorCode);
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
|
33
code/Model/ErrorPage_Controller.php
Normal file
33
code/Model/ErrorPage_Controller.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Model;
|
||||
|
||||
use Page_Controller;
|
||||
use SilverStripe\ORM\DataModel;
|
||||
use SS_HTTPRequest;
|
||||
use SS_HTTPResponse;
|
||||
|
||||
/**
|
||||
* Controller for ErrorPages.
|
||||
*
|
||||
* @package cms
|
||||
*/
|
||||
class ErrorPage_Controller extends Page_Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Overload the provided {@link Controller::handleRequest()} to append the
|
||||
* correct status code post request since otherwise permission related error
|
||||
* pages such as 401 and 403 pages won't be rendered due to
|
||||
* {@link SS_HTTPResponse::isFinished() ignoring the response body.
|
||||
*
|
||||
* @param SS_HTTPRequest $request
|
||||
* @param DataModel $model
|
||||
* @return SS_HTTPResponse
|
||||
*/
|
||||
public function handleRequest(SS_HTTPRequest $request, DataModel $model = null)
|
||||
{
|
||||
$response = parent::handleRequest($request, $model);
|
||||
$response->setStatusCode($this->ErrorCode);
|
||||
return $response;
|
||||
}
|
||||
}
|
@ -180,31 +180,3 @@ class RedirectorPage extends Page {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller for the {@link RedirectorPage}.
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class RedirectorPage_Controller extends Page_Controller {
|
||||
|
||||
public function init() {
|
||||
parent::init();
|
||||
|
||||
// Check we don't already have a redirect code set
|
||||
/** @var RedirectorPage $page */
|
||||
$page = $this->data();
|
||||
if(!$this->getResponse()->isFinished() && $link = $page->redirectionLink()) {
|
||||
$this->redirect($link, 301);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we ever get this far, it means that the redirection failed.
|
||||
*/
|
||||
public function Content() {
|
||||
return "<p class=\"message-setupWithoutRedirect\">" .
|
||||
_t('RedirectorPage.HASBEENSETUP', 'A redirector page has been set up without anywhere to redirect to.') .
|
||||
"</p>";
|
||||
}
|
||||
}
|
||||
|
35
code/Model/RedirectorPage_Controller.php
Normal file
35
code/Model/RedirectorPage_Controller.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Model;
|
||||
|
||||
use Page_Controller;
|
||||
|
||||
/**
|
||||
* Controller for the {@link RedirectorPage}.
|
||||
* @package cms
|
||||
* @subpackage content
|
||||
*/
|
||||
class RedirectorPage_Controller extends Page_Controller
|
||||
{
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
// Check we don't already have a redirect code set
|
||||
/** @var RedirectorPage $page */
|
||||
$page = $this->data();
|
||||
if (!$this->getResponse()->isFinished() && $link = $page->redirectionLink()) {
|
||||
$this->redirect($link, 301);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we ever get this far, it means that the redirection failed.
|
||||
*/
|
||||
public function Content()
|
||||
{
|
||||
return "<p class=\"message-setupWithoutRedirect\">" .
|
||||
_t('RedirectorPage.HASBEENSETUP', 'A redirector page has been set up without anywhere to redirect to.') .
|
||||
"</p>";
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ use SilverStripe\Security\Permission;
|
||||
use SilverStripe\Security\Group;
|
||||
use SilverStripe\Security\PermissionProvider;
|
||||
use i18nEntityProvider;
|
||||
use CMSPreviewable;
|
||||
use Director;
|
||||
use SilverStripe\CMS\Controllers\RootURLController;
|
||||
use ClassInfo;
|
||||
@ -52,9 +51,11 @@ use TreeDropdownField;
|
||||
use FieldGroup;
|
||||
use CheckboxField;
|
||||
use ListboxField;
|
||||
use AddToCampaignHandler_FormAction;
|
||||
use FormAction;
|
||||
use i18n;
|
||||
use SilverStripe\Admin\AddToCampaignHandler_FormAction;
|
||||
use SilverStripe\Admin\CMSPreviewable;
|
||||
|
||||
|
||||
/**
|
||||
* Basic data-object representing all pages within the site tree. All page types that live within the hierarchy should
|
||||
@ -81,8 +82,8 @@ use i18n;
|
||||
* @property string CanViewType Type of restriction for viewing this object.
|
||||
* @property string CanEditType Type of restriction for editing this object.
|
||||
*
|
||||
* @method ManyManyList ViewerGroups List of groups that can view this object.
|
||||
* @method ManyManyList EditorGroups List of groups that can edit this object.
|
||||
* @method ManyManyList ViewerGroups() List of groups that can view this object.
|
||||
* @method ManyManyList EditorGroups() List of groups that can edit this object.
|
||||
* @method SiteTree Parent()
|
||||
*
|
||||
* @mixin Hierarchy
|
||||
@ -352,13 +353,13 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
foreach($alternatives as $alternative) {
|
||||
if($alternative) {
|
||||
$sitetree = $alternative;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$sitetree) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we have any more URL parts to parse.
|
||||
@ -402,8 +403,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
public static function page_type_classes() {
|
||||
$classes = ClassInfo::getValidSubClasses();
|
||||
|
||||
$baseClassIndex = array_search('SilverStripe\\CMS\\Model\\SiteTree', $classes);
|
||||
if($baseClassIndex !== FALSE) unset($classes[$baseClassIndex]);
|
||||
$baseClassIndex = array_search(__CLASS__, $classes);
|
||||
if($baseClassIndex !== false) {
|
||||
unset($classes[$baseClassIndex]);
|
||||
}
|
||||
|
||||
$kill_ancestors = array();
|
||||
|
||||
@ -437,8 +440,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
/**
|
||||
* Replace a "[sitetree_link id=n]" shortcode with a link to the page with the corresponding ID.
|
||||
*
|
||||
* @param array $arguments
|
||||
* @param string $content
|
||||
* @param array $arguments
|
||||
* @param string $content
|
||||
* @param ShortcodeParser $parser
|
||||
* @return string
|
||||
*/
|
||||
@ -447,6 +450,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var SiteTree $page */
|
||||
if (
|
||||
!($page = DataObject::get_by_id(__CLASS__, $arguments['id'])) // Get the current page by ID.
|
||||
&& !($page = Versioned::get_latest_version(__CLASS__, $arguments['id'])) // Attempt link to old version.
|
||||
@ -609,7 +613,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
$currentPage = Director::get_current_page();
|
||||
if ($currentPage instanceof ContentController) {
|
||||
$currentPage = $currentPage->data();
|
||||
}
|
||||
}
|
||||
if($currentPage instanceof SiteTree) {
|
||||
return $currentPage === $this || $currentPage->ID === $this->ID;
|
||||
}
|
||||
@ -1467,7 +1471,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
}
|
||||
|
||||
if(Permission::check('CMS_ACCESS_CMSMain')
|
||||
&& in_array('CMSPreviewable', class_implements($this))
|
||||
&& !$this instanceof ErrorPage
|
||||
&& $this->ID > 0
|
||||
) {
|
||||
@ -1552,7 +1555,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
DB::alteration_message('Contact Us page created', 'created');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function onBeforeWrite() {
|
||||
parent::onBeforeWrite();
|
||||
@ -1877,10 +1880,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
if($parentPage && $parentPage->exists()) {
|
||||
$link = Convert::raw2att($parentPage->CMSEditLink());
|
||||
$title = Convert::raw2xml($parentPage->Title);
|
||||
} else {
|
||||
} else {
|
||||
$link = CMSPageEditController::singleton()->Link('show');
|
||||
$title = _t('SiteTree.TOPLEVEL', 'Site Content (Top Level)');
|
||||
}
|
||||
}
|
||||
$parentPageLinks[] = "<a class=\"cmsEditlink\" href=\"{$link}\">{$title}</a>";
|
||||
}
|
||||
|
||||
@ -1925,9 +1928,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
||||
$dependentPages
|
||||
);
|
||||
/** @var GridFieldDataColumns $dataColumns */
|
||||
$dataColumns = $dependentTable
|
||||
->getConfig()
|
||||
->getComponentByType('GridFieldDataColumns');
|
||||
$dataColumns = $dependentTable->getConfig()->getComponentByType('GridFieldDataColumns');
|
||||
$dataColumns
|
||||
->setDisplayFields($dependentColumns)
|
||||
->setFieldFormatting(array(
|
||||
|
@ -230,126 +230,3 @@ class SiteTreeLinkTracking extends DataExtension {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper object for extracting information about links.
|
||||
*/
|
||||
class SiteTreeLinkTracking_Parser {
|
||||
|
||||
/**
|
||||
* Finds the links that are of interest for the link tracking automation. Checks for brokenness and attaches
|
||||
* extracted metadata so consumers can decide what to do with the DOM element (provided as DOMReference).
|
||||
*
|
||||
* @param SS_HTMLValue $htmlValue Object to parse the links from.
|
||||
* @return array Associative array containing found links with the following field layout:
|
||||
* Type: string, name of the link type
|
||||
* Target: any, a reference to the target object, depends on the Type
|
||||
* Anchor: string, anchor part of the link
|
||||
* DOMReference: DOMElement, reference to the link to apply changes.
|
||||
* Broken: boolean, a flag highlighting whether the link should be treated as broken.
|
||||
*/
|
||||
public function process(SS_HTMLValue $htmlValue) {
|
||||
$results = array();
|
||||
|
||||
$links = $htmlValue->getElementsByTagName('a');
|
||||
if(!$links) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
foreach($links as $link) {
|
||||
if (!$link->hasAttribute('href')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$href = Director::makeRelative($link->getAttribute('href'));
|
||||
|
||||
// Definitely broken links.
|
||||
if($href == '' || $href[0] == '/') {
|
||||
$results[] = array(
|
||||
'Type' => 'broken',
|
||||
'Target' => null,
|
||||
'Anchor' => null,
|
||||
'DOMReference' => $link,
|
||||
'Broken' => true
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Link to a page on this site.
|
||||
$matches = array();
|
||||
if(preg_match('/\[sitetree_link(?:\s*|%20|,)?id=(?<id>[0-9]+)\](#(?<anchor>.*))?/i', $href, $matches)) {
|
||||
$page = DataObject::get_by_id('SilverStripe\\CMS\\Model\\SiteTree', $matches['id']);
|
||||
$broken = false;
|
||||
|
||||
if (!$page) {
|
||||
// Page doesn't exist.
|
||||
$broken = true;
|
||||
} else if (!empty($matches['anchor'])) {
|
||||
$anchor = preg_quote($matches['anchor'], '/');
|
||||
|
||||
if (!preg_match("/(name|id)=\"{$anchor}\"/", $page->Content)) {
|
||||
// Broken anchor on the target page.
|
||||
$broken = true;
|
||||
}
|
||||
}
|
||||
|
||||
$results[] = array(
|
||||
'Type' => 'sitetree',
|
||||
'Target' => $matches['id'],
|
||||
'Anchor' => empty($matches['anchor']) ? null : $matches['anchor'],
|
||||
'DOMReference' => $link,
|
||||
'Broken' => $broken
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Link to a file on this site.
|
||||
$matches = array();
|
||||
if(preg_match('/\[file_link(?:\s*|%20|,)?id=(?<id>[0-9]+)/i', $href, $matches)) {
|
||||
$results[] = array(
|
||||
'Type' => 'file',
|
||||
'Target' => $matches['id'],
|
||||
'Anchor' => null,
|
||||
'DOMReference' => $link,
|
||||
'Broken' => !DataObject::get_by_id('File', $matches['id'])
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Local anchor.
|
||||
$matches = array();
|
||||
if(preg_match('/^#(.*)/i', $href, $matches)) {
|
||||
$anchor = preg_quote($matches[1], '#');
|
||||
$results[] = array(
|
||||
'Type' => 'localanchor',
|
||||
'Target' => null,
|
||||
'Anchor' => $matches[1],
|
||||
'DOMReference' => $link,
|
||||
'Broken' => !preg_match("#(name|id)=\"{$anchor}\"#", $htmlValue->getContent())
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Find all [image ] shortcodes (will be inline, not inside attributes)
|
||||
$content = $htmlValue->getContent();
|
||||
if(preg_match_all('/\[image([^\]]+)\bid=(["])?(?<id>\d+)\D/i', $content, $matches)) {
|
||||
foreach($matches['id'] as $id) {
|
||||
$results[] = array(
|
||||
'Type' => 'image',
|
||||
'Target' => (int)$id,
|
||||
'Anchor' => null,
|
||||
'DOMReference' => null,
|
||||
'Broken' => !DataObject::get_by_id('Image', (int)$id)
|
||||
);
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
}
|
||||
|
133
code/Model/SiteTreeLinkTracking_Parser.php
Normal file
133
code/Model/SiteTreeLinkTracking_Parser.php
Normal file
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Model;
|
||||
|
||||
use Director;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SS_HTMLValue;
|
||||
|
||||
/**
|
||||
* A helper object for extracting information about links.
|
||||
*/
|
||||
class SiteTreeLinkTracking_Parser
|
||||
{
|
||||
|
||||
/**
|
||||
* Finds the links that are of interest for the link tracking automation. Checks for brokenness and attaches
|
||||
* extracted metadata so consumers can decide what to do with the DOM element (provided as DOMReference).
|
||||
*
|
||||
* @param SS_HTMLValue $htmlValue Object to parse the links from.
|
||||
* @return array Associative array containing found links with the following field layout:
|
||||
* Type: string, name of the link type
|
||||
* Target: any, a reference to the target object, depends on the Type
|
||||
* Anchor: string, anchor part of the link
|
||||
* DOMReference: DOMElement, reference to the link to apply changes.
|
||||
* Broken: boolean, a flag highlighting whether the link should be treated as broken.
|
||||
*/
|
||||
public function process(SS_HTMLValue $htmlValue)
|
||||
{
|
||||
$results = array();
|
||||
|
||||
$links = $htmlValue->getElementsByTagName('a');
|
||||
if (!$links) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
foreach ($links as $link) {
|
||||
if (!$link->hasAttribute('href')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$href = Director::makeRelative($link->getAttribute('href'));
|
||||
|
||||
// Definitely broken links.
|
||||
if ($href == '' || $href[0] == '/') {
|
||||
$results[] = array(
|
||||
'Type' => 'broken',
|
||||
'Target' => null,
|
||||
'Anchor' => null,
|
||||
'DOMReference' => $link,
|
||||
'Broken' => true
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Link to a page on this site.
|
||||
$matches = array();
|
||||
if (preg_match('/\[sitetree_link(?:\s*|%20|,)?id=(?<id>[0-9]+)\](#(?<anchor>.*))?/i', $href, $matches)) {
|
||||
$page = DataObject::get_by_id('SilverStripe\\CMS\\Model\\SiteTree', $matches['id']);
|
||||
$broken = false;
|
||||
|
||||
if (!$page) {
|
||||
// Page doesn't exist.
|
||||
$broken = true;
|
||||
} else {
|
||||
if (!empty($matches['anchor'])) {
|
||||
$anchor = preg_quote($matches['anchor'], '/');
|
||||
|
||||
if (!preg_match("/(name|id)=\"{$anchor}\"/", $page->Content)) {
|
||||
// Broken anchor on the target page.
|
||||
$broken = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$results[] = array(
|
||||
'Type' => 'sitetree',
|
||||
'Target' => $matches['id'],
|
||||
'Anchor' => empty($matches['anchor']) ? null : $matches['anchor'],
|
||||
'DOMReference' => $link,
|
||||
'Broken' => $broken
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Link to a file on this site.
|
||||
$matches = array();
|
||||
if (preg_match('/\[file_link(?:\s*|%20|,)?id=(?<id>[0-9]+)/i', $href, $matches)) {
|
||||
$results[] = array(
|
||||
'Type' => 'file',
|
||||
'Target' => $matches['id'],
|
||||
'Anchor' => null,
|
||||
'DOMReference' => $link,
|
||||
'Broken' => !DataObject::get_by_id('File', $matches['id'])
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Local anchor.
|
||||
$matches = array();
|
||||
if (preg_match('/^#(.*)/i', $href, $matches)) {
|
||||
$anchor = preg_quote($matches[1], '#');
|
||||
$results[] = array(
|
||||
'Type' => 'localanchor',
|
||||
'Target' => null,
|
||||
'Anchor' => $matches[1],
|
||||
'DOMReference' => $link,
|
||||
'Broken' => !preg_match("#(name|id)=\"{$anchor}\"#", $htmlValue->getContent())
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Find all [image ] shortcodes (will be inline, not inside attributes)
|
||||
$content = $htmlValue->getContent();
|
||||
if (preg_match_all('/\[image([^\]]+)\bid=(["])?(?<id>\d+)\D/i', $content, $matches)) {
|
||||
foreach ($matches['id'] as $id) {
|
||||
$results[] = array(
|
||||
'Type' => 'image',
|
||||
'Target' => (int)$id,
|
||||
'Anchor' => null,
|
||||
'DOMReference' => null,
|
||||
'Broken' => !DataObject::get_by_id('Image', (int)$id)
|
||||
);
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
}
|
@ -455,106 +455,3 @@ class VirtualPage extends Page {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller for the virtual page.
|
||||
* @package cms
|
||||
*/
|
||||
class VirtualPage_Controller extends Page_Controller {
|
||||
|
||||
private static $allowed_actions = array(
|
||||
'loadcontentall' => 'ADMIN',
|
||||
);
|
||||
|
||||
/**
|
||||
* Backup of virtualised controller
|
||||
*
|
||||
* @var ContentController
|
||||
*/
|
||||
protected $virtualController = null;
|
||||
|
||||
/**
|
||||
* Get virtual controller
|
||||
*
|
||||
* @return ContentController
|
||||
*/
|
||||
protected function getVirtualisedController() {
|
||||
if($this->virtualController) {
|
||||
return $this->virtualController;
|
||||
}
|
||||
|
||||
// Validate virtualised model
|
||||
/** @var VirtualPage $page */
|
||||
$page = $this->data();
|
||||
$virtualisedPage = $page->CopyContentFrom();
|
||||
if (!$virtualisedPage || !$virtualisedPage->exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create controller using standard mechanism
|
||||
$this->virtualController = ModelAsController::controller_for($virtualisedPage);
|
||||
return $this->virtualController;
|
||||
}
|
||||
|
||||
public function getViewer($action) {
|
||||
$controller = $this->getVirtualisedController() ?: $this;
|
||||
return $controller->getViewer($action);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the virtualpage is loaded, check to see if the versions are the same
|
||||
* if not, reload the content.
|
||||
* NOTE: Virtual page must have a container object of subclass of sitetree.
|
||||
* We can't load the content without an ID or record to copy it from.
|
||||
*/
|
||||
public function init(){
|
||||
parent::init();
|
||||
$this->__call('init', array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Also check the original object's original controller for the method
|
||||
*
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMethod($method) {
|
||||
if(parent::hasMethod($method)) {
|
||||
return true;
|
||||
};
|
||||
|
||||
// Fallback
|
||||
$controller = $this->getVirtualisedController();
|
||||
return $controller && $controller->hasMethod($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass unrecognized method calls on to the original controller
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $args
|
||||
* @return mixed
|
||||
*
|
||||
* @throws Exception Any error other than a 'no method' error.
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
// Check if we can safely call this method before passing it back
|
||||
// to custom methods.
|
||||
if($this->getExtraMethodConfig($method)) {
|
||||
return parent::__call($method, $args);
|
||||
}
|
||||
|
||||
// Pass back to copied page
|
||||
$controller = $this->getVirtualisedController();
|
||||
if(!$controller) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ensure request/response data is available on virtual controller
|
||||
$controller->setRequest($this->getRequest());
|
||||
$controller->setResponse($this->getResponse());
|
||||
|
||||
return call_user_func_array(array($controller, $method), $args);
|
||||
}
|
||||
}
|
||||
|
115
code/Model/VirtualPage_Controller.php
Normal file
115
code/Model/VirtualPage_Controller.php
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
namespace SilverStripe\CMS\Model;
|
||||
|
||||
use Exception;
|
||||
use Page_Controller;
|
||||
use SilverStripe\CMS\Controllers\ContentController;
|
||||
use SilverStripe\CMS\Controllers\ModelAsController;
|
||||
|
||||
/**
|
||||
* Controller for the virtual page.
|
||||
* @package cms
|
||||
*/
|
||||
class VirtualPage_Controller extends Page_Controller
|
||||
{
|
||||
|
||||
private static $allowed_actions = array(
|
||||
'loadcontentall' => 'ADMIN',
|
||||
);
|
||||
|
||||
/**
|
||||
* Backup of virtualised controller
|
||||
*
|
||||
* @var ContentController
|
||||
*/
|
||||
protected $virtualController = null;
|
||||
|
||||
/**
|
||||
* Get virtual controller
|
||||
*
|
||||
* @return ContentController
|
||||
*/
|
||||
protected function getVirtualisedController()
|
||||
{
|
||||
if ($this->virtualController) {
|
||||
return $this->virtualController;
|
||||
}
|
||||
|
||||
// Validate virtualised model
|
||||
/** @var VirtualPage $page */
|
||||
$page = $this->data();
|
||||
$virtualisedPage = $page->CopyContentFrom();
|
||||
if (!$virtualisedPage || !$virtualisedPage->exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create controller using standard mechanism
|
||||
$this->virtualController = ModelAsController::controller_for($virtualisedPage);
|
||||
return $this->virtualController;
|
||||
}
|
||||
|
||||
public function getViewer($action)
|
||||
{
|
||||
$controller = $this->getVirtualisedController() ?: $this;
|
||||
return $controller->getViewer($action);
|
||||
}
|
||||
|
||||
/**
|
||||
* When the virtualpage is loaded, check to see if the versions are the same
|
||||
* if not, reload the content.
|
||||
* NOTE: Virtual page must have a container object of subclass of sitetree.
|
||||
* We can't load the content without an ID or record to copy it from.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$this->__call('init', array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Also check the original object's original controller for the method
|
||||
*
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMethod($method)
|
||||
{
|
||||
if (parent::hasMethod($method)) {
|
||||
return true;
|
||||
};
|
||||
|
||||
// Fallback
|
||||
$controller = $this->getVirtualisedController();
|
||||
return $controller && $controller->hasMethod($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass unrecognized method calls on to the original controller
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $args
|
||||
* @return mixed
|
||||
*
|
||||
* @throws Exception Any error other than a 'no method' error.
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
// Check if we can safely call this method before passing it back
|
||||
// to custom methods.
|
||||
if ($this->getExtraMethodConfig($method)) {
|
||||
return parent::__call($method, $args);
|
||||
}
|
||||
|
||||
// Pass back to copied page
|
||||
$controller = $this->getVirtualisedController();
|
||||
if (!$controller) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ensure request/response data is available on virtual controller
|
||||
$controller->setRequest($this->getRequest());
|
||||
$controller->setResponse($this->getResponse());
|
||||
|
||||
return call_user_func_array(array($controller, $method), $args);
|
||||
}
|
||||
}
|
@ -1,37 +1,40 @@
|
||||
{
|
||||
"name": "silverstripe/cms",
|
||||
"type": "silverstripe-module",
|
||||
"description": "The SilverStripe Content Management System",
|
||||
"homepage": "http://silverstripe.org",
|
||||
"license": "BSD-3-Clause",
|
||||
"keywords": ["silverstripe", "cms"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "SilverStripe",
|
||||
"homepage": "http://silverstripe.com"
|
||||
},
|
||||
{
|
||||
"name": "The SilverStripe Community",
|
||||
"homepage": "http://silverstripe.org"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5.0",
|
||||
"composer/installers": "*",
|
||||
"silverstripe/framework": "^4.0",
|
||||
"silverstripe/reports": "^4.0",
|
||||
"silverstripe/siteconfig": "^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/PHPUnit": "~4.8"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": ["tests/behat/"]
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
"name": "silverstripe/cms",
|
||||
"type": "silverstripe-module",
|
||||
"description": "The SilverStripe Content Management System",
|
||||
"homepage": "http://silverstripe.org",
|
||||
"license": "BSD-3-Clause",
|
||||
"keywords": ["silverstripe", "cms"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "SilverStripe",
|
||||
"homepage": "http://silverstripe.com"
|
||||
},
|
||||
{
|
||||
"name": "The SilverStripe Community",
|
||||
"homepage": "http://silverstripe.org"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5.0",
|
||||
"composer/installers": "*",
|
||||
"silverstripe/framework": "^4.0",
|
||||
"silverstripe/reports": "^4.0",
|
||||
"silverstripe/siteconfig": "^4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/PHPUnit": "~4.8"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SilverStripe\\CMS\\": "code/"
|
||||
},
|
||||
"classmap": ["tests/behat/"]
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div class="cms-content-header north">
|
||||
<div class="cms-content-header-info">
|
||||
<% with $Controller %>
|
||||
<% include CMSBreadcrumbs %>
|
||||
<% include SilverStripe\\Admin\\CMSBreadcrumbs %>
|
||||
<% end_with %>
|
||||
</div>
|
||||
|
@ -1,24 +1,24 @@
|
||||
<div id="pages-controller-cms-content" class="has-panel cms-content center cms-tabset $BaseCSSClasses" data-layout-type="border" data-pjax-fragment="Content" data-ignore-tab-state="true">
|
||||
|
||||
<div class="cms-content-header north">
|
||||
|
||||
|
||||
|
||||
<div class="cms-content-header-nav">
|
||||
<% include CMSBreadcrumbs %>
|
||||
<% include SilverStripe\\Admin\\CMSBreadcrumbs %>
|
||||
|
||||
<div class="cms-content-header-tabs">
|
||||
<ul class="cms-tabset-nav-primary">
|
||||
<li class="content-treeview<% if class == 'CMSPageEditController' %> ui-tabs-active<% end_if %>">
|
||||
<li class="content-treeview<% if $class == 'SilverStripe\\CMS\\Controllers\\CMSPageEditController' %> ui-tabs-active<% end_if %>">
|
||||
<a href="$LinkPageEdit" class="cms-panel-link" title="Form_EditForm" data-href="$LinkPageEdit">
|
||||
<% _t('CMSMain.TabContent', 'Content') %>
|
||||
</a>
|
||||
</li>
|
||||
<li class="content-listview<% if class == 'CMSPageSettingsController' %> ui-tabs-active<% end_if %>">
|
||||
<li class="content-listview<% if $class == 'SilverStripe\\CMS\\Controllers\\CMSPageSettingsController' %> ui-tabs-active<% end_if %>">
|
||||
<a href="$LinkPageSettings" class="cms-panel-link" title="Form_EditForm" data-href="$LinkPageSettings">
|
||||
<% _t('CMSMain.TabSettings', 'Settings') %>
|
||||
</a>
|
||||
</li>
|
||||
<li class="content-listview<% if class == 'CMSPageHistoryController' %> ui-tabs-active<% end_if %>">
|
||||
<li class="content-listview<% if $class == 'SilverStripe\\CMS\\Controllers\\CMSPageHistoryController' %> ui-tabs-active<% end_if %>">
|
||||
<a href="$LinkPageHistory" class="cms-panel-link" title="Form_EditForm" data-href="$LinkPageHistory">
|
||||
<% _t('CMSMain.TabHistory', 'History') %>
|
||||
</a>
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
<div class="cms-content-header-info">
|
||||
<div class="section-heading">
|
||||
<% include CMSSectionIcon %>
|
||||
<% include SilverStripe\\Admin\\CMSSectionIcon %>
|
||||
<span class="section-label"><a href="$LinkPages">{$MenuCurrentItem.Title}</a></span>
|
||||
</div>
|
||||
|
@ -28,7 +28,7 @@
|
||||
</a>
|
||||
<% end_if %>
|
||||
|
||||
<% include LeftAndMain_ViewModeSelector SelectID="preview-mode-dropdown-in-content" %>
|
||||
<% include SilverStripe\\Admin\\LeftAndMain_ViewModeSelector SelectID="preview-mode-dropdown-in-content" %>
|
||||
</div>
|
||||
<% end_if %>
|
||||
</div>
|
@ -2,7 +2,7 @@
|
||||
|
||||
<div class="cms-content-header north">
|
||||
<div class="cms-content-header-info">
|
||||
<% include CMSBreadcrumbs %>
|
||||
<% include SilverStripe\\Admin\\CMSBreadcrumbs %>
|
||||
</div>
|
||||
|
||||
<div class="cms-content-header-tabs">
|
@ -6,6 +6,8 @@ use SilverStripe\ORM\Versioning\Versioned;
|
||||
use SilverStripe\ORM\HiddenClass;
|
||||
use SilverStripe\CMS\Controllers\CMSMain;
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\Admin\CMSBatchActionHandler;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user