mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
Split code into class-per-file
Add psr-4 directive in composer.json
This commit is contained in:
parent
041d12129a
commit
dab2a7ac9d
@ -697,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);
|
||||||
|
}
|
||||||
|
}
|
@ -240,220 +240,3 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
|
|||||||
return $ids;
|
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,7 +17,6 @@ use SilverStripe\Security\Member;
|
|||||||
use SilverStripe\Security\Permission;
|
use SilverStripe\Security\Permission;
|
||||||
use Controller;
|
use Controller;
|
||||||
use Page;
|
use Page;
|
||||||
|
|
||||||
use SiteConfig;
|
use SiteConfig;
|
||||||
use SS_HTTPRequest;
|
use SS_HTTPRequest;
|
||||||
use Translatable;
|
use Translatable;
|
||||||
|
@ -11,7 +11,6 @@ use SS_HTTPResponse;
|
|||||||
use Controller;
|
use Controller;
|
||||||
use SS_HTTPResponse_Exception;
|
use SS_HTTPResponse_Exception;
|
||||||
|
|
||||||
|
|
||||||
class OldPageRedirector extends Extension {
|
class OldPageRedirector extends Extension {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,7 +14,6 @@ use SS_HTTPRequest;
|
|||||||
use ClassInfo;
|
use ClassInfo;
|
||||||
use Director;
|
use Director;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @package cms
|
* @package cms
|
||||||
* @subpackage control
|
* @subpackage control
|
||||||
|
@ -4,18 +4,11 @@ namespace SilverStripe\CMS\Controllers;
|
|||||||
|
|
||||||
use SilverStripe\ORM\ArrayList;
|
use SilverStripe\ORM\ArrayList;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
|
||||||
use SilverStripe\ORM\SS_List;
|
use SilverStripe\ORM\SS_List;
|
||||||
use SilverStripe\ORM\Versioning\Versioned;
|
|
||||||
use SilverStripe\ORM\FieldType\DBField;
|
|
||||||
use SilverStripe\Security\Member;
|
|
||||||
use ViewableData;
|
use ViewableData;
|
||||||
use ClassInfo;
|
use ClassInfo;
|
||||||
use Controller;
|
|
||||||
use SilverStripe\Admin\CMSPreviewable;
|
use SilverStripe\Admin\CMSPreviewable;
|
||||||
use SilverStripe\Admin\LeftAndMain;
|
|
||||||
use SiteTreeFutureState;
|
use SiteTreeFutureState;
|
||||||
use SilverStripe\CMS\Model\RedirectorPage;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,310 +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()) {
|
|
||||||
/** @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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
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;
|
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();
|
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>";
|
||||||
|
}
|
||||||
|
}
|
@ -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",
|
"name": "silverstripe/cms",
|
||||||
"type": "silverstripe-module",
|
"type": "silverstripe-module",
|
||||||
"description": "The SilverStripe Content Management System",
|
"description": "The SilverStripe Content Management System",
|
||||||
"homepage": "http://silverstripe.org",
|
"homepage": "http://silverstripe.org",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"keywords": ["silverstripe", "cms"],
|
"keywords": ["silverstripe", "cms"],
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "SilverStripe",
|
"name": "SilverStripe",
|
||||||
"homepage": "http://silverstripe.com"
|
"homepage": "http://silverstripe.com"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "The SilverStripe Community",
|
"name": "The SilverStripe Community",
|
||||||
"homepage": "http://silverstripe.org"
|
"homepage": "http://silverstripe.org"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.5.0",
|
"php": ">=5.5.0",
|
||||||
"composer/installers": "*",
|
"composer/installers": "*",
|
||||||
"silverstripe/framework": "^4.0",
|
"silverstripe/framework": "^4.0",
|
||||||
"silverstripe/reports": "^4.0",
|
"silverstripe/reports": "^4.0",
|
||||||
"silverstripe/siteconfig": "^4.0"
|
"silverstripe/siteconfig": "^4.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/PHPUnit": "~4.8"
|
"phpunit/PHPUnit": "~4.8"
|
||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "4.0.x-dev"
|
"dev-master": "4.0.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"classmap": ["tests/behat/"]
|
"psr-4": {
|
||||||
},
|
"SilverStripe\\CMS\\": "code/"
|
||||||
"minimum-stability": "dev"
|
},
|
||||||
|
"classmap": ["tests/behat/"]
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user