Merge remote-tracking branch 'origin/3'

This commit is contained in:
Damian Mooyman 2015-06-09 11:12:30 +12:00
commit dc935628f8
34 changed files with 1219 additions and 573 deletions

View File

@ -22,21 +22,49 @@ class CMSBatchAction_Publish extends CMSBatchAction {
}
/**
* Un-publish items batch action.
* Unpublish items batch action.
*
* @package cms
* @subpackage batchaction
*/
class CMSBatchAction_Unpublish extends CMSBatchAction {
public function getActionTitle() {
return _t('CMSBatchActions.UNPUBLISH_PAGES', 'Un-publish');
return _t('CMSBatchActions.UNPUBLISH_PAGES', 'Unpublish');
}
public function run(SS_List $pages) {
return $this->batchaction($pages, 'doUnpublish',
_t('CMSBatchActions.UNPUBLISHED_PAGES', 'Un-published %d pages')
_t('CMSBatchActions.UNPUBLISHED_PAGES', 'Unpublished %d pages')
);
}
public function applicablePages($ids) {
return $this->applicablePagesHelper($ids, 'canDeleteFromLive', false, true);
}
}
/**
* Archives a page, removing it from both live and stage
*
* @package cms
* @subpackage batchaction
*/
class CMSBatchAction_Archive extends CMSBatchAction {
public function getActionTitle() {
return _t('CMSBatchActions.ARCHIVE', 'Archive');
}
public function run(SS_List $pages) {
return $this->batchaction($pages, 'doArchive',
_t('CMSBatchActions.ARCHIVED_PAGES', 'Archived %d pages')
);
}
public function applicablePages($ids) {
return $this->applicablePagesHelper($ids, 'canArchive', true, true);
}
}
/**
@ -44,6 +72,7 @@ class CMSBatchAction_Unpublish extends CMSBatchAction {
*
* @package cms
* @subpackage batchaction
* @deprecated since version 4.0
*/
class CMSBatchAction_Delete extends CMSBatchAction {
public function getActionTitle() {
@ -51,6 +80,7 @@ class CMSBatchAction_Delete extends CMSBatchAction {
}
public function run(SS_List $pages) {
Deprecation::notice('4.0', 'Delete is deprecated. Use Archive instead');
$status = array(
'modified'=>array(),
'deleted'=>array(),
@ -70,7 +100,6 @@ class CMSBatchAction_Delete extends CMSBatchAction {
'"SiteTree"."ID"' => $id
));
if($liveRecord) {
$liveRecord->IsDeletedFromStage = true;
$status['modified'][$liveRecord->ID] = array(
'TreeTitle' => $liveRecord->TreeTitle,
);
@ -93,14 +122,15 @@ class CMSBatchAction_Delete extends CMSBatchAction {
*
* @package cms
* @subpackage batchaction
* @deprecated since version 4.0
*/
class CMSBatchAction_DeleteFromLive extends CMSBatchAction {
public function getActionTitle() {
return _t('CMSBatchActions.DELETE_PAGES', 'Delete from published site');
}
public function run(SS_List $pages) {
Deprecation::notice('4.0', 'Delete From Live is deprecated. Use Unpublish instead');
$status = array(
'modified'=>array(),
'deleted'=>array()
@ -117,7 +147,6 @@ class CMSBatchAction_DeleteFromLive extends CMSBatchAction {
'"SiteTree"."ID"' => $id
));
if($stageRecord) {
$stageRecord->IsAddedToStage = true;
$status['modified'][$stageRecord->ID] = array(
'TreeTitle' => $stageRecord->TreeTitle,
);

View File

@ -294,9 +294,9 @@ JS
$actions = $form->Actions();
$saveBtn = $actions->fieldByName('action_save');
$deleteBtn = $actions->fieldByName('action_delete');
$actions->removeByName('action_save');
$actions->removeByName('action_delete');
if(($saveBtn || $deleteBtn) && $fields->fieldByName('Root.DetailsView')) {
$actions->removeByName('action_save');
$actions->removeByName('action_delete');
$fields->addFieldToTab(
'Root.DetailsView',
CompositeField::create($saveBtn,$deleteBtn)->addExtraClass('Actions')
@ -535,6 +535,7 @@ JS
public function getSiteTreeFor($className, $rootID = null, $childrenMethod = null, $numChildrenMethod = null, $filterFunction = null, $minNodeCount = 30) {
if (!$childrenMethod) $childrenMethod = 'ChildFolders';
if (!$numChildrenMethod) $numChildrenMethod = 'numChildFolders';
return parent::getSiteTreeFor($className, $rootID, $childrenMethod, $numChildrenMethod, $filterFunction, $minNodeCount);
}
@ -543,7 +544,7 @@ JS
}
public function SiteTreeAsUL() {
return $this->getSiteTreeFor($this->stat('tree_class'), null, 'ChildFolders');
return $this->getSiteTreeFor($this->stat('tree_class'), null, 'ChildFolders', 'numChildFolders');
}
//------------------------------------------------------------------------------------------//

View File

@ -36,6 +36,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
private static $page_length = 15;
private static $allowed_actions = array(
'archive',
'buildbrokenlinks',
'deleteitems',
'DeleteItemsForm',
@ -57,6 +58,14 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
'childfilter',
);
/**
* Enable legacy batch actions.
* @deprecated since version 4.0
* @var array
* @config
*/
private static $enabled_legacy_actions = array();
public function init() {
// set reading lang
if(SiteTree::has_extension('Translatable') && !$this->getRequest()->isAjax()) {
@ -88,8 +97,24 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
CMSBatchActionHandler::register('publish', 'CMSBatchAction_Publish');
CMSBatchActionHandler::register('unpublish', 'CMSBatchAction_Unpublish');
CMSBatchActionHandler::register('delete', 'CMSBatchAction_Delete');
CMSBatchActionHandler::register('deletefromlive', 'CMSBatchAction_DeleteFromLive');
// Check legacy actions
$legacy = $this->config()->enabled_legacy_actions;
// Delete from live is unnecessary since we have unpublish which does the same thing
if(in_array('CMSBatchAction_DeleteFromLive', $legacy)) {
Deprecation::notice('4.0', 'Delete From Live is deprecated. Use Un-publish instead');
CMSBatchActionHandler::register('deletefromlive', 'CMSBatchAction_DeleteFromLive');
}
// Delete action
if(in_array('CMSBatchAction_Delete', $legacy)) {
Deprecation::notice('4.0', 'Delete from Stage is deprecated. Use Archive instead.');
CMSBatchActionHandler::register('delete', 'CMSBatchAction_Delete');
} else {
CMSBatchActionHandler::register('archive', 'CMSBatchAction_Archive');
}
}
public function index($request) {
@ -576,8 +601,8 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
$actions = $form->Actions();
if($record) {
$deletedFromStage = $record->IsDeletedFromStage;
$deleteFromLive = !$record->ExistsOnLive;
$deletedFromStage = $record->getIsDeletedFromStage();
$deleteFromLive = !$record->getExistsOnLive();
$fields->push($idField = new HiddenField("ID", false, $id));
// Necessary for different subsites
@ -1059,13 +1084,13 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
* @see deletefromlive()
*/
public function delete($data, $form) {
Deprecation::notice('4.0', 'Delete from stage is deprecated. Use archive instead');
$id = $data['ID'];
$record = DataObject::get_by_id("SiteTree", $id);
if($record && !$record->canDelete()) return Security::permissionFailure();
if(!$record || !$record->ID) throw new SS_HTTPResponse_Exception("Bad record ID #$id", 404);
// save ID and delete record
$recordID = $record->ID;
// Delete record
$record->delete();
$this->response->addHeader(
@ -1077,6 +1102,34 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
return $this->getResponseNegotiator()->respond($this->getRequest());
}
/**
* Delete this page from both live and stage
*
* @param type $data
* @param type $form
*/
public function archive($data, $form) {
$id = $data['ID'];
$record = DataObject::get_by_id("SiteTree", $id);
if(!$record || !$record->exists()) {
throw new SS_HTTPResponse_Exception("Bad record ID #$id", 404);
}
if(!$record->canArchive()) {
return Security::permissionFailure();
}
// Archive record
$record->doArchive();
$this->response->addHeader(
'X-Status',
rawurlencode(sprintf(_t('CMSMain.ARCHIVEDPAGE',"Archived page '%s'"), $record->Title))
);
// Even if the record has been deleted from stage and live, it can be viewed in "archive mode"
return $this->getResponseNegotiator()->respond($this->getRequest());
}
public function publish($data, $form) {
$data['publish'] = '1';

View File

@ -259,7 +259,7 @@ class CMSSIteTreeFilter_PublishedPages extends CMSSiteTreeFilter {
$pages = Versioned::get_including_deleted('SiteTree');
$pages = $this->applyDefaultFilters($pages);
$pages = $pages->filterByCallback(function($page) {
return $page->ExistsOnLive;
return $page->getExistsOnLive();
});
return $pages;
}
@ -286,7 +286,7 @@ class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter {
protected $numChildrenMethod = 'numHistoricalChildren';
static public function title() {
return _t('CMSSiteTreeFilter_DeletedPages.Title', "All pages, including deleted");
return _t('CMSSiteTreeFilter_DeletedPages.Title', "All pages, including archived");
}
public function getFilteredPages() {
@ -305,7 +305,7 @@ class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter {
class CMSSiteTreeFilter_ChangedPages extends CMSSiteTreeFilter {
static public function title() {
return _t('CMSSiteTreeFilter_ChangedPages.Title', "Changed pages");
return _t('CMSSiteTreeFilter_ChangedPages.Title', "Modified pages");
}
public function getFilteredPages() {
@ -339,7 +339,7 @@ class CMSSiteTreeFilter_StatusRemovedFromDraftPages extends CMSSiteTreeFilter {
$pages = $this->applyDefaultFilters($pages);
$pages = $pages->filterByCallback(function($page) {
// If page is removed from stage but not live
return $page->IsDeletedFromStage && $page->ExistsOnLive;
return $page->getIsDeletedFromStage() && $page->getExistsOnLive();
});
return $pages;
}
@ -354,7 +354,7 @@ class CMSSiteTreeFilter_StatusRemovedFromDraftPages extends CMSSiteTreeFilter {
class CMSSiteTreeFilter_StatusDraftPages extends CMSSiteTreeFilter {
static public function title() {
return _t('CMSSiteTreeFilter_StatusDraftPages.Title', 'Draft unpublished pages');
return _t('CMSSiteTreeFilter_StatusDraftPages.Title', 'Draft pages');
}
/**
@ -368,7 +368,7 @@ class CMSSiteTreeFilter_StatusDraftPages extends CMSSiteTreeFilter {
$pages = $this->applyDefaultFilters($pages);
$pages = $pages->filterByCallback(function($page) {
// If page exists on stage but not on live
return (!$page->IsDeletedFromStage && $page->IsAddedToStage);
return (!$page->getIsDeletedFromStage() && $page->getIsAddedToStage());
});
return $pages;
}
@ -393,7 +393,7 @@ class CMSSiteTreeFilter_StatusDeletedPages extends CMSSiteTreeFilter {
protected $numChildrenMethod = 'numHistoricalChildren';
static public function title() {
return _t('CMSSiteTreeFilter_StatusDeletedPages.Title', 'Deleted pages');
return _t('CMSSiteTreeFilter_StatusDeletedPages.Title', 'Archived pages');
}
/**
@ -408,7 +408,7 @@ class CMSSiteTreeFilter_StatusDeletedPages extends CMSSiteTreeFilter {
$pages = $pages->filterByCallback(function($page) {
// Doesn't exist on either stage or live
return $page->IsDeletedFromStage && !$page->ExistsOnLive;
return $page->getIsDeletedFromStage() && !$page->getExistsOnLive();
});
return $pages;
}

View File

@ -119,7 +119,7 @@ class ContentController extends Controller {
|| (Versioned::current_stage() && Versioned::current_stage() != 'Live')
)
) {
if(!$this->dataRecord->canViewStage(Versioned::current_archived_date() ? 'Stage' : Versioned::current_stage())) {
if(!$this->dataRecord->canView()) {
Session::clear('currentStage');
Session::clear('archiveDate');

View File

@ -260,6 +260,7 @@ class ErrorPage extends Page {
$this->response->addHeader('X-Status', rawurlencode($fileErrorText));
return $this->httpError(405);
}
return true;
}
/**

View File

@ -1,17 +1,16 @@
<?php
/**
* Basic data-object representing all pages within the site tree.
* This data-object takes care of the heirachy. All page types that live within the hierarchy should inherit from this.
* In addition, it contains a number of static methods for querying the site tree.
* Basic data-object representing all pages within the site tree. All page types that live within the hierarchy should
* inherit from this. In addition, it contains a number of static methods for querying the site tree and working with
* draft and published states.
*
* <h2>URLs</h2>
* A page is identified during request handling via its "URLSegment" database column.
* As pages can be nested, the full path of a URL might contain multiple segments.
* Each segment is stored in its filtered representation (through {@link URLSegmentFilter}).
* The full path is constructed via {@link Link()}, {@link RelativeLink()} and {@link AbsoluteLink()}.
* You can allow these segments to contain multibyte characters through {@link URLSegmentFilter::$default_allow_multibyte}.
* A page is identified during request handling via its "URLSegment" database column. As pages can be nested, the full
* path of a URL might contain multiple segments. Each segment is stored in its filtered representation (through
* {@link URLSegmentFilter}). The full path is constructed via {@link Link()}, {@link RelativeLink()} and
* {@link AbsoluteLink()}. You can allow these segments to contain multibyte characters through
* {@link URLSegmentFilter::$default_allow_multibyte}.
*
* @property integer ID ID of the SiteTree object.
* @property string URLSegment
* @property string Title
* @property string MenuTitle
@ -21,17 +20,17 @@
* @property string ShowInMenus
* @property string ShowInSearch
* @property string Sort Integer value denoting the sort order.
* @property string HasBrokenFile
* @property string HasBrokenLink
* @property string ReportClass
* @property string CanViewType Type of restriction for viewing this object.
* @property string CanEditType Type of restriction for editing this object.
*
* @method ManyManyList LinkTracking() List of site pages linked on this page.
* @method ManyManyList ImageTracking() List of Images linked on this page.
* @method ManyManyList ViewerGroups() List of groups that can view this object.
* @method ManyManyList EditorGroups() List of groups that can edit this object.
* @method ManyManyList BackLinkTracking() List of site pages that link to this page.
* @method ManyManyList ViewerGroups List of groups that can view this object.
* @method ManyManyList EditorGroups List of groups that can edit this object.
* @method ManyManyList BackLinkTracking List of site pages that link to this page.
*
* @mixin Hierarchy
* @mixin Versioned
* @mixin SiteTreeLinkTracking
*
* @package cms
*/
@ -162,8 +161,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* If this is false, the class cannot be created in the CMS by regular content authors, only by ADMINs.
* @var boolean
* @config
*/
* @config
*/
private static $can_create = true;
/**
@ -228,7 +227,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
private static $enforce_strict_hierarchy = true;
/**
* The value used for the meta generator tag. Leave blank to omit the tag.
* The value used for the meta generator tag. Leave blank to omit the tag.
*
* @config
* @var string
@ -317,8 +316,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* Note that if no model can be found, this method will fall over to a extended alternateGetByLink method provided
* by a extension attached to {@link SiteTree}
*
* @param string $link
* @param bool $cache
* @param string $link The link of the page to search for
* @param bool $cache True (default) to use caching, false to force a fresh search from the database
* @return SiteTree
*/
static public function get_by_link($link, $cache = true) {
@ -389,9 +388,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Return a subclass map of SiteTree
* that shouldn't be hidden through
* {@link SiteTree::$hide_ancestor}
* Return a subclass map of SiteTree that shouldn't be hidden through {@link SiteTree::$hide_ancestor}
*
* @return array
*/
@ -414,7 +411,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
}
// If any of the descendents don't want any of the elders to show up, cruelly render the elders surplus to requirements.
// If any of the descendents don't want any of the elders to show up, cruelly render the elders surplus to
// requirements
if($kill_ancestors) {
$kill_ancestors = array_unique($kill_ancestors);
foreach($kill_ancestors as $mark) {
@ -430,10 +428,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Replace a "[sitetree_link id=n]" shortcode with a link to the page with the corresponding ID.
*
* @param array $arguments
* @param mixed $content
* @param object|null $parser
* @return string|void
* @param array $arguments
* @param string $content
* @param TextParser $parser
* @return string
*/
static public function link_shortcode_handler($arguments, $content = null, $parser = null) {
if(!isset($arguments['id']) || !is_numeric($arguments['id'])) return;
@ -459,9 +457,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* Return the link for this {@link SiteTree} object, with the {@link Director::baseURL()} included.
*
* @param string $action Optional controller action (method).
* Note: URI encoding of this parameter is applied automatically through template casting,
* don't encode the passed parameter.
* Please use {@link Controller::join_links()} instead to append GET parameters.
* Note: URI encoding of this parameter is applied automatically through template casting,
* don't encode the passed parameter. Please use {@link Controller::join_links()} instead to
* append GET parameters.
* @return string
*/
public function Link($action = null) {
@ -483,9 +481,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* 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.
* 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.
*
* @param string $action See {@link Link()}
* @return string
@ -501,7 +498,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Return the link for this {@link SiteTree} object relative to the SilverStripe root.
*
* By default, it this page is the current home page, and there is no action specified then this will return a link
* By default, if this page is the current home page, and there is no action specified then this will return a link
* to the root of the site. However, if you set the $action parameter to TRUE then the link will not be rewritten
* and returned in its full form.
*
@ -512,7 +509,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*/
public function RelativeLink($action = null) {
if($this->ParentID && self::config()->nested_urls) {
$base = $this->Parent()->RelativeLink($this->URLSegment);
$parent = $this->Parent();
// If page is removed select parent from version history (for archive page view)
if((!$parent || !$parent->exists()) && $this->IsDeletedFromStage) {
$parent = Versioned::get_latest_version('SiteTree', $this->ParentID);
}
$base = $parent->RelativeLink($this->URLSegment);
} elseif(!$action && $this->URLSegment == RootURLController::get_homepage_link()) {
// Unset base for root-level homepages.
// Note: Homepages with action parameters (or $action === true)
@ -533,6 +535,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Get the absolute URL for this page on the Live site.
*
* @param bool $includeStageEqualsLive Whether to append the URL with ?stage=Live to force Live mode
* @return string
*/
public function getAbsoluteLiveLink($includeStageEqualsLive = true) {
$oldStage = Versioned::current_stage();
@ -552,7 +557,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* @return String
* Generates a link to edit this page in the CMS.
*
* @return string
*/
public function CMSEditLink() {
return Controller::join_links(singleton('CMSPageEditController')->Link('show'), $this->ID);
@ -569,7 +576,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Returns TRUE if this is the currently active page that is being used to handle a request.
* Returns true if this is the currently active page being used to handle this request.
*
* @return bool
*/
@ -578,8 +585,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Check if this page is in the currently active section (e.g. it is either current or one of it's children is
* currently being viewed.
* 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).
*
* @return bool
*/
@ -590,9 +597,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* 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 to external users.
* 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
* to external users.
*
* @return bool
*/
@ -624,8 +631,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* 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.
* 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.
*
* @return string
*/
@ -642,8 +649,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Check if this page is in the given current section.
*
* @param string $sectionName Name of the section to check.
* @return boolean True if we are in the given section.
* @param string $sectionName Name of the section to check
* @return bool True if we are in the given section
*/
public function InSection($sectionName) {
$page = Director::get_current_page();
@ -656,11 +663,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Create a duplicate of this node. Doesn't affect joined data - create a
* custom overloading of this if you need such behaviour.
* Create a duplicate of this node. Doesn't affect joined data - create a custom overloading of this if you need
* such behaviour.
*
* @param bool $doWrite
* @return SiteTree The duplicated object.
* @param bool $doWrite Whether to write the new object before returning it
* @return self The duplicated object
*/
public function duplicate($doWrite = true) {
@ -678,12 +685,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $page;
}
/**
* Duplicates each child of this node recursively and returns the
* duplicate node.
* Duplicates each child of this node recursively and returns the top-level duplicate node.
*
* @return SiteTree The duplicated object.
* @return self The duplicated object
*/
public function duplicateWithChildren() {
$clone = $this->duplicate();
@ -702,10 +707,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $clone;
}
/**
* Duplicate this node and its children as a child of the node with the
* given ID
* Duplicate this node and its children as a child of the node with the given ID
*
* @param int $id ID of the new node's new parent
*/
@ -717,8 +720,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Return a breadcrumb trail to this page. Excludes "hidden" pages
* (with ShowInMenus=0).
* Return a breadcrumb trail to this page. Excludes "hidden" pages (with ShowInMenus=0) by default.
*
* @param int $maxDepth The maximum depth to traverse.
* @param boolean $unlinked Whether to link page titles.
@ -768,8 +770,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Make this page a child of another page.
*
* If the parent page does not exist, resolve it to a valid ID
* before updating this page's reference.
* If the parent page does not exist, resolve it to a valid ID before updating this page's reference.
*
* @param SiteTree|int $item Either the parent object, or the parent ID
*/
@ -785,7 +786,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Get the parent of this page.
*
* @return SiteTree Parent of this page.
* @return SiteTree Parent of this page
*/
public function getParent() {
if ($parentID = $this->getField("ParentID")) {
@ -794,8 +795,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Return a string of the form "parent - page" or
* "grandparent - parent - page".
* Return a string of the form "parent - page" or "grandparent - parent - page" using page titles
*
* @param int $level The maximum amount of levels to traverse.
* @param string $separator Seperating string
@ -812,8 +812,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* This function should return true if the current user can execute this action.
* It can be overloaded to customise the security model for an application.
* This function should return true if the current user can execute this action. It can be overloaded to customise
* the security model for an application.
*
* Slightly altered from parent behaviour in {@link DataObject->can()}:
* - Checks for existence of a method named "can<$perm>()" on the object
@ -823,10 +823,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*
* @uses DataObjectDecorator->can()
*
* @param string $perm The permission to be checked, such as 'View'.
* @param Member $member The member whose permissions need checking.
* Defaults to the currently logged in user.
* @return boolean True if the the member is allowed to do the given action.
* @param string $perm The permission to be checked, such as 'View'
* @param Member $member The member whose permissions need checking. Defaults to the currently logged in user.
* @return bool True if the the member is allowed to do the given action
*/
public function can($perm, $member = null) {
if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) {
@ -846,14 +845,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return ($member && Permission::checkMember($member, $perm));
}
/**
* This function should return true if the current user can add children
* to this page. It can be overloaded to customise the security model for an
* application.
* This function should return true if the current user can add children to this page. It can be overloaded to
* customise the security model for an application.
*
* Denies permission if any of the following conditions is TRUE:
* - alternateCanAddChildren() on a extension returns FALSE
* Denies permission if any of the following conditions is true:
* - alternateCanAddChildren() on a extension returns false
* - canEdit() is not granted
* - There are no classes defined in {@link $allowed_children}
*
@ -861,8 +858,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @uses canEdit()
* @uses $allowed_children
*
* @param Member|int|null $member
* @return boolean True if the current user can add children.
* @param Member|int $member
* @return bool True if the current user can add children
*/
public function canAddChildren($member = null) {
if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) {
@ -878,14 +875,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $this->canEdit($member) && $this->stat('allowed_children') != 'none';
}
/**
* This function should return true if the current user can view this
* page. It can be overloaded to customise the security model for an
* application.
* This function should return true if the current user can view this page. It can be overloaded to customise the
* security model for an application.
*
* Denies permission if any of the following conditions is TRUE:
* - canView() on any extension returns FALSE
* Denies permission if any of the following conditions is true:
* - canView() on any extension returns false
* - "CanViewType" directive is set to "Inherit" and any parent page return false for canView()
* - "CanViewType" directive is set to "LoggedInUsers" and no user is logged in
* - "CanViewType" directive is set to "OnlyTheseUsers" and user is not in the given groups
@ -893,8 +888,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* @uses DataExtension->canView()
* @uses ViewerGroups()
*
* @param Member|int|null $member
* @return boolean True if the current user can view this page.
* @param Member|int $member
* @return bool True if the current user can view this page
*/
public function canView($member = null) {
if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) {
@ -959,9 +954,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*
* @todo Implement in CMS UI.
*
* @param String $stage
* @param string $stage
* @param Member $member
* @return boolean
* @return bool
*/
public function canViewStage($stage = 'Live', $member = null) {
$oldMode = Versioned::get_reading_mode();
@ -974,21 +969,20 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* This function should return true if the current user can delete this
* page. It can be overloaded to customise the security model for an
* application.
* This function should return true if the current user can delete this page. It can be overloaded to customise the
* security model for an application.
*
* Denies permission if any of the following conditions is TRUE:
* - canDelete() returns FALSE on any extension
* - canEdit() returns FALSE
* - any descendant page returns FALSE for canDelete()
* Denies permission if any of the following conditions is true:
* - canDelete() returns false on any extension
* - canEdit() returns false
* - any descendant page returns false for canDelete()
*
* @uses canDelete()
* @uses SiteTreeExtension->canDelete()
* @uses canEdit()
*
* @param Member $member
* @return boolean True if the current user can delete this page.
* @return bool True if the current user can delete this page
*/
public function canDelete($member = null) {
if($member instanceof Member) $memberID = $member->ID;
@ -1012,13 +1006,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* This function should return true if the current user can create new
* pages of this class, regardless of context. It can be overloaded
* to customise the security model for an application.
* This function should return true if the current user can create new pages of this class, regardless of class. It
* can be overloaded to customise the security model for an application.
*
* By default, permission to create at the root level is based on the SiteConfig
* configuration, and permission to create beneath a parent is based on the
* ability to edit that parent page.
* By default, permission to create at the root level is based on the SiteConfig configuration, and permission to
* create beneath a parent is based on the ability to edit that parent page.
*
* Use {@link canAddChildren()} to control behaviour of creating children under this page.
*
@ -1027,9 +1019,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*
* @param Member $member
* @param array $context Optional array which may contain array('Parent' => $parentObj)
* If a parent page is known, it will be checked for validity.
* If omitted, it will be assumed this is to be created as a top level page.
* @return boolean True if the current user can create pages on this class.
* If a parent page is known, it will be checked for validity.
* If omitted, it will be assumed this is to be created as a top level page.
* @return bool True if the current user can create pages on this class.
*/
public function canCreate($member = null) {
if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) {
@ -1062,23 +1054,24 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* This function should return true if the current user can edit this
* page. It can be overloaded to customise the security model for an
* application.
* This function should return true if the current user can edit this page. It can be overloaded to customise the
* security model for an application.
*
* Denies permission if any of the following conditions is TRUE:
* - canEdit() on any extension returns FALSE
* Denies permission if any of the following conditions is true:
* - canEdit() on any extension returns false
* - canView() return false
* - "CanEditType" directive is set to "Inherit" and any parent page return false for canEdit()
* - "CanEditType" directive is set to "LoggedInUsers" and no user is logged in or doesn't have the CMS_Access_CMSMAIN permission code
* - "CanEditType" directive is set to "LoggedInUsers" and no user is logged in or doesn't have the
* CMS_Access_CMSMAIN permission code
* - "CanEditType" directive is set to "OnlyTheseUsers" and user is not in the given groups
*
* @uses canView()
* @uses EditorGroups()
* @uses DataExtension->canEdit()
*
* @param Member $member Set to FALSE if you want to explicitly test permissions without a valid user (useful for unit tests)
* @return boolean True if the current user can edit this page.
* @param Member $member Set to false if you want to explicitly test permissions without a valid user (useful for
* unit tests)
* @return bool True if the current user can edit this page
*/
public function canEdit($member = null) {
if($member instanceof Member) $memberID = $member->ID;
@ -1106,18 +1099,17 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* This function should return true if the current user can publish this
* page. It can be overloaded to customise the security model for an
* application.
* This function should return true if the current user can publish this page. It can be overloaded to customise
* the security model for an application.
*
* Denies permission if any of the following conditions is TRUE:
* - canPublish() on any extension returns FALSE
* - canEdit() returns FALSE
* Denies permission if any of the following conditions is true:
* - canPublish() on any extension returns false
* - canEdit() returns false
*
* @uses SiteTreeExtension->canPublish()
*
* @param Member $member
* @return boolean True if the current user can publish this page.
* @return bool True if the current user can publish this page.
*/
public function canPublish($member = null) {
if(!$member || !(is_a($member, 'Member')) || is_numeric($member)) $member = Member::currentUser();
@ -1141,7 +1133,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Stub method to get the site config, provided so it's easy to override
* Stub method to get the site config, unless the current class can provide an alternate.
*
* @return SiteConfig
*/
public function getSiteConfig() {
@ -1154,13 +1148,13 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Pre-populate the cache of canEdit, canView, canDelete, canPublish permissions.
* This method will use the static can_(perm)_multiple method for efficiency.
* Pre-populate the cache of canEdit, canView, canDelete, canPublish permissions. This method will use the static
* can_(perm)_multiple method for efficiency.
*
* @param string $permission The permission: edit, view, publish, approve, etc.
* @param array $ids An array of page IDs
* @param callback|null $batchCallback The function/static method to call to calculate permissions. Defaults
* to 'SiteTree::can_(permission)_multiple'
* @param string $permission The permission: edit, view, publish, approve, etc.
* @param array $ids An array of page IDs
* @param callable|string $batchCallback The function/static method to call to calculate permissions. Defaults
* to 'SiteTree::can_(permission)_multiple'
*/
static public function prepopulate_permission_cache($permission = 'CanEditType', $ids, $batchCallback = null) {
if(!$batchCallback) $batchCallback = "SiteTree::can_{$permission}_multiple";
@ -1174,24 +1168,25 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* This method is NOT a full replacement for the individual can*() methods, e.g. {@link canEdit()}.
* Rather than checking (potentially slow) PHP logic, it relies on the database group associations,
* e.g. the "CanEditType" field plus the "SiteTree_EditorGroups" many-many table.
* By batch checking multiple records, we can combine the queries efficiently.
* This method is NOT a full replacement for the individual can*() methods, e.g. {@link canEdit()}. Rather than
* checking (potentially slow) PHP logic, it relies on the database group associations, e.g. the "CanEditType" field
* plus the "SiteTree_EditorGroups" many-many table. By batch checking multiple records, we can combine the queries
* efficiently.
*
* Caches based on $typeField data. To invalidate the cache, use {@link SiteTree::reset()}
* or set the $useCached property to FALSE.
* Caches based on $typeField data. To invalidate the cache, use {@link SiteTree::reset()} or set the $useCached
* property to FALSE.
*
* @param Array $ids Of {@link SiteTree} IDs
* @param Int $memberID Member ID
* @param String $typeField A property on the data record, e.g. "CanEditType".
* @param String $groupJoinTable A many-many table name on this record, e.g. "SiteTree_EditorGroups"
* @param String $siteConfigMethod Method to call on {@link SiteConfig} for toplevel items, e.g. "canEdit"
* @param String $globalPermission If the member doesn't have this permission code, don't bother iterating deeper.
* @param Boolean $useCached
* @return Array An map of {@link SiteTree} ID keys, to boolean values
* @param array $ids Of {@link SiteTree} IDs
* @param int $memberID Member ID
* @param string $typeField A property on the data record, e.g. "CanEditType".
* @param string $groupJoinTable A many-many table name on this record, e.g. "SiteTree_EditorGroups"
* @param string $siteConfigMethod Method to call on {@link SiteConfig} for toplevel items, e.g. "canEdit"
* @param string $globalPermission If the member doesn't have this permission code, don't bother iterating deeper
* @param bool $useCached
* @return array An map of {@link SiteTree} ID keys to boolean values
*/
static public function batch_permission_check($ids, $memberID, $typeField, $groupJoinTable, $siteConfigMethod, $globalPermission = null, $useCached = true) {
public static function batch_permission_check($ids, $memberID, $typeField, $groupJoinTable, $siteConfigMethod,
$globalPermission = null, $useCached = true) {
if($globalPermission === NULL) $globalPermission = array('CMS_ACCESS_LeftAndMain', 'CMS_ACCESS_CMSMain');
// Sanitise the IDs
@ -1225,8 +1220,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
// Placeholder for parameterised ID list
$idPlaceholders = DB::placeholders($ids);
// if page can't be viewed, don't grant edit permissions
// to do - implement can_view_multiple(), so this can be enabled
// 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
@ -1271,15 +1266,16 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
);
if($potentiallyInherited) {
// Group $potentiallyInherited by ParentID; we'll look at the permission of all those
// parents and then see which ones the user has permission on
// Group $potentiallyInherited by ParentID; we'll look at the permission of all those parents and
// then see which ones the user has permission on
$groupedByParent = array();
foreach($potentiallyInherited as $item) {
if($item->ParentID) {
if(!isset($groupedByParent[$item->ParentID])) $groupedByParent[$item->ParentID] = array();
$groupedByParent[$item->ParentID][] = $item->ID;
} else {
// Might return different site config based on record context, e.g. when subsites module is used
// Might return different site config based on record context, e.g. when subsites module
// is used
$siteConfig = $item->getSiteConfig();
$result[$item->ID] = $siteConfig->{$siteConfigMethod}($memberID);
}
@ -1316,11 +1312,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Get the 'can edit' information for a number of SiteTree pages.
*
* @param array $ids An array of IDs of the SiteTree pages to look up.
* @param int $memberID ID of member.
* @param bool $useCached Return values from the permission cache if they exist.
* @return array A map where the IDs are keys and the values are booleans stating whether the given
* page can be edited.
* @param array $ids An array of IDs of the SiteTree pages to look up
* @param int $memberID ID of member
* @param bool $useCached Return values from the permission cache if they exist
* @return array A map where the IDs are keys and the values are booleans stating whether the given page can be
* edited
*/
static public function can_edit_multiple($ids, $memberID, $useCached = true) {
return self::batch_permission_check($ids, $memberID, 'CanEditType', 'SiteTree_EditorGroups', 'canEditPages', null, $useCached);
@ -1328,9 +1324,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Get the 'can edit' information for a number of SiteTree pages.
* @param array $ids An array of IDs of the SiteTree pages to look up.
* @param int $memberID ID of member.
* @param bool $useCached Return values from the permission cache if they exist.
*
* @param array $ids An array of IDs of the SiteTree pages to look up
* @param int $memberID ID of member
* @param bool $useCached Return values from the permission cache if they exist
* @return array
*/
static public function can_delete_multiple($ids, $memberID, $useCached = true) {
@ -1389,23 +1386,19 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$deletable = array();
}
// Convert the array of deletable IDs into a map of the original IDs with true/false as the
// value
// 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);
}
/**
* Collate selected descendants of this page.
*
* {@link $condition} will be evaluated on each descendant, and if it is
* succeeds, that item will be added to the $collator array.
* {@link $condition} will be evaluated on each descendant, and if it is succeeds, that item will be added to the
* $collator array.
*
* @param string $condition The PHP condition to be evaluated. The page
* will be called $item
* @param array $collator An array, passed by reference, to collect all
* of the matching descendants.
* @return true|void
* @param string $condition The PHP condition to be evaluated. The page will be called $item
* @param array $collator An array, passed by reference, to collect all of the matching descendants.
* @return bool
*/
public function collateDescendants($condition, &$collator) {
if($children = $this->Children()) {
@ -1417,13 +1410,12 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
}
/**
* Return the title, description, keywords and language metatags.
*
* @todo Move <title> tag in separate getter for easier customization and more obvious usage
*
* @param boolean|string $includeTitle Show default <title>-tag, set to false for custom templating
* @param bool $includeTitle Show default <title>-tag, set to false for custom templating
* @return string The XHTML metatags
*/
public function MetaTags($includeTitle = true) {
@ -1460,29 +1452,23 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $tags;
}
/**
* Returns the object that contains the content that a user would
* associate with this page.
* Returns the object that contains the content that a user would associate with this page.
*
* Ordinarily, this is just the page itself, but for example on
* RedirectorPages or VirtualPages ContentSource() will return the page
* that is linked to.
* Ordinarily, this is just the page itself, but for example on RedirectorPages or VirtualPages ContentSource() will
* return the page that is linked to.
*
* @return SiteTree The content source.
* @return $this
*/
public function ContentSource() {
return $this;
}
/**
* Add default records to database.
*
* This function is called whenever the database is built, after the
* database tables have all been created. Overload this to add default
* records when the database is built, but make sure you call
* parent::requireDefaultRecords().
* This function is called whenever the database is built, after the database tables have all been created. Overload
* this to add default records when the database is built, but make sure you call parent::requireDefaultRecords().
*/
public function requireDefaultRecords() {
parent::requireDefaultRecords();
@ -1534,9 +1520,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
}
//------------------------------------------------------------------------------------//
protected function onBeforeWrite() {
parent::onBeforeWrite();
@ -1574,10 +1557,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$fieldsIgnoredByVersioning = array('HasBrokenLink', 'Status', 'HasBrokenFile', 'ToDo', 'VersionID', 'SaveCount');
$changedFields = array_keys($this->getChangedFields(true, 2));
// This more rigorous check is inline with the test that write()
// does to dedcide whether or not to write to the DB. We use that
// to avoid cluttering the system with a migrateVersion() call
// that doesn't get used
// This more rigorous check is inline with the test that write() does to dedcide whether or not to write to the
// DB. We use that to avoid cluttering the system with a migrateVersion() call that doesn't get used
$oneChangedFields = array_keys($this->getChangedFields(true, 1));
if($oneChangedFields && !array_diff($changedFields, $fieldsIgnoredByVersioning)) {
@ -1621,7 +1602,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
}
public function onAfterDelete() {
// Need to flush cache to avoid outdated versionnumber references
$this->flushCache();
@ -1680,11 +1660,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Returns TRUE if this object has a URLSegment value that does not conflict with any other objects. This methods
* Returns true if this object has a URLSegment value that does not conflict with any other objects. This method
* checks for:
* - A page with the same URLSegment that has a conflict.
* - Conflicts with actions on the parent page.
* - A conflict caused by a root page having the same URLSegment as a class name.
* - A page with the same URLSegment that has a conflict
* - Conflicts with actions on the parent page
* - A conflict caused by a root page having the same URLSegment as a class name
*
* @return bool
*/
@ -1727,11 +1707,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
* Generate a URL segment based on the title provided.
*
* If {@link Extension}s wish to alter URL segment generation, they can do so by defining
* updateURLSegment(&$url, $title). $url will be passed by reference and should be modified.
* $title will contain the title that was originally used as the source of this generated URL.
* This lets extensions either start from scratch, or incrementally modify the generated URL.
* updateURLSegment(&$url, $title). $url will be passed by reference and should be modified. $title will contain
* the title that was originally used as the source of this generated URL. This lets extensions either start from
* scratch, or incrementally modify the generated URL.
*
* @param string $title Page title.
* @param string $title Page title
* @return string Generated url segment
*/
public function generateURLSegment($title){
@ -1748,6 +1728,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Gets the URL segment for the latest draft version of this page.
*
* @return string
*/
public function getStageURLSegment() {
@ -1758,6 +1740,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Gets the URL segment for the currently published version of this page.
*
* @return string
*/
public function getLiveURLSegment() {
@ -1768,8 +1752,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Rewrite a file URL on this page, after its been renamed.
* Triggers the onRenameLinkedAsset action on extensions.
* Rewrite a file URL on this page, after its been renamed. Triggers the onRenameLinkedAsset action on extensions.
*/
public function rewriteFileURL($old, $new) {
$fields = $this->inheritedDatabaseFields();
@ -1805,8 +1788,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Returns the pages that depend on this page.
* This includes virtual pages, pages that link to it, etc.
* Returns the pages that depend on this page. This includes virtual pages, pages that link to it, etc.
*
* @param bool $includeVirtuals Set to false to exlcude virtual pages.
* @return ArrayList
@ -1863,7 +1845,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Return all virtual pages that link to this page
* Return all virtual pages that link to this page.
*
* @return DataList
*/
public function VirtualPages() {
@ -1891,14 +1875,13 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Returns a FieldList with which to create the main editing form.
*
* You can override this in your child classes to add extra fields - first
* get the parent fields using parent::getCMSFields(), then use
* addFieldToTab() on the FieldList.
* You can override this in your child classes to add extra fields - first get the parent fields using
* parent::getCMSFields(), then use addFieldToTab() on the FieldList.
*
* See {@link getSettingsFields()} for a different set of fields
* concerned with configuration aspects on the record, e.g. access control
* See {@link getSettingsFields()} for a different set of fields concerned with configuration aspects on the record,
* e.g. access control.
*
* @return FieldList The fields to be displayed in the CMS.
* @return FieldList The fields to be displayed in the CMS
*/
public function getCMSFields() {
require_once("forms/Form.php");
@ -2079,8 +2062,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Returns fields related to configuration aspects on this record, e.g. access control.
* See {@link getCMSFields()} for content-related fields.
* Returns fields related to configuration aspects on this record, e.g. access control. See {@link getCMSFields()}
* for content-related fields.
*
* @return FieldList
*/
@ -2139,10 +2122,9 @@ 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.
*/
// 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');
@ -2195,9 +2177,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
*
* @param boolean $includerelations a boolean value to indicate if the labels returned include relation fields
* @return array|string
* @param bool $includerelations A boolean value to indicate if the labels returned should include relation fields
* @return array
*/
public function fieldLabels($includerelations = true) {
$cacheKey = $this->class . '_' . $includerelations;
@ -2238,17 +2219,15 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return self::$_cache_field_labels[$cacheKey];
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Get the actions available in the CMS for this page - eg Save, Publish.
*
* Frontend scripts and styles know how to handle the following FormFields:
* * top-level FormActions appear as standalone buttons
* * top-level CompositeField with FormActions within appear as grouped buttons
* * TabSet & Tabs appear as a drop ups
* * FormActions within the Tab are restyled as links
* * major actions can provide alternate states for richer presentation (see ssui.button widget extension).
* - top-level FormActions appear as standalone buttons
* - top-level CompositeField with FormActions within appear as grouped buttons
* - TabSet & Tabs appear as a drop ups
* - FormActions within the Tab are restyled as links
* - major actions can provide alternate states for richer presentation (see ssui.button widget extension)
*
* @return FieldList The available actions for this page.
*/
@ -2296,7 +2275,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $actions;
}
if($this->isPublished() && $this->canPublish() && !$this->IsDeletedFromStage && $this->canDeleteFromLive()) {
if($this->isPublished() && $this->canPublish() && !$this->getIsDeletedFromStage() && $this->canDeleteFromLive()) {
// "unpublish"
$moreOptions->push(
FormAction::create('unpublish', _t('SiteTree.BUTTONUNPUBLISH', 'Unpublish'), 'delete')
@ -2305,7 +2284,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
);
}
if($this->stagesDiffer('Stage', 'Live') && !$this->IsDeletedFromStage) {
if($this->stagesDiffer('Stage', 'Live') && !$this->getIsDeletedFromStage()) {
if($this->isPublished() && $this->canEdit()) {
// "rollback"
$moreOptions->push(
@ -2316,7 +2295,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
if($this->canEdit()) {
if($this->IsDeletedFromStage) {
if($this->getIsDeletedFromStage()) {
// The usual major actions are not available, so we provide alternatives here.
if($existsOnLive) {
// "restore"
@ -2324,20 +2303,50 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($this->canDelete() && $this->canDeleteFromLive()) {
// "delete from live"
$majorActions->push(
FormAction::create('deletefromlive',_t('CMSMain.DELETEFP','Delete'))->addExtraClass('ss-ui-action-destructive')
FormAction::create('deletefromlive',_t('CMSMain.DELETEFP','Delete'))
->addExtraClass('ss-ui-action-destructive')
);
}
} 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')
: _t('CMSMain.RESTORE','Restore draft');
$description = $restoreToRoot
? _t('CMSMain.RESTORE_TO_ROOT_DESC','Restore the archived version to draft as a top level page')
: _t('CMSMain.RESTORE_DESC', 'Restore the archived version to draft');
$majorActions->push(
FormAction::create('restore',_t('CMSMain.RESTORE','Restore'))->setAttribute('data-icon', 'decline')
FormAction::create('restore', $title)
->setDescription($description)
->setAttribute('data-to-root', $restoreToRoot)
->setAttribute('data-icon', 'decline')
);
}
} else {
if($this->canDelete()) {
// "delete"
// Detect use of legacy actions
// {@see CMSMain::enabled_legacy_actions}
$legacy = CMSMain::config()->enabled_legacy_actions;
if(in_array('CMSBatchAction_Delete', $legacy)) {
Deprecation::notice('4.0', 'Delete from Stage is deprecated. Use Archive instead.');
if($this->canDelete()) {
// delete
$moreOptions->push(
FormAction::create('delete',_t('CMSMain.DELETE','Delete draft'))
->addExtraClass('delete ss-ui-action-destructive')
);
}
} elseif($this->canArchive()) {
// "archive"
$moreOptions->push(
FormAction::create('delete',_t('CMSMain.DELETE','Delete draft'))->addExtraClass('delete ss-ui-action-destructive')
FormAction::create('archive',_t('CMSMain.ARCHIVE','Archive'))
->setDescription(_t(
'SiteTree.BUTTONARCHIVEDESC',
'Unpublish and send to archive'
))
->addExtraClass('delete ss-ui-action-destructive')
);
}
@ -2351,7 +2360,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
}
if($this->canPublish() && !$this->IsDeletedFromStage) {
if($this->canPublish() && !$this->getIsDeletedFromStage()) {
// "publish", as with "save", it supports an alternate state to show when action is needed.
$majorActions->push(
$publish = FormAction::create('publish', _t('SiteTree.BUTTONPUBLISHED', 'Published'))
@ -2379,6 +2388,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
*
* @uses SiteTreeExtension->onBeforePublish()
* @uses SiteTreeExtension->onAfterPublish()
* @return bool True if published
*/
public function doPublish() {
if (!$this->canPublish()) return false;
@ -2405,7 +2415,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
if($linkedPages) foreach($linkedPages as $page) {
$page->copyFrom($page->CopyContentFrom());
$page->write();
if($page->ExistsOnLive) $page->doPublish();
if($page->getExistsOnLive()) $page->doPublish();
}
// Need to update pages linking to this one as no longer broken, on the live site
@ -2487,13 +2497,35 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
$this->invokeWithExtensions('onAfterRevertToLive', $this);
return true;
}
/**
* Determine if this page references a parent which is archived, and not available in stage
*
* @return bool True if there is an archived parent
*/
protected function isParentArchived() {
if($parentID = $this->ParentID) {
$parentPage = Versioned::get_latest_version("SiteTree", $parentID);
if(!$parentPage || $parentPage->IsDeletedFromStage) {
return true;
}
}
return false;
}
/**
* Restore the content in the active copy of this SiteTree page to the stage site.
* @return The SiteTree object.
*
* @return self
*/
public function doRestoreToStage() {
// Ensure that the parent page is restored, otherwise restore to root
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()) {
@ -2521,6 +2553,50 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $result;
}
/**
* Removes the page from both live and stage
*
* @return bool Success
*/
public function doArchive() {
if($this->doUnpublish()) {
$this->delete();
return true;
}
return false;
}
/**
* Check if the current user is allowed to archive this page.
* If extended, ensure that both canDelete and canDeleteFromLive are extended also
*
* @param Member $member
* @return bool
*/
public function canArchive($member = null) {
if(!$member) {
$member = Member::currentUser();
}
// Standard mechanism for accepting permission changes from extensions
$extended = $this->extendedCan('canArchive', $member);
if($extended !== null) {
return $extended;
}
// Check if this page can be deleted
if(!$this->canDelete($member)) {
return false;
}
// If published, check if we can delete from live
if($this->ExistsOnLive && !$this->canDeleteFromLive($member)) {
return false;
}
return true;
}
/**
* Synonym of {@link doUnpublish}
*/
@ -2529,17 +2605,14 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Check if this page is new - that is, if it has yet to have been written
* to the database.
* Check if this page is new - that is, if it has yet to have been written to the database.
*
* @return boolean True if this page is new.
* @return bool
*/
public function isNew() {
/**
* This check was a problem for a self-hosted site, and may indicate a
* bug in the interpreter on their server, or a bug here
* Changing the condition from empty($this->ID) to
* !$this->ID && !$this->record['ID'] fixed this.
* This check was a problem for a self-hosted site, and may indicate a bug in the interpreter on their server,
* or a bug here. Changing the condition from empty($this->ID) to !$this->ID && !$this->record['ID'] fixed this.
*/
if(empty($this->ID)) return true;
@ -2552,7 +2625,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
/**
* Check if this page has been published.
*
* @return boolean True if this page has been published.
* @return bool
*/
public function isPublished() {
if($this->isNew())
@ -2564,10 +2637,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Get the class dropdown used in the CMS to change the class of a page.
* This returns the list of options in the drop as a Map from class name
* to text in dropdown. Filters by {@link SiteTree->canCreate()},
* as well as {@link SiteTree::$needs_permission}.
* Get the class dropdown used in the CMS to change the class of a page. This returns the list of options in the
* dropdown as a Map from class name to singular name. Filters by {@link SiteTree->canCreate()}, as well as
* {@link SiteTree::$needs_permission}.
*
* @return array
*/
@ -2580,7 +2652,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
foreach($classes as $class) {
$instance = singleton($class);
// if the current page type is this the same as the class type always show the page type in the list see open ticket 5880 for why
// if the current page type is this the same as the class type always show the page type in the list
if ($this->ClassName != $instance->ClassName) {
if((($instance instanceof HiddenClass) || !$instance->canCreate())) continue;
}
@ -2594,10 +2666,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$currentClass = $class;
$result[$class] = $pageTypeName;
// if we're in translation mode, the link between the translated pagetype
// title and the actual classname might not be obvious, so we add it in parantheses
// Example: class "RedirectorPage" has the title "Weiterleitung" in German,
// so it shows up as "Weiterleitung (RedirectorPage)"
// If we're in translation mode, the link between the translated pagetype title and the actual classname
// might not be obvious, so we add it in parantheses. Example: class "RedirectorPage" has the title
// "Weiterleitung" in German, so it shows up as "Weiterleitung (RedirectorPage)"
if(i18n::get_lang_from_locale(i18n::get_locale()) != 'en') {
$result[$class] = $result[$class] . " ({$class})";
}
@ -2616,20 +2687,18 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $result;
}
/**
* Returns an array of the class names of classes that are allowed
* to be children of this class.
* Returns an array of the class names of classes that are allowed to be children of this class.
*
* @return array
* @return string[]
*/
public function allowedChildren() {
$allowedChildren = array();
$candidates = $this->stat('allowed_children');
if($candidates && $candidates != "none" && $candidates != "SiteTree_root") {
foreach($candidates as $candidate) {
// If a classname is prefixed by "*", such as "*Page", then only that
// class is allowed - no subclasses. Otherwise, the class and all its subclasses are allowed.
// If a classname is prefixed by "*", such as "*Page", then only that class is allowed - no subclasses.
// Otherwise, the class and all its subclasses are allowed.
if(substr($candidate,0,1) == '*') {
$allowedChildren[] = substr($candidate,1);
} else {
@ -2644,7 +2713,6 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $allowedChildren;
}
/**
* Returns the class name of the default class for children of this page.
*
@ -2660,10 +2728,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
}
/**
* Returns the class name of the default class for the parent of this
* page.
* Returns the class name of the default class for the parent of this page.
*
* @return string
*/
@ -2672,8 +2738,8 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Get the title for use in menus for this page. If the MenuTitle
* field is set it returns that, else it returns the Title field.
* Get the title for use in menus for this page. If the MenuTitle field is set it returns that, else it returns the
* Title field.
*
* @return string
*/
@ -2700,42 +2766,41 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* 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 the flag.
* The unique key can be reused as a CSS class.
* Use the 'updateStatusFlags' extension point to customize the flags.
* 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
* the flag. The unique key can be reused as a CSS class. Use the 'updateStatusFlags' extension point to customize
* the flags.
*
* Example (simple):
* "deletedonlive" => "Deleted"
* "deletedonlive" => "Deleted"
*
* Example (with optional title attribute):
* "deletedonlive" => array('text' => "Deleted", 'title' => 'This page has been deleted')
* "deletedonlive" => array('text' => "Deleted", 'title' => 'This page has been deleted')
*
* @param Boolean $cached
* @param bool $cached Whether to serve the fields from cache; false regenerate them
* @return array
*/
public function getStatusFlags($cached = true) {
if(!$this->_cache_statusFlags || !$cached) {
$flags = array();
if($this->IsDeletedFromStage) {
if($this->ExistsOnLive) {
if($this->getIsDeletedFromStage()) {
if($this->getExistsOnLive()) {
$flags['removedfromdraft'] = array(
'text' => _t('SiteTree.REMOVEDFROMDRAFTSHORT', 'Removed from draft'),
'title' => _t('SiteTree.REMOVEDFROMDRAFTHELP', 'Page is published, but has been deleted from draft'),
);
} else {
$flags['deletedonlive'] = array(
'text' => _t('SiteTree.DELETEDPAGESHORT', 'Deleted'),
'title' => _t('SiteTree.DELETEDPAGEHELP', 'Page is no longer published'),
$flags['archived'] = array(
'text' => _t('SiteTree.ARCHIVEDPAGESHORT', 'Archived'),
'title' => _t('SiteTree.ARCHIVEDPAGEHELP', 'Page is removed from draft and live'),
);
}
} else if($this->IsAddedToStage) {
} else if($this->getIsAddedToStage()) {
$flags['addedtodraft'] = array(
'text' => _t('SiteTree.ADDEDTODRAFTSHORT', 'Draft'),
'title' => _t('SiteTree.ADDEDTODRAFTHELP', "Page has not been published yet")
);
} else if($this->IsModifiedOnStage) {
} else if($this->getIsModifiedOnStage()) {
$flags['modified'] = array(
'text' => _t('SiteTree.MODIFIEDONDRAFTSHORT', 'Modified'),
'title' => _t('SiteTree.MODIFIEDONDRAFTHELP', 'Page has unpublished changes'),
@ -2751,11 +2816,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* getTreeTitle will return three <span> html DOM elements, an empty <span> with
* the class 'jstree-pageicon' in front, following by a <span> wrapping around its
* MenutTitle, then following by a <span> indicating its publication status.
* getTreeTitle will return three <span> html DOM elements, an empty <span> with the class 'jstree-pageicon' in
* front, following by a <span> wrapping around its MenutTitle, then following by a <span> indicating its
* publication status.
*
* @return string a html string ready to be directly used in a template
* @return string An HTML string ready to be directly used in a template
*/
public function getTreeTitle() {
// Build the list of candidate children
@ -2788,8 +2853,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Returns the page in the current page stack of the given level.
* Level(1) will return the main menu item that we're currently inside, etc.
* Returns the page in the current page stack of the given level. Level(1) will return the main menu item that
* we're currently inside, etc.
*
* @param int $level
* @return SiteTree
*/
public function Level($level) {
$parent = $this;
@ -2802,7 +2870,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Return the CSS classes to apply to this node in the CMS tree
* Return the CSS classes to apply to this node in the CMS tree.
*
* @param string $numChildrenMethod
* @return string
@ -2840,11 +2908,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Compares current draft with live version,
* and returns TRUE if no draft version of this page exists,
* but the page is still published (after triggering "Delete from draft site" in the CMS).
* Compares current draft with live version, and returns true if no draft version of this page exists but the page
* is still published (eg, after triggering "Delete from draft site" in the CMS).
*
* @return boolean
* @return bool
*/
public function getIsDeletedFromStage() {
if(!$this->ID) return true;
@ -2852,26 +2919,27 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
// Return true for both completely deleted pages and for pages just deleted from stage.
// 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
*
* @return bool
*/
public function getExistsOnLive() {
return (bool)Versioned::get_versionnumber_by_stage('SiteTree', 'Live', $this->ID);
}
/**
* Compares current draft with live version,
* and returns TRUE if these versions differ,
* meaning there have been unpublished changes to the draft site.
* Compares current draft with live version, and returns true if these versions differ, meaning there have been
* unpublished changes to the draft site.
*
* @return boolean
* @return bool
*/
public function getIsModifiedOnStage() {
// new unsaved pages could be never be published
// New unsaved pages could be never be published
if($this->isNew()) return false;
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
@ -2884,14 +2952,13 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Compares current draft with live version,
* and returns true if no live version exists,
* meaning the page was never published.
* Compares current draft with live version, and returns true if no live version exists, meaning the page was never
* published.
*
* @return boolean
* @return bool
*/
public function getIsAddedToStage() {
// new unsaved pages could be never be published
// New unsaved pages could be never be published
if($this->isNew()) return false;
$stageVersion = Versioned::get_versionnumber_by_stage('SiteTree', 'Stage', $this->ID);
@ -2901,18 +2968,16 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* 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.
* 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.
*/
static public function disableCMSFieldsExtensions() {
self::$runCMSFieldsExtensions = false;
}
/**
* Reenables extendCMSFields() being called on getCMSFields() after
* it has been disabled by disableCMSFieldsExtensions().
* Reenables extendCMSFields() being called on getCMSFields() after it has been disabled by
* disableCMSFieldsExtensions().
*/
static public function enableCMSFieldsExtensions() {
self::$runCMSFieldsExtensions = true;
@ -2954,9 +3019,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Return the translated Singular name
* Return the translated Singular name.
*
* @return String
* @return string
*/
public function i18n_singular_name() {
// Convert 'Page' to 'SiteTree' for correct localization lookups
@ -2965,8 +3030,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
}
/**
* Overloaded to also provide entities for 'Page' class which is usually
* located in custom code, hence textcollector picks it up for the wrong folder.
* Overloaded to also provide entities for 'Page' class which is usually located in custom code, hence textcollector
* picks it up for the wrong folder.
*
* @return array
*/
public function provideI18nEntities() {
$entities = parent::provideI18nEntities();
@ -2985,11 +3052,19 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
return $entities;
}
/**
* Returns 'root' if the current page has no parent, or 'subpage' otherwise
*
* @return string
*/
public function getParentType() {
return $this->ParentID == 0 ? 'root' : 'subpage';
}
static public function reset() {
/**
* Clear the permissions cache for SiteTree
*/
public static function reset() {
self::$cache_permissions = array();
}

View File

@ -1,18 +1,18 @@
<?php
/**
* Adds tracking of links in any HTMLText fields which reference SiteTree or File items. Attaching this to any
* DataObject will add four fields which contain all links to SiteTree and File items referenced in any HTMLText fields,
* and two booleans to indicate if there are any broken links.
* Adds tracking of links in any HTMLText fields which reference SiteTree or File items.
*
* SiteTreeLinkTracking provides augmentSyncLinkTracking as an entry point for the tracking updater.
* Attaching this to any DataObject will add four fields which contain all links to SiteTree and File items
* referenced in any HTMLText fields, and two booleans to indicate if there are any broken links. Call
* augmentSyncLinkTracking to update those fields with any changes to those fields.
*
* Additionally, a SiteTreeLinkTracking_Highlighter extension is provided which, when applied to HtmlEditorField,
* will reuse the link SiteTreeLinkTracking's parser to add "ss-broken" classes to all broken links found this way.
* The resulting class will be saved to the Content on the subsequent write operation. If links are found to be
* no longer broken, the class will be removed on the next write.
* @property SiteTree owner
*
* The underlying SiteTreeLinkTracking_Parser can recognise broken internal links, broken internal anchors, and some
* typical broken links such as empty href, or a link starting with a slash.
* @property bool HasBrokenFile
* @property bool HasBrokenLink
*
* @method ManyManyList LinkTracking List of site pages linked on this page.
* @method ManyManyList ImageTracking List of Images linked on this page.
*/
class SiteTreeLinkTracking extends DataExtension {
@ -37,6 +37,11 @@ class SiteTreeLinkTracking extends DataExtension {
"ImageTracking" => array("FieldName" => "Varchar")
);
/**
* Scrape the content of a field to detect anly links to local SiteTree pages or files
*
* @param string $fieldName The name of the field on {@link @owner} to scrape
*/
public function trackLinksInField($fieldName) {
$record = $this->owner;
@ -137,6 +142,9 @@ class SiteTreeLinkTracking extends DataExtension {
}
}
/**
* Find HTMLText fields on {@link owner} to scrape for links that need tracking
*/
public function augmentSyncLinkTracking() {
// Reset boolean broken flags
$this->owner->HasBrokenLink = false;

View File

@ -86,14 +86,17 @@ class BrokenLinksReport extends SS_Report {
$dateTitle = _t('BrokenLinksReport.ColumnDateLastPublished', 'Date last published');
}
$linkBase = singleton('CMSPageEditController')->Link('show') . '/';
$linkBase = singleton('CMSPageEditController')->Link('show');
$fields = array(
"Title" => array(
"title" => _t('BrokenLinksReport.PageName', 'Page name'),
'formatting' => sprintf(
'<a href=\"' . $linkBase . '$ID\" title=\"%s\">$value</a>',
_t('BrokenLinksReport.HoverTitleEditPage', 'Edit page')
)
'formatting' => function($value, $item) use ($linkBase) {
return sprintf('<a href=\"%s\" title=\"%s\">%s</a>',
Controller::join_links($linkBase, $item->ID),
_t('BrokenLinksReport.HoverTitleEditPage', 'Edit page'),
$value
);
}
),
"LastEdited" => array(
"title" => $dateTitle,

View File

@ -27,7 +27,7 @@ class ContentControllerSearchExtension extends Extension {
$actions = new FieldList(
new FormAction('results', _t('SearchForm.GO', 'Go'))
);
$form = new SearchForm($this->owner, 'SearchForm', $fields, $actions);
$form = SearchForm::create($this->owner, 'SearchForm', $fields, $actions);
$form->classesToSearch(FulltextSearchable::get_searchable_classes());
return $form;
}

View File

@ -276,6 +276,116 @@
}
});
/**
* Class: .cms-edit-form .Actions #Form_EditForm_action_archive
*
* Informing the user about the archive action while requiring confirmation
*/
$('.cms-edit-form .Actions #Form_EditForm_action_archive').entwine({
/**
* Function: onclick
*
* Parameters:
* (Event) e
*/
onclick: function(e) {
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
message = ss.i18n.sprintf(
ss.i18n._t('CMSMain.Archive'),
version
);
if(confirm(message)) {
return this._super(e);
} else {
return false;
}
}
});
/**
* Class: .cms-edit-form .Actions #Form_EditForm_action_restore
*
* Informing the user about the archive action while requiring confirmation
*/
$('.cms-edit-form .Actions #Form_EditForm_action_restore').entwine({
/**
* Function: onclick
*
* Parameters:
* (Event) e
*/
onclick: function(e) {
var form = this.parents('form:first'),
version = form.find(':input[name=Version]').val(),
message = '',
toRoot = this.data('toRoot');
message = ss.i18n.sprintf(
ss.i18n._t(toRoot ? 'CMSMain.RestoreToRoot' : 'CMSMain.Restore'),
version
);
if(confirm(message)) {
return this._super(e);
} else {
return false;
}
}
});
/**
* Class: .cms-edit-form .Actions #Form_EditForm_action_delete
*
* Informing the user about the delete from draft action while requiring confirmation
*/
$('.cms-edit-form .Actions #Form_EditForm_action_delete').entwine({
/**
* Function: onclick
*
* Parameters:
* (Event) e
*/
onclick: function(e) {
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
message = ss.i18n.sprintf(
ss.i18n._t('CMSMain.DeleteFromDraft'),
version
);
if(confirm(message)) {
return this._super(e);
} else {
return false;
}
}
});
/**
* Class: .cms-edit-form .Actions #Form_EditForm_action_unpublish
* Informing the user about the unpublish action while requiring confirmation
*/
$('.cms-edit-form .Actions #Form_EditForm_action_unpublish').entwine({
/**
* Function: onclick
*
* Parameters:
* (Event) e
*/
onclick: function(e) {
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
message = ss.i18n.sprintf(
ss.i18n._t('CMSMain.Unpublish'),
version
);
if(confirm(message)) {
return this._super(e);
} else {
return false;
}
}
});
/**
* Enable save buttons upon detecting changes to content.
* "changed" class is added by jQuery.changetracker.

View File

@ -36,8 +36,13 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
"Tree.ThisPageOnly": "This page only",
"Tree.ThisPageAndSubpages": "This page and subpages",
"Tree.ShowAsList": "Show children as list",
"CMSMain.ConfirmRestoreFromLive": "Do you really want to copy the published content to the draft site?",
"CMSMain.ConfirmRestoreFromLive": "Are you sure you want to revert draft to when the page was last published?",
"CMSMain.RollbackToVersion": "Do you really want to roll back to version #%s of this page?",
"CMSMain.Archive": "Are you sure you want to archive this page?\n\nThe page will be unpublished and sent to the archive.",
"CMSMain.Restore": "Are you sure you want to restore this page from archive?",
"CMSMain.RestoreToRoot": "Are you sure you want to restore this page from archive?\n\nBecause the parent page is not available this will be restored to the top level.",
"CMSMain.Unpublish": "Are you sure you want to remove your page from the published site?\n\nThis page will still be available in the sitetree as draft.",
"CMSMain.DeleteFromDraft": "Are you sure you want to remove your page from the draft site?\n\nThis page will remain on the published site.",
"URLSEGMENT.Edit": "Edit",
"URLSEGMENT.OK": "OK",
"URLSEGMENT.Cancel": "Cancel",

View File

@ -4,42 +4,42 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
if(typeof(console) != 'undefined') console.error('Class ss.i18n not defined');
} else {
ss.i18n.addDictionary('id', {
"CMSMAIN.WARNINGSAVEPAGESBEFOREADDING": "You have to save a page before adding children underneath it",
"CMSMAIN.CANTADDCHILDREN": "You can't add children to the selected node",
"CMSMAIN.ERRORADDINGPAGE": "Error adding page",
"CMSMAIN.FILTEREDTREE": "Filtered tree to only show changed pages",
"CMSMAIN.ERRORFILTERPAGES": "Could not filter tree to only show changed pages<br />%s",
"CMSMAIN.ERRORUNFILTER": "Unfiltered tree",
"CMSMAIN.PUBLISHINGPAGES": "Publishing pages...",
"CMSMAIN.SELECTONEPAGE": "Mohon pilih minimal 1 halaman.",
"CMSMAIN.ERRORPUBLISHING": "Error publishing pages",
"CMSMAIN.REALLYDELETEPAGES": "Do you really want to delete the %s marked pages?",
"CMSMAIN.DELETINGPAGES": "Sedang menghapus halaman...",
"CMSMAIN.ERRORDELETINGPAGES": "Error deleting pages",
"CMSMAIN.PUBLISHING": "Publishing...",
"CMSMAIN.RESTORING": "Sedang pemulihan",
"CMSMAIN.ERRORREVERTING": "Error reverting to live content",
"CMSMAIN.SAVING": "Sedang menyimpan...",
"CMSMAIN.SELECTMOREPAGES": "You have %s pages selected.\n\nDo you really want to perform this action?",
"CMSMAIN.ALERTCLASSNAME": "The page type will be updated after the page is saved",
"CMSMAIN.URLSEGMENTVALIDATION": "URLs can only be made up of letters, digits and hyphens.",
"AssetAdmin.BATCHACTIONSDELETECONFIRM": "Apakah kamu yakin akan menghapus %s map?",
"AssetTableField.REALLYDELETE": "Do you really want to delete the marked files?",
"AssetTableField.MOVING": "Memindahkan %s berkas(s)",
"CMSMAIN.AddSearchCriteria": "Tambah kriteria",
"WidgetAreaEditor.TOOMANY": "Sorry, you have reached the maximum number of widgets in this area",
"AssetAdmin.ConfirmDelete": "Do you really want to delete this folder and all contained files?",
"Folder.Name": "Nama map",
"Tree.AddSubPage": "Tambah halaman baru di sini",
"Tree.Duplicate": "Duplikasi",
"Tree.EditPage": "Ubah",
"Tree.ThisPageOnly": "Hanya halaman ini",
"Tree.ThisPageAndSubpages": "This page and subpages",
"Tree.ShowAsList": "Show children as list",
"CMSMain.ConfirmRestoreFromLive": "Do you really want to copy the published content to the draft site?",
"CMSMain.RollbackToVersion": "Do you really want to roll back to version #%s of this page?",
"URLSEGMENT.Edit": "Ubah",
"URLSEGMENT.OK": "Oke",
"CMSMAIN.WARNINGSAVEPAGESBEFOREADDING": "Anda harus menyimpan laman sebelum menambahkan laman turunan.",
"CMSMAIN.CANTADDCHILDREN": "Anda tidak dapat menambahkan turunan pada simpul terpilih",
"CMSMAIN.ERRORADDINGPAGE": "Ada kesalahan menambahkan laman",
"CMSMAIN.FILTEREDTREE": "Hanya menampilkan laman yang berubah",
"CMSMAIN.ERRORFILTERPAGES": "Tidak dapat menyaring laman<br />%s",
"CMSMAIN.ERRORUNFILTER": "Tak tersaring",
"CMSMAIN.PUBLISHINGPAGES": "Menerbitkan laman...",
"CMSMAIN.SELECTONEPAGE": "Mohon pilih minimal 1 laman.",
"CMSMAIN.ERRORPUBLISHING": "Ada kesalahan menerbitkan laman",
"CMSMAIN.REALLYDELETEPAGES": "Anda ingin menghapus laman %s yang ditandai?",
"CMSMAIN.DELETINGPAGES": "Menghapus laman...",
"CMSMAIN.ERRORDELETINGPAGES": "Ada kesalahan menghapus laman",
"CMSMAIN.PUBLISHING": "Menerbitkan...",
"CMSMAIN.RESTORING": "Memulihkan...",
"CMSMAIN.ERRORREVERTING": "Ada kesalahan mengembalikan konten",
"CMSMAIN.SAVING": "Menyimpan...",
"CMSMAIN.SELECTMOREPAGES": "Anda memilih %s laman.\n\nAnda ingin melanjutkan?",
"CMSMAIN.ALERTCLASSNAME": "Jenis laman akan diperbarui setelah laman disimpan",
"CMSMAIN.URLSEGMENTVALIDATION": "URL hanya boleh terdiri dari huruf, angka dan tanda sambung.",
"AssetAdmin.BATCHACTIONSDELETECONFIRM": "Anda ingin menghapus folder %s?",
"AssetTableField.REALLYDELETE": "Anda ingin menghapus berkas yang ditandai?",
"AssetTableField.MOVING": "Memindahkan %s berkas",
"CMSMAIN.AddSearchCriteria": "Tambah Kriteria",
"WidgetAreaEditor.TOOMANY": "Maaf, Anda mencapai jumlah maksimal widget di area ini",
"AssetAdmin.ConfirmDelete": "Anda ingin menghapus folder dan berkas di dalamnya?",
"Folder.Name": "Nama folder",
"Tree.AddSubPage": "Tambah laman baru di sini",
"Tree.Duplicate": "Gandakan",
"Tree.EditPage": "Edit",
"Tree.ThisPageOnly": "Hanya laman ini",
"Tree.ThisPageAndSubpages": "Laman dan sublaman ini",
"Tree.ShowAsList": "Tampilkan turunan sebagai daftar",
"CMSMain.ConfirmRestoreFromLive": "Apakah Anda ingin menyalin konten yang sudah terbit ke draf?",
"CMSMain.RollbackToVersion": "Apakah Anda ingin kembali ke versi #%s dari laman ini?",
"URLSEGMENT.Edit": "Edit",
"URLSEGMENT.OK": "OK",
"URLSEGMENT.Cancel": "Batal"
});
}

View File

@ -31,8 +31,13 @@
"Tree.ThisPageOnly": "This page only",
"Tree.ThisPageAndSubpages": "This page and subpages",
"Tree.ShowAsList": "Show children as list",
"CMSMain.ConfirmRestoreFromLive": "Do you really want to copy the published content to the draft site?",
"CMSMain.ConfirmRestoreFromLive": "Are you sure you want to revert draft to when the page was last published?",
"CMSMain.RollbackToVersion": "Do you really want to roll back to version #%s of this page?",
"CMSMain.Archive": "Are you sure you want to archive this page?\n\nThe page will be unpublished and sent to the archive.",
"CMSMain.Restore": "Are you sure you want to restore this page from archive?",
"CMSMain.RestoreToRoot": "Are you sure you want to restore this page from archive?\n\nBecause the parent page is not available this will be restored to the top level.",
"CMSMain.Unpublish": "Are you sure you want to remove your page from the published site?\n\nThis page will still be available in the sitetree as draft.",
"CMSMain.DeleteFromDraft": "Are you sure you want to remove your page from the draft site?\n\nThis page will remain on the published site.",
"URLSEGMENT.Edit": "Edit",
"URLSEGMENT.OK": "OK",
"URLSEGMENT.Cancel": "Cancel",

View File

@ -1,39 +1,39 @@
{
"CMSMAIN.WARNINGSAVEPAGESBEFOREADDING": "You have to save a page before adding children underneath it",
"CMSMAIN.CANTADDCHILDREN": "You can't add children to the selected node",
"CMSMAIN.ERRORADDINGPAGE": "Error adding page",
"CMSMAIN.FILTEREDTREE": "Filtered tree to only show changed pages",
"CMSMAIN.ERRORFILTERPAGES": "Could not filter tree to only show changed pages<br />%s",
"CMSMAIN.ERRORUNFILTER": "Unfiltered tree",
"CMSMAIN.PUBLISHINGPAGES": "Publishing pages...",
"CMSMAIN.SELECTONEPAGE": "Mohon pilih minimal 1 halaman.",
"CMSMAIN.ERRORPUBLISHING": "Error publishing pages",
"CMSMAIN.REALLYDELETEPAGES": "Do you really want to delete the %s marked pages?",
"CMSMAIN.DELETINGPAGES": "Sedang menghapus halaman...",
"CMSMAIN.ERRORDELETINGPAGES": "Error deleting pages",
"CMSMAIN.PUBLISHING": "Publishing...",
"CMSMAIN.RESTORING": "Sedang pemulihan",
"CMSMAIN.ERRORREVERTING": "Error reverting to live content",
"CMSMAIN.SAVING": "Sedang menyimpan...",
"CMSMAIN.SELECTMOREPAGES": "You have %s pages selected.\n\nDo you really want to perform this action?",
"CMSMAIN.ALERTCLASSNAME": "The page type will be updated after the page is saved",
"CMSMAIN.URLSEGMENTVALIDATION": "URLs can only be made up of letters, digits and hyphens.",
"AssetAdmin.BATCHACTIONSDELETECONFIRM": "Apakah kamu yakin akan menghapus %s map?",
"AssetTableField.REALLYDELETE": "Do you really want to delete the marked files?",
"AssetTableField.MOVING": "Memindahkan %s berkas(s)",
"CMSMAIN.AddSearchCriteria": "Tambah kriteria",
"WidgetAreaEditor.TOOMANY": "Sorry, you have reached the maximum number of widgets in this area",
"AssetAdmin.ConfirmDelete": "Do you really want to delete this folder and all contained files?",
"Folder.Name": "Nama map",
"Tree.AddSubPage": "Tambah halaman baru di sini",
"Tree.Duplicate": "Duplikasi",
"Tree.EditPage": "Ubah",
"Tree.ThisPageOnly": "Hanya halaman ini",
"Tree.ThisPageAndSubpages": "This page and subpages",
"Tree.ShowAsList": "Show children as list",
"CMSMain.ConfirmRestoreFromLive": "Do you really want to copy the published content to the draft site?",
"CMSMain.RollbackToVersion": "Do you really want to roll back to version #%s of this page?",
"URLSEGMENT.Edit": "Ubah",
"URLSEGMENT.OK": "Oke",
"CMSMAIN.WARNINGSAVEPAGESBEFOREADDING": "Anda harus menyimpan laman sebelum menambahkan laman turunan.",
"CMSMAIN.CANTADDCHILDREN": "Anda tidak dapat menambahkan turunan pada simpul terpilih",
"CMSMAIN.ERRORADDINGPAGE": "Ada kesalahan menambahkan laman",
"CMSMAIN.FILTEREDTREE": "Hanya menampilkan laman yang berubah",
"CMSMAIN.ERRORFILTERPAGES": "Tidak dapat menyaring laman<br />%s",
"CMSMAIN.ERRORUNFILTER": "Tak tersaring",
"CMSMAIN.PUBLISHINGPAGES": "Menerbitkan laman...",
"CMSMAIN.SELECTONEPAGE": "Mohon pilih minimal 1 laman.",
"CMSMAIN.ERRORPUBLISHING": "Ada kesalahan menerbitkan laman",
"CMSMAIN.REALLYDELETEPAGES": "Anda ingin menghapus laman %s yang ditandai?",
"CMSMAIN.DELETINGPAGES": "Menghapus laman...",
"CMSMAIN.ERRORDELETINGPAGES": "Ada kesalahan menghapus laman",
"CMSMAIN.PUBLISHING": "Menerbitkan...",
"CMSMAIN.RESTORING": "Memulihkan...",
"CMSMAIN.ERRORREVERTING": "Ada kesalahan mengembalikan konten",
"CMSMAIN.SAVING": "Menyimpan...",
"CMSMAIN.SELECTMOREPAGES": "Anda memilih %s laman.\n\nAnda ingin melanjutkan?",
"CMSMAIN.ALERTCLASSNAME": "Jenis laman akan diperbarui setelah laman disimpan",
"CMSMAIN.URLSEGMENTVALIDATION": "URL hanya boleh terdiri dari huruf, angka dan tanda sambung.",
"AssetAdmin.BATCHACTIONSDELETECONFIRM": "Anda ingin menghapus folder %s?",
"AssetTableField.REALLYDELETE": "Anda ingin menghapus berkas yang ditandai?",
"AssetTableField.MOVING": "Memindahkan %s berkas",
"CMSMAIN.AddSearchCriteria": "Tambah Kriteria",
"WidgetAreaEditor.TOOMANY": "Maaf, Anda mencapai jumlah maksimal widget di area ini",
"AssetAdmin.ConfirmDelete": "Anda ingin menghapus folder dan berkas di dalamnya?",
"Folder.Name": "Nama folder",
"Tree.AddSubPage": "Tambah laman baru di sini",
"Tree.Duplicate": "Gandakan",
"Tree.EditPage": "Edit",
"Tree.ThisPageOnly": "Hanya laman ini",
"Tree.ThisPageAndSubpages": "Laman dan sublaman ini",
"Tree.ShowAsList": "Tampilkan turunan sebagai daftar",
"CMSMain.ConfirmRestoreFromLive": "Apakah Anda ingin menyalin konten yang sudah terbit ke draf?",
"CMSMain.RollbackToVersion": "Apakah Anda ingin kembali ke versi #%s dari laman ini?",
"URLSEGMENT.Edit": "Edit",
"URLSEGMENT.OK": "OK",
"URLSEGMENT.Cancel": "Batal"
}

View File

@ -6,7 +6,7 @@
"CMSMAIN.ERRORFILTERPAGES": "Kunde inte filtrera trädet för att visa enbart ändrade sidor<br />%s",
"CMSMAIN.ERRORUNFILTER": "Ofiltrerat träd",
"CMSMAIN.PUBLISHINGPAGES": "Publicerar sidor...",
"CMSMAIN.SELECTONEPAGE": "Vänligen välj åtminståne 1 sida.",
"CMSMAIN.SELECTONEPAGE": "Vänligen välj åtminstone 1 sida.",
"CMSMAIN.ERRORPUBLISHING": "Ett fel uppstod när sidorna skulle publiceras",
"CMSMAIN.REALLYDELETEPAGES": "Vill du verkligen radera de %s markerade sidorna?",
"CMSMAIN.DELETINGPAGES": "Raderar sidor...",
@ -21,7 +21,7 @@
"AssetAdmin.BATCHACTIONSDELETECONFIRM": "Vill du verkligen radera %s mappar?",
"AssetTableField.REALLYDELETE": "Vill du verkligen radera de markerade filerna?",
"AssetTableField.MOVING": "Flyttar %s fil(er)",
"CMSMAIN.AddSearchCriteria": "Lägg till kriterie",
"CMSMAIN.AddSearchCriteria": "Lägg till kriterium",
"WidgetAreaEditor.TOOMANY": "Du har tyvärr nått max antal widgetar i detta område.",
"AssetAdmin.ConfirmDelete": "Vill du verkligen radera denna mapp och alla filer i den?",
"Folder.Name": "Mappnamn",

View File

@ -11,7 +11,7 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
"CMSMAIN.ERRORFILTERPAGES": "Kunde inte filtrera trädet för att visa enbart ändrade sidor<br />%s",
"CMSMAIN.ERRORUNFILTER": "Ofiltrerat träd",
"CMSMAIN.PUBLISHINGPAGES": "Publicerar sidor...",
"CMSMAIN.SELECTONEPAGE": "Vänligen välj åtminståne 1 sida.",
"CMSMAIN.SELECTONEPAGE": "Vänligen välj åtminstone 1 sida.",
"CMSMAIN.ERRORPUBLISHING": "Ett fel uppstod när sidorna skulle publiceras",
"CMSMAIN.REALLYDELETEPAGES": "Vill du verkligen radera de %s markerade sidorna?",
"CMSMAIN.DELETINGPAGES": "Raderar sidor...",
@ -26,7 +26,7 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') {
"AssetAdmin.BATCHACTIONSDELETECONFIRM": "Vill du verkligen radera %s mappar?",
"AssetTableField.REALLYDELETE": "Vill du verkligen radera de markerade filerna?",
"AssetTableField.MOVING": "Flyttar %s fil(er)",
"CMSMAIN.AddSearchCriteria": "Lägg till kriterie",
"CMSMAIN.AddSearchCriteria": "Lägg till kriterium",
"WidgetAreaEditor.TOOMANY": "Du har tyvärr nått max antal widgetar i detta område.",
"AssetAdmin.ConfirmDelete": "Vill du verkligen radera denna mapp och alla filer i den?",
"Folder.Name": "Mappnamn",

View File

@ -238,7 +238,7 @@ cs:
HASBEENSETUP: 'Přesměrovací stránka byla nastavena bez cíle.'
HEADER: 'Tato stránka přesměruje uživatele na jinou stránku'
OTHERURL: 'Jiná web adresa'
PLURALNAME: 'Přesměrovací stránky'
PLURALNAME: 'Přesměrovací stránka'
REDIRECTTO: 'Přesměrovat na'
REDIRECTTOEXTERNAL: 'Jiná web stránka'
REDIRECTTOPAGE: 'Stránka na vašem webu'

View File

@ -200,6 +200,8 @@ de:
415: '415 - nicht-unterstützer Medientyp'
416: '416 - Anfragebereich nicht erfüllbar'
417: '417 - Erwartung nicht erfüllt'
422: '422 - Verarbeitung abgelehnt'
429: '429 - Zu viele Anfragen'
500: '500 - Interner Serverfehler'
501: '501 - nicht implementiert'
502: '502 - Fehlerhafter Gateway'
@ -236,7 +238,7 @@ de:
HASBEENSETUP: 'Eine Weiterleitungsseite wurde erstellt ohne das eine Weiterleitung definiert wurde.'
HEADER: 'Diese Seite wird Nutzer auf eine andere Seite weiterleiten'
OTHERURL: 'Andere Webseiten URL'
PLURALNAME: 'Umleitungsseite'
PLURALNAME: 'Weiterleitungsseiten'
REDIRECTTO: 'Weiterleiten zu'
REDIRECTTOEXTERNAL: 'Andere Website'
REDIRECTTOPAGE: 'Eine Seite auf Ihrer Website'

View File

@ -70,6 +70,7 @@ el:
DELETEFP: Διαγραφή
EMAIL: Email
EditTree: 'Επεξεργασία Δένδρου'
ListFiltered: 'Φιλτραρισμένη λίστα.'
NEWPAGE: 'Νέο {pagetype}'
PAGENOTEXISTS: 'Αυτή η σελίδα δεν υπάρχει'
PAGES: Σελίδες
@ -83,6 +84,7 @@ el:
TabContent: Περιεχόμενο
TabHistory: Ιστορικό
TabSettings: Ρυθμίσεις
TreeFiltered: 'Φιλτραρισμένο δένδρο.'
TreeFilteredClear: 'Καθαρισμός φίλτρου'
MENUTITLE: 'Επεξεργασία Σελίδας'
CMSMain_left_ss:
@ -133,7 +135,17 @@ el:
PUBLISHED: Δημοσιευμένο
Password: Κωδικός
VIEWPAGEIN: 'Προβολή Σελίδας σε:'
ErrorPage:
404: '404 - Δεν βρέθηκε'
CODE: 'Κωδικός σφάλματος'
DEFAULTERRORPAGETITLE: 'Η σελίδα δεν βρέθηκε'
DEFAULTSERVERERRORPAGETITLE: 'Σφάλμα διακομιστή'
PLURALNAME: 'Σελίδες Σφάλματος'
SINGULARNAME: 'Σελίδα Σφάλματος'
Folder:
AddFolderButton: 'Προσθήκη φακέλου'
DELETEUNUSEDTHUMBNAILS: 'Διαγραφή αχρησιμοποίητων εικονιδίων'
UNUSEDFILESTITLE: 'Αχρησιμοποίητα αρχεία'
UNUSEDTHUMBNAILSTITLE: 'Αχρησιμοποίητα εικονίδια'
UploadFilesButton: Μεταφόρτωση
LeftAndMain:
@ -149,8 +161,12 @@ el:
RedirectorPage:
DESCRIPTION: 'Κάνει ανακατεύθυνση σε μια διαφορετική εσωτερική σελίδα'
HEADER: 'Αυτή η σελίδα θα ανακατευθύνει τους χρήστες σε μια άλλη σελίδα'
REDIRECTTO: 'Ανακατεύθυνση σε'
ReportAdmin:
ReportTitle: Τίτλος
MENUTITLE: Αναφορές
ReportAdminForm:
FILTERBY: 'Φίλτρο κατά'
SearchForm:
GO: Μετάβαση
SEARCH: Αναζήτηση
@ -207,12 +223,14 @@ el:
MENUTITLE: 'Επίπεδο πλοίγησης'
METADESC: 'Μετα-Περιγραφή'
MODIFIEDONDRAFTHELP: 'Η σελίδα έχει μη δημοσιευμένες αλλαγές'
MODIFIEDONDRAFTSHORT: Τροποποιημένο
MetadataToggle: Μετα-δεδομένα
MoreOptions: 'Περισσότερες επιλογές'
NOTPUBLISHED: 'Δεν έχει δημοσιευθεί'
PAGELOCATION: 'Θέση σελίδας'
PAGETITLE: 'Όνομα σελίδας'
PAGETYPE: 'Τύπος σελίδας'
PARENTID: 'Γονική Σελίδα'
PARENTTYPE: 'Θέση σελίδας'
PLURALNAME: Σελίδες
REORGANISE_DESCRIPTION: 'Αλλαγή δομής του ιστοτόπου '
@ -240,6 +258,7 @@ el:
DESCRIPTION: 'Εμφανίζει το περιεχόμενο μιας άλλης σελίδας'
EditLink: επεξεργασία
HEADER: 'Αυτή είναι μια εικονική σελίδα'
PLURALNAME: 'Εικονικές Σελίδες'
SINGULARNAME: 'Εικονική Σελίδα'
CMSFileAddController:
MENUTITLE: Αρχεία

View File

@ -67,8 +67,8 @@ en:
DELETE_PAGES: 'Delete from published site'
PUBLISHED_PAGES: 'Published %d pages, %d failures'
PUBLISH_PAGES: Publish
UNPUBLISHED_PAGES: 'Un-published %d pages'
UNPUBLISH_PAGES: Un-publish
UNPUBLISHED_PAGES: 'Unpublished %d pages'
UNPUBLISH_PAGES: Unpublish
CMSMain:
ACCESS: 'Access to ''{title}'' section'
ACCESS_HELP: 'Allow viewing of the section containing page tree and content. View and edit permissions can be handled through page specific dropdowns, as well as the separate "Content permissions".'
@ -100,8 +100,11 @@ en:
REMOVED: 'Deleted ''{title}''{description} from live site'
REMOVEDPAGE: 'Removed ''{title}'' from the published site'
REMOVEDPAGEFROMDRAFT: 'Removed ''%s'' from the draft site'
RESTORE: Restore
RESTORE: 'Restore draft'
RESTORE_TO_ROOT: 'Restore draft at top level'
RESTORE_TO_ROOT_DESC: 'Restore the archived version to draft as a top level page'
RESTORED: 'Restored ''{title}'' successfully'
RESTORE_DESC: 'Restore the archived version to draft'
ROLLBACK: 'Roll back to this version'
ROLLEDBACKPUBv2: 'Rolled back to published version.'
ROLLEDBACKVERSIONv2: 'Rolled back to version #%d.'
@ -152,11 +155,19 @@ en:
FILTERDATETO: To
FILTERLABELTEXT: Content
CMSSiteTreeFilter_ChangedPages:
Title: 'Changed pages'
Title: 'Modified pages'
CMSSiteTreeFilter_DeletedPages:
Title: 'All pages, including deleted'
Title: 'All pages, including archived'
CMSSIteTreeFilter_PublishedPages:
Title: 'Published pages'
CMSSiteTreeFilter_Search:
Title: 'All pages'
CMSSiteTreeFilter_StatusDeletedPages:
Title: 'Archived pages'
CMSSiteTreeFilter_StatusDraftPages:
Title: 'Draft pages'
CMSSiteTreeFilter_StatusRemovedFromDraftPages:
Title: 'Live but removed from draft'
ContentControl:
NOTEWONTBESHOWN: 'Note: this message will not be shown to your visitors'
ContentController:

View File

@ -215,7 +215,7 @@ eo:
DEFAULTSERVERERRORPAGETITLE: 'Servila eraro'
DESCRIPTION: 'Propra enhavo por diversaj kazoj de eraro (ekzemple, "Ne trovis paĝon")'
ERRORFILEPROBLEM: 'Eraro okazis malfermante dosieron "{filename}" por skribi. Bonvolu kontroli permesojn.'
PLURALNAME: 'Prieraraj paĝoj'
PLURALNAME: 'Paĝoj pri eraroj'
SINGULARNAME: 'Prierara paĝo'
Folder:
AddFolderButton: 'Aldoni dosierujon'
@ -238,7 +238,7 @@ eo:
HASBEENSETUP: 'Alidirekta paĝo estis agordita sen ie al kie alidirekti.'
HEADER: 'Ĉi tiu paĝo redirektos uzantojn al alia paĝo'
OTHERURL: 'URL de alia retejo'
PLURALNAME: 'Alidirektaj paĝoj'
PLURALNAME: 'Paĝoj pri alidirekto'
REDIRECTTO: 'Alidirekti al'
REDIRECTTOEXTERNAL: 'Alia retejo'
REDIRECTTOPAGE: 'Paĝo en via retejo'

View File

@ -1,14 +1,40 @@
fa_IR:
AssetAdmin:
ADDFILES: 'اضافه کردن فایل'
ActionAdd: 'اضافه کردن پوشه'
AppCategoryAudio: صوتی
AppCategoryDocument: اسناد
AppCategoryImage: تصویر
AppCategoryVideo: ویدئو
BackToFolder: 'بازگشت به پوشه'
CREATED: تاریخ
DetailsView: جزییات
FILES: فایل ها
FROMTHEINTERNET: 'از اینترنت'
FROMYOURCOMPUTER: 'از کامپیوتر شما'
Filetype: 'نوع فایل'
NEWFOLDER: پوشه جديد
SIZE: حجم
TreeView: 'مشاهده درخت'
Upload: آپلود
AssetAdmin_DeleteBatchAction:
TITLE: 'حذف پوشه ها'
AssetAdmin_left_ss:
GO: برو
BrokenLinksReport:
ColumnURL: آدرس
HoverTitleEditPage: 'ویرایش صفحه'
PageName: 'نام صفحه'
ReasonDropdown: 'مشکل در بررسی'
CMSAddPageController:
Title: 'اضافه کردن صفحه'
CMSBatchActions:
DELETE_DRAFT_PAGES: 'حذف از پیش نویس سایت'
PUBLISH_PAGES: انتشار
CMSMain:
AddNewButton: 'جدید'
Cancel: لغو
Create: ایجاد
DELETE: 'حذف کردن از پیشنویس سایت'
DELETEFP: حذف کردن از منتشر شده های سایت
EMAIL: پست الکترونیک
@ -17,6 +43,10 @@ fa_IR:
SAVE: ذخیره
CMSPageHistoryController:
SHOWVERSION: 'نمایش ویرایش'
CMSPageHistoryController_versions_ss:
AUTHOR: ناشر
CMSPagesController:
MENUTITLE: صفحات
ContentController:
DRAFTSITE: 'تارگاه چرکنویس'
ErrorPage:

View File

@ -1,32 +1,39 @@
id:
AssetAdmin:
ADDFILES: 'Tambah Berkas'
ActionAdd: 'Tambah map'
ActionAdd: 'Tambah Folder'
AppCategoryArchive: Arsip
AppCategoryAudio: Suara
AppCategoryAudio: Audio
AppCategoryDocument: Dokumen
AppCategoryFlash: Flash
AppCategoryImage: Gambar
AppCategoryVideo: Video
BackToFolder: 'Kembali ke map'
BackToFolder: 'Kembali ke Folder'
CREATED: Tanggal
CurrentFolderOnly: 'Batas pada map sekarang?'
CurrentFolderOnly: 'Batasi sesuai folder ini?'
DetailsView: Perincian
FILES: Berkas-berkas
FILES: Berkas
FILESYSTEMSYNC: 'Selaraskan berkas'
FILESYSTEMSYNCTITLE: 'Perbarui entri database CMS untuk berkas-berkas pada sistem berkas (filesystem). Berguna saat berkas-berkas baru diunggah di luar sistem CMS, misalnya melalui FTP.'
FROMTHEINTERNET: 'Dari internet'
FROMYOURCOMPUTER: 'Dari komputer kamu'
FROMYOURCOMPUTER: 'Dari komputer Anda'
Filetype: 'Jenis berkas'
ListView: 'Tampilan daftar'
NEWFOLDER: Map baru
ListView: 'Tampilan Daftar'
NEWFOLDER: FolderBaru
SIZE: Ukuran
TreeView: 'Tampilan menurun'
MENUTITLE: Berkas-berkas
THUMBSDELETED: '{count} thumbnail tak terpakai telah dihapus'
TreeView: 'Tampilan Struktur'
Upload: Unggah
MENUTITLE: Berkas
AssetAdmin_DeleteBatchAction:
TITLE: 'Hapus map'
TITLE: 'Hapus Folder'
AssetAdmin_Tools:
FILTER: Saring
AssetAdmin_left_ss:
GO: Lanjut
AssetTableField:
BACKLINKCOUNT: 'Dipakai pada:'
PAGES: laman
BackLink_Button_ss:
Back: Kembali
BrokenLinksReport:
@ -34,83 +41,147 @@ id:
BROKENLINKS: 'Laporan tautan rusak'
CheckSite: 'Cek situs'
CheckSiteDropdownDraft: 'Draf situs'
CheckSiteDropdownPublished: 'Publikasi situs'
CheckSiteDropdownPublished: 'Situs Terbit'
ColumnDateLastModified: 'Tanggal terakhir modifikasi'
ColumnDateLastPublished: 'Tanggal terakhir terbit'
ColumnDateLastPublished: 'Tanggal terbit terakhir'
ColumnProblemType: 'Jenis masalah'
ColumnURL: URL
HoverTitleEditPage: 'Edit halaman '
PageName: 'Nama halaman'
HasBrokenFile: 'terdapat berkas yang rusak'
HasBrokenLink: 'terdapat tautan yang rusak'
HasBrokenLinkAndFile: 'terdapat berkas dan tautan yang rusak'
HoverTitleEditPage: 'Edit laman '
PageName: 'Nama laman'
ReasonDropdown: 'Masalah yang diperiksa'
ReasonDropdownBROKENFILE: 'Berkas rusak'
ReasonDropdownBROKENLINK: 'Tautan rusak'
ReasonDropdownRPBROKENLINK: 'Laman pengarah mengarah ke laman yang tidak ada'
ReasonDropdownVPBROKENLINK: 'Laman virtual mengarah ke laman yang tidak ada'
RedirectorNonExistent: 'laman pengarah mengarah ke laman yang tidak ada'
VirtualPageNonExistent: 'laman virtual mengarah ke laman yang tidak ada'
CMSAddPageController:
Title: 'Tambah halaman'
Title: 'Tambah laman'
CMSBatchActions:
DELETED_DRAFT_PAGES: '%d laman berhasil dihapus dari draft, %d laman gagal dihapus'
DELETED_PAGES: '%d laman berhasil dihapus dari situs terbit, %d gagal'
DELETE_DRAFT_PAGES: 'Hapus dari draf situs'
DELETE_PAGES: 'Hapus dari publikasi situs'
PUBLISHED_PAGES: 'Menerbitkan %d halaman, %d gagal'
DELETE_PAGES: 'Hapus dari situs terbit'
PUBLISHED_PAGES: 'Menerbitkan %d laman, %d gagal'
PUBLISH_PAGES: Terbitkan
UNPUBLISH_PAGES: Tidak terbit
UNPUBLISHED_PAGES: '%d laman dibatalterbitkan'
UNPUBLISH_PAGES: Batalterbitkan
CMSMain:
AddNew: 'Tambah halaman baru'
ACCESS: 'Akses ke bagian ''{title}'''
ACCESS_HELP: 'Perbolehkan menampilkan bagian dengan struktur laman dan konten. Perijinan menampilkan dan mengedit dapat diatur melalui pilihan terkait laman, sebagaimana "Perijinan Konten".'
AddNew: 'Tambah laman baru'
AddNewButton: 'Tambah baru'
AddPageRestriction: 'Catatan: Sebagian jenis laman tidak dapat dipilih'
Cancel: Batal
ChoosePageType: 'Pilih jenis halaman'
ChoosePageParentMode: 'Pilih lokasi untuk laman ini'
ChoosePageType: 'Pilih jenis laman'
Create: Buat
DELETE: 'Hapus dari situs draft'
DELETEFP: Hapus dari situs yang telah diterbitkan
DESCREMOVED: 'dan {count} turunannya'
DUPLICATED: '''{title}'' berhasil diduplikasi'
DUPLICATEDWITHCHILDREN: '''{title}'' dan turunannya berhasil diduplikasi'
EMAIL: Surel
NEWPAGE: 'Baru {pagetype}'
PAGENOTEXISTS: 'Halaman tidak ada'
PAGES: Halaman
EditTree: 'Edit Struktur'
ListFiltered: 'Daftar tersaring'
NEWPAGE: '{pagetype} baru'
PAGENOTEXISTS: 'Laman ini tidak ada'
PAGES: Laman
PAGETYPEANYOPT: Lain
PAGETYPEOPT: 'Jenis Halaman'
PUBPAGES: 'Selesai: Diterbitkan {count} halaman'
PageAdded: 'Berhasil buat halaman'
PAGETYPEOPT: 'Jenis Laman'
PUBALLCONFIRM: 'Mohon terbitkan semua laman pada situs'
PUBALLFUN: 'Fungsi "Terbitkan Semua"'
PUBALLFUN2: "Menekan tombol ini sama dengan membuka semua laman dan menerbitkannya. Hal ini \n\t\t\t\tditujukan untuk dilakukan setelah ada banyak pengeditan konten, misalnya saat situs pertama kali \n\t\t\t\tdiinstal."
PUBPAGES: 'Selesai: {count} laman terbit'
PageAdded: 'Laman berhasil dibuat'
REMOVED: 'Dihapus ''{title}''{description} dari situs langsung'
REMOVEDPAGE: 'Menghapus ''{title}'' dari terbitan situs '
REMOVEDPAGE: 'Menghapus ''{title}'' dari situs terbit'
REMOVEDPAGEFROMDRAFT: 'Menghapus ''%s'' dari draf situs'
RESTORE: Pulihkan
RESTORED: 'Pemulihan ''{title}'' sukses'
ROLLBACK: 'Kembali ke versi ini'
ROLLEDBACKPUBv2: 'Kembali ke versi terbit'
ROLLEDBACKVERSIONv2: 'Kembali ke versi #%d.'
SAVE: Simpan
SAVEDRAFT: 'Simpan draf'
TabContent: Konten
TabHistory: Sejarah
TabSettings: Pengaturan
TreeFiltered: 'Struktur tersaring.'
TreeFilteredClear: 'Bersihkan saring'
MENUTITLE: 'Edit Laman'
CMSMain_left_ss:
APPLY_FILTER: 'Terapkan Saring'
RESET: Reset
CMSPageAddController:
ParentMode_child: 'Di bawah laman lain'
ParentMode_top: 'Laman atas'
MENUTITLE: 'Tambah laman'
CMSPageHistoryController:
COMPAREMODE: 'Modus pembanding (pilih dua)'
COMPAREVERSIONS: 'Bandingkan Versi'
COMPARINGVERSION: 'Bandingkan versi {version1} dan {version2}.'
REVERTTOTHISVERSION: 'Kembali ke versi ini'
SHOWUNPUBLISHED: 'Tampilkan versi batalterbit'
SHOWVERSION: 'Tampilkan Versi'
VIEW: tampilkan
VIEWINGLATEST: 'Versi terakhir sedang ditampilkan.'
VIEWINGVERSION: 'Versi {version} sedang ditampilkan.'
MENUTITLE: Sejarah
CMSPageHistoryController_versions_ss:
AUTHOR: Penulis
NOTPUBLISHED: 'Batal terbit'
PUBLISHER: Penerbit
UNKNOWN: Tidak diketahui
WHEN: Ketika
CMSPagesController:
GalleryView: 'Tampilan Galeri'
ListView: 'Tampilan daftar'
MENUTITLE: Halaman
MENUTITLE: Laman
TreeView: 'Tampilan Struktur'
CMSPagesController_ContentToolbar_ss:
MULTISELECT: Multi-pilihan
CMSPagesController_Tools_ss:
FILTER: Saring
CMSSearch:
FILTERDATEFROM: Dari
FILTERDATEHEADING: Tanggal
FILTERDATETO: Ke
FILTERLABELTEXT: Isi
FILTERLABELTEXT: Konten
CMSSiteTreeFilter_ChangedPages:
Title: 'Perubahan halaman'
Title: 'Laman yang berubah'
CMSSiteTreeFilter_DeletedPages:
Title: 'Semua laman, termasuk yang terhapus'
CMSSiteTreeFilter_Search:
Title: 'Semua halaman'
Title: 'Semua laman'
ContentControl:
NOTEWONTBESHOWN: 'Catatan: pesan ini tidak akan ditampilkan kepada pengunjung'
ContentController:
ARCHIVEDSITE: 'Versi pratinjau'
ARCHIVEDSITEFROM: 'Arsip dari'
CMS: CMS
DRAFT: Draf
DRAFTSITE: 'Draf situs'
DRAFT_SITE_ACCESS_RESTRICTION: 'Anda harus login untuk menampilkan konten draft atau arsip. <a href="%s">Klik di sini untuk kembali ke situs terbit.</a>'
Email: Surel
INSTALL_SUCCESS: 'Pemasangan sukses'
InstallFilesDeleted: 'Berkas pemasangan telah berhasil dihapus'
InstallSuccessCongratulations: 'SilverStripe telah sukses dipasang!'
INSTALL_SUCCESS: 'Penginstalan berhasil!'
InstallFilesDeleted: 'Berkas penginstalan telah berhasil dihapus.'
InstallSecurityWarning: 'Untuk alasan keamanan, sekarang Anda perlu menghapus berkas-berkas penginstalan, kecuali Anda berencana untuk melakukan penginstalan ulang lagi (<em>memerlukan login admin, lihat di atas</em>). Selanjutnya server juga memerlukan akses tulis ke folder "assets", Anda dapat mencabut akses tulis dari folder lainnya. <a href="{link}" style="text-align: center;">Klik di sini untuk menghapus berkas-berkas penginstalan.</a>'
InstallSuccessCongratulations: 'SilverStripe telah berhasil diinstal!'
LOGGEDINAS: 'Masuk sebagai'
LOGIN: Masuk
LOGOUT: 'Keluar'
NOTLOGGEDIN: 'Tidak masuk'
PUBLISHED: Terbit
PUBLISHEDSITE: 'Situs Terbit'
Password: Kata kunci
PostInstallTutorialIntro: 'Situs ini adalah versi sederhana dari situs SilverStripe 3. Untuk meningkatkannya, mohon kunjungi {link}.'
StartEditing: 'Anda dapat mulai mengedit konten dengan membuka <a href="{link}">CMS</a>.'
UnableDeleteInstall: 'Gagal menghapus berkas-berkas penginstalan. Mohon lakukan penghapusan berkas-berkas berikut ini secara manual.'
VIEWPAGEIN: 'Tampikan Laman pada:'
ErrorPage:
400: '400 - Permintaan buruk'
401: '401 - Tidak ada otorisasi'
@ -129,103 +200,215 @@ id:
415: '425 - Tipe Media Tidak Disupport'
416: '416 - Lingkup Permintaan Tidak Dapat Dipuaskan'
417: '417 - Expectation Gagal'
422: '422 - Entitas Tidak Terproses'
429: '429 - Terlalu Banyak Permintaan'
500: '500 - Server Internal Error'
501: '501 - Tidak Diimplementasi'
502: '502 - Gateway Buruk'
503: '503 - Servis Tidak Tersedia'
505: '505 - Versi HTTP Tidak Disupport'
504: '504 - Masa Tunggu Terlewat'
505: '505 - Versi HTTP Tidak Didukung'
CODE: 'Kode yang salah'
DEFAULTERRORPAGECONTENT: '<p>Maaf, sepertinya anda berusha mengakses halaman yang tidak ada.</p><p>Mohon periksa ejaan URL yang ingin anda akses dan coba lagi.</p>'
DEFAULTERRORPAGETITLE: 'Halaman tidak ditemukan'
DEFAULTERRORPAGECONTENT: '<p>Maaf, sepertinya anda berusaha mengakses laman yang tidak ada.</p><p>Mohon periksa ejaan URL yang ingin anda akses dan coba lagi.</p>'
DEFAULTERRORPAGETITLE: 'Laman tidak ditemukan'
DEFAULTSERVERERRORPAGECONTENT: '<p>Maaf, ada masalah dalam penanganan permintaan Anda.</p>'
DEFAULTSERVERERRORPAGETITLE: 'Server mengalami kesalahan'
DESCRIPTION: 'Laman untuk berbagai kasus kesalahan (misalnya "Laman tidak ditemukan")'
ERRORFILEPROBLEM: 'Gagal membuka berkas "{filename}" untuk penulisan data. Mohon periksa pengaturan akses tulis.'
PLURALNAME: 'Laman Kesalahan'
SINGULARNAME: 'Laman Kesalahan'
Folder:
AddFolderButton: 'Tambah map'
DELETEUNUSEDTHUMBNAILS: 'Hapus thumbnail-thumbnail yang tidal dipakai'
UNUSEDFILESTITLE: 'File-file yang tidak dipakai'
UNUSEDFILESTITLE: 'Berkas tidak terpakai'
UNUSEDTHUMBNAILSTITLE: 'Thumbnail-thumbnail yang tidak dipakai'
UploadFilesButton: Unggah
LeftAndMain:
DELETED: Hapus
PreviewButton: Pratinjau
SAVEDUP: Disimpan
SearchResults: 'Hasil pencarian'
Permission:
CMS_ACCESS_CATEGORY: 'Akses CMS'
Permissions:
CONTENT_CATEGORY: 'Perijinan konten'
PERMISSIONS_CATEGORY: 'Peran dan akses perijinan'
RedirectorPage:
HASBEENSETUP: 'halaman yang mengirim user ke alamat lain dibuat tanpa tujuan dari pengiriman itu sendiri'
HEADER: 'Halaman ini akan mengarahkan user ke halaman lain'
DESCRIPTION: 'Mengarahkan ke laman internal berbeda'
HASBEENSETUP: 'Sebuah laman pengarah telah dibuat tanpa arah yang dituju.'
HEADER: 'Laman ini akan mengarahkan pengguna ke laman lain'
OTHERURL: 'URL situs web lain'
PLURALNAME: 'Laman Pengarah'
REDIRECTTO: 'Arahkan lagi ke'
REDIRECTTOEXTERNAL: 'Situs web yang lain'
REDIRECTTOPAGE: 'Sebuah halaman pada situs web Anda'
YOURPAGE: 'Halaman pada situs web Anda'
REDIRECTTOPAGE: 'Laman pada situs Anda'
SINGULARNAME: 'Laman Pengarah'
YOURPAGE: 'Laman pada situs Anda'
ReportAdmin:
ReportTitle: Judul
MENUTITLE: Laporan
ReportAdminForm:
FILTERBY: 'Saring dengan'
SITETREE:
VIRTUALPAGEDRAFTWARNING: 'Mohon terbitkan laman tertaut untuk menayangkan laman virtual'
VIRTUALPAGEWARNING: 'Mohon pilih laman tertaut dan simpan lebih dulu untuk menayangkan laman ini'
VIRTUALPAGEWARNINGSETTINGS: 'Mohon pilih laman tertaut pada konten utama untuk menayangkan'
SearchForm:
GO: Pergi
SEARCH: Cari
SearchResults: 'Hasil Pencarian'
SideReport:
ContentGroupTitle: 'Isi laporan'
BROKENFILES: 'Laman dengan berkas rusak'
BROKENLINKS: 'Laman dengan tautan rusak'
BROKENREDIRECTORPAGES: 'LamanPengarah mengarah pada laman terhapus'
BROKENVIRTUALPAGES: 'LamanVirtual mengarah pada laman terhapus'
BrokenLinksGroupTitle: 'Laporan tautan-tautan rusak'
ContentGroupTitle: 'Laporan konten'
EMPTYPAGES: 'Laman tanpa konten'
LAST2WEEKS: 'Laman diedit dalam 2 minggu terakhir'
OtherGroupTitle: Lainnya
ParameterLiveCheckbox: 'Periksa situs live'
REPEMPTY: 'Laporan {title} kosong.'
SilverStripeNavigator:
ARCHIVED: Terarsip
SilverStripeNavigatorLink:
ShareInstructions: 'Untuk membagi laman ini, salin dan tempel pada tautan berikut.'
ShareLink: 'Bagi tautan'
SilverStripeNavigatorLinkl:
CloseLink: Tutup
SiteConfig:
DEFAULTTHEME: '(Gunakan tema standar)'
EDITHEADER: 'Siapa yang boleh mengedit laman pada situs ini?'
EDIT_PERMISSION: 'Mengelola pengaturan situs'
EDIT_PERMISSION_HELP: 'Bolehkan mengedit pengaturan akses umum atau perijinan tingkat atas.'
PLURALNAME: 'Pengaturan Situs'
SINGULARNAME: 'Pengaturan Situs'
SITENAMEDEFAULT: 'Nama Situs'
SITETAGLINE: 'Slogan Situs'
SITETITLE: 'Judul Situs'
TABACCESS: Akses
TABMAIN: Tab Utama
TAGLINEDEFAULT: 'slogan situsmu disini'
THEME: Tema
TOPLEVELCREATE: 'Siapa yang dapat membuat laman utama yang baru?'
VIEWHEADER: 'Siapa yang dapat menampilkan laman pada situs ini?'
SiteTree:
ACCESSANYONE: Siapa saja
ACCESSHEADER: 'Siapa yang dapat melihat halaman ini pada situs saya?'
ACCESSHEADER: 'Siapa yang dapat melihat laman ini?'
ACCESSLOGGEDIN: 'User yang masuk'
ACCESSONLYTHESE: 'Hanya orang ini saja (pilih dari daftar)'
ALLOWCOMMENTS: 'Bolehkan komentar pada halaman ini?'
ADDEDTODRAFTHELP: 'Laman belum terbit'
ADDEDTODRAFTSHORT: Darft
ALLOWCOMMENTS: 'Bolehkan komentar pada laman ini?'
APPEARSVIRTUALPAGES: 'Konten ini akan tampil juga pada laman virtual di bagian {title}.'
BUTTONCANCELDRAFT: 'Batalkan perubahan draft'
BUTTONCANCELDRAFTDESC: 'Hapus draft dan kembalikan ke halaman yang sedang dipublikasikan'
BUTTONUNPUBLISH: Tidak Dipublikasi
BUTTONUNPUBLISHDESC: 'Pindahkan halaman ini dari situs yang dipublikasikan'
BUTTONCANCELDRAFTDESC: 'Hapus draft dan kembalikan ke laman terbit'
BUTTONPUBLISHED: Terbit
BUTTONSAVED: Tersimpan
BUTTONSAVEPUBLISH: 'Simpan dan terbitkan'
BUTTONUNPUBLISH: Batalterbitkan
BUTTONUNPUBLISHDESC: 'Hapus laman ini dari situs terbit'
Comments: Komen-komen
Content: Isi
DEFAULTABOUTCONTENT: '<p>Anda dapat mengisi halaman ini dengan isi anda sendiri, atau hapus dan buat halaman-halaman anda sendiri.<br /></p>'
Content: Konten
DEFAULTABOUTCONTENT: '<p>Anda dapat mengisi laman ini dengan konten Anda sendiri, atau menghapusnya dan membuat laman Anda sendiri.<br /></p>'
DEFAULTABOUTTITLE: 'Tentang Kami'
DEFAULTCONTACTCONTENT: '<p>Anda dapat mengisi halaman ini dengan isi anda sendiri, atau hapus dan buat halaman-halaman anda sendiri.<br /></p>'
DEFAULTCONTACTCONTENT: '<p>Anda dapat mengisi laman ini dengan konten Anda sendiri, atau menghapusnya dan membuat laman Anda sendiri.<br /></p>'
DEFAULTCONTACTTITLE: 'Hubungi Kami'
DEFAULTHOMECONTENT: '<p>Selamat datang di SilverStripe! Ini adalah homepage default anda. Anda dapat mengedit halaman ini dengan membuka <a href="admin/">CMS ini</a>. Sekarang anda dapat mengakses <a href="http://doc.silverstripe.com">dokumentasi developer</a>, atau memulai <a href="http://doc.silverstripe.com/doku.php?id=tutorials">tutorial-tutorial yang tersedia.</a></p>'
DEFAULTHOMECONTENT: '<p>Selamat datang di SilverStripe! Ini adalah halaman awal situs Anda. Anda dapat mengedit laman ini dengan membuka <a href="admin/">CMS ini</a>. Selanjutnya Anda dapat mengakses <a href="http://doc.silverstripe.com">dokumentasi pengembang</a>, atau mulai dengan <a href="http://doc.silverstripe.com/doku.php?id=tutorials">tutorial-tutorial yang tersedia.</a></p>'
DEFAULTHOMETITLE: Beranda
DELETEDPAGEHELP: 'Laman tidak lagi terbit'
DELETEDPAGESHORT: Hapus
DEPENDENT_NOTE: 'Laman-laman berikut ini bergantung pada laman ini. Termasuk laman virtual, laman pengarah, dan laman-laman dengan tautan konten.'
DESCRIPTION: 'Laman konten umum'
DependtPageColumnLinkType: 'Jenis tautan'
DependtPageColumnURL: URL
EDITANYONE: 'Siapa saja yang dapat masuk ke dalam CMS'
EDITHEADER: 'Siapa yang dapat mengedit ini dari dalam CMS?'
EDITHEADER: 'Siapa yang dapat mengedit laman ini?'
EDITONLYTHESE: 'Hanya orang ini saja (pilih dari daftar)'
EDITORGROUPS: 'Editor Grup'
HASBROKENLINKS: 'Halaman ini mempunyai link yang rusak'
EDITORGROUPS: 'Kelompok Editor'
EDIT_ALL_DESCRIPTION: 'Edit semua laman'
EDIT_ALL_HELP: 'Bolehkan mengedit semua laman pada situs, terlepas dari pengaturan Akses. Memerlukan perijinan "Akses ke bagian ''Laman''".'
Editors: 'Kelompok Editor'
GroupPlaceholder: 'Klik untuk memilih kelompok'
HASBROKENLINKS: 'Laman ini mempunyai tautan yang rusak.'
HTMLEDITORTITLE: Konten
INHERIT: 'Warisi dari laman induk'
LASTPUBLISHED: 'Terakhir terbit'
LASTSAVED: 'Terakhir tersimpan'
LASTUPDATED: 'Terakhir diperbarui'
LINKCHANGENOTE: 'Mengganti tautan laman ini akan mempengaruhi semua tautan pada laman terkait.'
MENUTITLE: 'Label navigasi'
METADESC: 'Deskripsi'
METADESCHELP: 'Mesin pencari menggunakan konten ini untuk menampilkan hasil pencarian (meskipun tidak mempengaruhi pemeringkatan situs).'
METAEXTRA: 'Penanda Meta'
METAEXTRAHELP: 'Penanda HTML untuk informasi meta tambahan. Contohnya &lt;meta name="namaMeta" content="konten Anda di sini" /&gt;'
MODIFIEDONDRAFTHELP: 'Laman memiliki perubahan yang tidak terbit'
MODIFIEDONDRAFTSHORT: Diubah
MetadataToggle: Metadata
MoreOptions: 'Pilihan lain'
PAGELOCATION: 'Lokasi halaman'
PAGETITLE: 'Nama Halaman'
PAGETYPE: 'Tipe halaman'
PARENTTYPE: 'Lokasi halaman'
NOTPUBLISHED: 'Tidak diterbitkan'
OBSOLETECLASS: 'Jenis laman {type} ini sudah usang. Menyimpannya akan memperbarui jenisnya dan Anda kemungkinan akan kehilangan data'
PAGELOCATION: 'Lokasi laman'
PAGETITLE: 'Nama laman'
PAGETYPE: 'Tipe laman'
PARENTID: 'Laman induk'
PARENTTYPE: 'Lokasi laman'
PARENTTYPE_ROOT: 'Laman atas'
PARENTTYPE_SUBPAGE: 'Sub-laman di bawah laman induk'
PERMISSION_GRANTACCESS_DESCRIPTION: 'Kelola hak akses untuk konten ini'
PERMISSION_GRANTACCESS_HELP: 'Perbolehkan pengaturan pencegahan akses ke laman tertentu di bagian "Laman".'
PLURALNAME: Laman
PageTypNotAllowedOnRoot: 'Jenis laman {type} tidak diperbolehkan di tingkat atas'
PageTypeNotAllowed: 'Jenis laman {type} tidak diperbolehkan menjadi turunan dari laman induk ini'
REMOVEDFROMDRAFTHELP: 'Laman sudah terbit, tapi telah dihapus dari draft'
REMOVEDFROMDRAFTSHORT: 'Dihapus dari draft'
REMOVE_INSTALL_WARNING: 'Peringatan: Anda perlu menghapus instal.php dari penginstalan SilverStripe ini untuk alasan keamanan.'
REORGANISE_DESCRIPTION: 'Ubah stuktur situs'
REORGANISE_HELP: 'Atur ulang laman pada struktur situs dengan drag&drop.'
SHOWINMENUS: 'Perlihatkan dalam menu?'
SHOWINSEARCH: 'Perlihatkan dalam pencarian'
SINGULARNAME: Laman
TABBEHAVIOUR: Perilaku
TABCONTENT: 'Kontain'
TOPLEVEL: 'Konten Situs (Level Atas)'
TABCONTENT: 'Konten Utama'
TABDEPENDENT: 'Laman terkait'
TOPLEVEL: 'Konten Situs (Tingkat Atas)'
TOPLEVELCREATORGROUPS: 'Pembuat tingkat atas'
URLSegment: 'Segmen URL'
has_one_Parent: 'Halaman Induk'
VIEWERGROUPS: 'Kelompok Penampil'
VIEW_ALL_DESCRIPTION: 'Tampilkan semua laman'
VIEW_ALL_HELP: 'Bolehkan menampilkan semua laman pada situs, terlepas dari pengaturan Akses. Memerlukan perijinan "Akses ke bagian ''Laman''".'
VIEW_DRAFT_CONTENT: 'Tampilkan konten draft'
VIEW_DRAFT_CONTENT_HELP: 'Untuk menampilkan laman di luar CMS pada modus draft. Berguna untuk kolaborasi eksternal tanpa akses CMS.'
Viewers: 'Kelompok Penampil'
Visibility: Visibilitas
has_one_Parent: 'Laman Induk'
many_many_BackLinkTracking: 'Jajaki Tautan Balik'
many_many_ImageTracking: 'Jajaki Gambar'
many_many_LinkTracking: 'Jajaki Tautan'
SiteTreeURLSegmentField:
EMPTY: 'Mohon isikan URL atau klik Batal'
HelpChars: 'Karakter khusus akan dikonversi secara otomatis atau dihapus.'
URLSegmentField:
Cancel: Batal
Edit: Edit
OK: OK
ViewArchivedEmail_ss:
CANACCESS: 'Anda dapat mengakses arsip situs pada tautan ini:'
HAVEASKED: 'Anda telah meminta menampilkan konten situs ini pada'
VirtualPage:
HEADER: 'Ini adalah halaman virtual'
PLURALNAME: 'Halaman-halaman Virtual'
SINGULARNAME: 'Halaman Virtual'
CHOOSE: 'Laman Tertaut'
DESCRIPTION: 'Tampilkan konten laman lain'
EditLink: edit
HEADER: 'Ini adalah laman virtual'
HEADERWITHLINK: 'Ini adalah laman virtual dengan konten salinan dari "{title}" ({link})'
PLURALNAME: 'Laman Virtual'
PageTypNotAllowedOnRoot: 'Laman asli jenis "{type}" tidak dibolehkan pada tingkat atas untuk laman virtual ini'
SINGULARNAME: 'Laman Virtual'
CMSFileAddController:
MENUTITLE: Berkas
CMSPageEditController:
MENUTITLE: 'Ubah halaman'
MENUTITLE: 'Edit Laman'
CMSPageSettingsController:
MENUTITLE: 'Ubah halaman'
MENUTITLE: 'Edit Laman'
CMSSettingsController:
MENUTITLE: Pengaturan
CMSSiteTreeFilter_StatusDeletedPages:
Title: 'Halaman yang dihapus'

View File

@ -215,7 +215,7 @@ sv:
DEFAULTSERVERERRORPAGETITLE: 'Serverfel'
DESCRIPTION: 'Anpassat innehåll för olika felärenden (t.ex. "Sidan kan inte hittas")'
ERRORFILEPROBLEM: 'Kunde inte skriva filen "{filename}". Var vänlig kontrollera skrivrättigheterna.'
PLURALNAME: 'Felmeddelandesidor'
PLURALNAME: 'Felsidor'
SINGULARNAME: 'Felsida'
Folder:
AddFolderButton: 'Skapa mapp'
@ -238,7 +238,7 @@ sv:
HASBEENSETUP: 'En omdirigeringssida har skapats utan att ha något mål.'
HEADER: 'Den här sidan omdirigerar användare till en annan sida'
OTHERURL: 'Andra sidans URL'
PLURALNAME: 'Omdirigerings sidor'
PLURALNAME: 'Omdirigeringssida'
REDIRECTTO: 'Omdirigera till'
REDIRECTTOEXTERNAL: 'En annan sajt'
REDIRECTTOPAGE: 'En sida på din sajt'

View File

@ -35,7 +35,7 @@ So that only high quality changes are seen by our visitors
When I click "More options" in the "#ActionMenus" element
Then I should not see "Unpublish" in the "#ActionMenus_MoreOptions" element
And I should see "Not published" in the "#ActionMenus_MoreOptions" element
And I should see "Delete draft" in the "#ActionMenus_MoreOptions" element
And I should see "Archive" in the "#ActionMenus_MoreOptions" element
And I should see a "Save & publish" button
And I should see a "Saved" button
@ -48,7 +48,7 @@ So that only high quality changes are seen by our visitors
When I press the "Publish" button
And I click "More options" in the "#ActionMenus" element
Then I should see "Unpublish" in the "#ActionMenus_MoreOptions" element
And I should see "Delete draft" in the "#ActionMenus_MoreOptions" element
And I should see "Archive" in the "#ActionMenus_MoreOptions" element
And I should see a "Published" button
And I should see a "Saved" button
@ -64,7 +64,7 @@ So that only high quality changes are seen by our visitors
And I click on "Hello" in the tree
When I click "More options" in the "#ActionMenus" element
And I press the "Unpublish" button
And I press the "Unpublish" button, confirming the dialog
Then I press the "Log out" button
And I go to "/hello"
@ -80,16 +80,16 @@ So that only high quality changes are seen by our visitors
And I click "More options" in the "#ActionMenus" element
Then I should see "Unpublish" in the "#ActionMenus_MoreOptions" element
When I press the "Unpublish" button
When I press the "Unpublish" button, confirming the dialog
And I click "More options" in the "#ActionMenus" element
Then I should see "Delete draft" in the "#ActionMenus_MoreOptions" element
Then I should see "Archive" in the "#ActionMenus_MoreOptions" element
When I press the "Delete draft" button
When I press the "Archive" button, confirming the dialog
Then I should see a "Restore" button
And I should not see a "Published" button
And I should not see a "Save & publish" button
And I should not see a "Saved" button
And I should not see a "Save draft" button
When I press the "Restore" button
When I press the "Restore" button, confirming the dialog
Then I should see a "Save & publish" button

View File

@ -46,7 +46,7 @@ Feature: Search for a page
And the "page" "Deleted Page" is deleted
When I press the "Apply Filter" button
Then I should not see "Deleted Page" in the tree
When I select "All pages, including deleted" from "Pages"
When I select "All pages, including archived" from "Pages"
And I press the "Apply Filter" button
Then I should see "Deleted Page" in the tree
@ -56,7 +56,7 @@ Feature: Search for a page
And the "page" "Deleted Page" is deleted
When I press the "Apply Filter" button
Then I should not see "Deleted Page" in the tree
When I select "Deleted pages" from "Pages"
When I select "Archived pages" from "Pages"
And I press the "Apply Filter" button
Then I should see "Deleted Page" in the tree
And I should not see "About Us" in the tree
@ -66,7 +66,7 @@ Feature: Search for a page
And the "page" "Draft Page" is not published
When I press the "Apply Filter" button
Then I should see "Draft Page" in the tree
When I select "Draft unpublished pages" from "Pages"
When I select "Draft pages" from "Pages"
And I press the "Apply Filter" button
Then I should see "Draft Page" in the tree
And I should not see "About Us" in the tree
@ -81,7 +81,7 @@ Feature: Search for a page
When I go to "/admin/pages"
And I expand the "Filter" CMS Panel
When I select "Changed pages" from "Pages"
When I select "Modified pages" from "Pages"
And I press the "Apply Filter" button
Then I should see "About Us" in the tree
And I should not see "Home" in the tree

View File

@ -0,0 +1,86 @@
<?php
/**
* Tests CMS Specific subclasses of {@see CMSBatchAction}
*/
class CMSBatchActionsTest extends SapphireTest {
protected static $fixture_file = 'CMSBatchActionsTest.yml';
public function setUp() {
parent::setUp();
// published page
$published = $this->objFromFixture('Page', 'published');
$published->doPublish();
// Deleted / archived page
$archived = $this->objFromFixture('Page', 'archived');
$archived->doArchive();
// Unpublished
$unpublished = $this->objFromFixture('Page', 'unpublished');
$unpublished->doPublish();
$unpublished->doUnpublish();
// Modified
$modified = $this->objFromFixture('Page', 'modified');
$modified->doPublish();
$modified->Title = 'modified2';
$modified->write();
}
/**
* Test which pages can be published via batch actions
*/
public function testBatchPublish() {
$this->logInWithPermission('ADMIN');
$pages = Versioned::get_including_deleted('Page');
$ids = $pages->column('ID');
$action = new CMSBatchAction_Publish();
// Test applicable pages
$applicable = $action->applicablePages($ids);
$this->assertContains($this->idFromFixture('Page', 'published'), $applicable);
$this->assertNotContains($this->idFromFixture('Page', 'archived'), $applicable);
$this->assertContains($this->idFromFixture('Page', 'unpublished'), $applicable);
$this->assertContains($this->idFromFixture('Page', 'modified'), $applicable);
}
/**
* Test which pages can be unpublished via batch actions
*/
public function testBatchUnpublish() {
$this->logInWithPermission('ADMIN');
$pages = Versioned::get_including_deleted('Page');
$ids = $pages->column('ID');
$action = new CMSBatchAction_Unpublish();
// Test applicable page
$applicable = $action->applicablePages($ids);
$this->assertContains($this->idFromFixture('Page', 'published'), $applicable);
$this->assertNotContains($this->idFromFixture('Page', 'archived'), $applicable);
$this->assertNotContains($this->idFromFixture('Page', 'unpublished'), $applicable);
$this->assertContains($this->idFromFixture('Page', 'modified'), $applicable);
}
/**
* Test which pages can be published via batch actions
*/
public function testBatchArchive() {
$this->logInWithPermission('ADMIN');
$pages = Versioned::get_including_deleted('Page');
$ids = $pages->column('ID');
$action = new CMSBatchAction_Archive();
// Test applicable pages
$applicable = $action->applicablePages($ids);
$this->assertContains($this->idFromFixture('Page', 'published'), $applicable);
$this->assertNotContains($this->idFromFixture('Page', 'archived'), $applicable);
$this->assertContains($this->idFromFixture('Page', 'unpublished'), $applicable);
$this->assertContains($this->idFromFixture('Page', 'modified'), $applicable);
}
}

View File

@ -0,0 +1,9 @@
Page:
published:
Title: Published
archived:
Title: archived
unpublished:
Title: unpublished
modified:
Title: modified1

View File

@ -263,7 +263,15 @@ class CMSMainTest extends FunctionalTest {
$this->get('admin/pages/add');
$response = $this->post(
'admin/pages/add/AddForm',
array('ParentID' => '0', 'PageType' => 'Page', 'Locale' => 'en_US', 'action_doAdd' => 1)
array(
'ParentID' => '0',
'PageType' => 'Page',
'Locale' => 'en_US',
'action_doAdd' => 1,
'ajax' => 1,
), array(
'X-Pjax' => 'CurrentForm,Breadcrumbs',
)
);
// should redirect, which is a permission error
$this->assertEquals(403, $response->getStatusCode(), 'Add TopLevel page must fail for normal user');
@ -274,11 +282,19 @@ class CMSMainTest extends FunctionalTest {
$response = $this->post(
'admin/pages/add/AddForm',
array('ParentID' => '0', 'PageType' => 'Page', 'Locale' => 'en_US', 'action_doAdd' => 1)
array(
'ParentID' => '0',
'PageType' => 'Page',
'Locale' => 'en_US',
'action_doAdd' => 1,
'ajax' => 1,
), array(
'X-Pjax' => 'CurrentForm,Breadcrumbs',
)
);
$this->assertEquals(302, $response->getStatusCode(), 'Must be a redirect on success');
$location=$response->getHeader('Location');
$location = $response->getHeader('X-ControllerURL');
$this->assertNotEmpty($location, 'Must be a redirect on success');
$this->assertContains('/show/',$location, 'Must redirect to /show/ the new page');
// TODO Logout
$this->session()->inst_set('loggedInAs', NULL);

View File

@ -71,7 +71,7 @@ class FileLinkTrackingTest extends SapphireTest {
// Publish the source page
$page = $this->objFromFixture('Page', 'page1');
$this->assertTrue($page->doPublish());
$this->assertFalse($page->IsModifiedOnStage);
$this->assertFalse($page->getIsModifiedOnStage());
// Rename the file
$file = $this->objFromFixture('File', 'file1');
@ -83,7 +83,7 @@ class FileLinkTrackingTest extends SapphireTest {
Versioned::prepopulate_versionnumber_cache('SiteTree', 'Live', array($page->ID));
// Confirm that the page hasn't gone green.
$this->assertFalse($page->IsModifiedOnStage);
$this->assertFalse($page->getIsModifiedOnStage());
}
public function testTwoFileRenamesInARowWork() {

View File

@ -4,7 +4,7 @@
* - action_save
* - action_publish
* - action_unpublish
* - action_delete
* - action_archive
* - action_deletefromlive
* - action_rollback
* - action_revert
@ -83,7 +83,7 @@ class SiteTreeActionsTest extends FunctionalTest {
$this->assertNotNull($actions->dataFieldByName('action_save'));
$this->assertNotNull($actions->dataFieldByName('action_publish'));
$this->assertNotNull($actions->dataFieldByName('action_unpublish'));
$this->assertNotNull($actions->dataFieldByName('action_delete'));
$this->assertNotNull($actions->dataFieldByName('action_archive'));
$this->assertNull($actions->dataFieldByName('action_deletefromlive'));
$this->assertNull($actions->dataFieldByName('action_rollback'));
$this->assertNull($actions->dataFieldByName('action_revert'));
@ -111,7 +111,7 @@ class SiteTreeActionsTest extends FunctionalTest {
$this->assertNull($actions->dataFieldByName('action_save'));
$this->assertNull($actions->dataFieldByName('action_publish'));
$this->assertNull($actions->dataFieldByName('action_unpublish'));
$this->assertNull($actions->dataFieldByName('action_delete'));
$this->assertNull($actions->dataFieldByName('action_archive'));
$this->assertNotNull($actions->dataFieldByName('action_deletefromlive'));
$this->assertNull($actions->dataFieldByName('action_rollback'));
$this->assertNotNull($actions->dataFieldByName('action_revert'));
@ -135,7 +135,7 @@ class SiteTreeActionsTest extends FunctionalTest {
$this->assertNotNull($actions->dataFieldByName('action_save'));
$this->assertNotNull($actions->dataFieldByName('action_publish'));
$this->assertNotNull($actions->dataFieldByName('action_unpublish'));
$this->assertNotNull($actions->dataFieldByName('action_delete'));
$this->assertNotNull($actions->dataFieldByName('action_archive'));
$this->assertNull($actions->dataFieldByName('action_deletefromlive'));
$this->assertNotNull($actions->dataFieldByName('action_rollback'));
$this->assertNull($actions->dataFieldByName('action_revert'));
@ -155,7 +155,7 @@ class SiteTreeActionsTest extends FunctionalTest {
$this->assertNull($actions->dataFieldByName('action_save'));
$this->assertNull($actions->dataFieldByName('action_publish'));
$this->assertNull($actions->dataFieldByName('action_unpublish'));
$this->assertNull($actions->dataFieldByName('action_delete'));
$this->assertNull($actions->dataFieldByName('action_archive'));
$this->assertNotNull($actions->dataFieldByName('action_email'));
$this->assertNotNull($actions->dataFieldByName('action_rollback'));
}

View File

@ -194,17 +194,17 @@ class SiteTreeTest extends SapphireTest {
// newly created page
$createdPage = new SiteTree();
$createdPage->write();
$this->assertFalse($createdPage->IsDeletedFromStage);
$this->assertTrue($createdPage->IsAddedToStage);
$this->assertTrue($createdPage->IsModifiedOnStage);
$this->assertFalse($createdPage->getIsDeletedFromStage());
$this->assertTrue($createdPage->getIsAddedToStage());
$this->assertTrue($createdPage->getIsModifiedOnStage());
// published page
$publishedPage = new SiteTree();
$publishedPage->write();
$publishedPage->publish('Stage','Live');
$this->assertFalse($publishedPage->IsDeletedFromStage);
$this->assertFalse($publishedPage->IsAddedToStage);
$this->assertFalse($publishedPage->IsModifiedOnStage);
$this->assertFalse($publishedPage->getIsDeletedFromStage());
$this->assertFalse($publishedPage->getIsAddedToStage());
$this->assertFalse($publishedPage->getIsModifiedOnStage());
// published page, deleted from stage
$deletedFromDraftPage = new SiteTree();
@ -212,9 +212,9 @@ class SiteTreeTest extends SapphireTest {
$deletedFromDraftPageID = $deletedFromDraftPage->ID;
$deletedFromDraftPage->publish('Stage','Live');
$deletedFromDraftPage->deleteFromStage('Stage');
$this->assertTrue($deletedFromDraftPage->IsDeletedFromStage);
$this->assertFalse($deletedFromDraftPage->IsAddedToStage);
$this->assertFalse($deletedFromDraftPage->IsModifiedOnStage);
$this->assertTrue($deletedFromDraftPage->getIsDeletedFromStage());
$this->assertFalse($deletedFromDraftPage->getIsAddedToStage());
$this->assertFalse($deletedFromDraftPage->getIsModifiedOnStage());
// published page, deleted from live
$deletedFromLivePage = new SiteTree();
@ -222,9 +222,9 @@ class SiteTreeTest extends SapphireTest {
$deletedFromLivePage->publish('Stage','Live');
$deletedFromLivePage->deleteFromStage('Stage');
$deletedFromLivePage->deleteFromStage('Live');
$this->assertTrue($deletedFromLivePage->IsDeletedFromStage);
$this->assertFalse($deletedFromLivePage->IsAddedToStage);
$this->assertFalse($deletedFromLivePage->IsModifiedOnStage);
$this->assertTrue($deletedFromLivePage->getIsDeletedFromStage());
$this->assertFalse($deletedFromLivePage->getIsAddedToStage());
$this->assertFalse($deletedFromLivePage->getIsModifiedOnStage());
// published page, modified
$modifiedOnDraftPage = new SiteTree();
@ -232,9 +232,9 @@ class SiteTreeTest extends SapphireTest {
$modifiedOnDraftPage->publish('Stage','Live');
$modifiedOnDraftPage->Content = 'modified';
$modifiedOnDraftPage->write();
$this->assertFalse($modifiedOnDraftPage->IsDeletedFromStage);
$this->assertFalse($modifiedOnDraftPage->IsAddedToStage);
$this->assertTrue($modifiedOnDraftPage->IsModifiedOnStage);
$this->assertFalse($modifiedOnDraftPage->getIsDeletedFromStage());
$this->assertFalse($modifiedOnDraftPage->getIsAddedToStage());
$this->assertTrue($modifiedOnDraftPage->getIsModifiedOnStage());
}
/**

View File

@ -209,46 +209,46 @@ class VirtualPageTest extends SapphireTest {
$vp->write();
// VP is oragne
$this->assertTrue($vp->IsAddedToStage);
$this->assertTrue($vp->getIsAddedToStage());
// VP is still orange after we publish
$p->doPublish();
$this->fixVersionNumberCache($vp);
$this->assertTrue($vp->IsAddedToStage);
$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->IsAddedToStage);
$this->assertTrue($vp2->getIsAddedToStage());
// Also remains orange after a republish
$p->Content = "new content";
$p->write();
$p->doPublish();
$this->fixVersionNumberCache($vp2);
$this->assertTrue($vp2->IsAddedToStage);
$this->assertTrue($vp2->getIsAddedToStage());
// VP is now published
$vp->doPublish();
$this->fixVersionNumberCache($vp);
$this->assertTrue($vp->ExistsOnLive);
$this->assertFalse($vp->IsModifiedOnStage);
$this->assertTrue($vp->getExistsOnLive());
$this->assertFalse($vp->getIsModifiedOnStage());
// P edited, VP and P both go green
$p->Content = "third content";
$p->write();
$this->fixVersionNumberCache($vp, $p);
$this->assertTrue($p->IsModifiedOnStage);
$this->assertTrue($vp->IsModifiedOnStage);
$this->assertTrue($p->getIsModifiedOnStage());
$this->assertTrue($vp->getIsModifiedOnStage());
// Publish, VP goes black
$p->doPublish();
$this->fixVersionNumberCache($vp);
$this->assertTrue($vp->ExistsOnLive);
$this->assertFalse($vp->IsModifiedOnStage);
$this->assertTrue($vp->getExistsOnLive());
$this->assertFalse($vp->getIsModifiedOnStage());
}
public function testVirtualPagesCreateVersionRecords() {