diff --git a/_config.php b/_config.php index e10207cd..0943fd88 100644 --- a/_config.php +++ b/_config.php @@ -25,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"); diff --git a/_config/adminpanels.yml b/_config/adminpanels.yml index e1fedb34..dd3abc74 100644 --- a/_config/adminpanels.yml +++ b/_config/adminpanels.yml @@ -1,2 +1,2 @@ -AdminRootController: +SilverStripe\Admin\AdminRootController: default_panel: 'SilverStripe\CMS\Controllers\CMSPagesController' diff --git a/_config/config.yml b/_config/config.yml index 0d85794f..af7be872 100644 --- a/_config/config.yml +++ b/_config/config.yml @@ -1,4 +1,4 @@ -LeftAndMain: +SilverStripe\Admin\LeftAndMain: extensions: - SilverStripe\CMS\Controllers\LeftAndMainPageIconsExtension Controller: diff --git a/_config/legacy.yml b/_config/legacy.yml index ed183c24..e1b262e2 100644 --- a/_config/legacy.yml +++ b/_config/legacy.yml @@ -3,4 +3,4 @@ Name: cmslegacy --- SilverStripe\ORM\DatabaseAdmin: classname_value_remapping: - SiteTree: 'SilverStripe\CMS\Model\SiteTree' + SiteTree: 'SilverStripe\CMS\Model\SiteTree' diff --git a/code/BatchActions/CMSBatchAction_Archive.php b/code/BatchActions/CMSBatchAction_Archive.php new file mode 100644 index 00000000..a9a5a6f1 --- /dev/null +++ b/code/BatchActions/CMSBatchAction_Archive.php @@ -0,0 +1,34 @@ +batchaction($pages, 'doArchive', + _t('CMSBatchActions.ARCHIVED_PAGES', 'Archived %d pages') + ); + } + + public function applicablePages($ids) + { + return $this->applicablePagesHelper($ids, 'canArchive', true, true); + } + +} diff --git a/code/BatchActions/CMSBatchAction_Delete.php b/code/BatchActions/CMSBatchAction_Delete.php new file mode 100644 index 00000000..ac70fb4a --- /dev/null +++ b/code/BatchActions/CMSBatchAction_Delete.php @@ -0,0 +1,55 @@ +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); + } +} diff --git a/code/BatchActions/CMSBatchAction_Publish.php b/code/BatchActions/CMSBatchAction_Publish.php new file mode 100644 index 00000000..1912b13f --- /dev/null +++ b/code/BatchActions/CMSBatchAction_Publish.php @@ -0,0 +1,32 @@ +batchaction($pages, 'publishRecursive', + _t('CMSBatchActions.PUBLISHED_PAGES', 'Published %d pages, %d failures') + ); + } + + public function applicablePages($ids) + { + return $this->applicablePagesHelper($ids, 'canPublish', true, false); + } +} diff --git a/code/BatchActions/CMSBatchAction_Restore.php b/code/BatchActions/CMSBatchAction_Restore.php new file mode 100644 index 00000000..d69b78e2 --- /dev/null +++ b/code/BatchActions/CMSBatchAction_Restore.php @@ -0,0 +1,62 @@ +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)); + } +} diff --git a/code/BatchActions/CMSBatchAction_Unpublish.php b/code/BatchActions/CMSBatchAction_Unpublish.php new file mode 100644 index 00000000..8f4c043a --- /dev/null +++ b/code/BatchActions/CMSBatchAction_Unpublish.php @@ -0,0 +1,32 @@ +batchaction($pages, 'doUnpublish', + _t('CMSBatchActions.UNPUBLISHED_PAGES', 'Unpublished %d pages') + ); + } + + public function applicablePages($ids) + { + return $this->applicablePagesHelper($ids, 'canUnpublish', false, true); + } +} diff --git a/code/BatchActions/CMSBatchActions.php b/code/BatchActions/CMSBatchActions.php deleted file mode 100644 index 6424144e..00000000 --- a/code/BatchActions/CMSBatchActions.php +++ /dev/null @@ -1,175 +0,0 @@ -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); - } -} diff --git a/code/Controllers/AssetAdmin.php b/code/Controllers/AssetAdmin.php index 08ad66b7..4dbde464 100644 --- a/code/Controllers/AssetAdmin.php +++ b/code/Controllers/AssetAdmin.php @@ -2,16 +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 SilverStripe\Admin\CMSBatchAction; +use SilverStripe\Admin\CMSBatchActionHandler; +use SilverStripe\Admin\LeftAndMain; use Session; use Requirements; -use CMSBatchActionHandler; use File; use DateField; use HiddenField; @@ -28,6 +34,7 @@ use GridFieldLevelup; use GridField; use Controller; use LiteralField; +use SS_HTTPRequest; use TabSet; use Tab; use CompositeField; @@ -49,10 +56,6 @@ use Folder; use Injector; use Director; use ArrayData; -use CMSBatchAction; -use SilverStripe\Admin\CMSBatchActionHandler; -use SilverStripe\Admin\LeftAndMain; -use SilverStripe\Admin\CMSBatchAction; @@ -97,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) */ @@ -139,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, @@ -219,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' => '', @@ -256,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) { @@ -373,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() @@ -413,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())); } @@ -529,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'); @@ -539,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']) diff --git a/code/Controllers/CMSMain.php b/code/Controllers/CMSMain.php index fbd1d822..e370b881 100644 --- a/code/Controllers/CMSMain.php +++ b/code/Controllers/CMSMain.php @@ -2,8 +2,9 @@ namespace SilverStripe\CMS\Controllers; +use FormField; +use Injector; use ResetFormAction; -use SilverStripe\Admin\CMSPreviewable; use SilverStripe\ORM\FieldType\DBHTMLText; use SilverStripe\ORM\SS_List; use SilverStripe\ORM\Versioning\Versioned; @@ -17,36 +18,33 @@ use SilverStripe\Security\Security; use SilverStripe\Security\SecurityToken; use SilverStripe\Security\Permission; use SilverStripe\Security\PermissionProvider; -use SilverStripe\Admin\CMSBatchActionHandler; use SilverStripe\Admin\AdminRootController; -use SilverStripe\Admin\AddToCampaignHandler; 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; @@ -59,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. @@ -79,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 { @@ -100,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. * @@ -176,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); } @@ -203,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) { @@ -230,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" ); @@ -404,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( @@ -422,6 +420,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr ); // Use