Cleanup trailing whitespace

This commit is contained in:
Damian Mooyman 2016-03-09 09:50:55 +13:00
parent 08202f018f
commit 849cd898a4
51 changed files with 1016 additions and 1016 deletions

View File

@ -50,7 +50,7 @@ class CMSBatchAction_Unpublish extends CMSBatchAction {
* @subpackage batchaction
*/
class CMSBatchAction_Archive extends CMSBatchAction {
public function getActionTitle() {
return _t('CMSBatchActions.ARCHIVE', 'Archive');
}
@ -73,7 +73,7 @@ class CMSBatchAction_Archive extends CMSBatchAction {
* @subpackage batchaction
*/
class CMSBatchAction_Restore extends CMSBatchAction {
public function getActionTitle() {
return _t('CMSBatchActions.RESTORE', 'Restore');
}
@ -107,7 +107,7 @@ class CMSBatchAction_Restore extends CMSBatchAction {
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));
@ -133,10 +133,10 @@ class CMSBatchAction_Delete extends CMSBatchAction {
'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;
@ -186,7 +186,7 @@ class CMSBatchAction_DeleteFromLive extends CMSBatchAction {
/** @var SiteTree $page */
foreach($pages as $page) {
$id = $page->ID;
// Perform the action
if($page->canUnpublish()) {
$page->doUnpublish();

View File

@ -254,7 +254,7 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
new HiddenField('ID'),
$gridField
));
// Tree view
$fields->addFieldsToTab('Root.TreeView', array(
clone $actionsComposite,

View File

@ -50,7 +50,7 @@ class CMSPageAddController extends CMSPageEditController {
new SelectionGroup_Item(
'child',
$parentField = new TreeDropdownField(
"ParentID",
"ParentID",
"",
'SiteTree',
'ID',
@ -61,8 +61,8 @@ class CMSPageAddController extends CMSPageEditController {
)
),
$typeField = new OptionsetField(
"PageType",
sprintf($numericLabelTmpl, 2, _t('CMSMain.ChoosePageType', 'Choose page type')),
"PageType",
sprintf($numericLabelTmpl, 2, _t('CMSMain.ChoosePageType', 'Choose page type')),
$pageTypes,
'Page'
),
@ -71,7 +71,7 @@ class CMSPageAddController extends CMSPageEditController {
sprintf(
'<p class="message notice message-restricted">%s</p>',
_t(
'CMSMain.AddPageRestriction',
'CMSMain.AddPageRestriction',
'Note: Some page types are not allowed for this selection'
)
)
@ -79,7 +79,7 @@ class CMSPageAddController extends CMSPageEditController {
);
$parentField->setSearchFunction(function ($sourceObject, $labelField, $search) {
return DataObject::get(
$sourceObject,
$sourceObject,
sprintf(
"\"MenuTitle\" LIKE '%%%s%%' OR \"Title\" LIKE '%%%s%%'",
Convert::raw2sql($search),
@ -88,10 +88,10 @@ class CMSPageAddController extends CMSPageEditController {
);
});
// TODO Re-enable search once it allows for HTML title display,
// TODO Re-enable search once it allows for HTML title display,
// see http://open.silverstripe.org/ticket/7455
// $parentField->setShowSearch(true);
$parentModeField->addExtraClass('parent-mode');
// CMSMain->currentPageID() automatically sets the homepage,
@ -102,7 +102,7 @@ class CMSPageAddController extends CMSPageEditController {
} else {
$parentModeField->setValue('top');
}
$actions = new FieldList(
FormAction::create("doAdd", _t('CMSMain.Create',"Create"))
->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept')
@ -111,7 +111,7 @@ class CMSPageAddController extends CMSPageEditController {
->addExtraClass('ss-ui-action-destructive ss-ui-action-cancel')
->setUseButtonTag(true)
);
$this->extend('updatePageOptions', $fields);
$negotiator = $this->getResponseNegotiator();
@ -152,7 +152,7 @@ class CMSPageAddController extends CMSPageEditController {
if(is_numeric($parentID) && $parentID > 0) $parentObj = DataObject::get_by_id("SiteTree", $parentID);
else $parentObj = null;
if(!$parentObj || !$parentObj->ID) $parentID = 0;
if(!singleton($className)->canCreate(Member::currentUser(), array('Parent' => $parentObj))) {
@ -175,11 +175,11 @@ class CMSPageAddController extends CMSPageEditController {
$editController->setCurrentPageID($record->ID);
Session::set(
"FormInfo.Form_EditForm.formError.message",
"FormInfo.Form_EditForm.formError.message",
_t('CMSMain.PageAdded', 'Successfully created page')
);
Session::set("FormInfo.Form_EditForm.formError.type", 'good');
return $this->redirect(Controller::join_links(singleton('CMSPageEditController')->Link('show'), $record->ID));
}

View File

@ -12,14 +12,14 @@ class CMSPageHistoryController extends CMSMain {
private static $menu_title = 'History';
private static $required_permission_codes = 'CMS_ACCESS_CMSMain';
private static $session_namespace = 'CMSMain';
private static $allowed_actions = array(
'VersionsForm',
'CompareVersionsForm',
'show',
'compare'
);
private static $url_handlers = array(
'$Action/$ID/$VersionID/$OtherVersionID' => 'handleAction'
);
@ -37,14 +37,14 @@ class CMSPageHistoryController extends CMSMain {
});
return $negotiator;
}
/**
* @param SS_HTTPRequest $request
* @return array
*/
public function show($request) {
$form = $this->ShowVersionForm($request->param('VersionID'));
$negotiator = $this->getResponseNegotiator();
$controller = $this;
$negotiator->setCallback('CurrentForm', function() use(&$controller, &$form) {
@ -56,14 +56,14 @@ class CMSPageHistoryController extends CMSMain {
return $negotiator->respond($request);
}
/**
* @param SS_HTTPRequest $request
* @return array
*/
public function compare($request) {
$form = $this->CompareVersionsForm(
$request->param('VersionID'),
$request->param('VersionID'),
$request->param('OtherVersionID')
);
@ -88,13 +88,13 @@ class CMSPageHistoryController extends CMSMain {
return false;
}
}
/**
* Returns the read only version of the edit form. Detaches all {@link FormAction}
* Returns the read only version of the edit form. Detaches all {@link FormAction}
* instances attached since only action relates to revert.
*
* Permission checking is done at the {@link CMSMain::getEditForm()} level.
*
*
* @param int $id ID of the record to show
* @param array $fields optional
* @param int $versionID
@ -104,10 +104,10 @@ class CMSPageHistoryController extends CMSMain {
*/
public function getEditForm($id = null, $fields = null, $versionID = null, $compareID = null) {
if(!$id) $id = $this->currentPageID();
$record = $this->getRecord($id, $versionID);
$versionID = ($record) ? $record->Version : $versionID;
$form = parent::getEditForm($record, ($record) ? $record->getCMSFields() : null);
// Respect permission failures from parent implementation
if(!($form instanceof Form)) return $form;
@ -118,14 +118,14 @@ class CMSPageHistoryController extends CMSMain {
$form->setActions(new FieldList(
$revert = FormAction::create('doRollback', _t('CMSPageHistoryController.REVERTTOTHISVERSION', 'Revert to this version'))->setUseButtonTag(true)
));
$fields = $form->Fields();
$fields->removeByName("Status");
$fields->push(new HiddenField("ID"));
$fields->push(new HiddenField("Version"));
$fields = $fields->makeReadonly();
$fields = $fields->makeReadonly();
if($compareID) {
$link = Controller::join_links(
$this->Link('show'),
@ -133,7 +133,7 @@ class CMSPageHistoryController extends CMSMain {
);
$view = _t('CMSPageHistoryController.VIEW',"view");
$message = _t(
'CMSPageHistoryController.COMPARINGVERSION',
"Comparing versions {version1} and {version2}.",
@ -142,7 +142,7 @@ class CMSPageHistoryController extends CMSMain {
'version2' => sprintf('%s (<a href="%s">%s</a>)', $compareID, Controller::join_links($link, $compareID), $view)
)
);
$revert->setReadonly(true);
} else {
if($record->isLatestVersion()) {
@ -155,8 +155,8 @@ class CMSPageHistoryController extends CMSMain {
);
}
}
$fields->addFieldToTab('Root.Main',
$fields->addFieldToTab('Root.Main',
new LiteralField('CurrentlyViewingMessage', $this->customise(array(
'Content' => $message,
'Classes' => 'notice'
@ -169,23 +169,23 @@ class CMSPageHistoryController extends CMSMain {
"ID" => $id,
"Version" => $versionID,
));
if(($record && $record->isLatestVersion())) {
$revert->setReadonly(true);
}
$form->removeExtraClass('cms-content');
return $form;
}
/**
* Version select form. Main interface between selecting versions to view
* Version select form. Main interface between selecting versions to view
* and comparing multiple versions.
*
*
* Because we can reload the page directly to a compare view (history/compare/1/2/3)
* this form has to adapt to those parameters as well.
* this form has to adapt to those parameters as well.
*
* @return Form
*/
@ -197,7 +197,7 @@ class CMSPageHistoryController extends CMSMain {
$action = $this->getRequest()->param('Action');
$versionID = $this->getRequest()->param('VersionID');
$otherVersionID = $this->getRequest()->param('OtherVersionID');
$showUnpublishedChecked = 0;
$compareModeChecked = ($action == "compare");
@ -208,19 +208,19 @@ class CMSPageHistoryController extends CMSMain {
if($versions) {
foreach($versions as $k => $version) {
$active = false;
if($version->Version == $versionID || $version->Version == $otherVersionID) {
$active = true;
if(!$version->WasPublished) $showUnpublishedChecked = 1;
}
$version->Active = ($active);
}
}
$vd = new ViewableData();
$versionsHtml = $vd->customise(array(
'Versions' => $versions
))->renderWith('CMSPageHistoryController_versions');
@ -246,7 +246,7 @@ class CMSPageHistoryController extends CMSMain {
'doCompare', _t('CMSPageHistoryController.COMPAREVERSIONS','Compare Versions')
),
new FormAction(
'doShowVersion', _t('CMSPageHistoryController.SHOWVERSION','Show Version')
'doShowVersion', _t('CMSPageHistoryController.SHOWVERSION','Show Version')
)
);
@ -263,15 +263,15 @@ class CMSPageHistoryController extends CMSMain {
$form->loadDataFrom($this->getRequest()->requestVars());
$hiddenID->setValue($id);
$form->unsetValidator();
$form
->addExtraClass('cms-versions-form') // placeholder, necessary for $.metadata() to work
->setAttribute('data-link-tmpl-compare', Controller::join_links($this->Link('compare'), '%s', '%s', '%s'))
->setAttribute('data-link-tmpl-show', Controller::join_links($this->Link('show'), '%s', '%s'));
return $form;
}
/**
* Process the {@link VersionsForm} compare function between two pages.
*
@ -283,7 +283,7 @@ class CMSPageHistoryController extends CMSMain {
public function doCompare($data, $form) {
$versions = $data['Versions'];
if(count($versions) < 2) return null;
$id = $this->currentPageID();
$version1 = array_shift($versions);
$version2 = array_shift($versions);
@ -295,11 +295,11 @@ class CMSPageHistoryController extends CMSMain {
return $this->customise(array(
"EditForm" => $form
))->renderWith(array(
$this->class . '_EditForm',
$this->class . '_EditForm',
'LeftAndMain_Content'
));
}
// non javascript, redirect the user to the page
$this->redirect(Controller::join_links(
$this->Link('compare'),
@ -316,21 +316,21 @@ class CMSPageHistoryController extends CMSMain {
* @param Form
*
* @return html
*/
*/
public function doShowVersion($data, $form) {
$versionID = null;
if(isset($data['Versions']) && is_array($data['Versions'])) {
if(isset($data['Versions']) && is_array($data['Versions'])) {
$versionID = array_shift($data['Versions']);
}
if(!$versionID) return;
if($request->isAjax()) {
return $this->customise(array(
"EditForm" => $this->ShowVersionForm($versionID)
))->renderWith(array(
$this->class . '_EditForm',
$this->class . '_EditForm',
'LeftAndMain_Content'
));
}
@ -354,7 +354,7 @@ class CMSPageHistoryController extends CMSMain {
return $form;
}
/**
* @param int $versionID
* @param int $otherVersionID
@ -370,10 +370,10 @@ class CMSPageHistoryController extends CMSMain {
}
if(!$toVersion || !$fromVersion) return false;
$id = $this->currentPageID();
$page = DataObject::get_by_id("SiteTree", $id);
if($page && !$page->canView()) {
return Security::permissionFailure($this);
}
@ -382,11 +382,11 @@ class CMSPageHistoryController extends CMSMain {
$fromVersionRecord = Versioned::get_version('SiteTree', $id, $fromVersion);
$toVersionRecord = Versioned::get_version('SiteTree', $id, $toVersion);
if(!$fromVersionRecord) {
user_error("Can't find version $fromVersion of page $id", E_USER_ERROR);
}
if(!$toVersionRecord) {
user_error("Can't find version $toVersion of page $id", E_USER_ERROR);
}
@ -395,23 +395,23 @@ class CMSPageHistoryController extends CMSMain {
$form = $this->getEditForm($id, null, null, true);
$form->setActions(new FieldList());
$form->addExtraClass('compare');
// Comparison views shouldn't be editable.
// Its important to convert fields *before* loading data,
// as the comparison output is HTML and not valid values for the various field types
$readonlyFields = $form->Fields()->makeReadonly();
$form->setFields($readonlyFields);
$form->loadDataFrom($record);
$form->loadDataFrom(array(
"ID" => $id,
"Version" => $fromVersion,
));
foreach($form->Fields()->dataFields() as $field) {
$field->dontEscape = true;
}
return $form;
}
}

View File

@ -1,7 +1,7 @@
<?php
/**
* Base class for filtering the subtree for certain node statuses.
*
*
* The simplest way of building a CMSSiteTreeFilter is to create a pagesToBeShown() method that
* returns an Iterator of maps, each entry containing the 'ID' and 'ParentID' of the pages to be
* included in the tree. The result of a DB::query() can then be returned directly.
@ -9,7 +9,7 @@
* If you wish to make a more complex tree, you can overload includeInTree($page) to return true/
* false depending on whether the given page should be included. Note that you will need to include
* parent helper pages yourself.
*
*
* @package cms
* @subpackage content
*/
@ -20,10 +20,10 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
* Caution: Unescaped data.
*/
protected $params = array();
/**
* List of filtered items and all their parents
*
*
* @var array
*/
protected $_cache_ids = null;
@ -37,14 +37,14 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
* @var array
*/
protected $_cache_highlight_ids = null;
/**
* @var Array
*/
protected $_cache_expanded = array();
/**
* @var string
* @var string
*/
protected $childrenMethod = null;
@ -55,38 +55,38 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
/**
* Returns a sorted array of all implementators of CMSSiteTreeFilter, suitable for use in a dropdown.
*
*
* @return array
*/
public static function get_all_filters() {
// get all filter instances
$filters = ClassInfo::subclassesFor('CMSSiteTreeFilter');
// remove abstract CMSSiteTreeFilter class
array_shift($filters);
// add filters to map
$filterMap = array();
foreach($filters as $filter) {
$filterMap[$filter] = $filter::title();
}
// Ensure that 'all pages' filter is on top position and everything else is sorted alphabetically
uasort($filterMap, function($a, $b) {
return ($a === CMSSiteTreeFilter_Search::title())
? -1
: strcasecmp($a, $b);
});
return $filterMap;
}
public function __construct($params = null) {
if($params) $this->params = $params;
parent::__construct();
}
public function getChildrenMethod() {
return $this->childrenMethod;
}
@ -120,7 +120,7 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
public function pagesIncluded() {
return $this->mapIDs($this->getFilteredPages());
}
/**
* Populate the IDs of the pages returned by pagesIncluded(), also including
* the necessary parent helper pages.
@ -129,10 +129,10 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
$parents = array();
$this->_cache_ids = array();
$this->_cache_highlight_ids = array();
if($pages = $this->pagesIncluded()) {
// And keep a record of parents we don't need to get
// And keep a record of parents we don't need to get
// parents of themselves, as well as IDs to mark
foreach($pages as $pageArr) {
$parents[$pageArr['ParentID']] = true;
@ -152,7 +152,7 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
}
}
}
public function isPageIncluded($page) {
if($this->_cache_ids === NULL) {
$this->populateIDs();
@ -160,10 +160,10 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
return !empty($this->_cache_ids[$page->ID]);
}
/**
* Applies the default filters to a specified DataList of pages
*
*
* @param DataList $query Unfiltered query
* @return DataList Filtered query
*/
@ -208,10 +208,10 @@ abstract class CMSSiteTreeFilter extends Object implements LeftAndMain_SearchFil
}
return $query;
}
/**
* Maps a list of pages to an array of associative arrays with ID and ParentID keys
*
*
* @param DataList $pages
* @return array
*/
@ -272,7 +272,7 @@ class CMSSiteTreeFilter_PublishedPages extends CMSSiteTreeFilter {
* 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
*/
@ -287,11 +287,11 @@ class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter {
* @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('SiteTree');
$pages = $this->applyDefaultFilters($pages);
@ -301,40 +301,40 @@ class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter {
/**
* 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('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() {
@ -345,24 +345,24 @@ class CMSSiteTreeFilter_StatusRemovedFromDraftPages extends CMSSiteTreeFilter {
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
*/
@ -374,12 +374,12 @@ class CMSSiteTreeFilter_StatusDraftPages extends CMSSiteTreeFilter {
return (!$page->getIsDeletedFromStage() && $page->getIsAddedToStage());
});
return $pages;
}
}
}
/**
* Filters pages which have a status "Deleted".
*
*
* @package cms
* @subpackage content
*/
@ -394,14 +394,14 @@ class CMSSiteTreeFilter_StatusDeletedPages extends CMSSiteTreeFilter {
* @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
*/
@ -414,7 +414,7 @@ class CMSSiteTreeFilter_StatusDeletedPages extends CMSSiteTreeFilter {
return $page->getIsDeletedFromStage() && !$page->getExistsOnLive();
});
return $pages;
}
}
}
/**
@ -426,11 +426,11 @@ 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() {

View File

@ -12,7 +12,7 @@
*
* Subclasses of ContentController are generally instantiated by ModelAsController; this will create
* a controller based on the URLSegment action variable, by looking in the SiteTree table.
*
*
* @todo Can this be used for anything other than SiteTree controllers?
*
* @package cms
@ -29,7 +29,7 @@ class ContentController extends Controller {
'deleteinstallfiles', // secured through custom code
'LoginForm'
);
/**
* The ContentController will take the URLSegment parameter from the URL and use that to look
* up a SiteTree record.
@ -41,14 +41,14 @@ class ContentController extends Controller {
$dataRecord->URLSegment = get_class($this);
$dataRecord->ID = -1;
}
$this->dataRecord = $dataRecord;
parent::__construct();
$this->setFailover($this->dataRecord);
}
/**
* Return the link to this controller, but force the expanded link to be returned so that form methods and
* similar will function properly.
@ -59,10 +59,10 @@ class ContentController extends Controller {
public function Link($action = null) {
return $this->data()->Link(($action ? $action : true));
}
//----------------------------------------------------------------------------------//
// These flexible data methods remove the need for custom code to do simple stuff
/**
* Return the children of a given page. The parent reference can either be a page link or an ID.
*
@ -71,14 +71,14 @@ class ContentController extends Controller {
*/
public function ChildrenOf($parentRef) {
$parent = SiteTree::get_by_link($parentRef);
if(!$parent && is_numeric($parentRef)) {
$parent = DataObject::get_by_id('SiteTree', $parentRef);
}
if($parent) return $parent->Children();
}
/**
* @param string $link
* @return SiteTree
@ -89,10 +89,10 @@ class ContentController extends Controller {
public function init() {
parent::init();
// If we've accessed the homepage as /home/, then we should redirect to /.
if($this->dataRecord && $this->dataRecord instanceof SiteTree
&& RootURLController::should_be_on_root($this->dataRecord) && (!isset($this->urlParams['Action']) || !$this->urlParams['Action'] )
&& RootURLController::should_be_on_root($this->dataRecord) && (!isset($this->urlParams['Action']) || !$this->urlParams['Action'] )
&& !$_POST && !$_FILES && !$this->redirectedTo() ) {
$getVars = $_GET;
unset($getVars['url']);
@ -101,7 +101,7 @@ class ContentController extends Controller {
$this->redirect($url, 301);
return;
}
if($this->dataRecord) $this->dataRecord->extend('contentcontrollerInit', $this);
else singleton('SiteTree')->extend('contentcontrollerInit', $this);
@ -117,7 +117,7 @@ class ContentController extends Controller {
Config::inst()->update('SSViewer', 'theme', $config->Theme);
}
}
/**
* This acts the same as {@link Controller::handleRequest()}, but if an action cannot be found this will attempt to
* fall over to a child controller in order to provide functionality for nested URLs.
@ -131,7 +131,7 @@ class ContentController extends Controller {
$child = null;
$action = $request->param('Action');
$this->setDataModel($model);
// If nested URLs are enabled, and there is no action handler for the current request then attempt to pass
// control to a child controller. This allows for the creation of chains of controllers which correspond to a
// nested URL.
@ -145,12 +145,12 @@ class ContentController extends Controller {
))->first();
if(class_exists('Translatable')) Translatable::enable_locale_filter();
}
// we found a page with this URLSegment.
if($child) {
$request->shiftAllParams();
$request->shift();
$response = ModelAsController::controller_for($child)->handleRequest($request, $model);
} else {
// If a specific locale is requested, and it doesn't match the page found by URLSegment,
@ -167,7 +167,7 @@ class ContentController extends Controller {
}
}
}
Director::set_current_page($this->data());
try {
@ -176,16 +176,16 @@ class ContentController extends Controller {
Director::set_current_page(null);
} catch(SS_HTTPResponse_Exception $e) {
$this->popCurrent();
Director::set_current_page(null);
throw $e;
}
}
return $response;
}
/**
* Get the project name
*
@ -195,7 +195,7 @@ class ContentController extends Controller {
global $project;
return $project;
}
/**
* Returns the associated database record
*/
@ -220,13 +220,13 @@ class ContentController extends Controller {
} else {
$parent = $this->data();
$stack = array($parent);
if($parent) {
while($parent = $parent->Parent) {
array_unshift($stack, $parent);
}
}
if(isset($stack[$level-2])) $result = $stack[$level-2]->Children();
}
@ -264,12 +264,12 @@ class ContentController extends Controller {
$items = '';
$message = '';
if(Director::isDev() || Permission::check('CMS_ACCESS_CMSMain') || Permission::check('VIEW_DRAFT_CONTENT')) {
if(Director::isDev() || Permission::check('CMS_ACCESS_CMSMain') || Permission::check('VIEW_DRAFT_CONTENT')) {
if($this->dataRecord) {
Requirements::css(CMS_DIR . '/css/SilverStripeNavigator.css');
Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js');
Requirements::javascript(CMS_DIR . '/javascript/dist/SilverStripeNavigator.js');
$return = $nav = SilverStripeNavigator::get_for_record($this->dataRecord);
$items = $return['items'];
$message = $return['message'];
@ -288,7 +288,7 @@ class ContentController extends Controller {
);
}
$viewPageIn = _t('ContentController.VIEWPAGEIN', 'View Page in:');
return <<<HTML
<div id="SilverStripeNavigator">
<div class="holder">
@ -297,7 +297,7 @@ class ContentController extends Controller {
</div>
<div id="switchView" class="bottomTabs">
$viewPageIn
$viewPageIn
$items
</div>
</div>
@ -315,7 +315,7 @@ HTML;
}
}
}
public function SiteConfig() {
if(method_exists($this->dataRecord, 'getSiteConfig')) {
return $this->dataRecord->getSiteConfig();
@ -329,10 +329,10 @@ HTML;
* Inspects the associated {@link dataRecord} for a {@link SiteTree->Locale} value if present,
* and falls back to {@link Translatable::get_current_locale()} or {@link i18n::default_locale()},
* depending if Translatable is enabled.
*
*
* Suitable for insertion into lang= and xml:lang=
* attributes in HTML or XHTML output.
*
*
* @return string
*/
public function ContentLocale() {
@ -343,9 +343,9 @@ HTML;
} else {
$locale = i18n::get_locale();
}
return i18n::convert_rfc1766($locale);
}
}
/**
@ -390,20 +390,20 @@ HTML;
if (!file_exists(BASE_PATH . '/install.php')) {
$this->httpError(410);
}
// TODO Allow this to work when allow_url_fopen=0
if(isset($_SESSION['StatsID']) && $_SESSION['StatsID']) {
$url = 'http://ss2stat.silverstripe.com/Installation/installed?ID=' . $_SESSION['StatsID'];
@file_get_contents($url);
}
global $project;
$data = new ArrayData(array(
'Project' => Convert::raw2xml($project),
'Username' => Convert::raw2xml(Session::get('username')),
'Password' => Convert::raw2xml(Session::get('password')),
));
return array(
"Title" => _t("ContentController.INSTALL_SUCCESS", "Installation Successful!"),
"Content" => $data->renderWith('Install_successfullyinstalled'),
@ -412,7 +412,7 @@ HTML;
public function deleteinstallfiles() {
if(!Permission::check("ADMIN")) return Security::permissionFailure($this);
$title = new Varchar("Title");
$content = new HTMLText('Content');

View File

@ -1,7 +1,7 @@
<?php
/**
* Extension to include custom page icons
*
*
* @package cms
* @subpackage controller
*/
@ -14,16 +14,16 @@ class LeftAndMainPageIconsExtension extends Extension {
/**
* Include CSS for page icons. We're not using the JSTree 'types' option
* because it causes too much performance overhead just to add some icons.
*
* @return string CSS
*
* @return string CSS
*/
public function generatePageIconsCss() {
$css = '';
$classes = ClassInfo::subclassesFor('SiteTree');
$css = '';
$classes = ClassInfo::subclassesFor('SiteTree');
foreach($classes as $class) {
$obj = singleton($class);
$iconSpec = $obj->stat('icon');
$obj = singleton($class);
$iconSpec = $obj->stat('icon');
if(!$iconSpec) continue;
@ -33,9 +33,9 @@ class LeftAndMainPageIconsExtension extends Extension {
// Legacy support: Add file extension if none exists
if(!pathinfo($iconFile, PATHINFO_EXTENSION)) $iconFile .= '-file.gif';
$iconPathInfo = pathinfo($iconFile);
// Base filename
$iconPathInfo = pathinfo($iconFile);
// Base filename
$baseFilename = $iconPathInfo['dirname'] . '/' . $iconPathInfo['filename'];
$fileExtension = $iconPathInfo['extension'];
@ -52,4 +52,4 @@ class LeftAndMainPageIconsExtension extends Extension {
return $css;
}
}
}

View File

@ -4,21 +4,21 @@
* for CMS authors, usually for {@link SiteTree} objects with "stage" and "live" links.
* Useful both in the CMS and alongside the page template (for logged in authors).
* The class can be used for any {@link DataObject} subclass implementing the {@link CMSPreviewable} interface.
*
*
* New item types can be defined by extending the {@link SilverStripeNavigatorItem} class,
* for example the "cmsworkflow" module defines a new "future state" item with a date selector
* to view embargoed data at a future point in time. So the item doesn't always have to be a simple link.
*
*
* @package cms
* @subpackage content
*/
class SilverStripeNavigator extends ViewableData {
/**
* @var DataObject
*/
protected $record;
/**
* @param DataObject $record
* @throws InvalidArgumentException if record doesn't implement CMSPreviewable
@ -30,7 +30,7 @@ class SilverStripeNavigator extends ViewableData {
get_class($record)
));
}
$this->record = $record;
}
@ -39,26 +39,26 @@ class SilverStripeNavigator extends ViewableData {
*/
public function getItems() {
$items = array();
$classes = ClassInfo::subclassesFor('SilverStripeNavigatorItem');
array_shift($classes);
// Sort menu items according to priority
$i = 0;
foreach($classes as $class) {
// Skip base class
if($class == 'SilverStripeNavigatorItem') continue;
$i++;
$item = new $class($this->record);
if(!$item->canView()) continue;
// This funny litle formula ensures that the first item added with the same priority will be left-most.
$priority = $item->getPriority() * 100 - 1;
// Ensure that we can have duplicates with the same (default) priority
while(isset($items[$priority])) $priority++;
$items[$priority] = $item;
}
ksort($items);
@ -66,7 +66,7 @@ class SilverStripeNavigator extends ViewableData {
// Drop the keys and let the ArrayList handle the numbering, so $First, $Last and others work properly.
return new ArrayList(array_values($items));
}
/**
* @return DataObject
*/
@ -83,13 +83,13 @@ class SilverStripeNavigator extends ViewableData {
$message = '';
$navigator = new SilverStripeNavigator($record);
$items = $navigator->getItems();
foreach($items as $item) {
foreach($items as $item) {
$text = $item->getHTML();
if($text) $html .= $text;
$newMessage = $item->getMessage();
if($newMessage && $item->isActive()) $message = $newMessage;
}
return array(
'items' => $html,
'message' => $message
@ -101,24 +101,24 @@ 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
*/
class SilverStripeNavigatorItem extends ViewableData {
/**
* @param DataObject
*/
protected $record;
/**
* @param DataObject
*/
public function __construct($record) {
$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.
@ -130,7 +130,7 @@ class SilverStripeNavigatorItem extends ViewableData {
* Get the Title of an item
*/
public function getTitle() {}
/**
* Machine-friendly name.
*/
@ -142,44 +142,44 @@ class SilverStripeNavigatorItem extends ViewableData {
* 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
* @return Boolean
*/
@ -189,12 +189,12 @@ class SilverStripeNavigatorItem extends ViewableData {
/**
* 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('Versioned')) return false;
if(!isset($this->record->_cached_isArchived)) {
$baseTable = ClassInfo::baseDataClass($this->record->class);
$currentDraft = Versioned::get_one_by_stage($baseTable, 'Stage', array(
@ -203,9 +203,9 @@ class SilverStripeNavigatorItem extends ViewableData {
$currentLive = Versioned::get_one_by_stage($baseTable, 'Live', array(
"\"$baseTable\".\"ID\"" => $this->record->ID
));
$this->record->_cached_isArchived = (
(!$currentDraft || ($currentDraft && $this->record->Version != $currentDraft->Version))
(!$currentDraft || ($currentDraft && $this->record->Version != $currentDraft->Version))
&& (!$currentLive || ($currentLive && $this->record->Version != $currentLive->Version))
);
}
@ -220,8 +220,8 @@ class SilverStripeNavigatorItem extends ViewableData {
*/
class SilverStripeNavigatorItem_CMSLink extends SilverStripeNavigatorItem {
/** @config */
private static $priority = 10;
private static $priority = 10;
public function getHTML() {
return sprintf(
'<a href="%s">%s</a>',
@ -229,19 +229,19 @@ class SilverStripeNavigatorItem_CMSLink extends SilverStripeNavigatorItem {
_t('ContentController.CMS', 'CMS')
);
}
public function getTitle() {
return _t('ContentController.CMS', 'CMS', 'Used in navigation. Should be a short label');
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
@ -272,37 +272,37 @@ class SilverStripeNavigatorItem_StageLink extends SilverStripeNavigatorItem {
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(),
$this->record->PreviewLink(),
'?stage=Stage',
$date ? '?archiveDate=' . $date : null
);
}
public function canView($member = null) {
return (
$this->record->hasExtension('Versioned')
$this->record->hasExtension('Versioned')
&& $this->getDraftPage()
// Don't follow redirects in preview, they break the CMS editing form
&& !($this->record instanceof RedirectorPage)
);
}
public function isActive() {
return (
Versioned::current_stage() == 'Stage'
Versioned::current_stage() == 'Stage'
&& !(ClassInfo::exists('SiteTreeFutureState') && SiteTreeFutureState::get_future_datetime())
&& !$this->isArchived()
);
}
protected function getDraftPage() {
$baseTable = ClassInfo::baseDataClass($this->record->class);
return Versioned::get_one_by_stage($baseTable, 'Stage', array(
@ -330,31 +330,31 @@ class SilverStripeNavigatorItem_LiveLink extends SilverStripeNavigatorItem {
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('Versioned')
$this->record->hasExtension('Versioned')
&& $this->getLivePage()
// Don't follow redirects in preview, they break the CMS editing form
&& !($this->record instanceof RedirectorPage)
);
}
public function isActive() {
return (
(!Versioned::current_stage() || Versioned::current_stage() == 'Live')
&& !$this->isArchived()
);
}
protected function getLivePage() {
$baseTable = ClassInfo::baseDataClass($this->record->class);
return Versioned::get_one_by_stage($baseTable, 'Live', array(
@ -375,31 +375,31 @@ class SilverStripeNavigatorItem_ArchiveLink extends SilverStripeNavigatorItem {
$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() {
public function getMessage() {
if($date = Versioned::current_archived_date()) {
$dateObj = DBField::create_field('Datetime', $date);
return "<div id=\"SilverStripeNavigatorMessage\" title=\"". _t('ContentControl.NOTEWONTBESHOWN', 'Note: this message will not be shown to your visitors') ."\">". _t('ContentController.ARCHIVEDSITEFROM', 'Archived site from') ."<br>" . $dateObj->Nice() . "</div>";
}
}
public function getLink() {
return $this->record->PreviewLink() . '?archiveDate=' . urlencode($this->record->LastEdited);
}
public function canView($member = null) {
return (
$this->record->hasExtension('Versioned')
$this->record->hasExtension('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();
}

View File

@ -4,17 +4,17 @@
* @subpackage filesystem
*/
class Folder_UnusedAssetsField extends CompositeField {
/**
* @var Folder
*/
protected $folder;
public function __construct($folder) {
$this->folder = $folder;
parent::__construct(new FieldList());
}
public function getChildren() {
if($this->children->Count() == 0) {
$inlineFormAction = new InlineFormAction("delete_unused_thumbnails", _t('Folder.DELETEUNUSEDTHUMBNAILS', 'Delete unused thumbnails'));
@ -32,7 +32,7 @@ class Folder_UnusedAssetsField extends CompositeField {
}
return $this->children;
}
public function FieldHolder($properties = array()) {
$output = "";
foreach($this->getChildren() as $child) {

View File

@ -11,12 +11,12 @@
*/
class SiteTreeURLSegmentField extends TextField {
/**
* @var string
*/
protected $helpText, $urlPrefix, $urlSuffix, $defaultUrl;
private static $allowed_actions = array(
'suggest'
);
@ -42,7 +42,7 @@ class SiteTreeURLSegmentField extends TextField {
Requirements::css(CMS_DIR . "/css/screen.css");
return parent::Field($properties);
}
public function suggest($request) {
if(!$request->getVar('value')) {
return $this->httpError(405,
@ -58,11 +58,11 @@ class SiteTreeURLSegmentField extends TextField {
$page->URLSegment = preg_replace('/-[0-9]+$/', null, $page->URLSegment) . '-' . $count;
$count++;
}
Controller::curr()->getResponse()->addHeader('Content-Type', 'application/json');
return Convert::raw2json(array('value' => $page->URLSegment));
}
/**
* @return SiteTree
*/
@ -70,7 +70,7 @@ class SiteTreeURLSegmentField extends TextField {
$idField = $this->getForm()->Fields()->dataFieldByName('ID');
return ($idField && $idField->Value()) ? DataObject::get_by_id('SiteTree', $idField->Value()) : singleton('SiteTree');
}
/**
* @param string $string The secondary text to show
*/
@ -78,15 +78,15 @@ class SiteTreeURLSegmentField extends TextField {
$this->helpText = $string;
return $this;
}
/**
* @return string the secondary text to show in the template
*/
public function getHelpText(){
return $this->helpText;
}
/**
* @param the url that prefixes the page url segment field
*/
@ -94,14 +94,14 @@ class SiteTreeURLSegmentField extends TextField {
$this->urlPrefix = $url;
return $this;
}
/**
* @return the url prefixes the page url segment field to show in template
*/
public function getURLPrefix(){
return $this->urlPrefix;
}
public function getURLSuffix() {
return $this->urlSuffix;
}
@ -114,7 +114,7 @@ class SiteTreeURLSegmentField extends TextField {
public function getDefaultURL(){
return $this->defaultUrl;
}
public function setDefaultURL($url) {
$this->defaultUrl = $url;
return $this;

View File

@ -9,13 +9,13 @@ use SilverStripe\Framework\Logging\DebugViewFriendlyErrorFormatter;
* Provides {@see ErrorPage}-gnostic error handling
*/
class ErrorPageErrorFormatter extends DebugViewFriendlyErrorFormatter {
public function output($statusCode) {
// Ajax content is plain-text only
if(\Director::is_ajax()) {
return $this->getTitle();
}
// Determine if cached ErrorPage content is available
$content = ErrorPage::get_content_for_errorcode($statusCode);
if($content) {

View File

@ -10,7 +10,7 @@ interface CurrentPageIdentifier {
* @return int
*/
public function currentPageID();
/**
* Check if the given DataObject is the current page.
* @param DataObject $page The page to check.

View File

@ -68,7 +68,7 @@ class ErrorPage extends Page {
$errorPage = ErrorPage::get()
->filter(array(
"ErrorCode" => $statusCode
))->first();
))->first();
if($errorPage) {
Requirements::clear();
@ -80,7 +80,7 @@ class ErrorPage extends Page {
DataModel::inst()
);
}
// then fall back on a cached version
$content = self::get_content_for_errorcode($statusCode);
if($content) {

View File

@ -7,23 +7,23 @@
*/
class RedirectorPage extends Page {
private static $description = 'Redirects to a different internal page';
private static $db = array(
"RedirectionType" => "Enum('Internal,External','Internal')",
"ExternalURL" => "Varchar(2083)" // 2083 is the maximum length of a URL in Internet Explorer.
);
private static $defaults = array(
"RedirectionType" => "Internal"
);
private static $has_one = array(
"LinkTo" => "SiteTree",
);
private static $many_many = array(
);
/**
* Returns this page if the redirect is external, otherwise
* returns the target page.
@ -34,9 +34,9 @@ class RedirectorPage extends Page {
return $this->LinkTo();
} else {
return $this;
}
}
}
/**
* Return the the link that should be used for this redirector page, in navigation, etc.
* If the redirectorpage has been appropriately configured, then it will return the redirection
@ -47,7 +47,7 @@ class RedirectorPage extends Page {
if($link = $this->redirectionLink()) return $link;
else return $this->regularLink();
}
/**
* Return the normal link directly to this page. Once you visit this link, a 30x redirection
* will take you to your final destination.
@ -55,7 +55,7 @@ class RedirectorPage extends Page {
public function regularLink($action = null) {
return parent::Link($action);
}
/**
* Return the link that we should redirect to.
* Only return a value if there is a legal redirection destination.
@ -65,7 +65,7 @@ class RedirectorPage extends Page {
if($this->ExternalURL) {
return $this->ExternalURL;
}
} else {
$linkTo = $this->LinkToID ? DataObject::get_by_id("SiteTree", $this->LinkToID) : null;
@ -74,7 +74,7 @@ class RedirectorPage extends Page {
// bad configuration
if($this->ID == $linkTo->ID) {
return null;
// If we're linking to another redirectorpage then just return the URLSegment, to prevent a cycle of redirector
// pages from causing an infinite loop. Instead, they will cause a 30x redirection loop in the browser, but
// this can be handled sufficiently gracefully by the browser.
@ -88,7 +88,7 @@ class RedirectorPage extends Page {
}
}
}
public function syncLinkTracking() {
if ($this->RedirectionType == 'Internal') {
if($this->LinkToID) {
@ -118,13 +118,13 @@ class RedirectorPage extends Page {
public function getCMSFields() {
Requirements::javascript(CMS_DIR . '/javascript/dist/RedirectorPage.js');
$fields = parent::getCMSFields();
$fields->removeByName('Content', true);
// Remove all metadata fields, does not apply for redirector pages
$fields->removeByName('Metadata');
$fields->addFieldsToTab('Root.Main',
array(
new HeaderField('RedirectorDescHeader',_t('RedirectorPage.HEADER', "This page will redirect users to another page")),
@ -137,7 +137,7 @@ class RedirectorPage extends Page {
),
"Internal"
),
new TreeDropdownField(
new TreeDropdownField(
"LinkToID",
_t('RedirectorPage.YOURPAGE', "Page on your website"),
"SiteTree"
@ -145,10 +145,10 @@ class RedirectorPage extends Page {
new TextField("ExternalURL", _t('RedirectorPage.OTHERURL', "Other website URL"))
)
);
return $fields;
}
// Don't cache RedirectorPages
public function subPagesToCache() {
return array();
@ -171,7 +171,7 @@ class RedirectorPage_Controller extends Page_Controller {
return;
}
}
/**
* If we ever get this far, it means that the redirection failed.
*/

View File

@ -171,7 +171,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @var string
*/
private static $icon = null;
/**
* @config
* @var string Description of the class functionality, typically shown to a user
@ -184,7 +184,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
"Versioned('Stage', 'Live')",
"SiteTreeLinkTracking"
);
private static $searchable_fields = array(
'Title',
'Content',
@ -193,22 +193,22 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
private static $field_labels = array(
'URLSegment' => 'URL'
);
/**
* @config
*/
private static $nested_urls = true;
/**
* @config
*/
private static $create_default_pages = true;
/**
* This controls whether of not extendCMSFields() is called by getCMSFields.
*/
private static $runCMSFieldsExtensions = true;
/**
* Cache for canView/Edit/Publish/Delete permissions.
* Keyed by permission type (e.g. 'edit'), with an array
@ -232,7 +232,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
private static $meta_generator = 'SilverStripe - http://silverstripe.org';
protected $_cache_statusFlags = null;
/**
* Determines if the system should avoid orphaned pages
* by deleting all children when the their parent is deleted (TRUE),
@ -245,7 +245,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
Deprecation::notice('4.0', 'Use the "SiteTree.enforce_strict_hierarchy" config setting instead');
Config::inst()->update('SiteTree', 'enforce_strict_hierarchy', $to);
}
/**
* @deprecated 4.0 Use the "SiteTree.enforce_strict_hierarchy" config setting instead
* @return boolean
@ -265,7 +265,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
Deprecation::notice('4.0', 'Use the "SiteTree.nested_urls" config setting instead');
return Config::inst()->get('SiteTree', 'nested_urls');
}
/**
* @deprecated 4.0 Use the "SiteTree.nested_urls" config setting instead
*/
@ -273,7 +273,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
Deprecation::notice('4.0', 'Use the "SiteTree.nested_urls" config setting instead');
Config::inst()->update('SiteTree', 'nested_urls', true);
}
/**
* @deprecated 4.0 Use the "SiteTree.nested_urls" config setting instead
*/
@ -281,7 +281,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
Deprecation::notice('4.0', 'Use the "SiteTree.nested_urls" config setting instead');
Config::inst()->update('SiteTree', 'nested_urls', false);
}
/**
* Set the (re)creation of default pages on /dev/build
*
@ -303,7 +303,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
Deprecation::notice('4.0', 'Use the "SiteTree.create_default_pages" config setting instead');
return Config::inst()->get('SiteTree', 'create_default_pages');
}
/**
* Fetches the {@link SiteTree} object that maps to a link.
*
@ -323,9 +323,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
} else {
$link = RootURLController::get_homepage_link();
}
$parts = preg_split('|/+|', $link);
// Grab the initial root level page to traverse down from.
$URLSegment = array_shift($parts);
$conditions = array('"SiteTree"."URLSegment"' => rawurlencode($URLSegment));
@ -333,7 +333,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$conditions[] = array('"SiteTree"."ParentID"' => 0);
}
$sitetree = DataObject::get_one('SiteTree', $conditions, $cache);
/// Fall back on a unique URLSegment for b/c.
if( !$sitetree
&& self::config()->nested_urls
@ -343,21 +343,21 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
) {
return $page;
}
// Attempt to grab an alternative page from extensions.
if(!$sitetree) {
$parentID = self::config()->nested_urls ? 0 : null;
if($alternatives = singleton('SiteTree')->extend('alternateGetByLink', $URLSegment, $parentID)) {
foreach($alternatives as $alternative) if($alternative) $sitetree = $alternative;
}
if(!$sitetree) return false;
}
// Check if we have any more URL parts to parse.
if(!self::config()->nested_urls || !count($parts)) return $sitetree;
// Traverse down the remaining URL segments and grab the relevant SiteTree objects.
foreach($parts as $segment) {
$next = DataObject::get_one('SiteTree', array(
@ -366,24 +366,24 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
),
$cache
);
if(!$next) {
$parentID = (int) $sitetree->ID;
if($alternatives = singleton('SiteTree')->extend('alternateGetByLink', $segment, $parentID)) {
foreach($alternatives as $alternative) if($alternative) $next = $alternative;
}
if(!$next) return false;
}
$sitetree->destroy();
$sitetree = $next;
}
return $sitetree;
}
/**
* Return a subclass map of SiteTree that shouldn't be hidden through {@link SiteTree::$hide_ancestor}
*
@ -423,7 +423,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $classes;
}
/**
* Replace a "[sitetree_link id=n]" shortcode with a link to the page with the corresponding ID.
*
@ -434,7 +434,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*/
static public function link_shortcode_handler($arguments, $content = null, $parser = null) {
if(!isset($arguments['id']) || !is_numeric($arguments['id'])) return;
if (
!($page = DataObject::get_by_id('SiteTree', $arguments['id'])) // Get the current page by ID.
&& !($page = Versioned::get_latest_version('SiteTree', $arguments['id'])) // Attempt link to old version.
@ -443,7 +443,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
$link = Convert::raw2att($page->Link());
if($content) {
return sprintf('<a href="%s">%s</a>', $link, $parser->parse($content));
} else {
@ -463,7 +463,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function Link($action = null) {
return Controller::join_links(Director::baseURL(), $this->RelativeLink($action));
}
/**
* Get the absolute URL for this page, including protocol and host.
*
@ -477,7 +477,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return Director::absoluteURL($this->Link($action));
}
}
/**
* Base link used for previewing. Defaults to absolute URL, in order to account for domain changes, e.g. on multi
* site setups. Does not contain hints about the stage, see {@link SilverStripeNavigator} for details.
@ -492,7 +492,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $this->AbsoluteLink($action);
}
}
/**
* Return the link for this {@link SiteTree} object relative to the SilverStripe root.
*
@ -521,9 +521,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
} else {
$base = $this->URLSegment;
}
$this->extend('updateRelativeLink', $base, $action);
// Legacy support: If $action === true, retain URLSegment for homepages,
// but don't append any action
if($action === true) $action = null;
@ -553,7 +553,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
Versioned::reading_stage($oldStage);
return $link;
}
/**
* Generates a link to edit this page in the CMS.
*
@ -562,8 +562,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function CMSEditLink() {
return Controller::join_links(singleton('CMSPageEditController')->Link('show'), $this->ID);
}
/**
* Return a CSS identifier generated from this page's link.
*
@ -572,7 +572,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function ElementName() {
return str_replace('/', '-', trim($this->RelativeLink(true), '/'));
}
/**
* Returns true if this is the currently active page being used to handle this request.
*
@ -581,7 +581,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function isCurrent() {
return $this->ID ? $this->ID == Director::get_current_page()->ID : $this === Director::get_current_page();
}
/**
* Check if this page is in the currently active section (e.g. it is either current or one of its children is
* currently being viewed).
@ -593,7 +593,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
Director::get_current_page() instanceof SiteTree && in_array($this->ID, Director::get_current_page()->getAncestors()->column())
);
}
/**
* Check if the parent of this page has been removed (or made otherwise unavailable), and is still referenced by
* this child. Any such orphaned page may still require access via the CMS, but should not be shown as accessible
@ -604,12 +604,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function isOrphaned() {
// Always false for root pages
if(empty($this->ParentID)) return false;
// Parent must exist and not be an orphan itself
$parent = $this->Parent();
return !$parent || !$parent->exists() || $parent->isOrphaned();
}
/**
* Return "link" or "current" depending on if this is the {@link SiteTree::isCurrent()} current page.
*
@ -618,7 +618,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function LinkOrCurrent() {
return $this->isCurrent() ? 'current' : 'link';
}
/**
* Return "link" or "section" depending on if this is the {@link SiteTree::isSeciton()} current section.
*
@ -627,7 +627,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function LinkOrSection() {
return $this->isSection() ? 'section' : 'link';
}
/**
* Return "link", "current" or "section" depending on if this page is the current page, or not on the current page
* but in the current section.
@ -643,7 +643,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return 'link';
}
}
/**
* Check if this page is in the given current section.
*
@ -668,18 +668,18 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return self The duplicated object
*/
public function duplicate($doWrite = true) {
$page = parent::duplicate(false);
$page->Sort = 0;
$this->invokeWithExtensions('onBeforeDuplicate', $page);
if($doWrite) {
$page->write();
$page = $this->duplicateManyManyRelations($this, $page);
}
$this->invokeWithExtensions('onAfterDuplicate', $page);
return $page;
}
@ -716,7 +716,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$newSiteTree->Sort = 0;
$newSiteTree->write();
}
/**
* Return a breadcrumb trail to this page. Excludes "hidden" pages (with ShowInMenus=0) by default.
*
@ -748,7 +748,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function getBreadcrumbItems($maxDepth = 20, $stopAtPageType = false, $showHidden = false) {
$page = $this;
$pages = array();
while(
$page
&& (!$maxDepth || count($pages) < $maxDepth)
@ -757,7 +757,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($showHidden || $page->ShowInMenus || ($page->ID == $this->ID)) {
$pages[] = $page;
}
$page = $page->Parent;
}
@ -780,7 +780,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$this->setField("ParentID", $item);
}
}
/**
* Get the parent of this page.
*
@ -831,12 +831,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
if($member && Permission::checkMember($member, "ADMIN")) return true;
if(is_string($perm) && method_exists($this, 'can' . ucfirst($perm))) {
$method = 'can' . ucfirst($perm);
return $this->$method($member);
}
$results = $this->extend('can', $member);
if($results && is_array($results)) if(!min($results)) return false;
@ -870,11 +870,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
if($member && Permission::checkMember($member, "ADMIN")) return true;
// Standard mechanism for accepting permission changes from extensions
$extended = $this->extendedCan('canAddChildren', $member);
if($extended !== null) return $extended;
return $this->canEdit($member) && $this->stat('allowed_children') != 'none';
}
@ -901,14 +901,14 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// admin override
if($member && Permission::checkMember($member, array("ADMIN", "SITETREE_VIEW_ALL"))) return true;
// Orphaned pages (in the current stage) are unavailable, except for admins via the CMS
if($this->isOrphaned()) return false;
// Standard mechanism for accepting permission changes from extensions
$extended = $this->extendedCan('canView', $member);
if($extended !== null) return $extended;
// check for empty spec
if(!$this->CanViewType || $this->CanViewType == 'Anyone') return true;
@ -917,12 +917,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($this->ParentID) return $this->Parent()->canView($member);
else return $this->getSiteConfig()->canViewPages($member);
}
// check for any logged-in users
if($this->CanViewType == 'LoggedInUsers' && $member) {
return true;
}
// check for specific groups
if($member && is_numeric($member)) $member = DataObject::get_by_id('Member', $member);
if(
@ -930,7 +930,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
&& $member
&& $member->inGroups($this->ViewerGroups())
) return true;
return false;
}
@ -954,18 +954,18 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($member instanceof Member) $memberID = $member->ID;
else if(is_numeric($member)) $memberID = $member;
else $memberID = Member::currentUserID();
if($memberID && Permission::checkMember($memberID, array("ADMIN", "SITETREE_EDIT_ALL"))) {
return true;
}
// Standard mechanism for accepting permission changes from extensions
$extended = $this->extendedCan('canDelete', $memberID);
if($extended !== null) return $extended;
// Regular canEdit logic is handled by can_edit_multiple
$results = self::can_delete_multiple(array($this->ID), $memberID);
// If this page no longer exists in stage/live results won't contain the page.
// Fail-over to false
return isset($results[$this->ID]) ? $results[$this->ID] : false;
@ -1046,9 +1046,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($member instanceof Member) $memberID = $member->ID;
else if(is_numeric($member)) $memberID = $member;
else $memberID = Member::currentUserID();
if($memberID && Permission::checkMember($memberID, array("ADMIN", "SITETREE_EDIT_ALL"))) return true;
// Standard mechanism for accepting permission changes from extensions
$extended = $this->extendedCan('canEdit', $memberID);
if($extended !== null) return $extended;
@ -1060,7 +1060,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// If this page no longer exists in stage/live results won't contain the page.
// Fail-over to false
return isset($results[$this->ID]) ? $results[$this->ID] : false;
// Default for unsaved pages
} else {
return $this->getSiteConfig()->canEditPages($member);
@ -1089,12 +1089,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return SiteConfig
*/
public function getSiteConfig() {
if($this->hasMethod('alternateSiteConfig')) {
$altConfig = $this->alternateSiteConfig();
if($altConfig) return $altConfig;
}
return SiteConfig::current_site_config();
}
@ -1109,7 +1109,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*/
static public function prepopulate_permission_cache($permission = 'CanEditType', $ids, $batchCallback = null) {
if(!$batchCallback) $batchCallback = "SiteTree::can_{$permission}_multiple";
if(is_callable($batchCallback)) {
call_user_func($batchCallback, $ids, Member::currentUserID(), false);
} else {
@ -1142,7 +1142,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// Sanitise the IDs
$ids = array_filter($ids, 'is_numeric');
// This is the name used on the permission cache
// converts something like 'CanEditType' to 'edit'.
$cacheKey = strtolower(substr($typeField, 3, -4)) . "-$memberID";
@ -1154,7 +1154,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// Look in the cache for values
if($useCached && isset(self::$cache_permissions[$cacheKey])) {
$cachedValues = array_intersect_key(self::$cache_permissions[$cacheKey], $result);
// If we can't find everything in the cache, then look up the remainder separately
$uncachedValues = array_diff_key($result, self::$cache_permissions[$cacheKey]);
if($uncachedValues) {
@ -1162,7 +1162,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
return $cachedValues;
}
// If a member doesn't have a certain permission then they can't edit anything
if(!$memberID || ($globalPermission && !Permission::checkMember($memberID, $globalPermission))) {
return $result;
@ -1174,18 +1174,18 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// If page can't be viewed, don't grant edit permissions to do - implement can_view_multiple(), so this can
// be enabled
//$ids = array_keys(array_filter(self::can_view_multiple($ids, $memberID)));
// Get the groups that the given member belongs to
$groupIDs = DataObject::get_by_id('Member', $memberID)->Groups()->column("ID");
$SQL_groupList = implode(", ", $groupIDs);
if (!$SQL_groupList) $SQL_groupList = '0';
$combinedStageResult = array();
foreach(array('Stage', 'Live') as $stage) {
// Start by filling the array with the pages that actually exist
$table = ($stage=='Stage') ? "SiteTree" : "SiteTree_$stage";
if($ids) {
$idQuery = "SELECT \"ID\" FROM \"$table\" WHERE \"ID\" IN ($idPlaceholders)";
$stageIds = DB::prepared_query($idQuery, $ids)->column();
@ -1193,7 +1193,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$stageIds = array();
}
$result = array_fill_keys($stageIds, false);
// Get the uninherited permissions
$uninheritedPermissions = Versioned::get_by_stage("SiteTree", $stage)
->where(array(
@ -1203,7 +1203,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
=> $ids
))
->leftJoin($groupJoinTable, "\"$groupJoinTable\".\"SiteTreeID\" = \"SiteTree\".\"ID\" AND \"$groupJoinTable\".\"GroupID\" IN ($SQL_groupList)");
if($uninheritedPermissions) {
// Set all the relevant items in $result to true
$result = array_fill_keys($uninheritedPermissions->column('ID'), true) + $result;
@ -1243,9 +1243,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
}
}
$combinedStageResult = $combinedStageResult + $result;
}
}
@ -1285,11 +1285,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$deletable = array();
$result = array_fill_keys($ids, false);
$cacheKey = "delete-$memberID";
// Look in the cache for values
if($useCached && isset(self::$cache_permissions[$cacheKey])) {
$cachedValues = array_intersect_key(self::$cache_permissions[$cacheKey], $result);
// If we can't find everything in the cache, then look up the remainder separately
$uncachedValues = array_diff_key($result, self::$cache_permissions[$cacheKey]);
if($uncachedValues) {
@ -1302,7 +1302,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// You can only delete pages that you can edit
$editableIDs = array_keys(array_filter(self::can_edit_multiple($ids, $memberID)));
if($editableIDs) {
// You can only delete pages whose children you can delete
$editablePlaceholders = DB::placeholders($editableIDs);
$childRecords = SiteTree::get()->where(array(
@ -1313,7 +1313,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// Find out the children that can be deleted
$deletableChildren = self::can_delete_multiple($children->keys(), $memberID);
// Get a list of all the parents that have no undeletable children
$deletableParents = array_fill_keys($editableIDs, true);
foreach($deletableChildren as $id => $canDelete) {
@ -1336,7 +1336,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
} else {
$deletable = array();
}
// Convert the array of deletable IDs into a map of the original IDs with true/false as the value
return array_fill_keys($deletable, true) + array_fill_keys($ids, false);
}
@ -1388,7 +1388,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($this->ExtraMeta) {
$tags .= $this->ExtraMeta . "\n";
}
if(Permission::check('CMS_ACCESS_CMSMain')
&& in_array('CMSPreviewable', class_implements($this))
&& !$this instanceof ErrorPage
@ -1423,7 +1423,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*/
public function requireDefaultRecords() {
parent::requireDefaultRecords();
// default pages
if($this->class == 'SiteTree' && $this->config()->create_default_pages) {
if(!SiteTree::get_by_link(Config::inst()->get('RootURLController', 'default_homepage_link'))) {
@ -1458,7 +1458,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
DB::alteration_message('Contact Us page created', 'created');
}
}
// schema migration
// @todo Move to migration task once infrastructure is implemented
if($this->class == 'SiteTree') {
@ -1498,7 +1498,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// If after sanitising there is no URLSegment, give it a reasonable default
if(!$this->URLSegment) $this->URLSegment = "page-$this->ID";
}
// Ensure that this object has a non-conflicting URLSegment value.
$count = 2;
while(!$this->validURLSegment()) {
@ -1530,11 +1530,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function syncLinkTracking() {
$this->extend('augmentSyncLinkTracking');
}
public function onAfterWrite() {
// Need to flush cache to avoid outdated versionnumber references
$this->flushCache();
$linkedPages = $this->VirtualPages();
if($linkedPages) {
// The only way after a write() call to determine if it was triggered by a writeWithoutVersion(),
@ -1547,13 +1547,13 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
else $page->write();
}
}
parent::onAfterWrite();
}
public function onBeforeDelete() {
parent::onBeforeDelete();
// If deleting this page, delete all its children.
if(SiteTree::config()->enforce_strict_hierarchy && $children = $this->AllChildren()) {
foreach($children as $child) {
@ -1561,18 +1561,18 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
}
}
public function onAfterDelete() {
// Need to flush cache to avoid outdated versionnumber references
$this->flushCache();
// Need to mark pages depending to this one as broken
$dependentPages = $this->DependentPages();
if($dependentPages) foreach($dependentPages as $page) {
// $page->write() calls syncLinkTracking, which does all the hard work for us.
$page->write();
}
parent::onAfterDelete();
}
@ -1580,7 +1580,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
parent::flushCache($persistent);
$this->_cache_statusFlags = null;
}
public function validate() {
$result = parent::validate();
@ -1592,7 +1592,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$allowed = $parent->allowedChildren();
$subject = ($this instanceof VirtualPage && $this->CopyContentFromID) ? $this->CopyContentFrom() : $this;
if(!in_array($subject->ClassName, $allowed)) {
$result->error(
_t(
'SiteTree.PageTypeNotAllowed',
@ -1615,10 +1615,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
'CAN_BE_ROOT'
);
}
return $result;
}
/**
* Returns true if this object has a URLSegment value that does not conflict with any other objects. This method
* checks for:
@ -1634,11 +1634,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($controller instanceof Controller && $controller->hasAction($this->URLSegment)) return false;
}
}
if(!self::config()->nested_urls || !$this->ParentID) {
if(class_exists($this->URLSegment) && is_subclass_of($this->URLSegment, 'RequestHandler')) return false;
}
// Filters by url, id, and parent
$filter = array('"SiteTree"."URLSegment"' => $this->URLSegment);
if($this->ID) {
@ -1647,7 +1647,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if(self::config()->nested_urls) {
$filter['"SiteTree"."ParentID"'] = $this->ParentID ? $this->ParentID : 0;
}
$votes = array_filter(
(array)$this->extend('augmentValidURLSegment'),
function($v) {return !is_null($v);}
@ -1662,7 +1662,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return !($existingPage);
}
/**
* Generate a URL segment based on the title provided.
*
@ -1677,16 +1677,16 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function generateURLSegment($title){
$filter = URLSegmentFilter::create();
$t = $filter->filter($title);
// Fallback to generic page name if path is empty (= no valid, convertable characters)
if(!$t || $t == '-' || $t == '-1') $t = "page-$this->ID";
// Hook for extensions
$this->extend('updateURLSegment', $t, $title);
return $t;
}
/**
* Gets the URL segment for the latest draft version of this page.
*
@ -1698,7 +1698,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
));
return ($stageRecord) ? $stageRecord->URLSegment : null;
}
/**
* Gets the URL segment for the currently published version of this page.
*
@ -1710,7 +1710,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
));
return ($liveRecord) ? $liveRecord->URLSegment : null;
}
/**
* Rewrites any linked images on this page without creating a new version record.
* Non-image files should be linked via shortcodes
@ -1750,7 +1750,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$this->invokeWithExtensions('onRenameLinkedAsset');
}
}
/**
* Returns the pages that depend on this page. This includes virtual pages, pages that link to it, etc.
*
@ -1762,7 +1762,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
Subsite::disable_subsite_filter(true);
}
// Content links
$items = new ArrayList();
@ -1775,7 +1775,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
$items->merge($linkList);
}
// Virtual pages
if($includeVirtuals) {
$virtuals = $this->VirtualPages();
@ -1804,7 +1804,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
if(class_exists('Subsite')) Subsite::disable_subsite_filter($origDisableSubsiteFilter);
return $items;
}
@ -1814,10 +1814,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @return DataList
*/
public function VirtualPages() {
// Ignore new records
if(!$this->ID) return null;
// Check subsite virtual pages
// @todo Refactor out subsite module specific code
if(class_exists('Subsite')) {
@ -1825,14 +1825,14 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
'"VirtualPage"."CopyContentFromID"' => $this->ID
));
}
// Check existing virtualpages
if(class_exists('VirtualPage')) {
return VirtualPage::get()->where(array(
'"VirtualPage"."CopyContentFromID"' => $this->ID
));
}
return null;
}
@ -1892,7 +1892,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$dependentNote = '';
$dependentTable = new LiteralField('DependentNote', '<p></p>');
// Create a table for showing pages linked to this one
$dependentPages = $this->DependentPages();
$dependentPagesCount = $dependentPages->Count();
@ -1903,7 +1903,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
'DependentLinkType' => _t('SiteTree.DependtPageColumnLinkType', 'Link type'),
);
if(class_exists('Subsite')) $dependentColumns['Subsite.Title'] = singleton('Subsite')->i18n_singular_name();
$dependentNote = new LiteralField('DependentNote', '<p>' . _t('SiteTree.DEPENDENT_NOTE', 'The following pages depend on this page. This includes virtual pages, redirector pages, and pages with content links.') . '</p>');
$dependentTable = GridField::create(
'DependentPages',
@ -1929,12 +1929,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
));
}
$baseLink = Controller::join_links (
Director::absoluteBaseURL(),
(self::config()->nested_urls && $this->ParentID ? $this->Parent()->RelativeLink(true) : null)
);
$urlsegment = SiteTreeURLSegmentField::create("URLSegment", $this->fieldLabel('URLSegment'))
->setURLPrefix($baseLink)
->setDefaultURL($this->generateURLSegment(_t(
@ -1947,7 +1947,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$helpText .= _t('SiteTreeURLSegmentField.HelpChars', ' Special characters are automatically converted or removed.');
}
$urlsegment->setHelpText($helpText);
$fields = new FieldList(
$rootTab = new TabSet("Root",
$tabMain = new Tab('Main',
@ -1969,7 +1969,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
)
);
$htmlField->addExtraClass('stacked');
// Help text for MetaData on page content editor
$metaFieldDesc
->setRightTitle(
@ -1991,7 +1991,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// Conditional dependent pages tab
if($dependentPagesCount) $tabDependent->setTitle(_t('SiteTree.TABDEPENDENT', "Dependent pages") . " ($dependentPagesCount)");
else $fields->removeFieldFromTab('Root', 'Dependent');
$tabMain->setTitle(_t('SiteTree.TABCONTENT', "Main Content"));
if($this->ObsoleteClassName) {
@ -2020,15 +2020,15 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
'/^Root\.Content\.Main$/' => 'Root.Main',
'/^Root\.Content\.([^.]+)$/' => 'Root.\\1',
));
if(self::$runCMSFieldsExtensions) {
$this->extend('updateCMSFields', $fields);
}
return $fields;
}
/**
* Returns fields related to configuration aspects on this record, e.g. access control. See {@link getCMSFields()}
* for content-related fields.
@ -2042,7 +2042,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$groupsMap[$group->ID] = $group->getBreadcrumbs(' > ');
}
asort($groupsMap);
$fields = new FieldList(
$rootTab = new TabSet("Root",
$tabBehaviour = new Tab('Settings',
@ -2085,17 +2085,17 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
)
)
);
$visibility->setTitle($this->fieldLabel('Visibility'));
// This filter ensures that the ParentID dropdown selection does not show this node,
// or its descendents, as this causes vanishing bugs
$parentIDField->setFilterFunction(create_function('$node', "return \$node->ID != {$this->ID};"));
$parentTypeSelector->addExtraClass('parentTypeSelector');
$tabBehaviour->setTitle(_t('SiteTree.TABBEHAVIOUR', "Behavior"));
// Make page location fields read-only if the user doesn't have the appropriate permission
if(!Permission::check("SITETREE_REORGANISE")) {
$fields->makeFieldReadonly('ParentType');
@ -2105,14 +2105,14 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$fields->makeFieldReadonly('ParentID');
}
}
$viewersOptionsSource = array();
$viewersOptionsSource["Inherit"] = _t('SiteTree.INHERIT', "Inherit from parent page");
$viewersOptionsSource["Anyone"] = _t('SiteTree.ACCESSANYONE', "Anyone");
$viewersOptionsSource["LoggedInUsers"] = _t('SiteTree.ACCESSLOGGEDIN', "Logged-in users");
$viewersOptionsSource["OnlyTheseUsers"] = _t('SiteTree.ACCESSONLYTHESE', "Only these people (choose from list)");
$viewersOptionsField->setSource($viewersOptionsSource);
$editorsOptionsSource = array();
$editorsOptionsSource["Inherit"] = _t('SiteTree.INHERIT', "Inherit from parent page");
$editorsOptionsSource["LoggedInUsers"] = _t('SiteTree.EDITANYONE', "Anyone who can log-in to the CMS");
@ -2126,7 +2126,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
} else {
$fields->removeByName('ViewerGroups');
}
$fields->makeFieldReadonly($editorsOptionsField);
if($this->CanEditType == 'OnlyTheseUsers') {
$fields->makeFieldReadonly($editorGroupsField);
@ -2134,14 +2134,14 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$fields->removeByName('EditorGroups');
}
}
if(self::$runCMSFieldsExtensions) {
$this->extend('updateSettingsFields', $fields);
}
return $fields;
}
/**
* @param bool $includerelations A boolean value to indicate if the labels returned should include relation fields
* @return array
@ -2171,7 +2171,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$labels['LinkChangeNote'] = _t (
'SiteTree.LINKCHANGENOTE', 'Changing this page\'s link will also affect the links of all child pages.'
);
if($includerelations){
$labels['Parent'] = _t('SiteTree.has_one_Parent', 'Parent Page', 'The parent page in the site hierarchy');
$labels['LinkTracking'] = _t('SiteTree.many_many_LinkTracking', 'Link Tracking');
@ -2276,7 +2276,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
} else {
// Determine if we should force a restore to root (where once it was a subpage)
$restoreToRoot = $this->isParentArchived();
// "restore"
$title = $restoreToRoot
? _t('CMSMain.RESTORE_TO_ROOT','Restore draft at top level')
@ -2315,7 +2315,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
->addExtraClass('delete ss-ui-action-destructive')
);
}
// "save", supports an alternate state that is still clickable, but notifies the user that the action is not needed.
$majorActions->push(
FormAction::create('save', _t('SiteTree.BUTTONSAVED', 'Saved'))
@ -2340,15 +2340,15 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$publish->addExtraClass('ss-ui-alternate');
}
}
$actions = new FieldList(array($majorActions, $rootTabSet));
// Hook for extensions to add/remove actions.
$this->extend('updateCMSActions', $actions);
return $actions;
}
/**
* Publish this page.
*
@ -2358,7 +2358,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*/
public function doPublish() {
if (!$this->canPublish()) return false;
$original = Versioned::get_one_by_stage("SiteTree", "Live", array(
'"SiteTree"."ID"' => $this->ID
));
@ -2375,7 +2375,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
WHERE EXISTS (SELECT "SiteTree"."Sort" FROM "SiteTree" WHERE "SiteTree_Live"."ID" = "SiteTree"."ID") AND "ParentID" = ?',
array($this->ParentID)
);
// Publish any virtual pages that might need publishing
$linkedPages = $this->VirtualPages();
if($linkedPages) foreach($linkedPages as $page) {
@ -2383,7 +2383,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$page->write();
if($page->getExistsOnLive()) $page->doPublish();
}
// Need to update pages linking to this one as no longer broken, on the live site
$origMode = Versioned::get_reading_mode();
Versioned::reading_stage('Live');
@ -2392,13 +2392,13 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$page->write();
}
Versioned::set_reading_mode($origMode);
// Handle activities undertaken by extensions
$this->invokeWithExtensions('onAfterPublish', $original);
return true;
}
/**
* Unpublish this page - remove it from the live site
*
@ -2410,9 +2410,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function doUnpublish() {
if(!$this->canUnpublish()) return false;
if(!$this->ID) return false;
$this->invokeWithExtensions('onBeforeUnpublish', $this);
$origStage = Versioned::current_stage();
Versioned::reading_stage('Live');
@ -2445,7 +2445,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return true;
}
/**
* Revert the draft changes: replace the draft content with the content on live
*/
@ -2463,7 +2463,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// $page->write() calls syncLinkTracking, which does all the hard work for us.
$page->write();
}
$this->invokeWithExtensions('onAfterRevertToLive', $this);
return true;
}
@ -2482,7 +2482,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
return false;
}
/**
* Restore the content in the active copy of this SiteTree page to the stage site.
*
@ -2495,7 +2495,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($this->isParentArchived()) {
$this->ParentID = 0;
}
// if no record can be found on draft stage (meaning it has been "deleted from draft" before),
// create an empty record
if(!DB::prepared_query("SELECT \"ID\" FROM \"SiteTree\" WHERE \"ID\" = ?", array($this->ID))->value()) {
@ -2504,12 +2504,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
DB::prepared_query("INSERT INTO \"SiteTree\" (\"ID\") VALUES (?)", array($this->ID));
if(method_exists($conn, 'allowPrimaryKeyEditing')) $conn->allowPrimaryKeyEditing('SiteTree', false);
}
$oldStage = Versioned::current_stage();
Versioned::reading_stage('Stage');
$this->forceChange();
$this->write();
$result = DataObject::get_by_id($this->class, $this->ID);
// Need to update pages linking to this one as no longer broken
@ -2517,11 +2517,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// $page->write() calls syncLinkTracking, which does all the hard work for us.
$page->write();
}
Versioned::reading_stage($oldStage);
$this->invokeWithExtensions('onAfterRestoreToStage', $this);
return $result;
}
@ -2561,7 +2561,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$classes = self::page_type_classes();
$currentClass = null;
$result = array();
$result = array();
foreach($classes as $class) {
$instance = singleton($class);
@ -2571,7 +2571,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($instance instanceof HiddenClass) continue;
if(!$instance->canCreate(null, array('Parent' => $this->ParentID ? $this->Parent() : null))) continue;
}
if($perms = $instance->stat('need_permission')) {
if(!$this->can($perms)) continue;
}
@ -2588,7 +2588,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$result[$class] = $result[$class] . " ({$class})";
}
}
// sort alphabetically, and put current on top
asort($result);
if($currentClass) {
@ -2598,7 +2598,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$result[$currentClass] = $currentPageTypeName;
$result = array_reverse($result);
}
return $result;
}
@ -2624,7 +2624,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
}
}
return $allowedChildren;
}
@ -2679,7 +2679,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$this->setField("MenuTitle", $value);
}
}
/**
* A flag provides the user with additional data about the current page status, for example a "removed from draft"
* status. Each page can have more than one status flag. Returns a map of a unique key to a (localized) title for
@ -2726,7 +2726,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$this->_cache_statusFlags = $flags;
}
return $this->_cache_statusFlags;
}
@ -2763,7 +2763,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
Convert::raw2xml($data['text'])
);
}
return $treeTitle;
}
@ -2823,7 +2823,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if(!$this->ShowInMenus) {
$classes .= " notinmenu";
}
//TODO: Add integration
/*
if($this->hasExtension('Translatable') && $controller->Locale != Translatable::default_locale() && !$this->isTranslation())
@ -2849,7 +2849,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// Return true for both completely deleted pages and for pages just deleted from stage
return !($stageVersion);
}
/**
* Return true if this page exists on the live site
*
@ -2868,16 +2868,16 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function getIsModifiedOnStage() {
// New unsaved pages could be never be published
if($this->isNew()) return false;
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
$liveVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->ID);
$isModified = ($stageVersion && $stageVersion != $liveVersion);
$this->extend('getIsModifiedOnStage', $isModified);
return $isModified;
}
/**
* Compares current draft with live version, and returns true if no live version exists, meaning the page was never
* published.
@ -2887,13 +2887,13 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public function getIsAddedToStage() {
// New unsaved pages could be never be published
if($this->isNew()) return false;
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
$liveVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->ID);
return ($stageVersion && !$liveVersion);
}
/**
* Stops extendCMSFields() being called on getCMSFields(). This is useful when you need access to fields added by
* subclasses of SiteTree in a extension. Call before calling parent::getCMSFields(), and reenable afterwards.
@ -2901,7 +2901,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
static public function disableCMSFieldsExtensions() {
self::$runCMSFieldsExtensions = false;
}
/**
* Reenables extendCMSFields() being called on getCMSFields() after it has been disabled by
* disableCMSFieldsExtensions().
@ -2944,7 +2944,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
)
);
}
/**
* Return the translated Singular name.
*
@ -2955,7 +2955,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$class = ($this->class == 'Page') ? 'SiteTree' : $this->class;
return _t($class.'.SINGULARNAME', $this->singular_name());
}
/**
* Overloaded to also provide entities for 'Page' class which is usually located in custom code, hence textcollector
* picks it up for the wrong folder.
@ -2964,9 +2964,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*/
public function provideI18nEntities() {
$entities = parent::provideI18nEntities();
if(isset($entities['Page.SINGULARNAME'])) $entities['Page.SINGULARNAME'][3] = CMS_DIR;
if(isset($entities['Page.PLURALNAME'])) $entities['Page.PLURALNAME'][3] = CMS_DIR;
if(isset($entities['Page.PLURALNAME'])) $entities['Page.PLURALNAME'][3] = CMS_DIR;
$entities[$this->class . '.DESCRIPTION'] = array(
$this->stat('description'),
@ -2994,7 +2994,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
public static function reset() {
self::$cache_permissions = array();
}
static public function on_db_reset() {
self::$cache_permissions = array();
}

View File

@ -23,20 +23,20 @@ abstract class SiteTreeExtension extends DataExtension {
*/
public function onAfterPublish(&$original) {
}
/**
* Hook called before the page's {@link SiteTree::doUnpublish()} action is completed
*/
public function onBeforeUnpublish() {
}
/**
* Hook called after the page's {@link SiteTree::doUnpublish()} action is completed
*/
public function onAfterUnpublish() {
}
/**
* Hook called to determine if a user may add children to this SiteTree object
*
@ -48,7 +48,7 @@ abstract class SiteTreeExtension extends DataExtension {
*/
public function canAddChildren($member) {
}
/**
* Hook called to determine if a user may publish this SiteTree object
*
@ -60,7 +60,7 @@ abstract class SiteTreeExtension extends DataExtension {
*/
public function canPublish($member) {
}
/**
* Hook called to modify the $base url of this page, with a given $action,
* before {@link SiteTree::RelativeLink()} calls {@link Controller::join_links()}

View File

@ -18,7 +18,7 @@ class SiteTreeFolderExtension extends DataExtension {
$usedFiles = array();
$where = '';
$classes = ClassInfo::subclassesFor('SiteTree');
if($result->numRecords() > 0) {
while($nextResult = $result->next()) {
$where .= $nextResult['FileID'] . ',';
@ -29,7 +29,7 @@ class SiteTreeFolderExtension extends DataExtension {
$query = new DataQuery($className);
$ids = $query->execute()->column();
if(!count($ids)) continue;
foreach(singleton($className)->hasOne() as $relName => $joinClass) {
if($joinClass == 'Image' || $joinClass == 'File') {
$fieldName = $relName .'ID';
@ -43,7 +43,7 @@ class SiteTreeFolderExtension extends DataExtension {
}
}
}
if($usedFiles) {
return "\"File\".\"ID\" NOT IN (" . implode(', ', $usedFiles) . ") AND (\"ClassName\" = 'File' OR \"ClassName\" = 'Image')";

View File

@ -2,15 +2,15 @@
/**
* Virtual Page creates an instance of a page, with the same fields that the original page had, but readonly.
* This allows you can have a page in mulitple places in the site structure, with different children without duplicating the content
* Note: This Only duplicates $db fields and not the $has_one etc..
* Note: This Only duplicates $db fields and not the $has_one etc..
* @package cms
*/
class VirtualPage extends Page {
private static $description = 'Displays the content of another page';
public static $virtualFields;
/**
* @var array Define fields that are not virtual - the virtual page must define these fields themselves.
* Note that anything in {@link self::config()->initially_copied_fields} is implicitly included in this list.
@ -32,7 +32,7 @@ class VirtualPage extends Page {
"CanViewType",
"CanEditType",
);
/**
* @var array Define fields that are initially copied to virtual pages but left modifiable after that.
*/
@ -41,16 +41,16 @@ class VirtualPage extends Page {
'ShowInSearch',
'URLSegment',
);
private static $has_one = array(
"CopyContentFrom" => "SiteTree",
"CopyContentFrom" => "SiteTree",
);
private static $db = array(
"VersionID" => "Int",
);
/**
/**
* Generates the array of fields required for the page type.
*/
public function getVirtualFields() {
@ -70,15 +70,15 @@ class VirtualPage extends Page {
* Returns the linked page, or failing that, a new object.
*
* Always returns a non-empty object
*
* @return SiteTree
*
* @return SiteTree
*/
public function CopyContentFrom() {
$copyContentFromID = $this->CopyContentFromID;
if(!$copyContentFromID) {
return new SiteTree();
}
if(!isset($this->components['CopyContentFrom'])) {
$this->components['CopyContentFrom'] = DataObject::get_by_id("SiteTree", $copyContentFromID);
@ -86,23 +86,23 @@ class VirtualPage extends Page {
if($this->components['CopyContentFrom'] instanceof VirtualPage) {
$this->components['CopyContentFrom'] = null;
}
// has_one component semantics incidate than an empty object should be returned
if(!$this->components['CopyContentFrom']) {
$this->components['CopyContentFrom'] = new SiteTree();
}
}
return $this->components['CopyContentFrom'] ? $this->components['CopyContentFrom'] : new SiteTree();
}
public function setCopyContentFromID($val) {
if($val && DataObject::get_by_id('SiteTree', $val) instanceof VirtualPage) {
$val = 0;
}
return $this->setField("CopyContentFromID", $val);
}
public function ContentSource() {
return $this->CopyContentFrom();
}
@ -121,14 +121,14 @@ class VirtualPage extends Page {
}
return $tags;
}
public function allowedChildren() {
if($this->CopyContentFrom()) {
return $this->CopyContentFrom()->allowedChildren();
}
return array();
}
public function syncLinkTracking() {
if($this->CopyContentFromID) {
$this->HasBrokenLink = !(bool) DataObject::get_by_id('SiteTree', $this->CopyContentFromID);
@ -136,7 +136,7 @@ class VirtualPage extends Page {
$this->HasBrokenLink = true;
}
}
/**
* We can only publish the page if there is a published source page
*
@ -146,11 +146,11 @@ class VirtualPage extends Page {
public function canPublish($member = null) {
return $this->isPublishable() && parent::canPublish($member);
}
/**
* Returns true if is page is publishable by anyone at all
* Return false if the source page isn't published yet.
*
*
* Note that isPublishable doesn't affect ete from live, only publish.
*/
public function isPublishable() {
@ -158,31 +158,31 @@ class VirtualPage extends Page {
if(!$this->CopyContentFrom() || !$this->CopyContentFrom()->ID) {
return false;
}
// Unpublished source
if(!Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->CopyContentFromID)) {
return false;
}
// Default - publishable
return true;
}
/**
* Generate the CMS fields from the fields from the original page.
*/
public function getCMSFields() {
$fields = parent::getCMSFields();
// Setup the linking to the original page.
$copyContentFromField = new TreeDropdownField(
"CopyContentFromID",
_t('VirtualPage.CHOOSE', "Linked Page"),
"CopyContentFromID",
_t('VirtualPage.CHOOSE', "Linked Page"),
"SiteTree"
);
// filter doesn't let you select children of virtual pages as as source page
//$copyContentFromField->setFilterFunction(create_function('$item', 'return !($item instanceof VirtualPage);'));
// Setup virtual fields
if($virtualFields = $this->getVirtualFields()) {
$roTransformation = new ReadonlyTransformation();
@ -193,16 +193,16 @@ class VirtualPage extends Page {
}
$msgs = array();
$fields->addFieldToTab("Root.Main", $copyContentFromField, "Title");
// Create links back to the original object in the CMS
if($this->CopyContentFrom()->exists()) {
$link = "<a class=\"cmsEditlink\" href=\"admin/pages/edit/show/$this->CopyContentFromID\">"
. _t('VirtualPage.EditLink', 'edit')
. "</a>";
$msgs[] = _t(
'VirtualPage.HEADERWITHLINK',
'VirtualPage.HEADERWITHLINK',
"This is a virtual page copying content from \"{title}\" ({link})",
array(
'title' => $this->CopyContentFrom()->obj('Title'),
@ -217,7 +217,7 @@ class VirtualPage extends Page {
);
}
if(
$this->CopyContentFromID
$this->CopyContentFromID
&& !Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->CopyContentFromID)
) {
$msgs[] = _t(
@ -226,21 +226,21 @@ class VirtualPage extends Page {
);
}
$fields->addFieldToTab("Root.Main",
$fields->addFieldToTab("Root.Main",
new LiteralField(
'VirtualPageMessage',
'<div class="message notice">' . implode('. ', $msgs) . '.</div>'
),
'CopyContentFromID'
);
return $fields;
}
public function getSettingsFields() {
$fields = parent::getSettingsFields();
if(!$this->CopyContentFrom()->exists()) {
$fields->addFieldToTab("Root.Settings",
$fields->addFieldToTab("Root.Settings",
new LiteralField(
'VirtualPageWarning',
'<div class="message notice">'
@ -256,8 +256,8 @@ class VirtualPage extends Page {
return $fields;
}
/**
/**
* We have to change it to copy all the content from the original page first.
*/
public function onBeforeWrite() {
@ -271,7 +271,7 @@ class VirtualPage extends Page {
) {
// On publication to live, copy from published source.
$performCopyFrom = true;
$stageSourceVersion = DB::prepared_query(
'SELECT "Version" FROM "SiteTree" WHERE "ID" = ?',
array($this->CopyContentFromID)
@ -280,7 +280,7 @@ class VirtualPage extends Page {
'SELECT "Version" FROM "SiteTree_Live" WHERE "ID" = ?',
array($this->CopyContentFromID)
)->value();
// We're going to create a new VP record in SiteTree_versions because the published
// version might not exist, unless we're publishing the latest version
if($stageSourceVersion != $liveSourceVersion) {
@ -290,7 +290,7 @@ class VirtualPage extends Page {
// On regular write, copy from draft source. This is only executed when the source page changes.
$performCopyFrom = $this->isChanged('CopyContentFromID', 2) && $this->CopyContentFromID != 0;
}
if($performCopyFrom && $this instanceof VirtualPage) {
// This flush is needed because the get_one cache doesn't respect site version :-(
singleton('SiteTree')->flushCache();
@ -299,10 +299,10 @@ class VirtualPage extends Page {
// Leave the updating of image tracking until after write, in case its a new record
$this->copyFrom($source, false);
}
parent::onBeforeWrite();
}
public function onAfterWrite() {
parent::onAfterWrite();
@ -310,7 +310,7 @@ class VirtualPage extends Page {
if(!$this->extension_instances['Versioned']->migratingVersion) {
if(
$this->isChanged('CopyContentFromID')
&& $this->CopyContentFromID != 0
&& $this->CopyContentFromID != 0
&& $this instanceof VirtualPage
) {
$this->updateImageTracking();
@ -359,8 +359,8 @@ class VirtualPage extends Page {
if(!$orig->stat('can_be_root') && !$this->ParentID) {
$result->error(
_t(
'VirtualPage.PageTypNotAllowedOnRoot',
'Original page type "{type}" is not allowed on the root level for this virtual page',
'VirtualPage.PageTypNotAllowedOnRoot',
'Original page type "{type}" is not allowed on the root level for this virtual page',
array('type' => $orig->i18n_singular_name())
),
'CAN_BE_ROOT_VIRTUAL'
@ -369,7 +369,7 @@ class VirtualPage extends Page {
return $result;
}
/**
* Ensure we have an up-to-date version of everything.
*
@ -381,7 +381,7 @@ class VirtualPage extends Page {
foreach($this->getVirtualFields() as $virtualField) {
$this->$virtualField = $source->$virtualField;
}
// We also want to copy certain, but only if we're copying the source page for the first
// time. After this point, the user is free to customise these for the virtual page themselves.
if($this->isChanged('CopyContentFromID', 2) && $this->CopyContentFromID != 0) {
@ -389,18 +389,18 @@ class VirtualPage extends Page {
$this->$fieldName = $source->$fieldName;
}
}
if($updateImageTracking) $this->updateImageTracking();
}
}
public function updateImageTracking() {
// Doesn't work on unsaved records
if(!$this->ID) return;
// Remove CopyContentFrom() from the cache
unset($this->components['CopyContentFrom']);
// Update ImageTracking
$this->ImageTracking()->setByIdList($this->CopyContentFrom()->ImageTracking()->column('ID'));
}
@ -412,12 +412,12 @@ class VirtualPage extends Page {
public function CMSTreeClasses($numChildrenMethod="numChildren") {
return parent::CMSTreeClasses($numChildrenMethod) . ' VirtualPage-' . $this->CopyContentFrom()->ClassName;
}
/**
* Allow attributes on the master page to pass
* through to the virtual page
*
* @param string $field
* @param string $field
* @return mixed
*/
public function __get($field) {
@ -429,11 +429,11 @@ class VirtualPage extends Page {
return $this->copyContentFrom()->$field;
}
}
/**
* Pass unrecognized method calls on to the original data object
*
* @param string $method
* @param string $method
* @param string $args
* @return mixed
*/
@ -452,14 +452,14 @@ class VirtualPage extends Page {
public function hasField($field) {
if(parent::hasField($field)) {
return true;
}
}
return $this->CopyContentFrom()->hasField($field);
}
}
/**
* Overwrite to also check for method on the original data object
*
* @param string $method
* @return bool
* @param string $method
* @return bool
*/
public function hasMethod($method) {
if(parent::hasMethod($method)) {
@ -488,11 +488,11 @@ class VirtualPage extends Page {
* @package cms
*/
class VirtualPage_Controller extends Page_Controller {
private static $allowed_actions = array(
'loadcontentall' => 'ADMIN',
);
/**
* Reloads the content if the version is different ;-)
*/
@ -501,7 +501,7 @@ class VirtualPage_Controller extends Page_Controller {
$this->failover->write();
return;
}
public function getViewer($action) {
$originalClass = get_class($this->CopyContentFrom());
if ($originalClass == 'SiteTree') $name = 'Page_Controller';
@ -509,7 +509,7 @@ class VirtualPage_Controller extends Page_Controller {
$controller = new $name();
return $controller->getViewer($action);
}
/**
* When the virtualpage is loaded, check to see if the versions are the same
* if not, reload the content.
@ -536,16 +536,16 @@ class VirtualPage_Controller extends Page_Controller {
echo "<li>Published $page->URLSegment";
}
}
/**
* Also check the original object's original controller for the method
*
* @param string $method
* @return bool
* @param string $method
* @return bool
*/
public function hasMethod($method) {
$haveIt = parent::hasMethod($method);
if (!$haveIt) {
if (!$haveIt) {
$originalClass = get_class($this->CopyContentFrom());
if ($originalClass == 'SiteTree') $name = 'ContentController';
else $name = $originalClass."_Controller";
@ -554,11 +554,11 @@ class VirtualPage_Controller extends Page_Controller {
}
return $haveIt;
}
/**
* Pass unrecognized method calls on to the original controller
*
* @param string $method
* @param string $method
* @param string $args
* @return mixed
*

View File

@ -25,7 +25,7 @@ class BrokenFilesReport extends SS_Report {
$classFilter = array(
"\"ClassName\" IN ($classParams) AND \"HasBrokenFile\" = 1" => $classes
);
$stage = isset($params['OnLive']) ? 'Live' : 'Stage';
return Versioned::get_by_stage('SiteTree', $stage, $classFilter);
}

View File

@ -11,7 +11,7 @@ class BrokenLinksReport extends SS_Report {
public function title() {
return _t('BrokenLinksReport.BROKENLINKS',"Broken links report");
}
public function sourceRecords($params, $sort, $limit) {
$join = '';
$sortBrokenReason = false;
@ -19,7 +19,7 @@ class BrokenLinksReport extends SS_Report {
$parts = explode(' ', $sort);
$field = $parts[0];
$direction = $parts[1];
if($field == 'AbsoluteLink') {
$sort = 'URLSegment ' . $direction;
} elseif($field == 'Subsite.Title') {
@ -38,13 +38,13 @@ class BrokenLinksReport extends SS_Report {
} else {
$ret = DataObject::get('SiteTree', $brokenFilter, $sort, $join, $limit);
}
$returnSet = new ArrayList();
if ($ret) foreach($ret as $record) {
$reason = false;
$isRedirectorPage = in_array($record->ClassName, ClassInfo::subclassesFor('RedirectorPage'));
$isVirtualPage = in_array($record->ClassName, ClassInfo::subclassesFor('VirtualPage'));
if ($isVirtualPage) {
if ($record->HasBrokenLink) {
$reason = _t('BrokenLinksReport.VirtualPageNonExistent', "virtual page pointing to non-existent page");
@ -67,16 +67,16 @@ class BrokenLinksReport extends SS_Report {
$reasonCodes = array("BROKENFILE");
}
}
if ($reason) {
if (isset($params['Reason']) && $params['Reason'] && !in_array($params['Reason'], $reasonCodes)) continue;
$record->BrokenReason = $reason;
$returnSet->push($record);
}
}
if($sortBrokenReason) $returnSet = $returnSet->sort('BrokenReason', $direction);
return $returnSet;
}
public function columns() {
@ -85,7 +85,7 @@ class BrokenLinksReport extends SS_Report {
} else {
$dateTitle = _t('BrokenLinksReport.ColumnDateLastPublished', 'Date last published');
}
$linkBase = singleton('CMSPageEditController')->Link('show');
$fields = array(
"Title" => array(
@ -118,7 +118,7 @@ class BrokenLinksReport extends SS_Report {
}
)
);
return $fields;
}
public function parameterFields() {

View File

@ -13,7 +13,7 @@ class BrokenRedirectorPagesReport extends SS_Report {
public function group() {
return _t('SideReport.BrokenLinksGroupTitle', "Broken links reports");
}
public function sourceRecords($params = null) {
$classes = ClassInfo::subclassesFor('RedirectorPage');
$classParams = DB::placeholders($classes);
@ -23,7 +23,7 @@ class BrokenRedirectorPagesReport extends SS_Report {
$stage = isset($params['OnLive']) ? 'Live' : 'Stage';
return Versioned::get_by_stage('SiteTree', $stage, $classFilter);
}
public function columns() {
return array(
"Title" => array(
@ -32,7 +32,7 @@ class BrokenRedirectorPagesReport extends SS_Report {
),
);
}
public function getParameterFields() {
return new FieldList(
new CheckboxField('OnLive', _t('SideReport.ParameterLiveCheckbox', 'Check live site'))

View File

@ -23,7 +23,7 @@ class BrokenVirtualPagesReport extends SS_Report {
$stage = isset($params['OnLive']) ? 'Live' : 'Stage';
return Versioned::get_by_stage('SiteTree', $stage, $classFilter);
}
public function columns() {
return array(
"Title" => array(

View File

@ -22,7 +22,7 @@ class RecentlyEditedReport extends SS_Report {
$threshold = strtotime('-14 days', SS_Datetime::now()->Format('U'));
return DataObject::get("SiteTree", "\"SiteTree\".\"LastEdited\" > '".date("Y-m-d H:i:s", $threshold)."'", "\"SiteTree\".\"LastEdited\" DESC");
}
public function columns() {
return array(
"Title" => array(

View File

@ -13,24 +13,24 @@
* @subpackage search
*/
class SearchForm extends Form {
/**
* @var int $pageLength How many results are shown per page.
* Relies on pagination being implemented in the search results template.
*/
protected $pageLength = 10;
/**
* Classes to search
*/
*/
protected $classesToSearch = array(
"SiteTree", "File"
);
private static $casting = array(
'SearchQuery' => 'Text'
);
/**
*
* @param Controller $controller
@ -45,25 +45,25 @@ class SearchForm extends Form {
new TextField('Search', _t('SearchForm.SEARCH', 'Search')
));
}
if(class_exists('Translatable') && singleton('SiteTree')->hasExtension('Translatable')) {
$fields->push(new HiddenField('searchlocale', 'searchlocale', Translatable::get_current_locale()));
}
if(!$actions) {
$actions = new FieldList(
new FormAction("getResults", _t('SearchForm.GO', 'Go'))
);
}
parent::__construct($controller, $name, $fields, $actions);
$this->setFormMethod('get');
$this->disableSecurityToken();
}
/**
* Return a rendered version of this form.
*
@ -91,10 +91,10 @@ class SearchForm extends Form {
if($illegalClasses) {
user_error("SearchForm::classesToSearch() passed illegal classes '" . implode("', '", $illegalClasses) . "'. At this stage, only File and SiteTree are allowed", E_USER_WARNING);
}
$legalClasses = array_intersect($classes, array('SiteTree', 'File'));
$legalClasses = array_intersect($classes, array('SiteTree', 'File'));
$this->classesToSearch = $legalClasses;
}
/**
* Get the classes to search
*
@ -115,7 +115,7 @@ class SearchForm extends Form {
public function getResults($pageLength = null, $data = null){
// legacy usage: $data was defaulting to $_REQUEST, parameter not passed in doc.silverstripe.org tutorials
if(!isset($data) || !is_array($data)) $data = $_REQUEST;
// set language (if present)
if(class_exists('Translatable')) {
if(singleton('SiteTree')->hasExtension('Translatable') && isset($data['searchlocale'])) {
@ -142,23 +142,23 @@ class SearchForm extends Form {
$keywords = preg_replace_callback('/(^| )([^() ]+)( and )([^ ()]+)( |$)/i', $andProcessor, $keywords);
$keywords = preg_replace_callback('/(^| )(not )("[^"()]+")/i', $notProcessor, $keywords);
$keywords = preg_replace_callback('/(^| )(not )([^() ]+)( |$)/i', $notProcessor, $keywords);
$keywords = $this->addStarsToKeywords($keywords);
if(!$pageLength) $pageLength = $this->pageLength;
$start = isset($_GET['start']) ? (int)$_GET['start'] : 0;
if(strpos($keywords, '"') !== false || strpos($keywords, '+') !== false || strpos($keywords, '-') !== false || strpos($keywords, '*') !== false) {
$results = DB::get_conn()->searchEngine($this->classesToSearch, $keywords, $start, $pageLength, "\"Relevance\" DESC", "", true);
} else {
$results = DB::get_conn()->searchEngine($this->classesToSearch, $keywords, $start, $pageLength);
}
// filter by permission
if($results) foreach($results as $result) {
if(!$result->canView()) $results->remove($result);
}
// reset locale
if(class_exists('Translatable')) {
if(singleton('SiteTree')->hasExtension('Translatable') && isset($data['searchlocale'])) {
@ -190,7 +190,7 @@ class SearchForm extends Form {
}
return implode(" ", $newWords);
}
/**
* Get the search query for display in a "You searched for ..." sentence.
*
@ -200,11 +200,11 @@ class SearchForm extends Form {
public function getSearchQuery($data = null) {
// legacy usage: $data was defaulting to $_REQUEST, parameter not passed in doc.silverstripe.org tutorials
if(!isset($data)) $data = $_REQUEST;
// The form could be rendered without the search being done, so check for that.
if (isset($data['Search'])) return $data['Search'];
}
/**
* Set the maximum number of records shown on each page.
*
@ -213,7 +213,7 @@ class SearchForm extends Form {
public function setPageLength($length) {
$this->pageLength = $length;
}
/**
* @return int
*/

View File

@ -6,11 +6,11 @@
* @subpackage tasks
*/
class MigrateSiteTreeLinkingTask extends BuildTask {
protected $title = 'Migrate SiteTree Linking Task';
protected $description = 'Rewrites plain internal HTML links into shortcode form, using existing link tracking information.';
public function run($request) {
$pages = 0;
$links = 0;
@ -25,7 +25,7 @@ class MigrateSiteTreeLinkingTask extends BuildTask {
foreach($tracking as $childID => $fieldName) {
$linked = DataObject::get_by_id('SiteTree', $childID);
// TOOD: Replace in all HTMLText fields
$page->Content = preg_replace (
"/href *= *([\"']?){$linked->URLSegment}\/?/i",
@ -34,17 +34,17 @@ class MigrateSiteTreeLinkingTask extends BuildTask {
-1,
$replaced
);
if($replaced) {
$links += $replaced;
}
}
$page->write();
$pages++;
}
echo "Rewrote $links link(s) on $pages page(s) to use shortcodes.\n";
}
}

View File

@ -22,16 +22,16 @@
*/
//class RemoveOrphanedPagesTask extends BuildTask {
class RemoveOrphanedPagesTask extends Controller {
private static $allowed_actions = array(
'index' => 'ADMIN',
'Form' => 'ADMIN',
'run' => 'ADMIN',
'handleAction' => 'ADMIN',
);
protected $title = 'Removed orphaned pages without existing parents from both stage and live';
protected $description = "
<p>
Identify 'orphaned' pages which point to a parent
@ -45,33 +45,33 @@ in the other stage:<br />
- A stage child is orphaned if its parent was deleted from stage, but still exists on live
</p>
";
protected $orphanedSearchClass = 'SiteTree';
public function Link() {
return $this->class;
}
public function init() {
parent::init();
if(!Permission::check('ADMIN')) {
return Security::permissionFailure($this);
}
}
public function index() {
Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js');
Requirements::customCSS('#OrphanIDs .middleColumn {width: auto;}');
Requirements::customCSS('#OrphanIDs label {display: inline;}');
return $this->renderWith('BlankPage');
}
public function Form() {
$fields = new FieldList();
$source = array();
$fields->push(new HeaderField(
'Header',
_t('RemoveOrphanedPagesTask.HEADER', 'Remove all orphaned pages task')
@ -80,7 +80,7 @@ in the other stage:<br />
'Description',
$this->description
));
$orphans = $this->getOrphanedPages($this->orphanedSearchClass);
if($orphans) foreach($orphans as $orphan) {
$latestVersion = Versioned::get_latest_version($this->orphanedSearchClass, $orphan->ID);
@ -107,7 +107,7 @@ in the other stage:<br />
);
$source[$orphan->ID] = $label;
}
if($orphans && $orphans->Count()) {
$fields->push(new CheckboxSetField('OrphanIDs', false, $source));
$fields->push(new LiteralField(
@ -157,7 +157,7 @@ in the other stage:<br />
)
));
}
$form = new Form(
$this,
'Form',
@ -166,23 +166,23 @@ in the other stage:<br />
new FormAction('doSubmit', _t('RemoveOrphanedPagesTask.BUTTONRUN', 'Run'))
)
);
if(!$orphans || !$orphans->Count()) {
$form->makeReadonly();
}
return $form;
}
public function run($request) {
// @todo Merge with BuildTask functionality
}
public function doSubmit($data, $form) {
set_time_limit(60*10); // 10 minutes
if(!isset($data['OrphanIDs']) || !isset($data['OrphanOperation'])) return false;
switch($data['OrphanOperation']) {
case 'remove':
$successIDs = $this->removeOrphans($data['OrphanIDs']);
@ -193,7 +193,7 @@ in the other stage:<br />
default:
user_error(sprintf("Unknown operation: '%s'", $data['OrphanOperation']), E_USER_ERROR);
}
$content = '';
if($successIDs) {
$content .= "<ul>";
@ -204,13 +204,13 @@ in the other stage:<br />
} else {
$content = _t('RemoveOrphanedPagesTask.NONEREMOVED', 'None removed');
}
return $this->customise(array(
'Content' => $content,
'Form' => ' '
))->renderWith('BlankPage');
}
protected function removeOrphans($orphanIDs) {
$removedOrphans = array();
$orphanBaseClass = ClassInfo::baseDataClass($this->orphanedSearchClass);
@ -240,14 +240,14 @@ in the other stage:<br />
unset($liveRecord);
}
}
return $removedOrphans;
}
protected function rebaseHolderTitle() {
return sprintf('Rebased Orphans (%s)', date('d/m/Y g:ia', time()));
}
protected function rebaseOrphans($orphanIDs) {
$holder = new SiteTree();
$holder->ShowInMenus = 0;
@ -255,7 +255,7 @@ in the other stage:<br />
$holder->ParentID = 0;
$holder->Title = $this->rebaseHolderTitle();
$holder->write();
$removedOrphans = array();
$orphanBaseClass = ClassInfo::baseDataClass($this->orphanedSearchClass);
foreach($orphanIDs as $id) {
@ -294,10 +294,10 @@ in the other stage:<br />
unset($stageRecord);
}
}
return $removedOrphans;
}
/**
* Gets all orphans from "Stage" and "Live" stages.
*
@ -315,7 +315,7 @@ in the other stage:<br />
else $where = array($filter);
$where[] = array("\"$class\".\"ParentID\" != ?" => 0);
$where[] = '"Parents"."ID" IS NULL';
$orphans = new ArrayList();
foreach(array('Stage', 'Live') as $stage) {
$joinByStage = $join;
@ -331,9 +331,9 @@ in the other stage:<br />
)->leftJoin($table, "\"$table\".\"ParentID\" = \"Parents\".\"ID\"", "Parents");
$orphans->merge($stageOrphans);
}
$orphans->removeDuplicates();
return $orphans;
}
}

View File

@ -7,7 +7,7 @@ class SiteTreeMaintenanceTask extends Controller {
private static $allowed_actions = array(
'*' => 'ADMIN'
);
public function makelinksunique() {
$badURLs = "'" . implode("', '", DB::query("SELECT URLSegment, count(*) FROM SiteTree GROUP BY URLSegment HAVING count(*) > 1")->column()) . "'";
$pages = DataObject::get("SiteTree", "\"SiteTree\".\"URLSegment\" IN ($badURLs)");

View File

@ -4,13 +4,13 @@
* @subpackage tasks
*/
class UpgradeSiteTreePermissionSchemaTask extends BuildTask {
private static $allowed_actions = array(
'*' => 'ADMIN'
);
protected $title = 'Upgrade SiteTree Permissions Schema';
protected $description = "Move data from legacy columns to new schema introduced in SilverStripe 2.1.<br />
SiteTree->Viewers to SiteTree->CanViewType<br />
SiteTree->Editors to SiteTree->CanEditType<br />
@ -18,7 +18,7 @@ class UpgradeSiteTreePermissionSchemaTask extends BuildTask {
SiteTree->Editorsroup to SiteTree->EditorGroups (has_one to many_many)<br />
See http://open.silverstripe.com/ticket/2847
";
public function run($request) {
// transfer values for changed column name
foreach(array('SiteTree','SiteTree_Live','SiteTree_versions') as $table) {
@ -27,25 +27,25 @@ class UpgradeSiteTreePermissionSchemaTask extends BuildTask {
}
//Debug::message('Moved SiteTree->Viewers to SiteTree->CanViewType');
//Debug::message('Moved SiteTree->Editors to SiteTree->CanEditType');
// convert has_many to many_many
$pageIDs = DB::query("SELECT ID FROM SiteTree")->column('ID');
foreach($pageIDs as $pageID) {
$page = DataObject::get_by_id('SiteTree', $pageID);
if($page->ViewersGroup && DataObject::get_by_id("Group", $page->ViewersGroup)) $page->ViewerGroups()->add($page->ViewersGroup);
if($page->EditorsGroup && DataObject::get_by_id("Group", $page->EditorsGroup)) $page->EditorGroups()->add($page->EditorsGroup);
$page->destroy();
unset($page);
}
//Debug::message('SiteTree->ViewersGroup to SiteTree->ViewerGroups (has_one to many_many)');
//Debug::message('SiteTree->EditorsGroup to SiteTree->EditorGroups (has_one to many_many)');
// rename legacy columns
foreach(array('SiteTree','SiteTree_Live','SiteTree_versions') as $table) {
foreach(array('Viewers','Editors','ViewersGroup','EditorsGroup') as $field) {
DB::get_conn()->dontRequireField($table, $field);
}
}
}
}
}

View File

@ -40,7 +40,7 @@ class FixtureContext extends \SilverStripe\BehatExtension\Context\FixtureContext
$obj->write();
$obj->publish('Stage', 'Live');
}
/**
*
* Check if the user can edit a page

View File

@ -18,7 +18,7 @@ class CMSBatchActionsTest extends SapphireTest {
// Deleted / archived page
$archived = $this->objFromFixture('SiteTree', 'archived');
$archived->doArchive(); // should archive all children
// Unpublished
$unpublished = $this->objFromFixture('SiteTree', 'unpublished');
$unpublished->doPublish();
@ -103,7 +103,7 @@ class CMSBatchActionsTest extends SapphireTest {
$this->assertContains($this->idFromFixture('SiteTree', 'archivedx'), $applicable);
$this->assertContains($this->idFromFixture('SiteTree', 'archivedy'), $applicable);
$this->assertNotContains($this->idFromFixture('SiteTree', 'unpublished'), $applicable);
$this->assertNotContains($this->idFromFixture('SiteTree', 'modified'), $applicable);
$this->assertNotContains($this->idFromFixture('SiteTree', 'modified'), $applicable);
}
public function testBatchRestore() {

View File

@ -6,46 +6,46 @@
*/
class CMSPageHistoryControllerTest extends FunctionalTest {
protected static $fixture_file = 'CMSPageHistoryControllerTest.yml';
private $versionUnpublishedCheck, $versionPublishCheck, $versionUnpublishedCheck2;
private $page;
public function setUp() {
parent::setUp();
$this->loginWithPermission('ADMIN');
// creates a series of published, unpublished versions of a page
$this->page = new Page();
$this->page->URLSegment = "test";
$this->page->Content = "new content";
$this->page->write();
$this->versionUnpublishedCheck = $this->page->Version;
$this->page->Content = "some further content";
$this->page->write();
$this->page->publish('Stage', 'Live');
$this->versionPublishCheck = $this->page->Version;
$this->page->Content = "No, more changes please";
$this->page->Title = "Changing titles too";
$this->page->write();
$this->versionUnpublishedCheck2 = $this->page->Version;
$this->page->Title = "Final Change";
$this->page->write();
$this->page->publish('Stage', 'Live');
$this->versionPublishCheck2 = $this->page->Version;
}
public function testGetEditForm() {
$controller = new CMSPageHistoryController();
// should get the latest version which we cannot rollback to
$form = $controller->getEditForm($this->page->ID);
$this->assertTrue($form->Actions()->dataFieldByName('action_doRollback')->isReadonly());
$this->assertEquals($this->page->ID, $form->Fields()->dataFieldByName('ID')->Value());
@ -55,7 +55,7 @@ class CMSPageHistoryControllerTest extends FunctionalTest {
'Currently viewing the latest version',
$form->Fields()->fieldByName('Root.Main.CurrentlyViewingMessage')->getContent()
);
// edit form with a given version
$form = $controller->getEditForm($this->page->ID, null, $this->versionPublishCheck);
$this->assertFalse($form->Actions()->dataFieldByName('action_doRollback')->isReadonly());
@ -66,14 +66,14 @@ class CMSPageHistoryControllerTest extends FunctionalTest {
sprintf("Currently viewing version %s.", $this->versionPublishCheck),
$form->Fields()->fieldByName('Root.Main.CurrentlyViewingMessage')->getContent()
);
// check that compare mode updates the message
$form = $controller->getEditForm($this->page->ID, null, $this->versionPublishCheck, $this->versionPublishCheck2);
$this->assertContains(
sprintf("Comparing versions %s", $this->versionPublishCheck),
$form->Fields()->fieldByName('Root.Main.CurrentlyViewingMessage')->getContent()
);
$this->assertContains(
sprintf("and %s", $this->versionPublishCheck2),
$form->Fields()->fieldByName('Root.Main.CurrentlyViewingMessage')->getContent()
@ -87,32 +87,32 @@ class CMSPageHistoryControllerTest extends FunctionalTest {
public function testVersionsForm() {
$history = $this->get('admin/pages/history/show/'. $this->page->ID);
$form = $this->cssParser()->getBySelector('#Form_VersionsForm');
$this->assertEquals(1, count($form));
// check the page ID is present
$hidden = $form[0]->xpath("fieldset/input[@type='hidden']");
$this->assertThat($hidden, $this->logicalNot($this->isNull()), 'Hidden ID field exists');
$this->assertEquals($this->page->ID, (int) $hidden[0]->attributes()->value);
// ensure that all the versions are present in the table and displayed
$rows = $form[0]->xpath("fieldset/table/tbody/tr");
$this->assertEquals(4, count($rows));
}
public function testVersionsFormTableContainsInformation() {
$history = $this->get('admin/pages/history/show/'. $this->page->ID);
$form = $this->cssParser()->getBySelector('#Form_VersionsForm');
$rows = $form[0]->xpath("fieldset/table/tbody/tr");
$expected = array(
array('version' => $this->versionPublishCheck2, 'status' => 'published'),
array('version' => $this->versionUnpublishedCheck2, 'status' => 'internal'),
array('version' => $this->versionPublishCheck, 'status' => 'published'),
array('version' => $this->versionUnpublishedCheck, 'status' => 'internal')
);
// goes the reverse order that we created in setUp()
$i = 0;
foreach($rows as $tr) {
@ -120,12 +120,12 @@ class CMSPageHistoryControllerTest extends FunctionalTest {
$this->assertContains($expected[$i]['status'], (string) $tr->attributes()->class);
$i++;
}
// test highlighting
$this->assertContains('active', (string) $rows[0]->attributes()->class);
$this->assertThat((string) $rows[1]->attributes()->class, $this->logicalNot($this->stringContains('active')));
}
public function testVersionsFormSelectsUnpublishedCheckbox() {
$history = $this->get('admin/pages/history/show/'. $this->page->ID);
$checkbox = $this->cssParser()->getBySelector('#Form_VersionsForm_ShowUnpublished');
@ -134,7 +134,7 @@ class CMSPageHistoryControllerTest extends FunctionalTest {
$checked = $checkbox[0]->attributes()->checked;
$this->assertThat($checked, $this->logicalNot($this->stringContains('checked')));
// viewing an unpublished
$history = $this->get('admin/pages/history/show/'.$this->page->ID .'/'.$this->versionUnpublishedCheck);
$checkbox = $this->cssParser()->getBySelector('#Form_VersionsForm_ShowUnpublished');

View File

@ -2,25 +2,25 @@
class CMSSiteTreeFilterTest extends SapphireTest {
protected static $fixture_file = 'CMSSiteTreeFilterTest.yml';
public function testSearchFilterEmpty() {
$page1 = $this->objFromFixture('Page', 'page1');
$page2 = $this->objFromFixture('Page', 'page2');
$f = new CMSSiteTreeFilter_Search();
$results = $f->pagesIncluded();
$this->assertTrue($f->isPageIncluded($page1));
$this->assertTrue($f->isPageIncluded($page2));
}
public function testSearchFilterByTitle() {
$page1 = $this->objFromFixture('Page', 'page1');
$page2 = $this->objFromFixture('Page', 'page2');
$f = new CMSSiteTreeFilter_Search(array('Title' => 'Page 1'));
$results = $f->pagesIncluded();
$this->assertTrue($f->isPageIncluded($page1));
$this->assertFalse($f->isPageIncluded($page2));
$this->assertEquals(1, count($results));
@ -29,14 +29,14 @@ class CMSSiteTreeFilterTest extends SapphireTest {
$results[0]
);
}
public function testIncludesParentsForNestedMatches() {
$parent = $this->objFromFixture('Page', 'page3');
$child = $this->objFromFixture('Page', 'page3b');
$f = new CMSSiteTreeFilter_Search(array('Title' => 'Page 3b'));
$results = $f->pagesIncluded();
$this->assertTrue($f->isPageIncluded($parent));
$this->assertTrue($f->isPageIncluded($child));
$this->assertEquals(1, count($results));
@ -45,21 +45,21 @@ class CMSSiteTreeFilterTest extends SapphireTest {
$results[0]
);
}
public function testChangedPagesFilter() {
$unchangedPage = $this->objFromFixture('Page', 'page1');
$unchangedPage->doPublish();
$changedPage = $this->objFromFixture('Page', 'page2');
$changedPage->Title = 'Original';
$changedPage->publish('Stage', 'Live');
$changedPage->Title = 'Changed';
$changedPage->write();
// Check that only changed pages are returned
$f = new CMSSiteTreeFilter_ChangedPages(array('Term' => 'Changed'));
$results = $f->pagesIncluded();
$this->assertTrue($f->isPageIncluded($changedPage));
$this->assertFalse($f->isPageIncluded($unchangedPage));
$this->assertEquals(1, count($results));
@ -67,7 +67,7 @@ class CMSSiteTreeFilterTest extends SapphireTest {
array('ID' => $changedPage->ID, 'ParentID' => 0),
$results[0]
);
// Check that only changed pages are returned
$f = new CMSSiteTreeFilter_ChangedPages(array('Term' => 'No Matches'));
$results = $f->pagesIncluded();
@ -84,7 +84,7 @@ class CMSSiteTreeFilterTest extends SapphireTest {
$this->assertEquals(1, count($results));
$this->assertEquals(array('ID' => $changedPage->ID, 'ParentID' => 0), $results[0]);
}
public function testDeletedPagesFilter() {
$deletedPage = $this->objFromFixture('Page', 'page2');
$deletedPage->publish('Stage', 'Live');
@ -98,12 +98,12 @@ class CMSSiteTreeFilterTest extends SapphireTest {
$f = new CMSSiteTreeFilter_DeletedPages(array('Term' => 'Page'));
$this->assertTrue($f->isPageIncluded($deletedPage));
// Check that only changed pages are returned
$f = new CMSSiteTreeFilter_DeletedPages(array('Term' => 'No Matches'));
$this->assertFalse($f->isPageIncluded($deletedPage));
}
public function testStatusDraftPagesFilter() {
$draftPage = $this->objFromFixture('Page', 'page4');
$draftPage->publish('Stage', 'Stage');
@ -116,15 +116,15 @@ class CMSSiteTreeFilterTest extends SapphireTest {
// Check draft page is shown
$f = new CMSSiteTreeFilter_StatusDraftPages(array('Term' => 'Page'));
$this->assertTrue($f->isPageIncluded($draftPage));
// Check filter respects parameters
$f = new CMSSiteTreeFilter_StatusDraftPages(array('Term' => 'No Match'));
$this->assertEmpty($f->isPageIncluded($draftPage));
// Ensures empty array returned if no data to show
$f = new CMSSiteTreeFilter_StatusDraftPages();
$draftPage->delete();
$this->assertEmpty($f->isPageIncluded($draftPage));
$this->assertEmpty($f->isPageIncluded($draftPage));
}
public function testDateFromToLastSameDate() {
@ -138,7 +138,7 @@ class CMSSiteTreeFilterTest extends SapphireTest {
));
$this->assertTrue($filter->isPageIncluded($draftPage), 'Using the same date for from and to should show find that page');
}
public function testStatusRemovedFromDraftFilter() {
$removedDraftPage = $this->objFromFixture('Page', 'page6');
$removedDraftPage->doPublish();
@ -156,18 +156,18 @@ class CMSSiteTreeFilterTest extends SapphireTest {
// Check filter is respected
$f = new CMSSiteTreeFilter_StatusRemovedFromDraftPages(array('LastEditedTo' => '1999-01-01 00:00'));
$this->assertEmpty($f->isPageIncluded($removedDraftPage));
// Ensures empty array returned if no data to show
$f = new CMSSiteTreeFilter_StatusRemovedFromDraftPages();
$removedDraftPage->delete();
$this->assertEmpty($f->isPageIncluded($removedDraftPage));
}
public function testStatusDeletedFilter() {
$deletedPage = $this->objFromFixture('Page', 'page7');
$deletedPage->publish('Stage', 'Live');
$deletedPageID = $deletedPage->ID;
// Can't use straight $blah->delete() as that blows it away completely and test fails
$deletedPage->deleteFromStage('Live');
$deletedPage->deleteFromStage('Draft');
@ -176,7 +176,7 @@ class CMSSiteTreeFilterTest extends SapphireTest {
// Check deleted page is included
$f = new CMSSiteTreeFilter_StatusDeletedPages(array('Title' => 'Page'));
$this->assertTrue($f->isPageIncluded($checkParentExists));
// Check filter is respected
$f = new CMSSiteTreeFilter_StatusDeletedPages(array('Title' => 'Bobby'));
$this->assertFalse($f->isPageIncluded($checkParentExists));

View File

@ -4,11 +4,11 @@
* @subpackage tests
*/
class ContentControllerPermissionsTest extends FunctionalTest {
protected $usesDatabase = true;
protected $autoFollowRedirection = false;
public function testCanViewStage() {
// Create a new page
$page = new Page();
@ -22,7 +22,7 @@ class ContentControllerPermissionsTest extends FunctionalTest {
$response = $this->get('/testpage');
$this->assertEquals($response->getStatusCode(), 200, "Doesn't require login for implicit live stage");
$response = $this->get('/testpage/?stage=Live');
$this->assertEquals($response->getStatusCode(), 200, "Doesn't require login for explicit live stage");
@ -37,12 +37,12 @@ class ContentControllerPermissionsTest extends FunctionalTest {
Config::inst()->get('Security', 'login_url'),
$response->getHeader('Location')
);
$this->logInWithPermission('CMS_ACCESS_CMSMain');
$response = $this->get('/testpage/?stage=Stage');
$this->assertEquals($response->getStatusCode(), 200, 'Doesnt redirect to login, but shows page for authenticated user');
}
}

View File

@ -9,7 +9,7 @@ class ContentControllerSearchExtensionTest extends SapphireTest {
$page->publish('Stage', 'Live');
$controller = new ContentController($page);
$form = $controller->SearchForm();
if (get_class($form) == 'SearchForm') $this->assertEquals(array('File'), $form->getClassesToSearch());
}

View File

@ -4,11 +4,11 @@
* @subpackage tests
*/
class ModelAsControllerTest extends FunctionalTest {
protected $usesDatabase = true;
protected static $fixture_file = 'ModelAsControllerTest.yml';
protected $autoFollowRedirection = false;
protected $orig = array();
@ -33,11 +33,11 @@ class ModelAsControllerTest extends FunctionalTest {
* after the tests have been performed.
*/
public function tearDown() {
if (isset($this->orig['nested_urls']) && !$this->orig['nested_urls']) {
SiteTree::config()->nested_urls = false;
}
parent::tearDown();
parent::tearDown();
}
@ -47,34 +47,34 @@ class ModelAsControllerTest extends FunctionalTest {
$level1->URLSegment = 'level1';
$level1->write();
$level1->publish('Stage', 'Live');
$level1->URLSegment = 'newlevel1';
$level1->write();
$level1->publish('Stage', 'Live');
$level2 = new Page();
$level2->Title = 'Second Level';
$level2->URLSegment = 'level2';
$level2->ParentID = $level1->ID;
$level2->write();
$level2->publish('Stage', 'Live');
$level2->URLSegment = 'newlevel2';
$level2->write();
$level2->publish('Stage', 'Live');
$level3 = New Page();
$level3->Title = "Level 3";
$level3->URLSegment = 'level3';
$level3->ParentID = $level2->ID;
$level3->write();
$level3->publish('Stage','Live');
$level3->URLSegment = 'newlevel3';
$level3->write();
$level3->publish('Stage','Live');
}
/**
* We're building up a page hierarchy ("nested URLs") and rename
* all the individual pages afterwards. The assumption is that
@ -87,7 +87,7 @@ class ModelAsControllerTest extends FunctionalTest {
*/
public function testRedirectsNestedRenamedPages(){
$this->generateNestedPagesFixture();
// check a first level URLSegment
$response = $this->get('level1/action');
$this->assertEquals($response->getStatusCode(),301);
@ -95,7 +95,7 @@ class ModelAsControllerTest extends FunctionalTest {
Controller::join_links(Director::baseURL() . 'newlevel1/action'),
$response->getHeader('Location')
);
// check second level URLSegment
$response = $this->get('newlevel1/level2');
$this->assertEquals($response->getStatusCode(),301 );
@ -103,7 +103,7 @@ class ModelAsControllerTest extends FunctionalTest {
Controller::join_links(Director::baseURL() . 'newlevel1/newlevel2/'),
$response->getHeader('Location')
);
// check third level URLSegment
$response = $this->get('newlevel1/newlevel2/level3');
$this->assertEquals($response->getStatusCode(), 301);
@ -111,7 +111,7 @@ class ModelAsControllerTest extends FunctionalTest {
Controller::join_links(Director::baseURL() . 'newlevel1/newlevel2/newlevel3/'),
$response->getHeader('Location')
);
$response = $this->get('newlevel1/newlevel2/level3');
}
@ -126,7 +126,7 @@ class ModelAsControllerTest extends FunctionalTest {
$page->URLSegment = 'oldurl';
$page->write();
$page->publish('Stage', 'Live');
$page->URLSegment = 'newurl';
$page->write();
$page->publish('Stage', 'Live');
@ -137,21 +137,21 @@ class ModelAsControllerTest extends FunctionalTest {
$page2->ParentID = $page->ID;
$page2->write();
$page2->publish('Stage', 'Live');
$page3 = new Page();
$page3->Title = 'Third Level Page';
$page3->URLSegment = 'level3';
$page3->ParentID = $page2->ID;
$page3->write();
$page3->publish('Stage', 'Live');
$page4 = new Page();
$page4->Title = 'Fourth Level Page';
$page4->URLSegment = 'level4';
$page4->ParentID = $page3->ID;
$page4->write();
$page4->publish('Stage', 'Live');
$page5 = new Page();
$page5->Title = 'Fifth Level Page';
$page5->URLSegment = 'level5';
@ -187,13 +187,13 @@ class ModelAsControllerTest extends FunctionalTest {
public function testDoesntRedirectToNestedChildrenOutsideOfOwnHierarchy() {
$this->generateNestedPagesFixture();
$otherParent = new Page(array(
'URLSegment' => 'otherparent'
));
$otherParent->write();
$otherParent->publish('Stage', 'Live');
$response = $this->get('level1/otherparent');
$this->assertEquals($response->getStatusCode(), 301);
@ -204,7 +204,7 @@ class ModelAsControllerTest extends FunctionalTest {
'Requesting an unrelated page on a renamed parent should be interpreted as a missing action, not a redirect'
);
}
/**
*
* NOTE: This test requires nested_urls
@ -212,7 +212,7 @@ class ModelAsControllerTest extends FunctionalTest {
*/
public function testRedirectsNestedRenamedPagesWithGetParameters() {
$this->generateNestedPagesFixture();
// check third level URLSegment
$response = $this->get('newlevel1/newlevel2/level3/?foo=bar&test=test');
$this->assertEquals($response->getStatusCode(), 301);
@ -221,7 +221,7 @@ class ModelAsControllerTest extends FunctionalTest {
$response->getHeader('Location')
);
}
/**
*
* NOTE: This test requires nested_urls
@ -229,20 +229,20 @@ class ModelAsControllerTest extends FunctionalTest {
*/
public function testDoesntRedirectToNestedRenamedPageWhenNewExists() {
$this->generateNestedPagesFixture();
$otherLevel1 = new Page(array(
'Title' => "Other Level 1",
'URLSegment' => 'level1'
));
$otherLevel1->write();
$otherLevel1->publish('Stage', 'Live');
$response = $this->get('level1');
$this->assertEquals(
$response->getStatusCode(),
200
);
$response = $this->get('level1/newlevel2');
$this->assertEquals(
$response->getStatusCode(),
@ -250,7 +250,7 @@ class ModelAsControllerTest extends FunctionalTest {
'The old newlevel2/ URLSegment is checked as an action on the new page, which shouldnt exist.'
);
}
/**
*
* NOTE: This test requires nested_urls
@ -262,30 +262,30 @@ class ModelAsControllerTest extends FunctionalTest {
$page->URLSegment = 'oldurl';
$page->write();
$page->publish('Stage', 'Live');
$page->URLSegment = 'newurl';
$page->write();
$page->publish('Stage', 'Live');
$url = OldPageRedirector::find_old_page('oldurl');
$matchedPage = SiteTree::get_by_link($url);
$this->assertEquals('First Level',$matchedPage->Title);
$page2 = new Page();
$page2->Title = 'Second Level Page';
$page2->URLSegment = 'oldpage2';
$page2->ParentID = $page->ID;
$page2->write();
$page2->publish('Stage', 'Live');
$page2->URLSegment = 'newpage2';
$page2->write();
$page2->publish('Stage', 'Live');
$url = OldPageRedirector::find_old_page('oldpage2',$page2->ParentID);
$matchedPage = SiteTree::get_by_link($url);
$this->assertEquals('Second Level Page',$matchedPage->Title);
$url = OldPageRedirector::find_old_page('oldpage2',$page2->ID);
$matchedPage = SiteTree::get_by_link($url);
$this->assertEquals(false, $matchedPage);

View File

@ -5,14 +5,14 @@
*/
class RootURLControllerTest extends SapphireTest {
protected static $fixture_file = 'RootURLControllerTest.yml';
public function testGetHomepageLink() {
$default = $this->objFromFixture('Page', 'home');
SiteTree::config()->nested_urls = false;
$this->assertEquals('home', RootURLController::get_homepage_link());
Config::inst()->update('SiteTree', 'nested_urls', true);
$this->assertEquals('home', RootURLController::get_homepage_link());
}
}

View File

@ -5,30 +5,30 @@
*/
class SilverStripeNavigatorTest extends SapphireTest {
protected static $fixture_file = 'cms/tests/controller/CMSMainTest.yml';
public function testGetItems() {
$page = $this->objFromFixture('Page', 'page1');
$navigator = new SilverStripeNavigator($page);
$items = $navigator->getItems();
$classes = array_map('get_class', $items->toArray());
$this->assertContains('SilverStripeNavigatorItem_StageLink', $classes,
'Adds default classes'
);
$this->assertContains('SilverStripeNavigatorTest_TestItem', $classes,
'Autodiscovers new classes'
);
}
public function testCanView() {
$page = $this->objFromFixture('Page', 'page1');
$admin = $this->objFromFixture('Member', 'admin');
$author = $this->objFromFixture('Member', 'assetsonlyuser');
$navigator = new SilverStripeNavigator($page);
// TODO Shouldn't be necessary but SapphireTest logs in as ADMIN by default
$this->logInWithPermission('CMS_ACCESS_AssetAdmin');
$items = $navigator->getItems();
@ -40,7 +40,7 @@ class SilverStripeNavigatorTest extends SapphireTest {
$classes = array_map('get_class', $items->toArray());
$this->assertContains('SilverStripeNavigatorTest_ProtectedTestItem', $classes);
}
}
class SilverStripeNavigatorTest_TestItem extends SilverStripeNavigatorItem implements TestOnly {

View File

@ -4,7 +4,7 @@
* @subpackage tests
*/
class ErrorPageTest extends FunctionalTest {
protected static $fixture_file = 'ErrorPageTest.yml';
/**
@ -27,30 +27,30 @@ class ErrorPageTest extends FunctionalTest {
AssetStoreTest_SpyStore::reset();
parent::tearDown();
}
public function test404ErrorPage() {
$page = $this->objFromFixture('ErrorPage', '404');
// ensure that the errorpage exists as a physical file
$page->publish('Stage', 'Live');
$response = $this->get('nonexistent-page');
/* We have body text from the error page */
$this->assertNotNull($response->getBody(), 'We have body text from the error page');
/* Status code of the SS_HTTPResponse for error page is "404" */
$this->assertEquals($response->getStatusCode(), '404', 'Status code of the SS_HTTPResponse for error page is "404"');
/* Status message of the SS_HTTPResponse for error page is "Not Found" */
$this->assertEquals($response->getStatusDescription(), 'Not Found', 'Status message of the HTTResponse for error page is "Not found"');
}
public function testBehaviourOfShowInMenuAndShowInSearchFlags() {
$page = $this->objFromFixture('ErrorPage', '404');
/* Don't show the error page in the menus */
$this->assertEquals($page->ShowInMenus, 0, 'Don\'t show the error page in the menus');
/* Don't show the error page in the search */
$this->assertEquals($page->ShowInSearch, 0, 'Don\'t show the error page in search');
}
@ -58,18 +58,18 @@ class ErrorPageTest extends FunctionalTest {
public function testBehaviourOf403() {
$page = $this->objFromFixture('ErrorPage', '403');
$page->publish('Stage', 'Live');
$response = $this->get($page->RelativeLink());
$this->assertEquals($response->getStatusCode(), '403');
$this->assertNotNull($response->getBody(), 'We have body text from the error page');
}
public function testSecurityError() {
// Generate 404 page
$page = $this->objFromFixture('ErrorPage', '404');
$page->publish('Stage', 'Live');
// Test invalid action
$response = $this->get('Security/nosuchaction');
$this->assertEquals($response->getStatusCode(), '404');
@ -90,7 +90,7 @@ class ErrorPageTest extends FunctionalTest {
$page->write();
$page->publish('Stage', 'Live');
$page->doPublish();
// Static cache should now exist
$this->assertNotEmpty(ErrorPage::get_content_for_errorcode('401'));
$expectedErrorPagePath = AssetStoreTest_SpyStore::base_path() . '/error-401.html';

View File

@ -5,7 +5,7 @@
*/
class FileLinkTrackingTest extends SapphireTest {
protected static $fixture_file = "FileLinkTrackingTest.yml";
public function setUp() {
parent::setUp();
@ -38,7 +38,7 @@ class FileLinkTrackingTest extends SapphireTest {
AssetStoreTest_SpyStore::reset();
parent::tearDown();
}
public function testFileRenameUpdatesDraftAndPublishedPages() {
$page = $this->objFromFixture('Page', 'page1');
$page->doPublish();
@ -52,7 +52,7 @@ class FileLinkTrackingTest extends SapphireTest {
'<img src="/assets/FileLinkTrackingTest/55b443b601/testscript-test-file.jpg"',
DB::prepared_query("SELECT \"Content\" FROM \"SiteTree_Live\" WHERE \"ID\" = ?", array($page->ID))->value()
);
$file = $this->objFromFixture('Image', 'file1');
$file->Name = 'renamed-test-file.jpg';
$file->write();
@ -105,12 +105,12 @@ class FileLinkTrackingTest extends SapphireTest {
$svp->CopyContentFromID = $page->ID;
$svp->write();
$svp->doPublish();
// Rename the file
$file = $this->objFromFixture('Image', 'file1');
$file->Name = 'renamed-test-file.jpg';
$file->write();
// Verify that the draft virtual pages have the correct content
$this->assertContains(
'<img src="/assets/55b443b601/renamed-test-file.jpg"',
@ -126,7 +126,7 @@ class FileLinkTrackingTest extends SapphireTest {
DB::prepared_query("SELECT \"Content\" FROM \"SiteTree_Live\" WHERE \"ID\" = ?", array($svp->ID))->value()
);
}
public function testLinkRewritingOnAPublishedPageDoesntMakeItEditedOnDraft() {
// Publish the source page
$page = $this->objFromFixture('Page', 'page1');
@ -164,7 +164,7 @@ class FileLinkTrackingTest extends SapphireTest {
$file->Name = 'renamed-test-file-second-time.jpg';
$file->write();
$file->doPublish();
// Confirm that the correct image is shown in both the draft and live site
$this->assertContains(
'<img src="/assets/FileLinkTrackingTest/55b443b601/renamed-test-file-second-time.jpg"',

View File

@ -4,7 +4,7 @@ class RedirectorPageTest extends FunctionalTest {
protected static $fixture_file = 'RedirectorPageTest.yml';
protected static $use_draft_site = true;
protected $autoFollowRedirection = false;
public function testGoodRedirectors() {
/* For good redirectors, the final destination URL will be returned */
$this->assertEquals("http://www.google.com", $this->objFromFixture('RedirectorPage','goodexternal')->Link());
@ -39,7 +39,7 @@ class RedirectorPageTest extends FunctionalTest {
* of the destination page - the middle-stop, so to speak. That should redirect to the final destination */
$page = $this->objFromFixture('RedirectorPage','transitive');
$this->assertEquals(Director::baseURL() . 'good-internal/', $page->Link());
$this->autoFollowRedirection = false;
$response = $this->get(Director::makeRelative($page->Link()));
$this->assertEquals(Director::baseURL() . "redirection-dest/", $response->getHeader("Location"));

View File

@ -15,20 +15,20 @@
class SiteTreeActionsTest extends FunctionalTest {
protected static $fixture_file = 'SiteTreeActionsTest.yml';
public function testActionsReadonly() {
if(class_exists('SiteTreeCMSWorkflow')) return true;
$readonlyEditor = $this->objFromFixture('Member', 'cmsreadonlyeditor');
$this->session()->inst_set('loggedInAs', $readonlyEditor->ID);
$page = new SiteTreeActionsTest_Page();
$page->CanEditType = 'LoggedInUsers';
$page->write();
$page->doPublish();
$actions = $page->getCMSActions();
$this->assertNull($actions->dataFieldByName('action_save'));
$this->assertNull($actions->dataFieldByName('action_publish'));
$this->assertNull($actions->dataFieldByName('action_unpublish'));
@ -37,23 +37,23 @@ class SiteTreeActionsTest extends FunctionalTest {
$this->assertNull($actions->dataFieldByName('action_rollback'));
$this->assertNull($actions->dataFieldByName('action_revert'));
}
public function testActionsNoDeletePublishedRecord() {
if(class_exists('SiteTreeCMSWorkflow')) return true;
$this->logInWithPermission('ADMIN');
$page = new SiteTreeActionsTest_Page();
$page->CanEditType = 'LoggedInUsers';
$page->write();
$pageID = $page->ID;
$page->doPublish();
$page->deleteFromStage('Stage');
// Get the live version of the page
$page = Versioned::get_one_by_stage("SiteTree", "Live", "\"SiteTree\".\"ID\" = $pageID");
$this->assertInstanceOf("SiteTree", $page);
// Check that someone without the right permission can't delete the page
$editor = $this->objFromFixture('Member', 'cmsnodeleteeditor');
$this->session()->inst_set('loggedInAs', $editor->ID);
@ -72,14 +72,14 @@ class SiteTreeActionsTest extends FunctionalTest {
$author = $this->objFromFixture('Member', 'cmseditor');
$this->session()->inst_set('loggedInAs', $author->ID);
$page = new Page();
$page->CanEditType = 'LoggedInUsers';
$page->write();
$page->doPublish();
$actions = $page->getCMSActions();
$this->assertNotNull($actions->dataFieldByName('action_save'));
$this->assertNotNull($actions->dataFieldByName('action_publish'));
$this->assertNotNull($actions->dataFieldByName('action_unpublish'));
@ -88,26 +88,26 @@ class SiteTreeActionsTest extends FunctionalTest {
$this->assertNull($actions->dataFieldByName('action_rollback'));
$this->assertNull($actions->dataFieldByName('action_revert'));
}
public function testActionsDeletedFromStageRecord() {
if(class_exists('SiteTreeCMSWorkflow')) return true;
$author = $this->objFromFixture('Member', 'cmseditor');
$this->session()->inst_set('loggedInAs', $author->ID);
$page = new Page();
$page->CanEditType = 'LoggedInUsers';
$page->write();
$pageID = $page->ID;
$page->doPublish();
$page->deleteFromStage('Stage');
// Get the live version of the page
$page = Versioned::get_one_by_stage("SiteTree", "Live", "\"SiteTree\".\"ID\" = $pageID");
$this->assertInstanceOf('SiteTree', $page);
$actions = $page->getCMSActions();
$this->assertNull($actions->dataFieldByName('action_save'));
$this->assertNull($actions->dataFieldByName('action_publish'));
$this->assertNull($actions->dataFieldByName('action_unpublish'));
@ -116,13 +116,13 @@ class SiteTreeActionsTest extends FunctionalTest {
$this->assertNull($actions->dataFieldByName('action_rollback'));
$this->assertNotNull($actions->dataFieldByName('action_revert'));
}
public function testActionsChangedOnStageRecord() {
if(class_exists('SiteTreeCMSWorkflow')) return true;
$author = $this->objFromFixture('Member', 'cmseditor');
$this->session()->inst_set('loggedInAs', $author->ID);
$page = new Page();
$page->CanEditType = 'LoggedInUsers';
$page->write();
@ -130,7 +130,7 @@ class SiteTreeActionsTest extends FunctionalTest {
$page->Content = 'Changed on Stage';
$page->write();
$page->flushCache();
$actions = $page->getCMSActions();
$this->assertNotNull($actions->dataFieldByName('action_save'));
$this->assertNotNull($actions->dataFieldByName('action_publish'));
@ -166,7 +166,7 @@ class SiteTreeActionsTest_Page extends Page implements TestOnly {
public function canEdit($member = null) {
return Permission::checkMember($member, 'SiteTreeActionsTest_Page_CANEDIT');
}
public function canDelete($member = null) {
return Permission::checkMember($member, 'SiteTreeActionsTest_Page_CANDELETE');
}

View File

@ -9,10 +9,10 @@ class SiteTreeBacklinksTest extends SapphireTest {
protected $requiredExtensions = array(
'SiteTree' => array('SiteTreeBacklinksTest_DOD'),
);
public function setUp() {
parent::setUp();
// Log in as admin so that we don't run into permission issues. That's not what we're
// testing here.
$this->logInWithPermission('ADMIN');
@ -21,37 +21,37 @@ class SiteTreeBacklinksTest extends SapphireTest {
public function testSavingPageWithLinkAddsBacklink() {
// load page 1
$page1 = $this->objFromFixture('Page', 'page1');
// assert backlink to page 2 doesn't exist
$page2 = $this->objFromFixture('Page', 'page2');
$this->assertNotContains($page2->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 2 doesn\'t exist');
// add hyperlink to page 1 on page 2
$page2->Content .= '<p><a href="[sitetree_link,id='.$page1->ID.']">Testing page 1 link</a></p>';
$page2->write();
// load page 1
$page1 = $this->objFromFixture('Page', 'page1');
// assert backlink to page 2 exists
$this->assertContains($page2->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 2 exists');
}
public function testRemovingLinkFromPageRemovesBacklink() {
// load page 1
$page1 = $this->objFromFixture('Page', 'page1');
// assert backlink to page 3 exits
$page3 = $this->objFromFixture('Page', 'page3');
$this->assertContains($page3->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 3 exists');
// remove hyperlink to page 1
$page3->Content = '<p>No links anymore!</p>';
$page3->write();
// load page 1
$page1 = $this->objFromFixture('Page', 'page1');
// assert backlink to page 3 exists
$this->assertNotContains($page3->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 3 doesn\'t exist');
}
@ -59,19 +59,19 @@ class SiteTreeBacklinksTest extends SapphireTest {
public function testChangingUrlOnDraftSiteRewritesLink() {
// load page 1
$page1 = $this->objFromFixture('Page', 'page1');
// assert backlink to page 3 exists
$page3 = $this->objFromFixture('Page', 'page3');
$this->assertContains($page3->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 3 exists');
// assert hyperlink to page 1's current url exists on page 3
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current url exists on page 3');
// change url of page 1
$page1->URLSegment = 'new-url-segment';
$page1->write();
// load page 3
$page3 = $this->objFromFixture('Page', 'page3');
@ -79,7 +79,7 @@ class SiteTreeBacklinksTest extends SapphireTest {
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'new-url-segment/', $links, 'Assert hyperlink to page 1\'s new url exists on page 3');
}
public function testChangingUrlOnLiveSiteRewritesLink() {
$this->markTestSkipped("Test disabled until versioned many_many implemented");
@ -88,25 +88,25 @@ class SiteTreeBacklinksTest extends SapphireTest {
$page3 = $this->objFromFixture('Page', 'page3');
$this->assertTrue($page1->doPublish());
$this->assertTrue($page3->doPublish());
// load pages from live
$page1live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page1->ID);
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
// assert backlink to page 3 exists
$this->assertContains($page3live->ID, $page1live->BackLinkTracking()->column('ID'), 'Assert backlink to page 3 exists');
// assert hyperlink to page 1's current url exists on page 3
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current url exists on page 3');
// change url of page 1
$page1live->URLSegment = 'new-url-segment';
$page1live->writeToStage('Live');
// load page 3 from live
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
// assert hyperlink to page 1's new url exists
Versioned::reading_stage('Live');
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
@ -119,37 +119,37 @@ class SiteTreeBacklinksTest extends SapphireTest {
// publish page 1 & 3
$page1 = $this->objFromFixture('Page', 'page1');
$page3 = $this->objFromFixture('Page', 'page3');
$this->assertTrue($page1->doPublish());
$this->assertTrue($page3->doPublish());
// load page 3 from live
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
// assert hyperlink to page 1's current url exists
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current url exists on page 3');
// rename url of page 1 on stage
$page1->URLSegment = 'new-url-segment';
$page1->write();
// assert hyperlink to page 1's current publish url exists
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
Versioned::reading_stage('Live');
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
// publish page 1
$this->assertTrue($page1->doPublish());
// assert hyperlink to page 1's new published url exists
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'new-url-segment/', $links, 'Assert hyperlink to page 1\'s new published url exists on page 3');
}
public function testPublishingPageWithModifiedLinksRewritesLinks() {
$this->markTestSkipped("Test disabled until versioned many_many implemented");
@ -158,49 +158,49 @@ class SiteTreeBacklinksTest extends SapphireTest {
$page3 = $this->objFromFixture('Page', 'page3');
$this->assertTrue($page1->doPublish());
$this->assertTrue($page3->doPublish());
// assert hyperlink to page 1's current url exists
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
// change page 1 url on draft
$page1->URLSegment = 'new-url-segment';
// save page 1
$page1->write();
// assert page 3 on draft contains new page 1 url
$page3 = $this->objFromFixture('Page', 'page3');
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'new-url-segment/', $links, 'Assert hyperlink to page 1\'s current draft url exists on page 3');
// publish page 3
$this->assertTrue($page3->doPublish());
// assert page 3 on published site contains old page 1 url
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
Versioned::reading_stage('Live');
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
// publish page 1
$this->assertTrue($page1->doPublish());
// assert page 3 on published site contains new page 1 url
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
$this->assertContains(Director::baseURL().'new-url-segment/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
}
public function testLinkTrackingOnExtraContentFields() {
$page1 = $this->objFromFixture('Page', 'page1');
$page2 = $this->objFromFixture('Page', 'page2');
$page1->doPublish();
$page2->doPublish();
// assert backlink to page 2 doesn't exist
$this->assertNotContains($page2->ID, $page1->BackLinkTracking()->column('ID'), 'Assert backlink to page 2 doesn\'t exist');
// add hyperlink to page 1 on page 2
$page2->ExtraContent .= '<p><a href="[sitetree_link,id='.$page1->ID.']">Testing page 1 link</a></p>';
$page2->write();
@ -225,12 +225,12 @@ class SiteTreeBacklinksTest extends SapphireTest {
$page2Live = Versioned::get_one_by_stage("Page", "Live", "\"SiteTree\".\"ID\" = $page2->ID");
Versioned::reading_stage('Live');
$this->assertEquals('<p><a href="'.Director::baseURL().'page1/">Testing page 1 link</a></p>', $page2Live->obj('ExtraContent')->forTemplate());
// publish page1 and confirm that the link on the published page2 has now been updated
$page1->doPublish();
$page2Live = Versioned::get_one_by_stage("Page", "Live", "\"SiteTree\".\"ID\" = $page2->ID");
$this->assertEquals('<p><a href="'.Director::baseURL().'page1-new-url/">Testing page 1 link</a></p>', $page2Live->obj('ExtraContent')->forTemplate());
// remove hyperlink to page 1
$page2->ExtraContent = '<p>No links anymore!</p>';

View File

@ -23,11 +23,11 @@ class SiteTreeBrokenLinksTest extends SapphireTest {
public function testBrokenLinksBetweenPages() {
$obj = $this->objFromFixture('Page','content');
$obj->Content = '<a href="[sitetree_link,id=3423423]">this is a broken link</a>';
$obj->syncLinkTracking();
$this->assertTrue($obj->HasBrokenLink, 'Page has a broken link');
$obj->Content = '<a href="[sitetree_link,id=' . $this->idFromFixture('Page','about') .']">this is not a broken link</a>';
$obj->syncLinkTracking();
$this->assertFalse($obj->HasBrokenLink, 'Page does NOT have a broken link');
@ -49,11 +49,11 @@ class SiteTreeBrokenLinksTest extends SapphireTest {
public function testBrokenVirtualPages() {
$obj = $this->objFromFixture('Page','content');
$vp = new VirtualPage();
$vp->CopyContentFromID = $obj->ID;
$vp->syncLinkTracking();
$this->assertFalse($vp->HasBrokenLink, 'Working virtual page is NOT marked as broken');
$vp->CopyContentFromID = 12345678;
$vp->syncLinkTracking();
$this->assertTrue($vp->HasBrokenLink, 'Broken virtual page IS marked as such');
@ -62,13 +62,13 @@ class SiteTreeBrokenLinksTest extends SapphireTest {
public function testBrokenInternalRedirectorPages() {
$obj = $this->objFromFixture('Page','content');
$rp = new RedirectorPage();
$rp->RedirectionType = 'Internal';
$rp->LinkToID = $obj->ID;
$rp->syncLinkTracking();
$this->assertFalse($rp->HasBrokenLink, 'Working redirector page is NOT marked as broken');
$rp->LinkToID = 12345678;
$rp->syncLinkTracking();
$this->assertTrue($rp->HasBrokenLink, 'Broken redirector page IS marked as such');
@ -94,7 +94,7 @@ class SiteTreeBrokenLinksTest extends SapphireTest {
$liveObj = Versioned::get_one_by_stage("SiteTree", "Live","\"SiteTree\".\"ID\" = $obj->ID");
$this->assertEquals(0, $liveObj->HasBrokenFile);
// Delete the file
$file->delete();
@ -112,14 +112,14 @@ class SiteTreeBrokenLinksTest extends SapphireTest {
public function testDeletingMarksBackLinkedPagesAsBroken() {
// Set up two published pages with a link from content -> about
$linkDest = $this->objFromFixture('Page','about');
$linkSrc = $this->objFromFixture('Page','content');
$linkSrc->Content = "<p><a href=\"[sitetree_link,id=$linkDest->ID]\">about us</a></p>";
$linkSrc->write();
// Confirm no broken link
$this->assertEquals(0, (int)$linkSrc->HasBrokenLink);
// Delete page from draft
$linkDestID = $linkDest->ID;
$linkDest->delete();
@ -135,19 +135,19 @@ class SiteTreeBrokenLinksTest extends SapphireTest {
$this->markTestSkipped("Test disabled until versioned many_many implemented");
$this->logInWithPermission('ADMIN');
// Set up two draft pages with a link from content -> about
$linkDest = $this->objFromFixture('Page','about');
// Ensure that it's not on the published site
$linkDest->doUnpublish();
$linkSrc = $this->objFromFixture('Page','content');
$linkSrc->Content = "<p><a href=\"[sitetree_link,id=$linkDest->ID]\">about us</a></p>";
$linkSrc->write();
// Publish the source of the link, while the dest is still unpublished.
$linkSrc->doPublish();
// Verify that the link isn't broken on draft but is broken on published
$this->assertEquals(0, (int)$linkSrc->HasBrokenLink);
$this->assertEquals(1, DB::query("SELECT \"HasBrokenLink\" FROM \"SiteTree_Live\"
@ -227,7 +227,7 @@ class SiteTreeBrokenLinksTest extends SapphireTest {
$rpLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $rp->ID);
$this->assertFalse((bool)$p2Live->HasBrokenLink);
$this->assertFalse((bool)$rpLive->HasBrokenLink);
}
public function testRevertToLiveFixesBrokenLinks() {
@ -266,7 +266,7 @@ class SiteTreeBrokenLinksTest extends SapphireTest {
// Delete from draft and confirm that broken links are marked
$pID = $p->ID;
$p->delete();
$vp->flushCache();
$vp = DataObject::get_by_id('SiteTree', $vp->ID);
$p2->flushCache();

View File

@ -8,37 +8,37 @@
*/
class SiteTreePermissionsTest extends FunctionalTest {
protected static $fixture_file = "SiteTreePermissionsTest.yml";
protected $illegalExtensions = array(
'SiteTree' => array('SiteTreeSubsites')
);
public function setUp() {
parent::setUp();
$this->useDraftSite();
// we're testing HTTP status codes before being redirected to login forms
$this->autoFollowRedirection = false;
}
public function testAccessingStageWithBlankStage() {
$this->useDraftSite(false);
$this->autoFollowRedirection = false;
$page = $this->objFromFixture('Page', 'draftOnlyPage');
if($member = Member::currentUser()) {
$member->logOut();
}
$response = $this->get($page->URLSegment . '?stage=Live');
$this->assertEquals($response->getStatusCode(), '404');
$response = $this->get($page->URLSegment . '?stage=');
$this->assertEquals($response->getStatusCode(), '404');
// should be prompted for a login
try {
$response = $this->get($page->URLSegment . '?stage=Stage');
@ -50,19 +50,19 @@ class SiteTreePermissionsTest extends FunctionalTest {
Config::inst()->get('Security', 'login_url'),
$response->getHeader('Location')
);
$this->logInWithPermission('ADMIN');
$response = $this->get($page->URLSegment . '?stage=Live');
$this->assertEquals($response->getStatusCode(), '404');
$response = $this->get($page->URLSegment . '?stage=Stage');
$this->assertEquals($response->getStatusCode(), '200');
$response = $this->get($page->URLSegment . '?stage=');
$this->assertEquals($response->getStatusCode(), '404');
}
public function testPermissionCheckingWorksOnDeletedPages() {
// Set up fixture - a published page deleted from draft
$this->logInWithPermission("ADMIN");
@ -77,18 +77,18 @@ class SiteTreePermissionsTest extends FunctionalTest {
// subadmin has edit rights on that page
$member = $this->objFromFixture('Member','subadmin');
$member->logIn();
// Test can_edit_multiple
$this->assertEquals(
array($pageID => true),
SiteTree::can_edit_multiple(array($pageID), $member->ID)
);
// Test canEdit
$member->logIn();
$this->assertTrue($page->canEdit());
}
public function testPermissionCheckingWorksOnUnpublishedPages() {
// Set up fixture - an unpublished page
$this->logInWithPermission("ADMIN");
@ -125,7 +125,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
// subadmin had edit rights on that page, but now it's gone
$member = $this->objFromFixture('Member','subadmin');
$member->logIn();
$this->assertFalse($page->canEdit());
}
@ -142,19 +142,19 @@ class SiteTreePermissionsTest extends FunctionalTest {
$editor = $this->objFromFixture('Member', 'editor');
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
$this->assertTrue($page->canViewStage('Live', $websiteuser));
$this->assertFalse($page->canViewStage('Stage', $websiteuser));
$this->assertTrue($page->canViewStage('Live', $editor));
$this->assertTrue($page->canViewStage('Stage', $editor));
$this->useDraftSite();
}
public function testAccessTabOnlyDisplaysWithGrantAccessPermissions() {
$page = $this->objFromFixture('Page', 'standardpage');
$subadminuser = $this->objFromFixture('Member', 'subadmin');
$this->session()->inst_set('loggedInAs', $subadminuser->ID);
$fields = $page->getSettingsFields();
@ -166,7 +166,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
$fields->dataFieldByName('CanEditType')->isReadonly(),
'Users with SITETREE_GRANT_ACCESS permission can change "edit" permissions in cms fields'
);
$editoruser = $this->objFromFixture('Member', 'editor');
$this->session()->inst_set('loggedInAs', $editoruser->ID);
$fields = $page->getSettingsFields();
@ -178,13 +178,13 @@ class SiteTreePermissionsTest extends FunctionalTest {
$fields->dataFieldByName('CanEditType')->isReadonly(),
'Users without SITETREE_GRANT_ACCESS permission cannot change "edit" permissions in cms fields'
);
$this->session()->inst_set('loggedInAs', null);
}
public function testRestrictedViewLoggedInUsers() {
$page = $this->objFromFixture('Page', 'restrictedViewLoggedInUsers');
// unauthenticated users
$this->assertFalse(
$page->canView(FALSE),
@ -197,7 +197,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
302,
'Unauthenticated members cant view a page marked as "Viewable for any logged in users"'
);
// website users
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
$this->assertTrue(
@ -213,10 +213,10 @@ class SiteTreePermissionsTest extends FunctionalTest {
);
$this->session()->inst_set('loggedInAs', null);
}
public function testRestrictedViewOnlyTheseUsers() {
$page = $this->objFromFixture('Page', 'restrictedViewOnlyWebsiteUsers');
// unauthenticcated users
$this->assertFalse(
$page->canView(FALSE),
@ -229,7 +229,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
302,
'Unauthenticated members cant view a page marked as "Viewable by these groups"'
);
// subadmin users
$subadminuser = $this->objFromFixture('Member', 'subadmin');
$this->assertFalse(
@ -244,7 +244,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
'Authenticated members cant view a page marked as "Viewable by these groups" if theyre not in the listed groups'
);
$this->session()->inst_set('loggedInAs', null);
// website users
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
$this->assertTrue(
@ -260,16 +260,16 @@ class SiteTreePermissionsTest extends FunctionalTest {
);
$this->session()->inst_set('loggedInAs', null);
}
public function testRestrictedEditLoggedInUsers() {
$page = $this->objFromFixture('Page', 'restrictedEditLoggedInUsers');
// unauthenticcated users
$this->assertFalse(
$page->canEdit(FALSE),
'Unauthenticated members cant edit a page marked as "Editable by logged in users"'
);
// website users
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
$websiteuser->logIn();
@ -277,7 +277,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
$page->canEdit($websiteuser),
'Authenticated members cant edit a page marked as "Editable by logged in users" if they dont have cms permissions'
);
// subadmin users
$subadminuser = $this->objFromFixture('Member', 'subadmin');
$this->assertTrue(
@ -285,23 +285,23 @@ class SiteTreePermissionsTest extends FunctionalTest {
'Authenticated members can edit a page marked as "Editable by logged in users" if they have cms permissions and belong to any of these groups'
);
}
public function testRestrictedEditOnlySubadminGroup() {
$page = $this->objFromFixture('Page', 'restrictedEditOnlySubadminGroup');
// unauthenticated users
$this->assertFalse(
$page->canEdit(FALSE),
'Unauthenticated members cant edit a page marked as "Editable by these groups"'
);
// subadmin users
$subadminuser = $this->objFromFixture('Member', 'subadmin');
$this->assertTrue(
$page->canEdit($subadminuser),
'Authenticated members can view a page marked as "Editable by these groups" if theyre in the listed groups'
);
// website users
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
$this->assertFalse(
@ -309,11 +309,11 @@ class SiteTreePermissionsTest extends FunctionalTest {
'Authenticated members cant edit a page marked as "Editable by these groups" if theyre not in the listed groups'
);
}
public function testRestrictedViewInheritance() {
$parentPage = $this->objFromFixture('Page', 'parent_restrictedViewOnlySubadminGroup');
$childPage = $this->objFromFixture('Page', 'child_restrictedViewOnlySubadminGroup');
// unauthenticated users
$this->assertFalse(
$childPage->canView(FALSE),
@ -326,7 +326,7 @@ class SiteTreePermissionsTest extends FunctionalTest {
302,
'Unauthenticated members cant view a page marked as "Viewable by these groups" by inherited permission'
);
// subadmin users
$subadminuser = $this->objFromFixture('Member', 'subadmin');
$this->assertTrue(
@ -342,17 +342,17 @@ class SiteTreePermissionsTest extends FunctionalTest {
);
$this->session()->inst_set('loggedInAs', null);
}
public function testRestrictedEditInheritance() {
$parentPage = $this->objFromFixture('Page', 'parent_restrictedEditOnlySubadminGroup');
$childPage = $this->objFromFixture('Page', 'child_restrictedEditOnlySubadminGroup');
// unauthenticated users
$this->assertFalse(
$childPage->canEdit(FALSE),
'Unauthenticated members cant edit a page marked as "Editable by these groups" by inherited permission'
);
// subadmin users
$subadminuser = $this->objFromFixture('Member', 'subadmin');
$this->assertTrue(
@ -360,11 +360,11 @@ class SiteTreePermissionsTest extends FunctionalTest {
'Authenticated members can edit a page marked as "Editable by these groups" if theyre in the listed groups by inherited permission'
);
}
public function testDeleteRestrictedChild() {
$parentPage = $this->objFromFixture('Page', 'deleteTestParentPage');
$childPage = $this->objFromFixture('Page', 'deleteTestChildPage');
// unauthenticated users
$this->assertFalse(
$parentPage->canDelete(FALSE),
@ -375,13 +375,13 @@ class SiteTreePermissionsTest extends FunctionalTest {
'Unauthenticated members cant delete a child page marked as "Editable by these groups"'
);
}
public function testRestrictedEditLoggedInUsersDeletedFromStage() {
$page = $this->objFromFixture('Page', 'restrictedEditLoggedInUsers');
$pageID = $page->ID;
$this->logInWithPermission("ADMIN");
$page->doPublish();
$page->deleteFromStage('Stage');
@ -402,40 +402,40 @@ class SiteTreePermissionsTest extends FunctionalTest {
$siteconfig = $this->objFromFixture('SiteConfig', 'default');
$editor = $this->objFromFixture('Member', 'editor');
$editorGroup = $this->objFromFixture('Group', 'editorgroup');
$siteconfig->CanViewType = 'Anyone';
$siteconfig->write();
$this->assertTrue($page->canView(FALSE), 'Anyone can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
$siteconfig->CanViewType = 'LoggedInUsers';
$siteconfig->write();
$this->assertFalse($page->canView(FALSE), 'Anonymous can\'t view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
$siteconfig->CanViewType = 'LoggedInUsers';
$siteconfig->write();
$this->assertTrue($page->canView($editor), 'Users can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
$siteconfig->CanViewType = 'OnlyTheseUsers';
$siteconfig->ViewerGroups()->add($editorGroup);
$siteconfig->write();
$this->assertTrue($page->canView($editor), 'Editors can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to OnlyTheseUsers');
$this->assertFalse($page->canView(FALSE), 'Anonymous can\'t view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to OnlyTheseUsers');
}
public function testInheritCanEditFromSiteConfig() {
$page = $this->objFromFixture('Page', 'inheritWithNoParent');
$siteconfig = $this->objFromFixture('SiteConfig', 'default');
$editor = $this->objFromFixture('Member', 'editor');
$user = $this->objFromFixture('Member', 'websiteuser');
$editorGroup = $this->objFromFixture('Group', 'editorgroup');
$siteconfig->CanEditType = 'LoggedInUsers';
$siteconfig->write();
$this->assertFalse($page->canEdit(FALSE), 'Anonymous can\'t edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to LoggedInUsers');
$this->session()->inst_set('loggedInAs', $editor->ID);
$this->assertTrue($page->canEdit(), 'Users can edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to LoggedInUsers');
$siteconfig->CanEditType = 'OnlyTheseUsers';
$siteconfig->EditorGroups()->add($editorGroup);
$siteconfig->write();
@ -445,5 +445,5 @@ class SiteTreePermissionsTest extends FunctionalTest {
$this->session()->inst_set('loggedInAs', $user->ID);
$this->assertFalse($page->canEdit($user), 'Website user can\'t edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to OnlyTheseUsers');
}
}

View File

@ -4,13 +4,13 @@
* @subpackage tests
*/
class SiteTreeTest extends SapphireTest {
protected static $fixture_file = 'SiteTreeTest.yml';
protected $illegalExtensions = array(
'SiteTree' => array('SiteTreeSubsites', 'Translatable')
);
protected $extraDataObjects = array(
'SiteTreeTest_ClassA',
'SiteTreeTest_ClassB',
@ -27,7 +27,7 @@ class SiteTreeTest extends SapphireTest {
public function logOut() {
if($member = Member::currentUser()) $member->logOut();
}
public function testCreateDefaultpages() {
$remove = SiteTree::get();
if($remove) foreach($remove as $page) $page->delete();
@ -513,7 +513,7 @@ class SiteTreeTest extends SapphireTest {
$this->assertFalse(singleton('SiteTreeTest_ClassA')->canCreate(null, array('Parent' => $parentB)));
$this->assertTrue(singleton('SiteTreeTest_ClassC')->canCreate(null, array('Parent' => $parentB)));
}
public function testEditPermissionsOnDraftVsLive() {
// Create an inherit-permission page
$page = new Page();
@ -705,7 +705,7 @@ class SiteTreeTest extends SapphireTest {
$this->assertEquals($sitetree->URLSegment, 'new-page',
'Sets based on default title on first save'
);
$sitetree->Title = 'Changed';
$sitetree->write();
$this->assertEquals($sitetree->URLSegment, 'changed',
@ -1071,7 +1071,7 @@ class SiteTreeTest extends SapphireTest {
$this->assertEquals($breadcrumbs->first()->Title, "Breadcrumbs 4", "First item should be Breadrcumbs 4.");
$this->assertEquals($breadcrumbs->last()->Title, "Breadcrumbs 5", "Breadcrumbs 5 should be last.");
}
/**
* Tests SiteTree::MetaTags
* Note that this test makes no assumption on the closing of tags (other than <title></title>)
@ -1189,11 +1189,11 @@ class SiteTreeTest_PageNode_Controller extends Page_Controller implements TestOn
class SiteTreeTest_Conflicted extends Page implements TestOnly { }
class SiteTreeTest_Conflicted_Controller extends Page_Controller implements TestOnly {
private static $allowed_actions = array (
'conflicted-action'
);
public function hasActionTemplate($template) {
if($template == 'conflicted-template') {
return true;
@ -1201,7 +1201,7 @@ class SiteTreeTest_Conflicted_Controller extends Page_Controller implements Test
return parent::hasActionTemplate($template);
}
}
}
class SiteTreeTest_NullHtmlCleaner extends HTMLCleaner {
@ -1213,7 +1213,7 @@ class SiteTreeTest_NullHtmlCleaner extends HTMLCleaner {
class SiteTreeTest_ClassA extends Page implements TestOnly {
private static $need_permission = array('ADMIN', 'CMS_ACCESS_CMSMain');
private static $allowed_children = array('SiteTreeTest_ClassB');
}

View File

@ -4,7 +4,7 @@ class VirtualPageTest extends FunctionalTest {
protected static $fixture_file = 'VirtualPageTest.yml';
protected static $use_draft_site = false;
protected $autoFollowRedirection = false;
protected $extraDataObjects = array(
'VirtualPageTest_ClassA',
'VirtualPageTest_ClassB',
@ -36,7 +36,7 @@ class VirtualPageTest extends FunctionalTest {
$this->origInitiallyCopiedFields,
array('MyInitiallyCopiedField')
);
$this->origNonVirtualField = VirtualPage::config()->non_virtual_fields;
Config::inst()->remove('VirtualPage', 'non_virtual_fields');
VirtualPage::config()->non_virtual_fields = array_merge(
@ -53,7 +53,7 @@ class VirtualPageTest extends FunctionalTest {
VirtualPage::config()->initially_copied_fields = $this->origInitiallyCopiedFields;
VirtualPage::config()->non_virtual_fields = $this->origNonVirtualField;
}
/**
* Test that, after you update the source page of a virtual page, all the virtual pages
* are updated
@ -64,10 +64,10 @@ class VirtualPageTest extends FunctionalTest {
$master->MenuTitle = "New menutitle";
$master->Content = "<p>New content</p>";
$master->write();
$vp1 = $this->objFromFixture('VirtualPage', 'vp1');
$vp2 = $this->objFromFixture('VirtualPage', 'vp2');
$this->assertEquals("New title", $vp1->Title);
$this->assertEquals("New title", $vp2->Title);
$this->assertEquals("New menutitle", $vp1->MenuTitle);
@ -101,10 +101,10 @@ class VirtualPageTest extends FunctionalTest {
Versioned::reading_stage("Live");
$vp1 = DataObject::get_by_id("VirtualPage", $this->idFromFixture('VirtualPage', 'vp1'));
$vp2 = DataObject::get_by_id("VirtualPage", $this->idFromFixture('VirtualPage', 'vp2'));
$this->assertNotNull($vp1);
$this->assertNotNull($vp2);
$this->assertEquals("New title", $vp1->Title);
$this->assertEquals("New title", $vp2->Title);
$this->assertEquals("New menutitle", $vp1->MenuTitle);
@ -113,17 +113,17 @@ class VirtualPageTest extends FunctionalTest {
$this->assertEquals("<p>New content</p>", $vp2->Content);
Versioned::reading_stage("Stage");
}
/**
* Test that virtual pages get the content from the master page when they are created.
*/
public function testNewVirtualPagesGrabTheContentFromTheirMaster() {
$vp = new VirtualPage();
$vp->write();
$vp->CopyContentFromID = $this->idFromFixture('Page', 'master');
$vp->write();
$this->assertEquals("My Page", $vp->Title);
$this->assertEquals("My Page Nav", $vp->MenuTitle);
@ -133,7 +133,7 @@ class VirtualPageTest extends FunctionalTest {
$this->assertEquals("My Other Page", $vp->Title);
$this->assertEquals("My Other Page Nav", $vp->MenuTitle);
}
/**
* Virtual pages are always supposed to chose the same content as the published source page.
* This means that when you publish them, they should show the published content of the source
@ -144,17 +144,17 @@ class VirtualPageTest extends FunctionalTest {
$p->Content = "published content";
$p->write();
$p->doPublish();
// Don't publish this change - published page will still say 'published content'
$p->Content = "draft content";
$p->write();
$vp = new VirtualPage();
$vp->CopyContentFromID = $p->ID;
$vp->write();
$vp->doPublish();
// The draft content of the virtual page should say 'draft content'
$this->assertEquals('draft content',
DB::query('SELECT "Content" from "SiteTree" WHERE "ID" = ' . $vp->ID)->value());
@ -169,7 +169,7 @@ class VirtualPageTest extends FunctionalTest {
$p = new Page();
$p->Content = "test content";
$p->write();
// With no source page, we can't publish
$vp = new VirtualPage();
$vp->write();
@ -179,7 +179,7 @@ class VirtualPageTest extends FunctionalTest {
$vp->CopyContentFromID = $p->ID;
$vp->write();
$this->assertFalse($vp->canPublish());
// Once the source page gets published, then we can publish
$p->doPublish();
$this->assertTrue($vp->canPublish());
@ -191,7 +191,7 @@ class VirtualPageTest extends FunctionalTest {
$p->Content = "test content";
$p->write();
$p->doPublish();
$vp = new VirtualPage();
$vp->CopyContentFromID = $p->ID;
$vp->write();
@ -199,11 +199,11 @@ class VirtualPageTest extends FunctionalTest {
// Delete the source page
$this->assertTrue($vp->canPublish());
$this->assertTrue($p->doUnpublish());
// Confirm that we can unpublish, but not publish
$this->assertTrue($vp->canUnpublish());
$this->assertFalse($vp->canPublish());
// Confirm that the action really works
$this->assertTrue($vp->doUnpublish());
$this->assertNull(DB::query("SELECT \"ID\" FROM \"SiteTree_Live\" WHERE \"ID\" = $vp->ID")->value());
@ -244,7 +244,7 @@ class VirtualPageTest extends FunctionalTest {
$this->assertTrue($parentPage->canView());
$this->assertFalse($virtualPage->canView());
}
public function testVirtualPagesArentInappropriatelyPublished() {
// Fixture
$p = new Page();
@ -261,27 +261,27 @@ class VirtualPageTest extends FunctionalTest {
$p->doPublish();
$this->fixVersionNumberCache($vp);
$this->assertTrue($vp->getIsAddedToStage());
// A new VP created after P's initial construction
$vp2 = new VirtualPage();
$vp2->CopyContentFromID = $p->ID;
$vp2->write();
$this->assertTrue($vp2->getIsAddedToStage());
// Also remains orange after a republish
$p->Content = "new content";
$p->write();
$p->doPublish();
$this->fixVersionNumberCache($vp2);
$this->assertTrue($vp2->getIsAddedToStage());
// VP is now published
$vp->doPublish();
$this->fixVersionNumberCache($vp);
$this->assertTrue($vp->getExistsOnLive());
$this->assertFalse($vp->getIsModifiedOnStage());
// P edited, VP and P both go green
$p->Content = "third content";
$p->write();
@ -296,13 +296,13 @@ class VirtualPageTest extends FunctionalTest {
$this->assertTrue($vp->getExistsOnLive());
$this->assertFalse($vp->getIsModifiedOnStage());
}
public function testVirtualPagesCreateVersionRecords() {
$source = $this->objFromFixture('Page', 'master');
$source->Title = "T0";
$source->write();
$source->doPublish();
// Creating a new VP to ensure that Version #s are out of alignment
$vp = new VirtualPage();
$vp->CopyContentFromID = $source->ID;
@ -312,14 +312,14 @@ class VirtualPageTest extends FunctionalTest {
$source->write();
$source->Title = "T2";
$source->write();
$this->assertEquals($vp->ID, DB::query("SELECT \"RecordID\" FROM \"SiteTree_versions\"
WHERE \"RecordID\" = $vp->ID AND \"Title\" = 'T1'")->value());
$this->assertEquals($vp->ID, DB::query("SELECT \"RecordID\" FROM \"SiteTree_versions\"
WHERE \"RecordID\" = $vp->ID AND \"Title\" = 'T2'")->value());
$this->assertEquals($vp->ID, DB::query("SELECT \"RecordID\" FROM \"SiteTree_versions\"
WHERE \"RecordID\" = $vp->ID AND \"Version\" = $vp->Version")->value());
$vp->doPublish();
// Check that the published content is copied from the published page, with a legal
@ -334,7 +334,7 @@ class VirtualPageTest extends FunctionalTest {
$this->assertEquals("T0", DB::query("SELECT \"Title\" FROM \"SiteTree_versions\"
WHERE \"RecordID\" = $vp->ID AND \"Version\" = $liveVersion")->value());
}
public function fixVersionNumberCache($page) {
$pages = func_get_args();
foreach($pages as $p) {
@ -353,10 +353,10 @@ class VirtualPageTest extends FunctionalTest {
$vp->CopyContentFromID = $p->ID;
$vp->write();
$this->assertTrue($vp->doPublish());
// All is fine, the virtual page doesn't have a broken link
$this->assertFalse($vp->HasBrokenLink);
// Unpublish the source page, confirm that the virtual page has also been unpublished
$p->doUnpublish();
@ -367,13 +367,13 @@ class VirtualPageTest extends FunctionalTest {
$vpLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $vp->ID);
$this->assertNull($vpLive);
// Delete from draft, confirm that the virtual page has a broken link on the draft site
$p->delete();
$vp->flushCache();
$vp = DataObject::get_by_id('SiteTree', $vp->ID);
$this->assertEquals(1, $vp->HasBrokenLink);
}
}
public function testDeletingFromLiveSourcePageOfAVirtualPageAlsoUnpublishesVirtualPage() {
// Create page and virutal page
@ -385,30 +385,30 @@ class VirtualPageTest extends FunctionalTest {
$vp->CopyContentFromID = $p->ID;
$vp->write();
$this->assertTrue($vp->doPublish());
// All is fine, the virtual page doesn't have a broken link
$this->assertFalse($vp->HasBrokenLink);
// Delete the source page from draft, confirm that this creates a broken link
$pID = $p->ID;
$p->delete();
$vp->flushCache();
$vp = DataObject::get_by_id('SiteTree', $vp->ID);
$this->assertEquals(1, $vp->HasBrokenLink);
// Delete the source page form live, confirm that the virtual page has also been unpublished
$pLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $pID);
$this->assertTrue($pLive->doUnpublish());
$vpLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $vp->ID);
$this->assertNull($vpLive);
// Delete from draft, confirm that the virtual page has a broken link on the draft site
$pLive->delete();
$vp->flushCache();
$vp = DataObject::get_by_id('SiteTree', $vp->ID);
$this->assertEquals(1, $vp->HasBrokenLink);
}
}
/**
* Base functionality tested in {@link SiteTreeTest->testAllowedChildrenValidation()}.
*/
@ -425,16 +425,16 @@ class VirtualPageTest extends FunctionalTest {
$classCVirtual = new VirtualPage();
$classCVirtual->CopyContentFromID = $classC->ID;
$classCVirtual->write();
$classBVirtual->ParentID = $classA->ID;
$valid = $classBVirtual->doValidate();
$this->assertTrue($valid->valid(), "Does allow child linked to virtual page type allowed by parent");
$classCVirtual->ParentID = $classA->ID;
$valid = $classCVirtual->doValidate();
$this->assertFalse($valid->valid(), "Doesn't allow child linked to virtual page type disallowed by parent");
}
public function testGetVirtualFields() {
// Needs association with an original, otherwise will just return the "base" virtual fields
$page = new VirtualPageTest_ClassA();
@ -447,7 +447,7 @@ class VirtualPageTest extends FunctionalTest {
$this->assertNotContains('MyNonVirtualField', $virtual->getVirtualFields());
$this->assertNotContains('MyInitiallyCopiedField', $virtual->getVirtualFields());
}
public function testCopyFrom() {
$original = new VirtualPageTest_ClassA();
$original->MyInitiallyCopiedField = 'original';
@ -458,7 +458,7 @@ class VirtualPageTest extends FunctionalTest {
$virtual = new VirtualPage();
$virtual->CopyContentFromID = $original->ID;
$virtual->write();
$virtual->copyFrom($original);
// Using getField() to avoid side effects from an overloaded __get()
$this->assertEquals(
@ -475,7 +475,7 @@ class VirtualPageTest extends FunctionalTest {
$virtual->getField('MyNonVirtualField'),
'Fields listed in $non_virtual_fields are not copied in copyFrom()'
);
$original->MyInitiallyCopiedField = 'changed';
$original->write();
$virtual->copyFrom($original);
@ -485,7 +485,7 @@ class VirtualPageTest extends FunctionalTest {
'Fields listed in $initially_copied_fields are not copied on subsequent copyFrom() invocations'
);
}
public function testWriteWithoutVersion() {
$original = new SiteTree();
$original->write();
@ -502,7 +502,7 @@ class VirtualPageTest extends FunctionalTest {
$virtual->Title = 'prepare';
$virtual->write();
$virtualVersion = $virtual->Version;
$virtual->Title = 'changed 1';
$virtual->writeWithoutVersion();
$this->assertEquals(
@ -521,7 +521,7 @@ class VirtualPageTest extends FunctionalTest {
$virtualVersion,
'writeWithoutVersion() on original page doesnt increment version on related VirtualPage'
);
$original->Title = 'changed 3';
$original->write();
DataObject::flush_and_destroy_cache();
@ -698,7 +698,7 @@ class VirtualPageTest extends FunctionalTest {
$rp = new RedirectorPage(array('ExternalURL' => 'http://google.com', 'RedirectionType' => 'External'));
$rp->write();
$rp->doPublish();
$vp = new VirtualPage(array('URLSegment' => 'vptest', 'CopyContentFromID' => $rp->ID));
$vp->write();
$vp->doPublish();
@ -710,14 +710,14 @@ class VirtualPageTest extends FunctionalTest {
}
class VirtualPageTest_ClassA extends Page implements TestOnly {
private static $db = array(
'MyInitiallyCopiedField' => 'Text',
'MyVirtualField' => 'Text',
'MyNonVirtualField' => 'Text',
'CastingTest' => 'VirtualPageTest_TestDBField'
);
private static $allowed_children = array('VirtualPageTest_ClassB');
}

View File

@ -9,7 +9,7 @@ class CmsReportsTest extends SapphireTest {
protected static $fixture_file = 'CmsReportsTest.yml';
private static $daysAgo = 14;
public function setUp() {
parent::setUp();
@ -19,7 +19,7 @@ class CmsReportsTest extends SapphireTest {
$after = $this->objFromFixture('SiteTree', 'after');
$before = $this->objFromFixture('SiteTree', 'before');
DB::query("UPDATE \"SiteTree\" SET \"Created\"='2009-01-01 00:00:00', \"LastEdited\"='".date('Y-m-d H:i:s', $afterThreshold)."' WHERE \"ID\"='".$after->ID."'");
DB::query("UPDATE \"SiteTree\" SET \"Created\"='2009-01-01 00:00:00', \"LastEdited\"='".date('Y-m-d H:i:s', $beforeThreshold)."' WHERE \"ID\"='".$before->ID."'");
}
@ -54,12 +54,12 @@ class CmsReportsTest extends SapphireTest {
$before = $this->objFromFixture('SiteTree', 'before');
$r = new RecentlyEditedReport();
// check if contains only elements not older than $daysAgo days
$this->assertNotNull($r->records(array()));
$this->assertContains($after->ID, $r->records(array())->column('ID'));
$this->assertNotContains($before->ID, $r->records(array())->column('ID'));
SS_DateTime::clear_mock_now();
}

View File

@ -1,8 +1,8 @@
<?php
class CMSMainSearchFormTest extends FunctionalTest {
protected static $fixture_file = '../controller/CMSMainTest.yml';
public function testTitleFilter() {
$this->session()->inst_set('loggedInAs', $this->idFromFixture('Member', 'admin'));
@ -16,14 +16,14 @@ class CMSMainSearchFormTest extends FunctionalTest {
'action_doSearch' => true
))
);
$titles = $this->getPageTitles();
$this->assertEquals(count($titles), 1);
// For some reason the title gets split into two lines
$this->assertContains('Page 1', $titles[0]);
}
protected function getPageTitles() {
$titles = array();
$links = $this->cssParser()->getBySelector('li.class-Page a');

View File

@ -9,7 +9,7 @@
* Because this manipulates the test database in severe ways, I've renamed the test to force it to run last...
*/
class ZZZSearchFormTest extends FunctionalTest {
protected static $fixture_file = 'SearchFormTest.yml';
protected $illegalExtensions = array(
@ -17,12 +17,12 @@ class ZZZSearchFormTest extends FunctionalTest {
);
protected $mockController;
public function waitUntilIndexingFinished() {
$schema = DB::get_schema();
if (method_exists($schema, 'waitUntilIndexingFinished')) $schema->waitUntilIndexingFinished();
}
public function setUpOnce() {
// HACK Postgres doesn't refresh TSearch indexes when the schema changes after CREATE TABLE
// MySQL will need a different table type
@ -32,16 +32,16 @@ class ZZZSearchFormTest extends FunctionalTest {
$this->resetDBSchema(true);
parent::setUpOnce();
}
public function setUp() {
parent::setUp();
$holderPage = $this->objFromFixture('SiteTree', 'searchformholder');
$this->mockController = new ContentController($holderPage);
$this->waitUntilIndexingFinished();
}
/**
* @return Boolean
*/
@ -55,28 +55,28 @@ class ZZZSearchFormTest extends FunctionalTest {
if(!$supports) $this->markTestSkipped('Fulltext not supported by DB driver or setup');
return $supports;
}
public function testSearchFormTemplateCanBeChanged() {
if(!$this->checkFulltextSupport()) return;
$sf = new SearchForm($this->mockController, 'SearchForm');
$sf->setTemplate('BlankPage');
$this->assertContains(
'<body class="SearchForm Form RequestHandler BlankPage">',
$sf->forTemplate()
);
}
public function testPublishedPagesMatchedByTitle() {
if(!$this->checkFulltextSupport()) return;
$sf = new SearchForm($this->mockController, 'SearchForm');
$publishedPage = $this->objFromFixture('SiteTree', 'publicPublishedPage');
$publishedPage->publish('Stage', 'Live');
$this->waitUntilIndexingFinished();
$results = $sf->getResults(null, array('Search'=>'publicPublishedPage'));
$this->assertContains(
@ -85,7 +85,7 @@ class ZZZSearchFormTest extends FunctionalTest {
'Published pages are found by searchform'
);
}
public function testDoubleQuotesPublishedPagesMatchedByTitle() {
if(!$this->checkFulltextSupport()) return;
@ -95,7 +95,7 @@ class ZZZSearchFormTest extends FunctionalTest {
$publishedPage->Title = "finding butterflies";
$publishedPage->write();
$publishedPage->publish('Stage', 'Live');
$this->waitUntilIndexingFinished();
$results = $sf->getResults(null, array('Search'=>'"finding butterflies"'));
$this->assertContains(
@ -104,12 +104,12 @@ class ZZZSearchFormTest extends FunctionalTest {
'Published pages are found by searchform'
);
}
public function testUnpublishedPagesNotIncluded() {
if(!$this->checkFulltextSupport()) return;
$sf = new SearchForm($this->mockController, 'SearchForm');
$results = $sf->getResults(null, array('Search'=>'publicUnpublishedPage'));
$unpublishedPage = $this->objFromFixture('SiteTree', 'publicUnpublishedPage');
$this->assertNotContains(
@ -118,12 +118,12 @@ class ZZZSearchFormTest extends FunctionalTest {
'Unpublished pages are not found by searchform'
);
}
public function testPagesRestrictedToLoggedinUsersNotIncluded() {
if(!$this->checkFulltextSupport()) return;
$sf = new SearchForm($this->mockController, 'SearchForm');
$page = $this->objFromFixture('SiteTree', 'restrictedViewLoggedInUsers');
$page->publish('Stage', 'Live');
$results = $sf->getResults(null, array('Search'=>'restrictedViewLoggedInUsers'));
@ -132,7 +132,7 @@ class ZZZSearchFormTest extends FunctionalTest {
$results->column('ID'),
'Page with "Restrict to logged in users" doesnt show without valid login'
);
$member = $this->objFromFixture('Member', 'randomuser');
$member->logIn();
$results = $sf->getResults(null, array('Search'=>'restrictedViewLoggedInUsers'));
@ -148,7 +148,7 @@ class ZZZSearchFormTest extends FunctionalTest {
if(!$this->checkFulltextSupport()) return;
$sf = new SearchForm($this->mockController, 'SearchForm');
$page = $this->objFromFixture('SiteTree', 'restrictedViewOnlyWebsiteUsers');
$page->publish('Stage', 'Live');
$results = $sf->getResults(null, array('Search'=>'restrictedViewOnlyWebsiteUsers'));
@ -157,7 +157,7 @@ class ZZZSearchFormTest extends FunctionalTest {
$results->column('ID'),
'Page with "Restrict to these users" doesnt show without valid login'
);
$member = $this->objFromFixture('Member', 'randomuser');
$member->logIn();
$results = $sf->getResults(null, array('Search'=>'restrictedViewOnlyWebsiteUsers'));
@ -167,7 +167,7 @@ class ZZZSearchFormTest extends FunctionalTest {
'Page with "Restrict to these users" doesnt show if logged in user is not in the right group'
);
$member->logOut();
$member = $this->objFromFixture('Member', 'websiteuser');
$member->logIn();
$results = $sf->getResults(null, array('Search'=>'restrictedViewOnlyWebsiteUsers'));
@ -178,13 +178,13 @@ class ZZZSearchFormTest extends FunctionalTest {
);
$member->logOut();
}
public function testInheritedRestrictedPagesNotIncluded() {
$sf = new SearchForm($this->mockController, 'SearchForm');
$parent = $this->objFromFixture('SiteTree', 'restrictedViewLoggedInUsers');
$parent->publish('Stage', 'Live');
$page = $this->objFromFixture('SiteTree', 'inheritRestrictedView');
$page->publish('Stage', 'Live');
$results = $sf->getResults(null, array('Search'=>'inheritRestrictedView'));
@ -193,7 +193,7 @@ class ZZZSearchFormTest extends FunctionalTest {
$results->column('ID'),
'Page inheriting "Restrict to loggedin users" doesnt show without valid login'
);
$member = $this->objFromFixture('Member', 'websiteuser');
$member->logIn();
$results = $sf->getResults(null, array('Search'=>'inheritRestrictedView'));
@ -204,12 +204,12 @@ class ZZZSearchFormTest extends FunctionalTest {
);
$member->logOut();
}
public function testDisabledShowInSearchFlagNotIncludedForSiteTree() {
if(!$this->checkFulltextSupport()) return;
$sf = new SearchForm($this->mockController, 'SearchForm');
$page = $this->objFromFixture('SiteTree', 'dontShowInSearchPage');
$results = $sf->getResults(null, array('Search'=>'dontShowInSearchPage'));
$this->assertNotContains(
@ -218,12 +218,12 @@ class ZZZSearchFormTest extends FunctionalTest {
'Page with "Show in Search" disabled doesnt show'
);
}
public function testDisabledShowInSearchFlagNotIncludedForFiles() {
if(!$this->checkFulltextSupport()) return;
$sf = new SearchForm($this->mockController, 'SearchForm');
$dontShowInSearchFile = $this->objFromFixture('File', 'dontShowInSearchFile');
$dontShowInSearchFile->publish('Stage', 'Live');
$showInSearchFile = $this->objFromFixture('File', 'showInSearchFile');
@ -235,7 +235,7 @@ class ZZZSearchFormTest extends FunctionalTest {
$results->column('ID'),
'File with "Show in Search" disabled doesnt show'
);
$results = $sf->getResults(null, array('Search'=>'showInSearchFile'));
$this->assertContains(
$showInSearchFile->ID,
@ -252,17 +252,17 @@ class ZZZSearchFormTest extends FunctionalTest {
}
$sf = new SearchForm($this->mockController, 'SearchForm');
$pageWithSpecialChars = $this->objFromFixture('SiteTree', 'pageWithSpecialChars');
$pageWithSpecialChars->publish('Stage', 'Live');
$results = $sf->getResults(null, array('Search'=>'Brötchen'));
$this->assertContains(
$pageWithSpecialChars->ID,
$results->column('ID'),
'Published pages with umlauts in title are found'
);
$results = $sf->getResults(null, array('Search'=>'Bäcker'));
$this->assertContains(
$pageWithSpecialChars->ID,

View File

@ -4,30 +4,30 @@
* @subpackage tests
*/
class MigrateSiteTreeLinkingTaskTest extends SapphireTest {
protected static $fixture_file = 'MigrateSiteTreeLinkingTaskTest.yml';
protected static $use_draft_site = true;
public function testLinkingMigration() {
ob_start();
$task = new MigrateSiteTreeLinkingTask();
$task->run(null);
$this->assertEquals (
"Rewrote 9 link(s) on 5 page(s) to use shortcodes.\n",
ob_get_contents(),
'Rewritten links are correctly reported'
);
ob_end_clean();
$homeID = $this->idFromFixture('SiteTree', 'home');
$aboutID = $this->idFromFixture('SiteTree', 'about');
$staffID = $this->idFromFixture('SiteTree', 'staff');
$actionID = $this->idFromFixture('SiteTree', 'action');
$hashID = $this->idFromFixture('SiteTree', 'hash_link');
$homeContent = sprintf (
'<a href="[sitetree_link,id=%d]">About</a><a href="[sitetree_link,id=%d]">Staff</a><a href="http://silverstripe.org/">External Link</a><a name="anchor"></a>',
$aboutID,
@ -51,7 +51,7 @@ class MigrateSiteTreeLinkingTaskTest extends SapphireTest {
$homeID,
$aboutID
);
$this->assertEquals (
$homeContent,
DataObject::get_by_id('SiteTree', $homeID)->Content,
@ -76,5 +76,5 @@ class MigrateSiteTreeLinkingTaskTest extends SapphireTest {
'Hash/anchor links are correctly handled.'
);
}
}

View File

@ -31,50 +31,50 @@
* @subpackage tests
*/
class RemoveOrphanedPagesTaskTest extends FunctionalTest {
protected static $fixture_file = 'RemoveOrphanedPagesTaskTest.yml';
protected static $use_draft_site = false;
public function setUp() {
parent::setUp();
$parent1_published = $this->objFromFixture('Page', 'parent1_published');
$parent1_published->publish('Stage', 'Live');
$child1_1_published = $this->objFromFixture('Page', 'child1_1_published');
$child1_1_published->publish('Stage', 'Live');
$child1_2_published = $this->objFromFixture('Page', 'child1_2_published');
$child1_2_published->publish('Stage', 'Live');
$child1_3_orphaned = $this->objFromFixture('Page', 'child1_3_orphaned');
$child1_3_orphaned->ParentID = 9999;
$child1_3_orphaned->write();
$child1_4_orphaned_published = $this->objFromFixture('Page', 'child1_4_orphaned_published');
$child1_4_orphaned_published->ParentID = 9999;
$child1_4_orphaned_published->write();
$child1_4_orphaned_published->publish('Stage', 'Live');
$grandchild1_1_2_published = $this->objFromFixture('Page', 'grandchild1_1_2_published');
$grandchild1_1_2_published->publish('Stage', 'Live');
$grandchild1_1_3_orphaned = $this->objFromFixture('Page', 'grandchild1_1_3_orphaned');
$grandchild1_1_3_orphaned->ParentID = 9999;
$grandchild1_1_3_orphaned->write();
$grandchild1_1_4_orphaned_published = $this->objFromFixture('Page',
'grandchild1_1_4_orphaned_published'
);
$grandchild1_1_4_orphaned_published->ParentID = 9999;
$grandchild1_1_4_orphaned_published->write();
$grandchild1_1_4_orphaned_published->publish('Stage', 'Live');
$child2_1_published_orphaned = $this->objFromFixture('Page', 'child2_1_published_orphaned');
$child2_1_published_orphaned->publish('Stage', 'Live');
}
public function testGetOrphansByStage() {
// all orphans
$child1_3_orphaned = $this->objFromFixture('Page', 'child1_3_orphaned');
@ -84,7 +84,7 @@ class RemoveOrphanedPagesTaskTest extends FunctionalTest {
'grandchild1_1_4_orphaned_published'
);
$child2_1_published_orphaned = $this->objFromFixture('Page', 'child2_1_published_orphaned');
$task = singleton('RemoveOrphanedPagesTask');
$orphans = $task->getOrphanedPages();
$orphanIDs = $orphans->column('ID');
@ -97,8 +97,8 @@ class RemoveOrphanedPagesTaskTest extends FunctionalTest {
$child2_1_published_orphaned->ID
);
sort($compareIDs);
$this->assertEquals($orphanIDs, $compareIDs);
}
}