diff --git a/_config.php b/_config.php
index 0cbece5e..e0b5703c 100644
--- a/_config.php
+++ b/_config.php
@@ -25,4 +25,3 @@
CMSPagesController::add_extension('SubsiteMenuExtension');
SubsiteAdmin::add_extension('SubsiteMenuExtension');
CMSSettingsController::add_extension('SubsiteMenuExtension');
-
diff --git a/code/SubsiteAdmin.php b/code/SubsiteAdmin.php
index abea9a1b..7de900d8 100644
--- a/code/SubsiteAdmin.php
+++ b/code/SubsiteAdmin.php
@@ -4,30 +4,30 @@
*
* @package subsites
*/
-class SubsiteAdmin extends ModelAdmin {
-
- private static $managed_models = array('Subsite');
+class SubsiteAdmin extends ModelAdmin
+{
+ private static $managed_models = array('Subsite');
- private static $url_segment = 'subsites';
-
- private static $menu_title = "Subsites";
+ private static $url_segment = 'subsites';
+
+ private static $menu_title = "Subsites";
- private static $menu_icon = "subsites/images/subsites.png";
-
- public $showImportForm=false;
+ private static $menu_icon = "subsites/images/subsites.png";
+
+ public $showImportForm=false;
- private static $tree_class = 'Subsite';
+ private static $tree_class = 'Subsite';
- public function getEditForm($id = null, $fields = null) {
- $form = parent::getEditForm($id, $fields);
+ public function getEditForm($id = null, $fields = null)
+ {
+ $form = parent::getEditForm($id, $fields);
- $grid=$form->Fields()->dataFieldByName('Subsite');
- if($grid) {
- $grid->getConfig()->removeComponentsByType('GridFieldDetailForm');
- $grid->getConfig()->addComponent(new GridFieldSubsiteDetailForm());
- }
-
- return $form;
- }
+ $grid=$form->Fields()->dataFieldByName('Subsite');
+ if ($grid) {
+ $grid->getConfig()->removeComponentsByType('GridFieldDetailForm');
+ $grid->getConfig()->addComponent(new GridFieldSubsiteDetailForm());
+ }
+ return $form;
+ }
}
diff --git a/code/SubsiteReportWrapper.php b/code/SubsiteReportWrapper.php
index 2774cfcb..3e85c24e 100644
--- a/code/SubsiteReportWrapper.php
+++ b/code/SubsiteReportWrapper.php
@@ -4,62 +4,66 @@
* Creates a subsite-aware version of another report.
* Pass another report (or its classname) into the constructor.
*/
-class SubsiteReportWrapper extends SS_ReportWrapper {
- ///////////////////////////////////////////////////////////////////////////////////////////
- // Filtering
-
- function parameterFields() {
- $subsites = Subsite::accessible_sites('CMS_ACCESS_CMSMain', true);
- $options = $subsites->toDropdownMap('ID', 'Title');
-
- $subsiteField = new TreeMultiselectField(
- 'Subsites',
- _t('SubsiteReportWrapper.ReportDropdown', 'Sites'),
- $options
- );
- $subsiteField->setValue(array_keys($options));
+class SubsiteReportWrapper extends SS_ReportWrapper
+{
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Filtering
- // We don't need to make the field editable if only one subsite is available
- if(sizeof($options) <= 1) {
- $subsiteField = $subsiteField->performReadonlyTransformation();
- }
-
- $fields = parent::parameterFields();
- if($fields) {
- $fields->insertBefore($subsiteField, $fields->First()->Name());
- } else {
- $fields = new FieldList($subsiteField);
- }
- return $fields;
- }
+ public function parameterFields()
+ {
+ $subsites = Subsite::accessible_sites('CMS_ACCESS_CMSMain', true);
+ $options = $subsites->toDropdownMap('ID', 'Title');
+
+ $subsiteField = new TreeMultiselectField(
+ 'Subsites',
+ _t('SubsiteReportWrapper.ReportDropdown', 'Sites'),
+ $options
+ );
+ $subsiteField->setValue(array_keys($options));
- ///////////////////////////////////////////////////////////////////////////////////////////
- // Columns
-
- function columns() {
- $columns = parent::columns();
- $columns['Subsite.Title'] = "Subsite";
- return $columns;
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////
- // Querying
-
- function beforeQuery($params) {
- // The user has select a few specific sites
- if(!empty($params['Subsites'])) {
- Subsite::$force_subsite = $params['Subsites'];
-
- // Default: restrict to all accessible sites
- } else {
- $subsites = Subsite::accessible_sites('CMS_ACCESS_CMSMain');
- $options = $subsites->toDropdownMap('ID', 'Title');
- Subsite::$force_subsite = join(',', array_keys($options));
- }
- }
- function afterQuery() {
- // Manually manage the subsite filtering
- Subsite::$force_subsite = null;
- }
-
-}
\ No newline at end of file
+ // We don't need to make the field editable if only one subsite is available
+ if (sizeof($options) <= 1) {
+ $subsiteField = $subsiteField->performReadonlyTransformation();
+ }
+
+ $fields = parent::parameterFields();
+ if ($fields) {
+ $fields->insertBefore($subsiteField, $fields->First()->Name());
+ } else {
+ $fields = new FieldList($subsiteField);
+ }
+ return $fields;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Columns
+
+ public function columns()
+ {
+ $columns = parent::columns();
+ $columns['Subsite.Title'] = "Subsite";
+ return $columns;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // Querying
+
+ public function beforeQuery($params)
+ {
+ // The user has select a few specific sites
+ if (!empty($params['Subsites'])) {
+ Subsite::$force_subsite = $params['Subsites'];
+
+ // Default: restrict to all accessible sites
+ } else {
+ $subsites = Subsite::accessible_sites('CMS_ACCESS_CMSMain');
+ $options = $subsites->toDropdownMap('ID', 'Title');
+ Subsite::$force_subsite = join(',', array_keys($options));
+ }
+ }
+ public function afterQuery()
+ {
+ // Manually manage the subsite filtering
+ Subsite::$force_subsite = null;
+ }
+}
diff --git a/code/SubsiteXHRController.php b/code/SubsiteXHRController.php
index 052768ec..74687325 100644
--- a/code/SubsiteXHRController.php
+++ b/code/SubsiteXHRController.php
@@ -3,43 +3,52 @@
/**
* Section-agnostic PJAX controller.
*/
-class SubsiteXHRController extends LeftAndMain {
-
- /**
- * Relax the access permissions, so anyone who has access to any CMS subsite can access this controller.
- */
- public function canView($member = null) {
- if (parent::canView()) return true;
-
- if (Subsite::all_accessible_sites()->count()>0) return true;
-
- return false;
- }
-
- /**
- * Similar as above, but for the LeftAndMainSubsites - allow access if user allowed into the CMS at all.
- */
- public function canAccess() {
- if (Subsite::all_accessible_sites()->count()>0) return true;
- }
-
- public function getResponseNegotiator() {
- $negotiator = parent::getResponseNegotiator();
- $self = $this;
-
- // Register a new callback
- $negotiator->setCallback('SubsiteList', function() use(&$self) {
- return $self->SubsiteList();
- });
-
- return $negotiator;
- }
-
- /**
- * Provide the list of available subsites as a cms-section-agnostic PJAX handler.
- */
- public function SubsiteList() {
- return $this->renderWith('SubsiteList');
- }
-
+class SubsiteXHRController extends LeftAndMain
+{
+ /**
+ * Relax the access permissions, so anyone who has access to any CMS subsite can access this controller.
+ */
+ public function canView($member = null)
+ {
+ if (parent::canView()) {
+ return true;
+ }
+
+ if (Subsite::all_accessible_sites()->count()>0) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Similar as above, but for the LeftAndMainSubsites - allow access if user allowed into the CMS at all.
+ */
+ public function canAccess()
+ {
+ if (Subsite::all_accessible_sites()->count()>0) {
+ return true;
+ }
+ }
+
+ public function getResponseNegotiator()
+ {
+ $negotiator = parent::getResponseNegotiator();
+ $self = $this;
+
+ // Register a new callback
+ $negotiator->setCallback('SubsiteList', function () use (&$self) {
+ return $self->SubsiteList();
+ });
+
+ return $negotiator;
+ }
+
+ /**
+ * Provide the list of available subsites as a cms-section-agnostic PJAX handler.
+ */
+ public function SubsiteList()
+ {
+ return $this->renderWith('SubsiteList');
+ }
}
diff --git a/code/SubsitesVirtualPage.php b/code/SubsitesVirtualPage.php
index c63fa131..ccc801db 100644
--- a/code/SubsitesVirtualPage.php
+++ b/code/SubsitesVirtualPage.php
@@ -1,212 +1,233 @@
'Varchar(255)',
+ 'CustomMetaKeywords' => 'Varchar(255)',
+ 'CustomMetaDescription' => 'Text',
+ 'CustomExtraMeta' => 'HTMLText'
+ );
+
+ public function getCMSFields()
+ {
+ $fields = parent::getCMSFields();
+
+ $subsites = DataObject::get('Subsite');
+ if (!$subsites) {
+ $subsites = new ArrayList();
+ } else {
+ $subsites=ArrayList::create($subsites->toArray());
+ }
+
+ $subsites->push(new ArrayData(array('Title' => 'Main site', 'ID' => 0)));
- private static $db = array(
- 'CustomMetaTitle' => 'Varchar(255)',
- 'CustomMetaKeywords' => 'Varchar(255)',
- 'CustomMetaDescription' => 'Text',
- 'CustomExtraMeta' => 'HTMLText'
- );
-
- public function getCMSFields() {
- $fields = parent::getCMSFields();
-
- $subsites = DataObject::get('Subsite');
- if(!$subsites) {
- $subsites = new ArrayList();
- }else {
- $subsites=ArrayList::create($subsites->toArray());
- }
-
- $subsites->push(new ArrayData(array('Title' => 'Main site', 'ID' => 0)));
+ $fields->addFieldToTab(
+ 'Root.Main',
+ DropdownField::create(
+ "CopyContentFromID_SubsiteID",
+ _t('SubsitesVirtualPage.SubsiteField', "Subsite"),
+ $subsites->map('ID', 'Title')
+ )->addExtraClass('subsitestreedropdownfield-chooser no-change-track'),
+ 'CopyContentFromID'
+ );
+
+ // Setup the linking to the original page.
+ $pageSelectionField = new SubsitesTreeDropdownField(
+ "CopyContentFromID",
+ _t('VirtualPage.CHOOSE', "Choose a page to link to"),
+ "SiteTree",
+ "ID",
+ "MenuTitle"
+ );
+
+ if (Controller::has_curr() && Controller::curr()->getRequest()) {
+ $subsiteID = Controller::curr()->getRequest()->requestVar('CopyContentFromID_SubsiteID');
+ $pageSelectionField->setSubsiteID($subsiteID);
+ }
+ $fields->replaceField('CopyContentFromID', $pageSelectionField);
+
+ // Create links back to the original object in the CMS
+ if ($this->CopyContentFromID) {
+ $editLink = "admin/pages/edit/show/$this->CopyContentFromID/?SubsiteID=" . $this->CopyContentFrom()->SubsiteID;
+ $linkToContent = "
+ " .
+ _t('VirtualPage.EDITCONTENT', 'Click here to edit the content') .
+ "";
+ $fields->removeByName("VirtualPageContentLinkLabel");
+ $fields->addFieldToTab(
+ "Root.Main",
+ $linkToContentLabelField = new LabelField('VirtualPageContentLinkLabel', $linkToContent),
+ 'Title'
+ );
+ $linkToContentLabelField->setAllowHTML(true);
+ }
+
+
+ $fields->addFieldToTab(
+ 'Root.Main',
+ TextField::create(
+ 'CustomMetaTitle',
+ $this->fieldLabel('CustomMetaTitle')
+ )->setDescription(_t('SubsitesVirtualPage.OverrideNote', 'Overrides inherited value from the source')),
+ 'MetaTitle'
+ );
+ $fields->addFieldToTab(
+ 'Root.Main',
+ TextareaField::create(
+ 'CustomMetaKeywords',
+ $this->fieldLabel('CustomMetaTitle')
+ )->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
+ 'MetaKeywords'
+ );
+ $fields->addFieldToTab(
+ 'Root.Main',
+ TextareaField::create(
+ 'CustomMetaDescription',
+ $this->fieldLabel('CustomMetaTitle')
+ )->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
+ 'MetaDescription'
+ );
+ $fields->addFieldToTab(
+ 'Root.Main',
+ TextField::create(
+ 'CustomExtraMeta',
+ $this->fieldLabel('CustomMetaTitle')
+ )->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
+ 'ExtraMeta'
+ );
+
+ return $fields;
+ }
- $fields->addFieldToTab(
- 'Root.Main',
- DropdownField::create(
- "CopyContentFromID_SubsiteID",
- _t('SubsitesVirtualPage.SubsiteField',"Subsite"),
- $subsites->map('ID', 'Title')
- )->addExtraClass('subsitestreedropdownfield-chooser no-change-track'),
- 'CopyContentFromID'
- );
-
- // Setup the linking to the original page.
- $pageSelectionField = new SubsitesTreeDropdownField(
- "CopyContentFromID",
- _t('VirtualPage.CHOOSE', "Choose a page to link to"),
- "SiteTree",
- "ID",
- "MenuTitle"
- );
-
- if(Controller::has_curr() && Controller::curr()->getRequest()) {
- $subsiteID = Controller::curr()->getRequest()->requestVar('CopyContentFromID_SubsiteID');
- $pageSelectionField->setSubsiteID($subsiteID);
- }
- $fields->replaceField('CopyContentFromID', $pageSelectionField);
-
- // Create links back to the original object in the CMS
- if($this->CopyContentFromID) {
- $editLink = "admin/pages/edit/show/$this->CopyContentFromID/?SubsiteID=" . $this->CopyContentFrom()->SubsiteID;
- $linkToContent = "
- " .
- _t('VirtualPage.EDITCONTENT', 'Click here to edit the content') .
- "";
- $fields->removeByName("VirtualPageContentLinkLabel");
- $fields->addFieldToTab(
- "Root.Main",
- $linkToContentLabelField = new LabelField('VirtualPageContentLinkLabel', $linkToContent),
- 'Title'
- );
- $linkToContentLabelField->setAllowHTML(true);
- }
-
-
- $fields->addFieldToTab(
- 'Root.Main',
- TextField::create(
- 'CustomMetaTitle',
- $this->fieldLabel('CustomMetaTitle')
- )->setDescription(_t('SubsitesVirtualPage.OverrideNote', 'Overrides inherited value from the source')),
- 'MetaTitle'
- );
- $fields->addFieldToTab(
- 'Root.Main',
- TextareaField::create(
- 'CustomMetaKeywords',
- $this->fieldLabel('CustomMetaTitle')
- )->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
- 'MetaKeywords'
- );
- $fields->addFieldToTab(
- 'Root.Main',
- TextareaField::create(
- 'CustomMetaDescription',
- $this->fieldLabel('CustomMetaTitle')
- )->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
- 'MetaDescription'
- );
- $fields->addFieldToTab(
- 'Root.Main',
- TextField::create(
- 'CustomExtraMeta',
- $this->fieldLabel('CustomMetaTitle')
- )->setDescription(_t('SubsitesVirtualPage.OverrideNote')),
- 'ExtraMeta'
- );
-
- return $fields;
- }
+ public function fieldLabels($includerelations = true)
+ {
+ $labels = parent::fieldLabels($includerelations);
+ $labels['CustomMetaTitle'] = _t('Subsite.CustomMetaTitle', 'Title');
+ $labels['CustomMetaKeywords'] = _t('Subsite.CustomMetaKeywords', 'Keywords');
+ $labels['CustomMetaDescription'] = _t('Subsite.CustomMetaDescription', 'Description');
+ $labels['CustomExtraMeta'] = _t('Subsite.CustomExtraMeta', 'Custom Meta Tags');
- public function fieldLabels($includerelations = true) {
- $labels = parent::fieldLabels($includerelations);
- $labels['CustomMetaTitle'] = _t('Subsite.CustomMetaTitle','Title');
- $labels['CustomMetaKeywords'] = _t('Subsite.CustomMetaKeywords','Keywords');
- $labels['CustomMetaDescription'] = _t('Subsite.CustomMetaDescription','Description');
- $labels['CustomExtraMeta'] = _t('Subsite.CustomExtraMeta','Custom Meta Tags');
+ return $labels;
+ }
- return $labels;
- }
+ public function getCopyContentFromID_SubsiteID()
+ {
+ return ($this->CopyContentFromID) ? (int)$this->CopyContentFrom()->SubsiteID : (int)Session::get('SubsiteID');
+ }
+
+ public function getVirtualFields()
+ {
+ $fields = parent::getVirtualFields();
+ foreach ($fields as $k => $v) {
+ if ($v == 'SubsiteID') {
+ unset($fields[$k]);
+ }
+ }
+
+ foreach (self::$db as $field => $type) {
+ if (in_array($field, $fields)) {
+ unset($fields[array_search($field, $fields)]);
+ }
+ }
- public function getCopyContentFromID_SubsiteID() {
- return ($this->CopyContentFromID) ? (int)$this->CopyContentFrom()->SubsiteID : (int)Session::get('SubsiteID');
- }
-
- public function getVirtualFields() {
- $fields = parent::getVirtualFields();
- foreach($fields as $k => $v) {
- if($v == 'SubsiteID') unset($fields[$k]);
- }
-
- foreach(self::$db as $field => $type) if (in_array($field, $fields)) unset($fields[array_search($field, $fields)]);
+ return $fields;
+ }
+
+ public function syncLinkTracking()
+ {
+ $oldState = Subsite::$disable_subsite_filter;
+ Subsite::$disable_subsite_filter = true;
+ if ($this->CopyContentFromID) {
+ $this->HasBrokenLink = DataObject::get_by_id('SiteTree', $this->CopyContentFromID) ? false : true;
+ }
+ Subsite::$disable_subsite_filter = $oldState;
+ }
- return $fields;
- }
-
- public function syncLinkTracking() {
- $oldState = Subsite::$disable_subsite_filter;
- Subsite::$disable_subsite_filter = true;
- if ($this->CopyContentFromID) $this->HasBrokenLink = DataObject::get_by_id('SiteTree', $this->CopyContentFromID) ? false : true;
- Subsite::$disable_subsite_filter = $oldState;
- }
+ public function onBeforeWrite()
+ {
+ parent::onBeforeWrite();
+
+ if ($this->CustomMetaTitle) {
+ $this->MetaTitle = $this->CustomMetaTitle;
+ } else {
+ $this->MetaTitle = $this->ContentSource()->MetaTitle ? $this->ContentSource()->MetaTitle : $this->MetaTitle;
+ }
+ if ($this->CustomMetaKeywords) {
+ $this->MetaKeywords = $this->CustomMetaKeywords;
+ } else {
+ $this->MetaKeywords = $this->ContentSource()->MetaKeywords ? $this->ContentSource()->MetaKeywords : $this->MetaKeywords;
+ }
+ if ($this->CustomMetaDescription) {
+ $this->MetaDescription = $this->CustomMetaDescription;
+ } else {
+ $this->MetaDescription = $this->ContentSource()->MetaDescription ? $this->ContentSource()->MetaDescription : $this->MetaDescription;
+ }
+ if ($this->CustomExtraMeta) {
+ $this->ExtraMeta = $this->CustomExtraMeta;
+ } else {
+ $this->ExtraMeta = $this->ContentSource()->ExtraMeta ? $this->ContentSource()->ExtraMeta : $this->ExtraMeta;
+ }
+ }
+
+ public function validURLSegment()
+ {
+ $isValid = parent::validURLSegment();
+
+ // Veto the validation rules if its false. In this case, some logic
+ // needs to be duplicated from parent to find out the exact reason the validation failed.
+ if (!$isValid) {
+ $IDFilter = ($this->ID) ? "AND \"SiteTree\".\"ID\" <> $this->ID" : null;
+ $parentFilter = null;
- public function onBeforeWrite() {
- parent::onBeforeWrite();
-
- if($this->CustomMetaTitle) $this->MetaTitle = $this->CustomMetaTitle;
- else {
- $this->MetaTitle = $this->ContentSource()->MetaTitle ? $this->ContentSource()->MetaTitle : $this->MetaTitle;
- }
- if($this->CustomMetaKeywords) $this->MetaKeywords = $this->CustomMetaKeywords;
- else {
- $this->MetaKeywords = $this->ContentSource()->MetaKeywords ? $this->ContentSource()->MetaKeywords : $this->MetaKeywords;
- }
- if($this->CustomMetaDescription) $this->MetaDescription = $this->CustomMetaDescription;
- else {
- $this->MetaDescription = $this->ContentSource()->MetaDescription ? $this->ContentSource()->MetaDescription : $this->MetaDescription;
- }
- if($this->CustomExtraMeta) $this->ExtraMeta = $this->CustomExtraMeta;
- else {
- $this->ExtraMeta = $this->ContentSource()->ExtraMeta ? $this->ContentSource()->ExtraMeta : $this->ExtraMeta;
- }
- }
-
- public function validURLSegment() {
- $isValid = parent::validURLSegment();
-
- // Veto the validation rules if its false. In this case, some logic
- // needs to be duplicated from parent to find out the exact reason the validation failed.
- if(!$isValid) {
- $IDFilter = ($this->ID) ? "AND \"SiteTree\".\"ID\" <> $this->ID" : null;
- $parentFilter = null;
+ if (Config::inst()->get('SiteTree', 'nested_urls')) {
+ if ($this->ParentID) {
+ $parentFilter = " AND \"SiteTree\".\"ParentID\" = $this->ParentID";
+ } else {
+ $parentFilter = ' AND "SiteTree"."ParentID" = 0';
+ }
+ }
+
+ $origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
+ Subsite::$disable_subsite_filter = true;
+ $existingPage = DataObject::get_one(
+ 'SiteTree',
+ "\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter",
+ false // disable cache, it doesn't include subsite status in the key
+ );
+ Subsite::$disable_subsite_filter = $origDisableSubsiteFilter;
+ $existingPageInSubsite = DataObject::get_one(
+ 'SiteTree',
+ "\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter",
+ false // disable cache, it doesn't include subsite status in the key
+ );
- if(Config::inst()->get('SiteTree', 'nested_urls')) {
- if($this->ParentID) {
- $parentFilter = " AND \"SiteTree\".\"ParentID\" = $this->ParentID";
- } else {
- $parentFilter = ' AND "SiteTree"."ParentID" = 0';
- }
- }
-
- $origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
- Subsite::$disable_subsite_filter = true;
- $existingPage = DataObject::get_one(
- 'SiteTree',
- "\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter",
- false // disable cache, it doesn't include subsite status in the key
- );
- Subsite::$disable_subsite_filter = $origDisableSubsiteFilter;
- $existingPageInSubsite = DataObject::get_one(
- 'SiteTree',
- "\"URLSegment\" = '$this->URLSegment' $IDFilter $parentFilter",
- false // disable cache, it doesn't include subsite status in the key
- );
-
- // If URL has been vetoed because of an existing page,
- // be more specific and allow same URLSegments in different subsites
- $isValid = !($existingPage && $existingPageInSubsite);
- }
-
- return $isValid;
- }
+ // If URL has been vetoed because of an existing page,
+ // be more specific and allow same URLSegments in different subsites
+ $isValid = !($existingPage && $existingPageInSubsite);
+ }
+
+ return $isValid;
+ }
}
-class SubsitesVirtualPage_Controller extends VirtualPage_Controller {
-
- public function reloadContent() {
- $this->failover->copyFrom($this->failover->CopyContentFrom());
- $this->failover->write();
- return;
- }
-
- public function init(){
- $origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
- Subsite::$disable_subsite_filter = true;
-
- parent::init();
-
- Subsite::$disable_subsite_filter = $origDisableSubsiteFilter;
- }
+class SubsitesVirtualPage_Controller extends VirtualPage_Controller
+{
+ public function reloadContent()
+ {
+ $this->failover->copyFrom($this->failover->CopyContentFrom());
+ $this->failover->write();
+ return;
+ }
+
+ public function init()
+ {
+ $origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
+ Subsite::$disable_subsite_filter = true;
+
+ parent::init();
+
+ Subsite::$disable_subsite_filter = $origDisableSubsiteFilter;
+ }
}
diff --git a/code/extensions/CMSPageAddControllerExtension.php b/code/extensions/CMSPageAddControllerExtension.php
index 8db4418d..d7402890 100644
--- a/code/extensions/CMSPageAddControllerExtension.php
+++ b/code/extensions/CMSPageAddControllerExtension.php
@@ -1,8 +1,8 @@
push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
- }
-
+class CMSPageAddControllerExtension extends Extension
+{
+ public function updatePageOptions(&$fields)
+ {
+ $fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
+ }
}
diff --git a/code/extensions/ControllerSubsites.php b/code/extensions/ControllerSubsites.php
index 82b3cfd9..6ad723d0 100644
--- a/code/extensions/ControllerSubsites.php
+++ b/code/extensions/ControllerSubsites.php
@@ -2,19 +2,21 @@
/**
* @package subsites
*/
-class ControllerSubsites extends Extension {
- function controllerAugmentInit(){
- if($subsite = Subsite::currentSubsite()){
- if($theme = $subsite->Theme)
- SSViewer::set_theme($theme);
- }
- }
-
- function CurrentSubsite(){
- if($subsite = Subsite::currentSubsite()){
- return $subsite;
- }
- }
+class ControllerSubsites extends Extension
+{
+ public function controllerAugmentInit()
+ {
+ if ($subsite = Subsite::currentSubsite()) {
+ if ($theme = $subsite->Theme) {
+ SSViewer::set_theme($theme);
+ }
+ }
+ }
+
+ public function CurrentSubsite()
+ {
+ if ($subsite = Subsite::currentSubsite()) {
+ return $subsite;
+ }
+ }
}
-
-?>
\ No newline at end of file
diff --git a/code/extensions/ErrorPageSubsite.php b/code/extensions/ErrorPageSubsite.php
index 0e620ca4..5129767a 100644
--- a/code/extensions/ErrorPageSubsite.php
+++ b/code/extensions/ErrorPageSubsite.php
@@ -1,40 +1,43 @@
get($this->owner->ClassName, 'static_filepath');
- $subdomainPart = "";
-
- // Try to get current subsite from session
- $subsite = Subsite::currentSubsite(false);
-
- // since this function is called from Page class before the controller is created, we have to get subsite from domain instead
- if(!$subsite) {
- $subsiteID = Subsite::getSubsiteIDForDomain();
- if($subsiteID != 0) $subsite = DataObject::get_by_id("Subsite", $subsiteID);
- else $subsite = null;
- }
-
- if($subsite) {
- $subdomain = $subsite->domain();
- $subdomainPart = "-{$subdomain}";
- }
-
- if(singleton('SiteTree')->hasExtension('Translatable') && $locale && $locale != Translatable::default_locale()) {
- $filepath = $static_filepath . "/error-{$statusCode}-{$locale}{$subdomainPart}.html";
- } else {
- $filepath = $static_filepath . "/error-{$statusCode}{$subdomainPart}.html";
- }
+class ErrorPageSubsite extends DataExtension
+{
+ /**
+ * Alter file path to generated a static (static) error page file to handle error page template on different sub-sites
+ *
+ * @see Error::get_filepath_for_errorcode()
+ *
+ * FIXME since {@link Subsite::currentSubsite()} partly relies on Session, viewing other sub-site (including main site) between
+ * opening ErrorPage in the CMS and publish ErrorPage causes static error page to get generated incorrectly.
+ */
+ public function alternateFilepathForErrorcode($statusCode, $locale = null)
+ {
+ $static_filepath = Config::inst()->get($this->owner->ClassName, 'static_filepath');
+ $subdomainPart = "";
+
+ // Try to get current subsite from session
+ $subsite = Subsite::currentSubsite(false);
+
+ // since this function is called from Page class before the controller is created, we have to get subsite from domain instead
+ if (!$subsite) {
+ $subsiteID = Subsite::getSubsiteIDForDomain();
+ if ($subsiteID != 0) {
+ $subsite = DataObject::get_by_id("Subsite", $subsiteID);
+ } else {
+ $subsite = null;
+ }
+ }
+
+ if ($subsite) {
+ $subdomain = $subsite->domain();
+ $subdomainPart = "-{$subdomain}";
+ }
+
+ if (singleton('SiteTree')->hasExtension('Translatable') && $locale && $locale != Translatable::default_locale()) {
+ $filepath = $static_filepath . "/error-{$statusCode}-{$locale}{$subdomainPart}.html";
+ } else {
+ $filepath = $static_filepath . "/error-{$statusCode}{$subdomainPart}.html";
+ }
- return $filepath;
- }
-
-}
\ No newline at end of file
+ return $filepath;
+ }
+}
diff --git a/code/extensions/FileSubsites.php b/code/extensions/FileSubsites.php
index 2aee52cd..db760dda 100644
--- a/code/extensions/FileSubsites.php
+++ b/code/extensions/FileSubsites.php
@@ -4,126 +4,138 @@
*
* @package subsites
*/
-class FileSubsites extends DataExtension {
-
- // If this is set to true, all folders created will be default be
- // considered 'global', unless set otherwise
- static $default_root_folders_global = false;
-
- private static $has_one=array(
- 'Subsite' => 'Subsite',
- );
+class FileSubsites extends DataExtension
+{
+ // If this is set to true, all folders created will be default be
+ // considered 'global', unless set otherwise
+ public static $default_root_folders_global = false;
+
+ private static $has_one=array(
+ 'Subsite' => 'Subsite',
+ );
- /**
- * Amends the CMS tree title for folders in the Files & Images section.
- * Prefixes a '* ' to the folders that are accessible from all subsites.
- */
- function alternateTreeTitle() {
- if($this->owner->SubsiteID == 0) return " * " . $this->owner->Title;
- else return $this->owner->Title;
- }
+ /**
+ * Amends the CMS tree title for folders in the Files & Images section.
+ * Prefixes a '* ' to the folders that are accessible from all subsites.
+ */
+ public function alternateTreeTitle()
+ {
+ if ($this->owner->SubsiteID == 0) {
+ return " * " . $this->owner->Title;
+ } else {
+ return $this->owner->Title;
+ }
+ }
- /**
- * Add subsites-specific fields to the folder editor.
- */
- function updateCMSFields(FieldList $fields) {
- if($this->owner instanceof Folder) {
- $sites = Subsite::accessible_sites('CMS_ACCESS_AssetAdmin');
- $values = array();
- $values[0] = _t('FileSubsites.AllSitesDropdownOpt','All sites');
- foreach ($sites as $site) {
- $values[$site->ID] = $site->Title;
- }
- ksort($values);
- if($sites){
- //Dropdown needed to move folders between subsites
- $dropdown = new DropdownField(
- 'SubsiteID',
- _t('FileSubsites.SubsiteFieldLabel','Subsite'),
- $values
- );
- $dropdown->addExtraClass('subsites-move-dropdown');
- $fields->push($dropdown);
- $fields->push(new LiteralField(
- 'Message',
- '
'.
- _t('ASSETADMIN.SUBSITENOTICE', 'Folders and files created in the main site are accessible by all subsites.')
- .'
'
- ));
- }
- }
- }
+ /**
+ * Add subsites-specific fields to the folder editor.
+ */
+ public function updateCMSFields(FieldList $fields)
+ {
+ if ($this->owner instanceof Folder) {
+ $sites = Subsite::accessible_sites('CMS_ACCESS_AssetAdmin');
+ $values = array();
+ $values[0] = _t('FileSubsites.AllSitesDropdownOpt', 'All sites');
+ foreach ($sites as $site) {
+ $values[$site->ID] = $site->Title;
+ }
+ ksort($values);
+ if ($sites) {
+ //Dropdown needed to move folders between subsites
+ $dropdown = new DropdownField(
+ 'SubsiteID',
+ _t('FileSubsites.SubsiteFieldLabel', 'Subsite'),
+ $values
+ );
+ $dropdown->addExtraClass('subsites-move-dropdown');
+ $fields->push($dropdown);
+ $fields->push(new LiteralField(
+ 'Message',
+ ''.
+ _t('ASSETADMIN.SUBSITENOTICE', 'Folders and files created in the main site are accessible by all subsites.')
+ .'
'
+ ));
+ }
+ }
+ }
- /**
- * Update any requests to limit the results to the current site
- */
- public function augmentSQL(SQLQuery &$query) {
- if(Subsite::$disable_subsite_filter) return;
+ /**
+ * Update any requests to limit the results to the current site
+ */
+ public function augmentSQL(SQLQuery &$query)
+ {
+ if (Subsite::$disable_subsite_filter) {
+ return;
+ }
- // If you're querying by ID, ignore the sub-site - this is a bit ugly... (but it was WAYYYYYYYYY worse)
- //@TODO I don't think excluding if SiteTree_ImageTracking is a good idea however because of the SS 3.0 api and ManyManyList::removeAll() changing the from table after this function is called there isn't much of a choice
+ // If you're querying by ID, ignore the sub-site - this is a bit ugly... (but it was WAYYYYYYYYY worse)
+ //@TODO I don't think excluding if SiteTree_ImageTracking is a good idea however because of the SS 3.0 api and ManyManyList::removeAll() changing the from table after this function is called there isn't much of a choice
- $from = $query->getFrom();
- if(isset($from['SiteTree_ImageTracking']) || $query->filtersOnID()) return;
+ $from = $query->getFrom();
+ if (isset($from['SiteTree_ImageTracking']) || $query->filtersOnID()) {
+ return;
+ }
- $subsiteID = (int) Subsite::currentSubsiteID();
+ $subsiteID = (int) Subsite::currentSubsiteID();
- // The foreach is an ugly way of getting the first key :-)
- foreach($query->getFrom() as $tableName => $info) {
- $where = "\"$tableName\".\"SubsiteID\" IN (0, $subsiteID)";
- $query->addWhere($where);
- break;
- }
+ // The foreach is an ugly way of getting the first key :-)
+ foreach ($query->getFrom() as $tableName => $info) {
+ $where = "\"$tableName\".\"SubsiteID\" IN (0, $subsiteID)";
+ $query->addWhere($where);
+ break;
+ }
- $sect=array_values($query->getSelect());
- $isCounting = strpos($sect[0], 'COUNT') !== false;
+ $sect=array_values($query->getSelect());
+ $isCounting = strpos($sect[0], 'COUNT') !== false;
- // Ordering when deleting or counting doesn't apply
- if(!$isCounting) {
- $query->addOrderBy("\"SubsiteID\"");
- }
- }
+ // Ordering when deleting or counting doesn't apply
+ if (!$isCounting) {
+ $query->addOrderBy("\"SubsiteID\"");
+ }
+ }
- function onBeforeWrite() {
- if (!$this->owner->ID && !$this->owner->SubsiteID) {
- if (self::$default_root_folders_global) {
- $this->owner->SubsiteID = 0;
- } else {
- $this->owner->SubsiteID = Subsite::currentSubsiteID();
- }
- }
- }
+ public function onBeforeWrite()
+ {
+ if (!$this->owner->ID && !$this->owner->SubsiteID) {
+ if (self::$default_root_folders_global) {
+ $this->owner->SubsiteID = 0;
+ } else {
+ $this->owner->SubsiteID = Subsite::currentSubsiteID();
+ }
+ }
+ }
- function onAfterUpload() {
- // If we have a parent, use it's subsite as our subsite
- if ($this->owner->Parent()) {
- $this->owner->SubsiteID = $this->owner->Parent()->SubsiteID;
- } else {
- $this->owner->SubsiteID = Subsite::currentSubsiteID();
- }
- $this->owner->write();
- }
+ public function onAfterUpload()
+ {
+ // If we have a parent, use it's subsite as our subsite
+ if ($this->owner->Parent()) {
+ $this->owner->SubsiteID = $this->owner->Parent()->SubsiteID;
+ } else {
+ $this->owner->SubsiteID = Subsite::currentSubsiteID();
+ }
+ $this->owner->write();
+ }
- function canEdit($member = null) {
- // Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group
- $subsiteID = Session::get('SubsiteID');
- if($subsiteID&&$subsiteID == $this->owner->SubsiteID) {
- return true;
- } else {
- Session::set('SubsiteID', $this->owner->SubsiteID);
- $access = Permission::check(array('CMS_ACCESS_AssetAdmin', 'CMS_ACCESS_LeftAndMain'));
- Session::set('SubsiteID', $subsiteID);
+ public function canEdit($member = null)
+ {
+ // Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group
+ $subsiteID = Session::get('SubsiteID');
+ if ($subsiteID&&$subsiteID == $this->owner->SubsiteID) {
+ return true;
+ } else {
+ Session::set('SubsiteID', $this->owner->SubsiteID);
+ $access = Permission::check(array('CMS_ACCESS_AssetAdmin', 'CMS_ACCESS_LeftAndMain'));
+ Session::set('SubsiteID', $subsiteID);
- return $access;
- }
- }
-
- /**
- * Return a piece of text to keep DataObject cache keys appropriately specific
- */
- function cacheKeyComponent() {
- return 'subsite-'.Subsite::currentSubsiteID();
- }
-
+ return $access;
+ }
+ }
+
+ /**
+ * Return a piece of text to keep DataObject cache keys appropriately specific
+ */
+ public function cacheKeyComponent()
+ {
+ return 'subsite-'.Subsite::currentSubsiteID();
+ }
}
-
diff --git a/code/extensions/GroupSubsites.php b/code/extensions/GroupSubsites.php
index 11f0b9d7..06558b9e 100644
--- a/code/extensions/GroupSubsites.php
+++ b/code/extensions/GroupSubsites.php
@@ -4,185 +4,192 @@
*
* @package subsites
*/
-class GroupSubsites extends DataExtension implements PermissionProvider {
-
- private static $db = array(
- 'AccessAllSubsites' => 'Boolean'
- );
-
- private static $many_many = array(
- 'Subsites' => 'Subsite'
- );
-
- private static $defaults = array(
- 'AccessAllSubsites' => true
- );
-
- /**
- * Migrations for GroupSubsites data.
- */
- function requireDefaultRecords() {
- // Migration for Group.SubsiteID data from when Groups only had a single subsite
- $groupFields = DB::field_list('Group');
-
- // Detection of SubsiteID field is the trigger for old-style-subsiteID migration
- if(isset($groupFields['SubsiteID'])) {
- // Migrate subsite-specific data
- DB::query('INSERT INTO "Group_Subsites" ("GroupID", "SubsiteID")
+class GroupSubsites extends DataExtension implements PermissionProvider
+{
+ private static $db = array(
+ 'AccessAllSubsites' => 'Boolean'
+ );
+
+ private static $many_many = array(
+ 'Subsites' => 'Subsite'
+ );
+
+ private static $defaults = array(
+ 'AccessAllSubsites' => true
+ );
+
+ /**
+ * Migrations for GroupSubsites data.
+ */
+ public function requireDefaultRecords()
+ {
+ // Migration for Group.SubsiteID data from when Groups only had a single subsite
+ $groupFields = DB::field_list('Group');
+
+ // Detection of SubsiteID field is the trigger for old-style-subsiteID migration
+ if (isset($groupFields['SubsiteID'])) {
+ // Migrate subsite-specific data
+ DB::query('INSERT INTO "Group_Subsites" ("GroupID", "SubsiteID")
SELECT "ID", "SubsiteID" FROM "Group" WHERE "SubsiteID" > 0');
-
- // Migrate global-access data
- DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1 WHERE "SubsiteID" = 0');
-
- // Move the field out of the way so that this migration doesn't get executed again
- DB::get_schema()->renameField('Group', 'SubsiteID', '_obsolete_SubsiteID');
-
- // No subsite access on anything means that we've just installed the subsites module.
- // Make all previous groups global-access groups
- } else if(!DB::query('SELECT "Group"."ID" FROM "Group"
+
+ // Migrate global-access data
+ DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1 WHERE "SubsiteID" = 0');
+
+ // Move the field out of the way so that this migration doesn't get executed again
+ DB::get_schema()->renameField('Group', 'SubsiteID', '_obsolete_SubsiteID');
+
+ // No subsite access on anything means that we've just installed the subsites module.
+ // Make all previous groups global-access groups
+ } elseif (!DB::query('SELECT "Group"."ID" FROM "Group"
LEFT JOIN "Group_Subsites" ON "Group_Subsites"."GroupID" = "Group"."ID" AND "Group_Subsites"."SubsiteID" > 0
WHERE "AccessAllSubsites" = 1
OR "Group_Subsites"."GroupID" IS NOT NULL ')->value()) {
-
- DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1');
- }
- }
-
- function updateCMSFields(FieldList $fields) {
- if($this->owner->canEdit() ){
- // i18n tab
- $fields->findOrMakeTab('Root.Subsites',_t('GroupSubsites.SECURITYTABTITLE','Subsites'));
-
- $subsites = Subsite::accessible_sites(array('ADMIN', 'SECURITY_SUBSITE_GROUP'), true);
- $subsiteMap = $subsites->map();
-
- // Prevent XSS injection
- $subsiteMap = Convert::raw2xml($subsiteMap);
-
- // Interface is different if you have the rights to modify subsite group values on
- // all subsites
- if(isset($subsiteMap[0])) {
- $fields->addFieldToTab("Root.Subsites", new OptionsetField("AccessAllSubsites",
- _t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
- array(
- 1 => _t('GroupSubsites.ACCESSALL', "All subsites"),
- 0 => _t('GroupSubsites.ACCESSONLY', "Only these subsites"),
- )
- ));
-
- unset($subsiteMap[0]);
- $fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites", "",
- $subsiteMap));
-
- } else {
- if (sizeof($subsiteMap) <= 1) {
- $fields->addFieldToTab("Root.Subsites", new ReadonlyField("SubsitesHuman",
- _t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
- reset($subsiteMap)));
- } else {
- $fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites",
- _t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
- $subsiteMap));
- }
- }
- }
- }
-
- /**
- * If this group belongs to a subsite,
- * append the subsites title to the group title
- * to make it easy to distinguish in the tree-view
- * of the security admin interface.
- */
- function alternateTreeTitle() {
- if($this->owner->AccessAllSubsites) {
- $title = _t('GroupSubsites.GlobalGroup', 'global group');
- return htmlspecialchars($this->owner->Title, ENT_QUOTES) . ' (' . $title . ')';
- } else {
- $subsites = Convert::raw2xml(implode(", ", $this->owner->Subsites()->column('Title')));
- return htmlspecialchars($this->owner->Title) . " ($subsites)";
- }
- }
-
- /**
- * Update any requests to limit the results to the current site
- */
- public function augmentSQL(SQLQuery &$query) {
- if(Subsite::$disable_subsite_filter) return;
- if(Cookie::get('noSubsiteFilter') == 'true') return;
-
- // If you're querying by ID, ignore the sub-site - this is a bit ugly...
- if(!$query->filtersOnID()) {
-
- /*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
- else */$subsiteID = (int)Subsite::currentSubsiteID();
-
- // Don't filter by Group_Subsites if we've already done that
- $hasGroupSubsites = false;
- foreach($query->getFrom() as $item) {
- if((is_array($item) && strpos($item['table'], 'Group_Subsites')!==false) || (!is_array($item) && strpos($item, 'Group_Subsites')!==false)) {
- $hasGroupSubsites = true;
- break;
- }
- }
-
- if(!$hasGroupSubsites) {
- if($subsiteID) {
- $query->addLeftJoin("Group_Subsites", "\"Group_Subsites\".\"GroupID\"
+ DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1');
+ }
+ }
+
+ public function updateCMSFields(FieldList $fields)
+ {
+ if ($this->owner->canEdit()) {
+ // i18n tab
+ $fields->findOrMakeTab('Root.Subsites', _t('GroupSubsites.SECURITYTABTITLE', 'Subsites'));
+
+ $subsites = Subsite::accessible_sites(array('ADMIN', 'SECURITY_SUBSITE_GROUP'), true);
+ $subsiteMap = $subsites->map();
+
+ // Prevent XSS injection
+ $subsiteMap = Convert::raw2xml($subsiteMap);
+
+ // Interface is different if you have the rights to modify subsite group values on
+ // all subsites
+ if (isset($subsiteMap[0])) {
+ $fields->addFieldToTab("Root.Subsites", new OptionsetField("AccessAllSubsites",
+ _t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
+ array(
+ 1 => _t('GroupSubsites.ACCESSALL', "All subsites"),
+ 0 => _t('GroupSubsites.ACCESSONLY', "Only these subsites"),
+ )
+ ));
+
+ unset($subsiteMap[0]);
+ $fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites", "",
+ $subsiteMap));
+ } else {
+ if (sizeof($subsiteMap) <= 1) {
+ $fields->addFieldToTab("Root.Subsites", new ReadonlyField("SubsitesHuman",
+ _t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
+ reset($subsiteMap)));
+ } else {
+ $fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites",
+ _t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
+ $subsiteMap));
+ }
+ }
+ }
+ }
+
+ /**
+ * If this group belongs to a subsite,
+ * append the subsites title to the group title
+ * to make it easy to distinguish in the tree-view
+ * of the security admin interface.
+ */
+ public function alternateTreeTitle()
+ {
+ if ($this->owner->AccessAllSubsites) {
+ $title = _t('GroupSubsites.GlobalGroup', 'global group');
+ return htmlspecialchars($this->owner->Title, ENT_QUOTES) . ' (' . $title . ')';
+ } else {
+ $subsites = Convert::raw2xml(implode(", ", $this->owner->Subsites()->column('Title')));
+ return htmlspecialchars($this->owner->Title) . " ($subsites)";
+ }
+ }
+
+ /**
+ * Update any requests to limit the results to the current site
+ */
+ public function augmentSQL(SQLQuery &$query)
+ {
+ if (Subsite::$disable_subsite_filter) {
+ return;
+ }
+ if (Cookie::get('noSubsiteFilter') == 'true') {
+ return;
+ }
+
+ // If you're querying by ID, ignore the sub-site - this is a bit ugly...
+ if (!$query->filtersOnID()) {
+
+ /*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
+ else */$subsiteID = (int)Subsite::currentSubsiteID();
+
+ // Don't filter by Group_Subsites if we've already done that
+ $hasGroupSubsites = false;
+ foreach ($query->getFrom() as $item) {
+ if ((is_array($item) && strpos($item['table'], 'Group_Subsites')!==false) || (!is_array($item) && strpos($item, 'Group_Subsites')!==false)) {
+ $hasGroupSubsites = true;
+ break;
+ }
+ }
+
+ if (!$hasGroupSubsites) {
+ if ($subsiteID) {
+ $query->addLeftJoin("Group_Subsites", "\"Group_Subsites\".\"GroupID\"
= \"Group\".\"ID\" AND \"Group_Subsites\".\"SubsiteID\" = $subsiteID");
- $query->addWhere("(\"Group_Subsites\".\"SubsiteID\" IS NOT NULL OR
+ $query->addWhere("(\"Group_Subsites\".\"SubsiteID\" IS NOT NULL OR
\"Group\".\"AccessAllSubsites\" = 1)");
- } else {
- $query->addWhere("\"Group\".\"AccessAllSubsites\" = 1");
- }
- }
-
- // WORKAROUND for databases that complain about an ORDER BY when the column wasn't selected (e.g. SQL Server)
- $select=$query->getSelect();
- if(isset($select[0]) && !$select[0] == 'COUNT(*)') {
- $query->orderby = "\"AccessAllSubsites\" DESC" . ($query->orderby ? ', ' : '') . $query->orderby;
- }
- }
- }
-
- function onBeforeWrite() {
- // New record test approximated by checking whether the ID has changed.
- // Note also that the after write test is only used when we're *not* on a subsite
- if($this->owner->isChanged('ID') && !Subsite::currentSubsiteID()) {
- $this->owner->AccessAllSubsites = 1;
- }
- }
-
- function onAfterWrite() {
- // New record test approximated by checking whether the ID has changed.
- // Note also that the after write test is only used when we're on a subsite
- if($this->owner->isChanged('ID') && $currentSubsiteID = Subsite::currentSubsiteID()) {
- $subsites = $this->owner->Subsites();
- $subsites->add($currentSubsiteID);
- }
- }
-
- function alternateCanEdit() {
- // Find the sites that this group belongs to and the sites where we have appropriate perm.
- $accessibleSites = Subsite::accessible_sites('CMS_ACCESS_SecurityAdmin')->column('ID');
- $linkedSites = $this->owner->Subsites()->column('ID');
+ } else {
+ $query->addWhere("\"Group\".\"AccessAllSubsites\" = 1");
+ }
+ }
+
+ // WORKAROUND for databases that complain about an ORDER BY when the column wasn't selected (e.g. SQL Server)
+ $select=$query->getSelect();
+ if (isset($select[0]) && !$select[0] == 'COUNT(*)') {
+ $query->orderby = "\"AccessAllSubsites\" DESC" . ($query->orderby ? ', ' : '') . $query->orderby;
+ }
+ }
+ }
+
+ public function onBeforeWrite()
+ {
+ // New record test approximated by checking whether the ID has changed.
+ // Note also that the after write test is only used when we're *not* on a subsite
+ if ($this->owner->isChanged('ID') && !Subsite::currentSubsiteID()) {
+ $this->owner->AccessAllSubsites = 1;
+ }
+ }
+
+ public function onAfterWrite()
+ {
+ // New record test approximated by checking whether the ID has changed.
+ // Note also that the after write test is only used when we're on a subsite
+ if ($this->owner->isChanged('ID') && $currentSubsiteID = Subsite::currentSubsiteID()) {
+ $subsites = $this->owner->Subsites();
+ $subsites->add($currentSubsiteID);
+ }
+ }
+
+ public function alternateCanEdit()
+ {
+ // Find the sites that this group belongs to and the sites where we have appropriate perm.
+ $accessibleSites = Subsite::accessible_sites('CMS_ACCESS_SecurityAdmin')->column('ID');
+ $linkedSites = $this->owner->Subsites()->column('ID');
- // We are allowed to access this site if at we have CMS_ACCESS_SecurityAdmin permission on
- // at least one of the sites
- return (bool)array_intersect($accessibleSites, $linkedSites);
- }
-
- function providePermissions() {
- return array(
- 'SECURITY_SUBSITE_GROUP' => array(
- 'name' => _t('GroupSubsites.MANAGE_SUBSITES', 'Manage subsites for groups'),
- 'category' => _t('Permissions.PERMISSIONS_CATEGORY', 'Roles and access permissions'),
- 'help' => _t('GroupSubsites.MANAGE_SUBSITES_HELP', 'Ability to limit the permissions for a group to one or more subsites.'),
- 'sort' => 200
- )
- );
- }
-
+ // We are allowed to access this site if at we have CMS_ACCESS_SecurityAdmin permission on
+ // at least one of the sites
+ return (bool)array_intersect($accessibleSites, $linkedSites);
+ }
+
+ public function providePermissions()
+ {
+ return array(
+ 'SECURITY_SUBSITE_GROUP' => array(
+ 'name' => _t('GroupSubsites.MANAGE_SUBSITES', 'Manage subsites for groups'),
+ 'category' => _t('Permissions.PERMISSIONS_CATEGORY', 'Roles and access permissions'),
+ 'help' => _t('GroupSubsites.MANAGE_SUBSITES_HELP', 'Ability to limit the permissions for a group to one or more subsites.'),
+ 'sort' => 200
+ )
+ );
+ }
}
-
-?>
diff --git a/code/extensions/LeftAndMainSubsites.php b/code/extensions/LeftAndMainSubsites.php
index ae077124..6d163144 100644
--- a/code/extensions/LeftAndMainSubsites.php
+++ b/code/extensions/LeftAndMainSubsites.php
@@ -4,303 +4,325 @@
*
* @package subsites
*/
-class LeftAndMainSubsites extends Extension {
-
- private static $allowed_actions = array('CopyToSubsite');
-
- /**
- * Normally SubsiteID=0 on a DataObject means it is only accessible from the special "main site".
- * However in some situations SubsiteID=0 will be understood as a "globally accessible" object in which
- * case this property is set to true (i.e. in AssetAdmin).
- */
- private static $treats_subsite_0_as_global = false;
-
- function init() {
- Requirements::css('subsites/css/LeftAndMain_Subsites.css');
- Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
- Requirements::javascript('subsites/javascript/VirtualPage_Subsites.js');
- }
-
- /**
- * Set the title of the CMS tree
- */
- function getCMSTreeTitle() {
- $subsite = Subsite::currentSubSite();
- return $subsite ? Convert::raw2xml($subsite->Title) : _t('LeftAndMain.SITECONTENTLEFT');
- }
-
- function updatePageOptions(&$fields) {
- $fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
- }
-
- /**
- * Find all subsites accessible for current user on this controller.
- *
- * @return ArrayList of {@link Subsite} instances.
- */
- function sectionSites($includeMainSite = true, $mainSiteTitle = "Main site", $member = null) {
- if($mainSiteTitle == 'Main site') {
- $mainSiteTitle = _t('Subsites.MainSiteTitle', 'Main site');
- }
-
- // Rationalise member arguments
- if(!$member) $member = Member::currentUser();
- if(!$member) return new ArrayList();
- if(!is_object($member)) $member = DataObject::get_by_id('Member', $member);
-
- // Collect permissions - honour the LeftAndMain::required_permission_codes, current model requires
- // us to check if the user satisfies ALL permissions. Code partly copied from LeftAndMain::canView.
- $codes = array();
- $extraCodes = Config::inst()->get($this->owner->class, 'required_permission_codes');
- if($extraCodes !== false) {
- if($extraCodes) $codes = array_merge($codes, (array)$extraCodes);
- else $codes[] = "CMS_ACCESS_{$this->owner->class}";
- } else {
- // Check overriden - all subsites accessible.
- return Subsite::all_sites();
- }
-
- // Find subsites satisfying all permissions for the Member.
- $codesPerSite = array();
- $sitesArray = array();
- foreach ($codes as $code) {
- $sites = Subsite::accessible_sites($code, $includeMainSite, $mainSiteTitle, $member);
- foreach ($sites as $site) {
- // Build the structure for checking how many codes match.
- $codesPerSite[$site->ID][$code] = true;
-
- // Retain Subsite objects for later.
- $sitesArray[$site->ID] = $site;
- }
- }
-
- // Find sites that satisfy all codes conjuncitvely.
- $accessibleSites = new ArrayList();
- foreach ($codesPerSite as $siteID => $siteCodes) {
- if (count($siteCodes)==count($codes)) {
- $accessibleSites->push($sitesArray[$siteID]);
- }
- }
-
- return $accessibleSites;
- }
-
- /*
- * Returns a list of the subsites accessible to the current user.
- * It's enough for any section to be accessible for the section to be included.
- */
- public function Subsites() {
- return Subsite::all_accessible_sites();
- }
-
- /*
- * Generates a list of subsites with the data needed to
- * produce a dropdown site switcher
- * @return ArrayList
- */
-
- public function ListSubsites(){
- $list = $this->Subsites();
- $currentSubsiteID = Subsite::currentSubsiteID();
-
- if($list == null || $list->Count() == 1 && $list->First()->DefaultSite == true){
- return false;
- }
-
- Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
-
- $output = new ArrayList();
-
- foreach($list as $subsite) {
- $CurrentState = $subsite->ID == $currentSubsiteID ? 'selected' : '';
-
- $output->push(new ArrayData(array(
- 'CurrentState' => $CurrentState,
- 'ID' => $subsite->ID,
- 'Title' => Convert::raw2xml($subsite->Title)
- )));
- }
-
- return $output;
- }
-
- public function alternateMenuDisplayCheck($controllerName) {
- if(!class_exists($controllerName)){
- return false;
- }
-
- // Check subsite support.
- if(Subsite::currentSubsiteID() == 0){
- // Main site always supports everything.
- return true;
- } else {
- $controller = singleton($controllerName);
- if($controller->hasMethod('subsiteCMSShowInMenu') && $controller->subsiteCMSShowInMenu()){
- return true;
- }
- }
-
- // It's not necessary to check access permissions here. Framework calls canView on the controller,
- // which in turn uses the Permission API which is augmented by our GroupSubsites.
-
- return false;
- }
-
- public function CanAddSubsites() {
- return Permission::check("ADMIN", "any", null, "all");
- }
-
- /**
- * Helper for testing if the subsite should be adjusted.
- */
- public function shouldChangeSubsite($adminClass, $recordSubsiteID, $currentSubsiteID) {
- if (Config::inst()->get($adminClass, 'treats_subsite_0_as_global') && $recordSubsiteID==0) return false;
- if ($recordSubsiteID!=$currentSubsiteID) return true;
- return false;
- }
-
- /**
- * Check if the current controller is accessible for this user on this subsite.
- */
- function canAccess() {
- // Admin can access everything, no point in checking.
- $member = Member::currentUser();
- if($member &&
- (
- Permission::checkMember($member, 'ADMIN') || // 'Full administrative rights' in SecurityAdmin
- Permission::checkMember($member, 'CMS_ACCESS_LeftAndMain') // 'Access to all CMS sections' in SecurityAdmin
- )) {
- return true;
- }
-
- // Check if we have access to current section on the current subsite.
- $accessibleSites = $this->owner->sectionSites(true, "Main site", $member);
- if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) {
- // Current section can be accessed on the current site, all good.
- return true;
- }
-
- return false;
- }
-
- /**
- * Prevent accessing disallowed resources. This happens after onBeforeInit has executed,
- * so all redirections should've already taken place.
- */
- public function alternateAccessCheck() {
- return $this->owner->canAccess();
- }
-
- /**
- * Redirect the user to something accessible if the current section/subsite is forbidden.
- *
- * This is done via onBeforeInit as it needs to be done before the LeftAndMain::init has a
- * chance to forbids access via alternateAccessCheck.
- *
- * If we need to change the subsite we force the redirection to /admin/ so the frontend is
- * fully re-synchronised with the internal session. This is better than risking some panels
- * showing data from another subsite.
- */
- public function onBeforeInit() {
- // We are accessing the CMS, so we need to let Subsites know we will be using the session.
- Subsite::$use_session_subsiteid = true;
-
- // FIRST, check if we need to change subsites due to the URL.
-
- // Catch forced subsite changes that need to cause CMS reloads.
- if(isset($_GET['SubsiteID'])) {
- // Clear current page when subsite changes (or is set for the first time)
- if(!Session::get('SubsiteID') || $_GET['SubsiteID'] != Session::get('SubsiteID')) {
- Session::clear("{$this->owner->class}.currentPage");
- }
-
- // Update current subsite in session
- Subsite::changeSubsite($_GET['SubsiteID']);
-
- //Redirect to clear the current page
- if ($this->owner->canView(Member::currentUser())) {
- //Redirect to clear the current page
- return $this->owner->redirect($this->owner->Link());
- }
- //Redirect to the default CMS section
- return $this->owner->redirect('admin/');
- }
-
- // Automatically redirect the session to appropriate subsite when requesting a record.
- // This is needed to properly initialise the session in situations where someone opens the CMS via a link.
- $record = $this->owner->currentPage();
- if($record && isset($record->SubsiteID) && is_numeric($record->SubsiteID) && isset($this->owner->urlParams['ID'])) {
-
- if ($this->shouldChangeSubsite($this->owner->class, $record->SubsiteID, Subsite::currentSubsiteID())) {
- // Update current subsite in session
- Subsite::changeSubsite($record->SubsiteID);
-
- if ($this->owner->canView(Member::currentUser())) {
- //Redirect to clear the current page
- return $this->owner->redirect($this->owner->Link());
- }
- //Redirect to the default CMS section
- return $this->owner->redirect('admin/');
- }
-
- }
-
- // SECOND, check if we need to change subsites due to lack of permissions.
-
- if (!$this->owner->canAccess()) {
-
- $member = Member::currentUser();
-
- // Current section is not accessible, try at least to stick to the same subsite.
- $menu = CMSMenu::get_menu_items();
- foreach($menu as $candidate) {
- if($candidate->controller && $candidate->controller!=$this->owner->class) {
-
- $accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member);
- if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) {
- // Section is accessible, redirect there.
- return $this->owner->redirect(singleton($candidate->controller)->Link());
- }
- }
- }
-
- // If no section is available, look for other accessible subsites.
- foreach($menu as $candidate) {
- if($candidate->controller) {
- $accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member);
- if ($accessibleSites->count()) {
- Subsite::changeSubsite($accessibleSites->First()->ID);
- return $this->owner->redirect(singleton($candidate->controller)->Link());
- }
- }
- }
-
- // We have not found any accessible section or subsite. User should be denied access.
- return Security::permissionFailure($this->owner);
-
- }
-
- // Current site is accessible. Allow through.
- return;
- }
-
- function augmentNewSiteTreeItem(&$item) {
- $item->SubsiteID = isset($_POST['SubsiteID']) ? $_POST['SubsiteID'] : Subsite::currentSubsiteID();
- }
-
- function onAfterSave($record) {
- if($record->hasMethod('NormalRelated') && ($record->NormalRelated() || $record->ReverseRelated())) {
- $this->owner->response->addHeader('X-Status', rawurlencode(_t('LeftAndMainSubsites.Saved', 'Saved, please update related pages.')));
- }
- }
-
- function copytosubsite($data, $form) {
- $page = DataObject::get_by_id('SiteTree', $data['ID']);
- $subsite = DataObject::get_by_id('Subsite', $data['CopyToSubsiteID']);
- $newPage = $page->duplicateToSubsite($subsite->ID, true);
- $response = $this->owner->getResponse();
- $response->addHeader('X-Reload', true);
- return $this->owner->redirect(Controller::join_links($this->owner->Link('show'), $newPage->ID));
- }
-
+class LeftAndMainSubsites extends Extension
+{
+ private static $allowed_actions = array('CopyToSubsite');
+
+ /**
+ * Normally SubsiteID=0 on a DataObject means it is only accessible from the special "main site".
+ * However in some situations SubsiteID=0 will be understood as a "globally accessible" object in which
+ * case this property is set to true (i.e. in AssetAdmin).
+ */
+ private static $treats_subsite_0_as_global = false;
+
+ public function init()
+ {
+ Requirements::css('subsites/css/LeftAndMain_Subsites.css');
+ Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
+ Requirements::javascript('subsites/javascript/VirtualPage_Subsites.js');
+ }
+
+ /**
+ * Set the title of the CMS tree
+ */
+ public function getCMSTreeTitle()
+ {
+ $subsite = Subsite::currentSubSite();
+ return $subsite ? Convert::raw2xml($subsite->Title) : _t('LeftAndMain.SITECONTENTLEFT');
+ }
+
+ public function updatePageOptions(&$fields)
+ {
+ $fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
+ }
+
+ /**
+ * Find all subsites accessible for current user on this controller.
+ *
+ * @return ArrayList of {@link Subsite} instances.
+ */
+ public function sectionSites($includeMainSite = true, $mainSiteTitle = "Main site", $member = null)
+ {
+ if ($mainSiteTitle == 'Main site') {
+ $mainSiteTitle = _t('Subsites.MainSiteTitle', 'Main site');
+ }
+
+ // Rationalise member arguments
+ if (!$member) {
+ $member = Member::currentUser();
+ }
+ if (!$member) {
+ return new ArrayList();
+ }
+ if (!is_object($member)) {
+ $member = DataObject::get_by_id('Member', $member);
+ }
+
+ // Collect permissions - honour the LeftAndMain::required_permission_codes, current model requires
+ // us to check if the user satisfies ALL permissions. Code partly copied from LeftAndMain::canView.
+ $codes = array();
+ $extraCodes = Config::inst()->get($this->owner->class, 'required_permission_codes');
+ if ($extraCodes !== false) {
+ if ($extraCodes) {
+ $codes = array_merge($codes, (array)$extraCodes);
+ } else {
+ $codes[] = "CMS_ACCESS_{$this->owner->class}";
+ }
+ } else {
+ // Check overriden - all subsites accessible.
+ return Subsite::all_sites();
+ }
+
+ // Find subsites satisfying all permissions for the Member.
+ $codesPerSite = array();
+ $sitesArray = array();
+ foreach ($codes as $code) {
+ $sites = Subsite::accessible_sites($code, $includeMainSite, $mainSiteTitle, $member);
+ foreach ($sites as $site) {
+ // Build the structure for checking how many codes match.
+ $codesPerSite[$site->ID][$code] = true;
+
+ // Retain Subsite objects for later.
+ $sitesArray[$site->ID] = $site;
+ }
+ }
+
+ // Find sites that satisfy all codes conjuncitvely.
+ $accessibleSites = new ArrayList();
+ foreach ($codesPerSite as $siteID => $siteCodes) {
+ if (count($siteCodes)==count($codes)) {
+ $accessibleSites->push($sitesArray[$siteID]);
+ }
+ }
+
+ return $accessibleSites;
+ }
+
+ /*
+ * Returns a list of the subsites accessible to the current user.
+ * It's enough for any section to be accessible for the section to be included.
+ */
+ public function Subsites()
+ {
+ return Subsite::all_accessible_sites();
+ }
+
+ /*
+ * Generates a list of subsites with the data needed to
+ * produce a dropdown site switcher
+ * @return ArrayList
+ */
+
+ public function ListSubsites()
+ {
+ $list = $this->Subsites();
+ $currentSubsiteID = Subsite::currentSubsiteID();
+
+ if ($list == null || $list->Count() == 1 && $list->First()->DefaultSite == true) {
+ return false;
+ }
+
+ Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
+
+ $output = new ArrayList();
+
+ foreach ($list as $subsite) {
+ $CurrentState = $subsite->ID == $currentSubsiteID ? 'selected' : '';
+
+ $output->push(new ArrayData(array(
+ 'CurrentState' => $CurrentState,
+ 'ID' => $subsite->ID,
+ 'Title' => Convert::raw2xml($subsite->Title)
+ )));
+ }
+
+ return $output;
+ }
+
+ public function alternateMenuDisplayCheck($controllerName)
+ {
+ if (!class_exists($controllerName)) {
+ return false;
+ }
+
+ // Check subsite support.
+ if (Subsite::currentSubsiteID() == 0) {
+ // Main site always supports everything.
+ return true;
+ } else {
+ $controller = singleton($controllerName);
+ if ($controller->hasMethod('subsiteCMSShowInMenu') && $controller->subsiteCMSShowInMenu()) {
+ return true;
+ }
+ }
+
+ // It's not necessary to check access permissions here. Framework calls canView on the controller,
+ // which in turn uses the Permission API which is augmented by our GroupSubsites.
+
+ return false;
+ }
+
+ public function CanAddSubsites()
+ {
+ return Permission::check("ADMIN", "any", null, "all");
+ }
+
+ /**
+ * Helper for testing if the subsite should be adjusted.
+ */
+ public function shouldChangeSubsite($adminClass, $recordSubsiteID, $currentSubsiteID)
+ {
+ if (Config::inst()->get($adminClass, 'treats_subsite_0_as_global') && $recordSubsiteID==0) {
+ return false;
+ }
+ if ($recordSubsiteID!=$currentSubsiteID) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check if the current controller is accessible for this user on this subsite.
+ */
+ public function canAccess()
+ {
+ // Admin can access everything, no point in checking.
+ $member = Member::currentUser();
+ if ($member &&
+ (
+ Permission::checkMember($member, 'ADMIN') || // 'Full administrative rights' in SecurityAdmin
+ Permission::checkMember($member, 'CMS_ACCESS_LeftAndMain') // 'Access to all CMS sections' in SecurityAdmin
+ )) {
+ return true;
+ }
+
+ // Check if we have access to current section on the current subsite.
+ $accessibleSites = $this->owner->sectionSites(true, "Main site", $member);
+ if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) {
+ // Current section can be accessed on the current site, all good.
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Prevent accessing disallowed resources. This happens after onBeforeInit has executed,
+ * so all redirections should've already taken place.
+ */
+ public function alternateAccessCheck()
+ {
+ return $this->owner->canAccess();
+ }
+
+ /**
+ * Redirect the user to something accessible if the current section/subsite is forbidden.
+ *
+ * This is done via onBeforeInit as it needs to be done before the LeftAndMain::init has a
+ * chance to forbids access via alternateAccessCheck.
+ *
+ * If we need to change the subsite we force the redirection to /admin/ so the frontend is
+ * fully re-synchronised with the internal session. This is better than risking some panels
+ * showing data from another subsite.
+ */
+ public function onBeforeInit()
+ {
+ // We are accessing the CMS, so we need to let Subsites know we will be using the session.
+ Subsite::$use_session_subsiteid = true;
+
+ // FIRST, check if we need to change subsites due to the URL.
+
+ // Catch forced subsite changes that need to cause CMS reloads.
+ if (isset($_GET['SubsiteID'])) {
+ // Clear current page when subsite changes (or is set for the first time)
+ if (!Session::get('SubsiteID') || $_GET['SubsiteID'] != Session::get('SubsiteID')) {
+ Session::clear("{$this->owner->class}.currentPage");
+ }
+
+ // Update current subsite in session
+ Subsite::changeSubsite($_GET['SubsiteID']);
+
+ //Redirect to clear the current page
+ if ($this->owner->canView(Member::currentUser())) {
+ //Redirect to clear the current page
+ return $this->owner->redirect($this->owner->Link());
+ }
+ //Redirect to the default CMS section
+ return $this->owner->redirect('admin/');
+ }
+
+ // Automatically redirect the session to appropriate subsite when requesting a record.
+ // This is needed to properly initialise the session in situations where someone opens the CMS via a link.
+ $record = $this->owner->currentPage();
+ if ($record && isset($record->SubsiteID) && is_numeric($record->SubsiteID) && isset($this->owner->urlParams['ID'])) {
+ if ($this->shouldChangeSubsite($this->owner->class, $record->SubsiteID, Subsite::currentSubsiteID())) {
+ // Update current subsite in session
+ Subsite::changeSubsite($record->SubsiteID);
+
+ if ($this->owner->canView(Member::currentUser())) {
+ //Redirect to clear the current page
+ return $this->owner->redirect($this->owner->Link());
+ }
+ //Redirect to the default CMS section
+ return $this->owner->redirect('admin/');
+ }
+ }
+
+ // SECOND, check if we need to change subsites due to lack of permissions.
+
+ if (!$this->owner->canAccess()) {
+ $member = Member::currentUser();
+
+ // Current section is not accessible, try at least to stick to the same subsite.
+ $menu = CMSMenu::get_menu_items();
+ foreach ($menu as $candidate) {
+ if ($candidate->controller && $candidate->controller!=$this->owner->class) {
+ $accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member);
+ if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) {
+ // Section is accessible, redirect there.
+ return $this->owner->redirect(singleton($candidate->controller)->Link());
+ }
+ }
+ }
+
+ // If no section is available, look for other accessible subsites.
+ foreach ($menu as $candidate) {
+ if ($candidate->controller) {
+ $accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member);
+ if ($accessibleSites->count()) {
+ Subsite::changeSubsite($accessibleSites->First()->ID);
+ return $this->owner->redirect(singleton($candidate->controller)->Link());
+ }
+ }
+ }
+
+ // We have not found any accessible section or subsite. User should be denied access.
+ return Security::permissionFailure($this->owner);
+ }
+
+ // Current site is accessible. Allow through.
+ return;
+ }
+
+ public function augmentNewSiteTreeItem(&$item)
+ {
+ $item->SubsiteID = isset($_POST['SubsiteID']) ? $_POST['SubsiteID'] : Subsite::currentSubsiteID();
+ }
+
+ public function onAfterSave($record)
+ {
+ if ($record->hasMethod('NormalRelated') && ($record->NormalRelated() || $record->ReverseRelated())) {
+ $this->owner->response->addHeader('X-Status', rawurlencode(_t('LeftAndMainSubsites.Saved', 'Saved, please update related pages.')));
+ }
+ }
+
+ public function copytosubsite($data, $form)
+ {
+ $page = DataObject::get_by_id('SiteTree', $data['ID']);
+ $subsite = DataObject::get_by_id('Subsite', $data['CopyToSubsiteID']);
+ $newPage = $page->duplicateToSubsite($subsite->ID, true);
+ $response = $this->owner->getResponse();
+ $response->addHeader('X-Reload', true);
+ return $this->owner->redirect(Controller::join_links($this->owner->Link('show'), $newPage->ID));
+ }
}
diff --git a/code/extensions/SiteConfigSubsites.php b/code/extensions/SiteConfigSubsites.php
index c0f66c22..ad5789bc 100644
--- a/code/extensions/SiteConfigSubsites.php
+++ b/code/extensions/SiteConfigSubsites.php
@@ -3,47 +3,61 @@
/**
* Extension for the SiteConfig object to add subsites support
*/
-class SiteConfigSubsites extends DataExtension {
-
- private static $has_one = array(
- 'Subsite' => 'Subsite', // The subsite that this page belongs to
- );
-
- /**
- * Update any requests to limit the results to the current site
- */
- public function augmentSQL(SQLQuery &$query) {
- if(Subsite::$disable_subsite_filter) return;
-
- // If you're querying by ID, ignore the sub-site - this is a bit ugly...
- if($query->filtersOnID()) return;
- $regexp = '/^(.*\.)?("|`)?SubsiteID("|`)?\s?=/';
- foreach($query->getWhereParameterised($parameters) as $predicate) {
- if(preg_match($regexp, $predicate)) return;
- }
-
- /*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
- else */$subsiteID = (int)Subsite::currentSubsiteID();
-
- $froms=$query->getFrom();
- $froms=array_keys($froms);
- $tableName = array_shift($froms);
- if($tableName != 'SiteConfig') return;
- $query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
- }
-
- function onBeforeWrite() {
- if((!is_numeric($this->owner->ID) || !$this->owner->ID) && !$this->owner->SubsiteID) $this->owner->SubsiteID = Subsite::currentSubsiteID();
- }
-
- /**
- * Return a piece of text to keep DataObject cache keys appropriately specific
- */
- function cacheKeyComponent() {
- return 'subsite-'.Subsite::currentSubsiteID();
- }
-
- function updateCMSFields(FieldList $fields) {
- $fields->push(new HiddenField('SubsiteID','SubsiteID', Subsite::currentSubsiteID()));
- }
+class SiteConfigSubsites extends DataExtension
+{
+ private static $has_one = array(
+ 'Subsite' => 'Subsite', // The subsite that this page belongs to
+ );
+
+ /**
+ * Update any requests to limit the results to the current site
+ */
+ public function augmentSQL(SQLQuery &$query)
+ {
+ if (Subsite::$disable_subsite_filter) {
+ return;
+ }
+
+ // If you're querying by ID, ignore the sub-site - this is a bit ugly...
+ if ($query->filtersOnID()) {
+ return;
+ }
+ $regexp = '/^(.*\.)?("|`)?SubsiteID("|`)?\s?=/';
+ foreach ($query->getWhereParameterised($parameters) as $predicate) {
+ if (preg_match($regexp, $predicate)) {
+ return;
+ }
+ }
+
+ /*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
+ else */$subsiteID = (int)Subsite::currentSubsiteID();
+
+ $froms=$query->getFrom();
+ $froms=array_keys($froms);
+ $tableName = array_shift($froms);
+ if ($tableName != 'SiteConfig') {
+ return;
+ }
+ $query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
+ }
+
+ public function onBeforeWrite()
+ {
+ if ((!is_numeric($this->owner->ID) || !$this->owner->ID) && !$this->owner->SubsiteID) {
+ $this->owner->SubsiteID = Subsite::currentSubsiteID();
+ }
+ }
+
+ /**
+ * Return a piece of text to keep DataObject cache keys appropriately specific
+ */
+ public function cacheKeyComponent()
+ {
+ return 'subsite-'.Subsite::currentSubsiteID();
+ }
+
+ public function updateCMSFields(FieldList $fields)
+ {
+ $fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
+ }
}
diff --git a/code/extensions/SiteTreeSubsites.php b/code/extensions/SiteTreeSubsites.php
index 2a82701f..540f6656 100644
--- a/code/extensions/SiteTreeSubsites.php
+++ b/code/extensions/SiteTreeSubsites.php
@@ -3,297 +3,346 @@
/**
* Extension for the SiteTree object to add subsites support
*/
-class SiteTreeSubsites extends DataExtension {
+class SiteTreeSubsites extends DataExtension
+{
+ private static $has_one = array(
+ 'Subsite' => 'Subsite', // The subsite that this page belongs to
+ );
- private static $has_one = array(
- 'Subsite' => 'Subsite', // The subsite that this page belongs to
- );
+ private static $many_many = array(
+ 'CrossSubsiteLinkTracking' => 'SiteTree' // Stored separately, as the logic for URL rewriting is different
+ );
- private static $many_many = array(
- 'CrossSubsiteLinkTracking' => 'SiteTree' // Stored separately, as the logic for URL rewriting is different
- );
+ private static $many_many_extraFields = array(
+ "CrossSubsiteLinkTracking" => array("FieldName" => "Varchar")
+ );
- private static $many_many_extraFields = array(
- "CrossSubsiteLinkTracking" => array("FieldName" => "Varchar")
- );
+ public function isMainSite()
+ {
+ if ($this->owner->SubsiteID == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Update any requests to limit the results to the current site
+ */
+ public function augmentSQL(SQLQuery &$query, DataQuery &$dataQuery = null)
+ {
+ if (Subsite::$disable_subsite_filter) {
+ return;
+ }
+ if ($dataQuery->getQueryParam('Subsite.filter') === false) {
+ return;
+ }
+
+ // If you're querying by ID, ignore the sub-site - this is a bit ugly...
+ // if(!$query->where || (strpos($query->where[0], ".\"ID\" = ") === false && strpos($query->where[0], ".`ID` = ") === false && strpos($query->where[0], ".ID = ") === false && strpos($query->where[0], "ID = ") !== 0)) {
+ if ($query->filtersOnID()) {
+ return;
+ }
- function isMainSite() {
- if($this->owner->SubsiteID == 0) return true;
- return false;
- }
-
- /**
- * Update any requests to limit the results to the current site
- */
- public function augmentSQL(SQLQuery &$query, DataQuery &$dataQuery = null) {
- if(Subsite::$disable_subsite_filter) return;
- if($dataQuery->getQueryParam('Subsite.filter') === false) return;
-
- // If you're querying by ID, ignore the sub-site - this is a bit ugly...
- // if(!$query->where || (strpos($query->where[0], ".\"ID\" = ") === false && strpos($query->where[0], ".`ID` = ") === false && strpos($query->where[0], ".ID = ") === false && strpos($query->where[0], "ID = ") !== 0)) {
- if($query->filtersOnID()) return;
+ if (Subsite::$force_subsite) {
+ $subsiteID = Subsite::$force_subsite;
+ } else {
+ /*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
+ else */$subsiteID = (int)Subsite::currentSubsiteID();
+ }
- if (Subsite::$force_subsite) $subsiteID = Subsite::$force_subsite;
- else {
- /*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
- else */$subsiteID = (int)Subsite::currentSubsiteID();
- }
+ // The foreach is an ugly way of getting the first key :-)
+ foreach ($query->getFrom() as $tableName => $info) {
+ // The tableName should be SiteTree or SiteTree_Live...
+ if (strpos($tableName, 'SiteTree') === false) {
+ break;
+ }
+ $query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
+ break;
+ }
+ }
+
+ public function onBeforeWrite()
+ {
+ if (!$this->owner->ID && !$this->owner->SubsiteID) {
+ $this->owner->SubsiteID = Subsite::currentSubsiteID();
+ }
+
+ parent::onBeforeWrite();
+ }
- // The foreach is an ugly way of getting the first key :-)
- foreach($query->getFrom() as $tableName => $info) {
- // The tableName should be SiteTree or SiteTree_Live...
- if(strpos($tableName,'SiteTree') === false) break;
- $query->addWhere("\"$tableName\".\"SubsiteID\" IN ($subsiteID)");
- break;
- }
- }
-
- function onBeforeWrite() {
- if(!$this->owner->ID && !$this->owner->SubsiteID) $this->owner->SubsiteID = Subsite::currentSubsiteID();
-
- parent::onBeforeWrite();
- }
+ public function updateCMSFields(FieldList $fields)
+ {
+ $subsites = Subsite::accessible_sites("CMS_ACCESS_CMSMain");
+ $subsitesMap = array();
+ if ($subsites && $subsites->Count()) {
+ $subsitesMap = $subsites->map('ID', 'Title');
+ unset($subsitesMap[$this->owner->SubsiteID]);
+ }
- function updateCMSFields(FieldList $fields) {
- $subsites = Subsite::accessible_sites("CMS_ACCESS_CMSMain");
- $subsitesMap = array();
- if($subsites && $subsites->Count()) {
- $subsitesMap = $subsites->map('ID', 'Title');
- unset($subsitesMap[$this->owner->SubsiteID]);
- }
+ // Master page edit field (only allowed from default subsite to avoid inconsistent relationships)
+ $isDefaultSubsite = $this->owner->SubsiteID == 0 || $this->owner->Subsite()->DefaultSite;
+ if ($isDefaultSubsite && $subsitesMap) {
+ $fields->addFieldToTab(
+ 'Root.Main',
+ new DropdownField(
+ "CopyToSubsiteID",
+ _t('SiteTreeSubsites.CopyToSubsite', "Copy page to subsite"),
+ $subsitesMap,
+ ''
+ )
+ );
+ $fields->addFieldToTab(
+ 'Root.Main',
+ $copyAction = new InlineFormAction(
+ "copytosubsite",
+ _t('SiteTreeSubsites.CopyAction', "Copy")
+ )
+ );
+ $copyAction->includeDefaultJS(false);
+ }
- // Master page edit field (only allowed from default subsite to avoid inconsistent relationships)
- $isDefaultSubsite = $this->owner->SubsiteID == 0 || $this->owner->Subsite()->DefaultSite;
- if($isDefaultSubsite && $subsitesMap) {
- $fields->addFieldToTab(
- 'Root.Main',
- new DropdownField(
- "CopyToSubsiteID",
- _t('SiteTreeSubsites.CopyToSubsite', "Copy page to subsite"),
- $subsitesMap,
- ''
- )
- );
- $fields->addFieldToTab(
- 'Root.Main',
- $copyAction = new InlineFormAction(
- "copytosubsite",
- _t('SiteTreeSubsites.CopyAction', "Copy")
- )
- );
- $copyAction->includeDefaultJS(false);
- }
+ // replace readonly link prefix
+ $subsite = $this->owner->Subsite();
+ $nested_urls_enabled = Config::inst()->get('SiteTree', 'nested_urls');
+ if ($subsite && $subsite->ID) {
+ $baseUrl = Director::protocol() . $subsite->domain() . '/';
+ $baseLink = Controller::join_links(
+ $baseUrl,
+ ($nested_urls_enabled && $this->owner->ParentID ? $this->owner->Parent()->RelativeLink(true) : null)
+ );
+
+ $urlsegment = $fields->dataFieldByName('URLSegment');
+ $urlsegment->setURLPrefix($baseLink);
+ }
+ }
+
+ public function alternateSiteConfig()
+ {
+ if (!$this->owner->SubsiteID) {
+ return false;
+ }
+ $sc = DataObject::get_one('SiteConfig', '"SubsiteID" = ' . $this->owner->SubsiteID);
+ if (!$sc) {
+ $sc = new SiteConfig();
+ $sc->SubsiteID = $this->owner->SubsiteID;
+ $sc->Title = _t('Subsite.SiteConfigTitle', 'Your Site Name');
+ $sc->Tagline = _t('Subsite.SiteConfigSubtitle', 'Your tagline here');
+ $sc->write();
+ }
+ return $sc;
+ }
+
+ /**
+ * Only allow editing of a page if the member satisfies one of the following conditions:
+ * - Is in a group which has access to the subsite this page belongs to
+ * - Is in a group with edit permissions on the "main site"
+ *
+ * @return boolean
+ */
+ public function canEdit($member = null)
+ {
+ if (!$member) {
+ $member = Member::currentUser();
+ }
+
+ // Find the sites that this user has access to
+ $goodSites = Subsite::accessible_sites('CMS_ACCESS_CMSMain', true, 'all', $member)->column('ID');
- // replace readonly link prefix
- $subsite = $this->owner->Subsite();
- $nested_urls_enabled = Config::inst()->get('SiteTree', 'nested_urls');
- if($subsite && $subsite->ID) {
- $baseUrl = Director::protocol() . $subsite->domain() . '/';
- $baseLink = Controller::join_links (
- $baseUrl,
- ($nested_urls_enabled && $this->owner->ParentID ? $this->owner->Parent()->RelativeLink(true) : null)
- );
-
- $urlsegment = $fields->dataFieldByName('URLSegment');
- $urlsegment->setURLPrefix($baseLink);
- }
- }
-
- function alternateSiteConfig() {
- if(!$this->owner->SubsiteID) return false;
- $sc = DataObject::get_one('SiteConfig', '"SubsiteID" = ' . $this->owner->SubsiteID);
- if(!$sc) {
- $sc = new SiteConfig();
- $sc->SubsiteID = $this->owner->SubsiteID;
- $sc->Title = _t('Subsite.SiteConfigTitle','Your Site Name');
- $sc->Tagline = _t('Subsite.SiteConfigSubtitle','Your tagline here');
- $sc->write();
- }
- return $sc;
- }
-
- /**
- * Only allow editing of a page if the member satisfies one of the following conditions:
- * - Is in a group which has access to the subsite this page belongs to
- * - Is in a group with edit permissions on the "main site"
- *
- * @return boolean
- */
- function canEdit($member = null) {
+ if (!is_null($this->owner->SubsiteID)) {
+ $subsiteID = $this->owner->SubsiteID;
+ } else {
+ // The relationships might not be available during the record creation when using a GridField.
+ // In this case the related objects will have empty fields, and SubsiteID will not be available.
+ //
+ // We do the second best: fetch the likely SubsiteID from the session. The drawback is this might
+ // make it possible to force relations to point to other (forbidden) subsites.
+ $subsiteID = Subsite::currentSubsiteID();
+ }
- if(!$member) $member = Member::currentUser();
-
- // Find the sites that this user has access to
- $goodSites = Subsite::accessible_sites('CMS_ACCESS_CMSMain',true,'all',$member)->column('ID');
+ // Return true if they have access to this object's site
+ if (!(in_array(0, $goodSites) || in_array($subsiteID, $goodSites))) {
+ return false;
+ }
+ }
+
+ /**
+ * @return boolean
+ */
+ public function canDelete($member = null)
+ {
+ if (!$member && $member !== false) {
+ $member = Member::currentUser();
+ }
+
+ return $this->canEdit($member);
+ }
+
+ /**
+ * @return boolean
+ */
+ public function canAddChildren($member = null)
+ {
+ if (!$member && $member !== false) {
+ $member = Member::currentUser();
+ }
+
+ return $this->canEdit($member);
+ }
+
+ /**
+ * @return boolean
+ */
+ public function canPublish($member = null)
+ {
+ if (!$member && $member !== false) {
+ $member = Member::currentUser();
+ }
- if (!is_null($this->owner->SubsiteID)) {
- $subsiteID = $this->owner->SubsiteID;
- } else {
- // The relationships might not be available during the record creation when using a GridField.
- // In this case the related objects will have empty fields, and SubsiteID will not be available.
- //
- // We do the second best: fetch the likely SubsiteID from the session. The drawback is this might
- // make it possible to force relations to point to other (forbidden) subsites.
- $subsiteID = Subsite::currentSubsiteID();
- }
+ return $this->canEdit($member);
+ }
- // Return true if they have access to this object's site
- if(!(in_array(0, $goodSites) || in_array($subsiteID, $goodSites))) return false;
- }
-
- /**
- * @return boolean
- */
- function canDelete($member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
-
- return $this->canEdit($member);
- }
-
- /**
- * @return boolean
- */
- function canAddChildren($member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
-
- return $this->canEdit($member);
- }
-
- /**
- * @return boolean
- */
- function canPublish($member = null) {
- if(!$member && $member !== FALSE) $member = Member::currentUser();
+ /**
+ * Create a duplicate of this page and save it to another subsite
+ * @param $subsiteID int|Subsite The Subsite to copy to, or its ID
+ */
+ public function duplicateToSubsite($subsiteID = null)
+ {
+ if (is_object($subsiteID)) {
+ $subsite = $subsiteID;
+ $subsiteID = $subsite->ID;
+ } else {
+ $subsite = DataObject::get_by_id('Subsite', $subsiteID);
+ }
+
+ $oldSubsite=Subsite::currentSubsiteID();
+ if ($subsiteID) {
+ Subsite::changeSubsite($subsiteID);
+ } else {
+ $subsiteID=$oldSubsite;
+ }
- return $this->canEdit($member);
- }
+ $page = $this->owner->duplicate(false);
- /**
- * Create a duplicate of this page and save it to another subsite
- * @param $subsiteID int|Subsite The Subsite to copy to, or its ID
- */
- public function duplicateToSubsite($subsiteID = null) {
- if(is_object($subsiteID)) {
- $subsite = $subsiteID;
- $subsiteID = $subsite->ID;
- } else $subsite = DataObject::get_by_id('Subsite', $subsiteID);
-
- $oldSubsite=Subsite::currentSubsiteID();
- if($subsiteID) {
- Subsite::changeSubsite($subsiteID);
- }else {
- $subsiteID=$oldSubsite;
- }
+ $page->CheckedPublicationDifferences = $page->AddedToStage = true;
+ $subsiteID = ($subsiteID ? $subsiteID : $oldSubsite);
+ $page->SubsiteID = $subsiteID;
- $page = $this->owner->duplicate(false);
+ // MasterPageID is here for legacy purposes, to satisfy the subsites_relatedpages module
+ $page->MasterPageID = $this->owner->ID;
+ $page->write();
- $page->CheckedPublicationDifferences = $page->AddedToStage = true;
- $subsiteID = ($subsiteID ? $subsiteID : $oldSubsite);
- $page->SubsiteID = $subsiteID;
+ Subsite::changeSubsite($oldSubsite);
- // MasterPageID is here for legacy purposes, to satisfy the subsites_relatedpages module
- $page->MasterPageID = $this->owner->ID;
- $page->write();
+ return $page;
+ }
- Subsite::changeSubsite($oldSubsite);
+ /**
+ * Called by ContentController::init();
+ */
+ public static function contentcontrollerInit($controller)
+ {
+ $subsite = Subsite::currentSubsite();
- return $page;
- }
+ if ($subsite && $subsite->Theme) {
+ Config::inst()->update('SSViewer', 'theme', Subsite::currentSubsite()->Theme);
+ }
+ }
- /**
- * Called by ContentController::init();
- */
- static function contentcontrollerInit($controller) {
- $subsite = Subsite::currentSubsite();
+ public function alternateAbsoluteLink()
+ {
+ // Generate the existing absolute URL and replace the domain with the subsite domain.
+ // This helps deal with Link() returning an absolute URL.
+ $url = Director::absoluteURL($this->owner->Link());
+ if ($this->owner->SubsiteID) {
+ $url = preg_replace('/\/\/[^\/]+\//', '//' . $this->owner->Subsite()->domain() . '/', $url);
+ }
+ return $url;
+ }
- if($subsite && $subsite->Theme){
- Config::inst()->update('SSViewer', 'theme', Subsite::currentSubsite()->Theme);
- }
- }
+ /**
+ * Use the CMS domain for iframed CMS previews to prevent single-origin violations
+ * and SSL cert problems.
+ */
+ public function alternatePreviewLink($action = null)
+ {
+ $url = Director::absoluteURL($this->owner->Link());
+ if ($this->owner->SubsiteID) {
+ $url = HTTP::setGetVar('SubsiteID', $this->owner->SubsiteID, $url);
+ }
+ return $url;
+ }
- function alternateAbsoluteLink() {
- // Generate the existing absolute URL and replace the domain with the subsite domain.
- // This helps deal with Link() returning an absolute URL.
- $url = Director::absoluteURL($this->owner->Link());
- if($this->owner->SubsiteID) {
- $url = preg_replace('/\/\/[^\/]+\//', '//' . $this->owner->Subsite()->domain() . '/', $url);
- }
- return $url;
- }
+ /**
+ * Inject the subsite ID into the content so it can be used by frontend scripts.
+ */
+ public function MetaTags(&$tags)
+ {
+ if ($this->owner->SubsiteID) {
+ $tags .= "owner->SubsiteID . "\" />\n";
+ }
- /**
- * Use the CMS domain for iframed CMS previews to prevent single-origin violations
- * and SSL cert problems.
- */
- function alternatePreviewLink($action = null) {
- $url = Director::absoluteURL($this->owner->Link());
- if($this->owner->SubsiteID) {
- $url = HTTP::setGetVar('SubsiteID', $this->owner->SubsiteID, $url);
- }
- return $url;
- }
+ return $tags;
+ }
- /**
- * Inject the subsite ID into the content so it can be used by frontend scripts.
- */
- function MetaTags(&$tags) {
- if($this->owner->SubsiteID) {
- $tags .= "owner->SubsiteID . "\" />\n";
- }
+ public function augmentSyncLinkTracking()
+ {
+ // Set LinkTracking appropriately
+ $links = HTTP::getLinksIn($this->owner->Content);
+ $linkedPages = array();
+
+ if ($links) {
+ foreach ($links as $link) {
+ if (substr($link, 0, strlen('http://')) == 'http://') {
+ $withoutHttp = substr($link, strlen('http://'));
+ if (strpos($withoutHttp, '/') && strpos($withoutHttp, '/') < strlen($withoutHttp)) {
+ $domain = substr($withoutHttp, 0, strpos($withoutHttp, '/'));
+ $rest = substr($withoutHttp, strpos($withoutHttp, '/') + 1);
+
+ $subsiteID = Subsite::getSubsiteIDForDomain($domain);
+ if ($subsiteID == 0) {
+ continue;
+ } // We have no idea what the domain for the main site is, so cant track links to it
- return $tags;
- }
-
- function augmentSyncLinkTracking() {
- // Set LinkTracking appropriately
- $links = HTTP::getLinksIn($this->owner->Content);
- $linkedPages = array();
-
- if($links) foreach($links as $link) {
- if(substr($link, 0, strlen('http://')) == 'http://') {
- $withoutHttp = substr($link, strlen('http://'));
- if(strpos($withoutHttp, '/') && strpos($withoutHttp, '/') < strlen($withoutHttp)) {
- $domain = substr($withoutHttp, 0, strpos($withoutHttp, '/'));
- $rest = substr($withoutHttp, strpos($withoutHttp, '/') + 1);
-
- $subsiteID = Subsite::getSubsiteIDForDomain($domain);
- if($subsiteID == 0) continue; // We have no idea what the domain for the main site is, so cant track links to it
-
- $origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
- Subsite::disable_subsite_filter(true);
- $candidatePage = DataObject::get_one("SiteTree", "\"URLSegment\" = '" . Convert::raw2sql(urldecode( $rest)) . "' AND \"SubsiteID\" = " . $subsiteID, false);
- Subsite::disable_subsite_filter($origDisableSubsiteFilter);
-
- if($candidatePage) {
- $linkedPages[] = $candidatePage->ID;
- } else {
- $this->owner->HasBrokenLink = true;
- }
- }
- }
- }
-
- $this->owner->CrossSubsiteLinkTracking()->setByIDList($linkedPages);
- }
-
- /**
- * Return a piece of text to keep DataObject cache keys appropriately specific
- */
- function cacheKeyComponent() {
- return 'subsite-'.Subsite::currentSubsiteID();
- }
-
- /**
- * @param Member
- * @return boolean|null
- */
- function canCreate($member = null) {
- // Typically called on a singleton, so we're not using the Subsite() relation
- $subsite = Subsite::currentSubsite();
- if($subsite && $subsite->exists() && $subsite->PageTypeBlacklist) {
- $blacklisted = explode(',', $subsite->PageTypeBlacklist);
- // All subclasses need to be listed explicitly
- if(in_array($this->owner->class, $blacklisted)) return false;
- }
- }
+ $origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
+ Subsite::disable_subsite_filter(true);
+ $candidatePage = DataObject::get_one("SiteTree", "\"URLSegment\" = '" . Convert::raw2sql(urldecode($rest)) . "' AND \"SubsiteID\" = " . $subsiteID, false);
+ Subsite::disable_subsite_filter($origDisableSubsiteFilter);
+
+ if ($candidatePage) {
+ $linkedPages[] = $candidatePage->ID;
+ } else {
+ $this->owner->HasBrokenLink = true;
+ }
+ }
+ }
+ }
+ }
+
+ $this->owner->CrossSubsiteLinkTracking()->setByIDList($linkedPages);
+ }
+
+ /**
+ * Return a piece of text to keep DataObject cache keys appropriately specific
+ */
+ public function cacheKeyComponent()
+ {
+ return 'subsite-'.Subsite::currentSubsiteID();
+ }
+
+ /**
+ * @param Member
+ * @return boolean|null
+ */
+ public function canCreate($member = null)
+ {
+ // Typically called on a singleton, so we're not using the Subsite() relation
+ $subsite = Subsite::currentSubsite();
+ if ($subsite && $subsite->exists() && $subsite->PageTypeBlacklist) {
+ $blacklisted = explode(',', $subsite->PageTypeBlacklist);
+ // All subclasses need to be listed explicitly
+ if (in_array($this->owner->class, $blacklisted)) {
+ return false;
+ }
+ }
+ }
}
diff --git a/code/extensions/SubsiteMenuExtension.php b/code/extensions/SubsiteMenuExtension.php
index aab9af28..a4811d78 100644
--- a/code/extensions/SubsiteMenuExtension.php
+++ b/code/extensions/SubsiteMenuExtension.php
@@ -10,10 +10,10 @@
* Or you can include the subsiteCMSShowInMenu function in your admin class and have it return true
*/
-class SubsiteMenuExtension extends Extension{
-
- public function subsiteCMSShowInMenu(){
- return true;
- }
-
+class SubsiteMenuExtension extends Extension
+{
+ public function subsiteCMSShowInMenu()
+ {
+ return true;
+ }
}
diff --git a/code/forms/GridFieldSubsiteDetailForm.php b/code/forms/GridFieldSubsiteDetailForm.php
index fee6244c..ae509717 100644
--- a/code/forms/GridFieldSubsiteDetailForm.php
+++ b/code/forms/GridFieldSubsiteDetailForm.php
@@ -1,52 +1,55 @@
record->ID == 0) {
+ $templates = Subsite::get()->sort('Title');
+ $templateArray = array();
+ if ($templates) {
+ $templateArray = $templates->map('ID', 'Title');
+ }
- /**
- * Builds an item edit form. The arguments to getCMSFields() are the popupController and
- * popupFormName, however this is an experimental API and may change.
- *
- * @todo In the future, we will probably need to come up with a tigher object representing a partially
- * complete controller with gaps for extra functionality. This, for example, would be a better way
- * of letting Security/login put its log-in form inside a UI specified elsewhere.
- *
- * @return Form
- * @see GridFieldDetailForm_ItemRequest::ItemEditForm()
- */
- function ItemEditForm() {
- $form=parent::ItemEditForm();
-
- if($this->record->ID == 0) {
- $templates = Subsite::get()->sort('Title');
- $templateArray = array();
- if($templates) {
- $templateArray = $templates->map('ID', 'Title');
- }
+ $templateDropdown = new DropdownField('TemplateID', _t('Subsite.COPYSTRUCTURE', 'Copy structure from:'), $templateArray);
+ $templateDropdown->setEmptyString('(' . _t('Subsite.NOTEMPLATE', 'No template') . ')');
+ $form->Fields()->addFieldToTab('Root.Configuration', $templateDropdown);
+ }
+
+ return $form;
+ }
+
+ public function doSave($data, $form)
+ {
+ $new_record = $this->record->ID == 0;
+ if ($new_record && isset($data['TemplateID']) && !empty($data['TemplateID'])) {
+ $template = Subsite::get()->byID(intval($data['TemplateID']));
+ if ($template) {
+ $this->record = $template->duplicate();
+ }
+ }
- $templateDropdown = new DropdownField('TemplateID', _t('Subsite.COPYSTRUCTURE', 'Copy structure from:'), $templateArray);
- $templateDropdown->setEmptyString('(' . _t('Subsite.NOTEMPLATE', 'No template') . ')');
- $form->Fields()->addFieldToTab('Root.Configuration', $templateDropdown);
- }
-
- return $form;
- }
-
- function doSave($data, $form) {
- $new_record = $this->record->ID == 0;
- if($new_record && isset($data['TemplateID']) && !empty($data['TemplateID'])) {
- $template = Subsite::get()->byID(intval($data['TemplateID']));
- if($template) {
- $this->record = $template->duplicate();
- }
- }
-
- return parent::doSave($data, $form);
- }
+ return parent::doSave($data, $form);
+ }
}
diff --git a/code/forms/SubsitesTreeDropdownField.php b/code/forms/SubsitesTreeDropdownField.php
index 85847730..513c27c3 100644
--- a/code/forms/SubsitesTreeDropdownField.php
+++ b/code/forms/SubsitesTreeDropdownField.php
@@ -5,40 +5,44 @@
*
* @package subsites
*/
-class SubsitesTreeDropdownField extends TreeDropdownField {
-
- private static $allowed_actions = array(
- 'tree'
- );
-
- protected $subsiteID = 0;
-
- protected $extraClasses = array('SubsitesTreeDropdownField');
-
- function Field($properties = array()) {
- $html = parent::Field($properties);
-
- Requirements::javascript('subsites/javascript/SubsitesTreeDropdownField.js');
-
- return $html;
- }
-
- function setSubsiteID($id) {
- $this->subsiteID = $id;
- }
-
- function getSubsiteID() {
- return $this->subsiteID;
- }
-
- function tree(SS_HTTPRequest $request) {
- $oldSubsiteID = Session::get('SubsiteID');
- Session::set('SubsiteID', $this->subsiteID);
-
- $results = parent::tree($request);
-
- Session::set('SubsiteID', $oldSubsiteID);
-
- return $results;
- }
-}
\ No newline at end of file
+class SubsitesTreeDropdownField extends TreeDropdownField
+{
+ private static $allowed_actions = array(
+ 'tree'
+ );
+
+ protected $subsiteID = 0;
+
+ protected $extraClasses = array('SubsitesTreeDropdownField');
+
+ public function Field($properties = array())
+ {
+ $html = parent::Field($properties);
+
+ Requirements::javascript('subsites/javascript/SubsitesTreeDropdownField.js');
+
+ return $html;
+ }
+
+ public function setSubsiteID($id)
+ {
+ $this->subsiteID = $id;
+ }
+
+ public function getSubsiteID()
+ {
+ return $this->subsiteID;
+ }
+
+ public function tree(SS_HTTPRequest $request)
+ {
+ $oldSubsiteID = Session::get('SubsiteID');
+ Session::set('SubsiteID', $this->subsiteID);
+
+ $results = parent::tree($request);
+
+ Session::set('SubsiteID', $oldSubsiteID);
+
+ return $results;
+ }
+}
diff --git a/code/model/Subsite.php b/code/model/Subsite.php
index e5f81827..01574c1c 100644
--- a/code/model/Subsite.php
+++ b/code/model/Subsite.php
@@ -5,421 +5,485 @@
*
* @package subsites
*/
-class Subsite extends DataObject {
-
- /**
- * @var $use_session_subsiteid Boolean Set to TRUE when using the CMS and FALSE
- * when browsing the frontend of a website.
- *
- * @todo Remove flag once the Subsite CMS works without session state,
- * similarly to the Translatable module.
- */
- public static $use_session_subsiteid = false;
-
- /**
- * @var boolean $disable_subsite_filter If enabled, bypasses the query decoration
- * to limit DataObject::get*() calls to a specific subsite. Useful for debugging.
- */
- public static $disable_subsite_filter = false;
-
- /**
- * Allows you to force a specific subsite ID, or comma separated list of IDs.
- * Only works for reading. An object cannot be written to more than 1 subsite.
- */
- public static $force_subsite = null;
-
- /**
- *
- * @var boolean
- */
- public static $write_hostmap = true;
-
- /**
- * Memory cache of accessible sites
- *
- * @array
- */
- private static $_cache_accessible_sites = array();
-
- /**
- * Memory cache of subsite id for domains
- *
- * @var array
- */
- private static $_cache_subsite_for_domain = array();
-
- /**
- * @var array $allowed_themes Numeric array of all themes which are allowed to be selected for all subsites.
- * Corresponds to subfolder names within the /themes folder. By default, all themes contained in this folder
- * are listed.
- */
- private static $allowed_themes = array();
-
- /**
- * @var Boolean If set to TRUE, don't assume 'www.example.com' and 'example.com' are the same.
- * Doesn't affect wildcard matching, so '*.example.com' will match 'www.example.com' (but not 'example.com')
- * in both TRUE or FALSE setting.
- */
- public static $strict_subdomain_matching = false;
-
- /**
- * @var boolean Respects the IsPublic flag when retrieving subsites
- */
- public static $check_is_public = true;
-
- /**
- * Set allowed themes
- *
- * @param array $themes - Numeric array of all themes which are allowed to be selected for all subsites.
- */
- public static function set_allowed_themes($themes) {
- self::$allowed_themes = $themes;
- }
-
- /**
- * Gets the subsite currently set in the session.
- *
- * @uses ControllerSubsites->controllerAugmentInit()
- * @return Subsite
- */
- public static function currentSubsite() {
- // get_by_id handles caching so we don't have to
- return DataObject::get_by_id('Subsite', self::currentSubsiteID());
- }
-
- /**
- * This function gets the current subsite ID from the session. It used in the backend so Ajax requests
- * use the correct subsite. The frontend handles subsites differently. It calls getSubsiteIDForDomain
- * directly from ModelAsController::getNestedController. Only gets Subsite instances which have their
- * {@link IsPublic} flag set to TRUE.
- *
- * You can simulate subsite access without creating virtual hosts by appending ?SubsiteID= to the request.
- *
- * @todo Pass $request object from controller so we don't have to rely on $_GET
- *
- * @param boolean $cache
- * @return int ID of the current subsite instance
- */
- public static function currentSubsiteID() {
- $id = NULL;
-
- if(isset($_GET['SubsiteID'])) {
- $id = (int)$_GET['SubsiteID'];
- } else if (Subsite::$use_session_subsiteid) {
- $id = Session::get('SubsiteID');
- }
-
- if($id === NULL) {
- $id = self::getSubsiteIDForDomain();
- }
-
- return (int)$id;
- }
-
- /**
- * Switch to another subsite through storing the subsite identifier in the current PHP session.
- * Only takes effect when {@link Subsite::$use_session_subsiteid} is set to TRUE.
- *
- * @param int|Subsite $subsite Either the ID of the subsite, or the subsite object itself
- */
- public static function changeSubsite($subsite) {
- // Session subsite change only meaningful if the session is active.
- // Otherwise we risk setting it to wrong value, e.g. if we rely on currentSubsiteID.
- if (!Subsite::$use_session_subsiteid) return;
-
- if(is_object($subsite)) $subsiteID = $subsite->ID;
- else $subsiteID = $subsite;
-
- Session::set('SubsiteID', (int)$subsiteID);
-
- // Set locale
- if (is_object($subsite) && $subsite->Language != '') {
- $locale = i18n::get_locale_from_lang($subsite->Language);
- if($locale) {
- i18n::set_locale($locale);
- }
- }
-
- Permission::flush_permission_cache();
- }
-
- /**
- * Get a matching subsite for the given host, or for the current HTTP_HOST.
- * Supports "fuzzy" matching of domains by placing an asterisk at the start of end of the string,
- * for example matching all subdomains on *.example.com with one subsite,
- * and all subdomains on *.example.org on another.
- *
- * @param $host The host to find the subsite for. If not specified, $_SERVER['HTTP_HOST'] is used.
- * @return int Subsite ID
- */
- public static function getSubsiteIDForDomain($host = null, $checkPermissions = true) {
- if($host == null && isset($_SERVER['HTTP_HOST'])) {
- $host = $_SERVER['HTTP_HOST'];
- }
-
- $matchingDomains = null;
- $cacheKey = null;
- if ($host) {
- if(!self::$strict_subdomain_matching) $host = preg_replace('/^www\./', '', $host);
-
- $cacheKey = implode('_', array($host, Member::currentUserID(), self::$check_is_public));
- if(isset(self::$_cache_subsite_for_domain[$cacheKey])) return self::$_cache_subsite_for_domain[$cacheKey];
-
- $SQL_host = Convert::raw2sql($host);
- $matchingDomains = DataObject::get(
- "SubsiteDomain",
- "'$SQL_host' LIKE replace(\"SubsiteDomain\".\"Domain\",'*','%')",
- "\"IsPrimary\" DESC"
- )->innerJoin('Subsite', "\"Subsite\".\"ID\" = \"SubsiteDomain\".\"SubsiteID\" AND \"Subsite\".\"IsPublic\"=1");
- }
-
- if($matchingDomains && $matchingDomains->Count()) {
- $subsiteIDs = array_unique($matchingDomains->column('SubsiteID'));
- $subsiteDomains = array_unique($matchingDomains->column('Domain'));
- if(sizeof($subsiteIDs) > 1) {
- throw new UnexpectedValueException(sprintf(
- "Multiple subsites match on '%s': %s",
- $host,
- implode(',', $subsiteDomains)
- ));
- }
-
- $subsiteID = $subsiteIDs[0];
- } else if($default = DataObject::get_one('Subsite', "\"DefaultSite\" = 1")) {
- // Check for a 'default' subsite
- $subsiteID = $default->ID;
- } else {
- // Default subsite id = 0, the main site
- $subsiteID = 0;
- }
-
- if ($cacheKey) {
- self::$_cache_subsite_for_domain[$cacheKey] = $subsiteID;
- }
-
- return $subsiteID;
- }
-
- /**
- *
- * @param string $className
- * @param string $filter
- * @param string $sort
- * @param string $join
- * @param string $limit
- * @return DataList
- */
- public static function get_from_all_subsites($className, $filter = "", $sort = "", $join = "", $limit = "") {
- $result = DataObject::get($className, $filter, $sort, $join, $limit);
- $result = $result->setDataQueryParam('Subsite.filter', false);
- return $result;
- }
-
- /**
- * Disable the sub-site filtering; queries will select from all subsites
- */
- public static function disable_subsite_filter($disabled = true) {
- self::$disable_subsite_filter = $disabled;
- }
-
- /**
- * Flush caches on database reset
- */
- public static function on_db_reset() {
- self::$_cache_accessible_sites = array();
- self::$_cache_subsite_for_domain = array();
- }
-
- /**
- * Return all subsites, regardless of permissions (augmented with main site).
- *
- * @return SS_List List of {@link Subsite} objects (DataList or ArrayList).
- */
- public static function all_sites($includeMainSite = true, $mainSiteTitle = "Main site") {
- $subsites = Subsite::get();
-
- if($includeMainSite) {
- $subsites = $subsites->toArray();
-
- $mainSite = new Subsite();
- $mainSite->Title = $mainSiteTitle;
- array_unshift($subsites, $mainSite);
-
- $subsites = ArrayList::create($subsites);
- }
-
- return $subsites;
- }
-
- /*
- * Returns an ArrayList of the subsites accessible to the current user.
- * It's enough for any section to be accessible for the site to be included.
- *
- * @return ArrayList of {@link Subsite} instances.
- */
- public static function all_accessible_sites($includeMainSite = true, $mainSiteTitle = "Main site", $member = null) {
- // Rationalise member arguments
- if(!$member) $member = Member::currentUser();
- if(!$member) return new ArrayList();
- if(!is_object($member)) $member = DataObject::get_by_id('Member', $member);
-
- $subsites = new ArrayList();
-
- // Collect subsites for all sections.
- $menu = CMSMenu::get_viewable_menu_items();
- foreach($menu as $candidate) {
- if ($candidate->controller) {
- $accessibleSites = singleton($candidate->controller)->sectionSites(
- $includeMainSite,
- $mainSiteTitle,
- $member
- );
-
- // Replace existing keys so no one site appears twice.
- $subsites->merge($accessibleSites);
- }
- }
-
- $subsites->removeDuplicates();
-
- return $subsites;
- }
-
- /**
- * Return the subsites that the current user can access by given permission.
- * Sites will only be included if they have a Title.
- *
- * @param $permCode array|string Either a single permission code or an array of permission codes.
- * @param $includeMainSite If true, the main site will be included if appropriate.
- * @param $mainSiteTitle The label to give to the main site
- * @param $member
- * @return DataList of {@link Subsite} instances
- */
- public static function accessible_sites($permCode, $includeMainSite = true, $mainSiteTitle = "Main site", $member = null) {
- // Rationalise member arguments
- if(!$member) $member = Member::currentUser();
- if(!$member) return new ArrayList();
- if(!is_object($member)) $member = DataObject::get_by_id('Member', $member);
-
- // Rationalise permCode argument
- if(is_array($permCode)) $SQL_codes = "'" . implode("', '", Convert::raw2sql($permCode)) . "'";
- else $SQL_codes = "'" . Convert::raw2sql($permCode) . "'";
-
- // Cache handling
- $cacheKey = $SQL_codes . '-' . $member->ID . '-' . $includeMainSite . '-' . $mainSiteTitle;
- if(isset(self::$_cache_accessible_sites[$cacheKey])) {
- return self::$_cache_accessible_sites[$cacheKey];
- }
-
- $subsites = DataList::create('Subsite')
- ->where("\"Subsite\".\"Title\" != ''")
- ->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
- ->innerJoin('Group', "\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
- ->innerJoin('Group_Members', "\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
- ->innerJoin('Permission', "\"Group\".\"ID\"=\"Permission\".\"GroupID\" AND \"Permission\".\"Code\" IN ($SQL_codes, 'CMS_ACCESS_LeftAndMain', 'ADMIN')");
-
- if(!$subsites) $subsites = new ArrayList();
-
- $rolesSubsites = DataList::create('Subsite')
- ->where("\"Subsite\".\"Title\" != ''")
- ->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
- ->innerJoin('Group', "\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
- ->innerJoin('Group_Members', "\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
- ->innerJoin('Group_Roles', "\"Group_Roles\".\"GroupID\"=\"Group\".\"ID\"")
- ->innerJoin('PermissionRole', "\"Group_Roles\".\"PermissionRoleID\"=\"PermissionRole\".\"ID\"")
- ->innerJoin('PermissionRoleCode', "\"PermissionRole\".\"ID\"=\"PermissionRoleCode\".\"RoleID\" AND \"PermissionRoleCode\".\"Code\" IN ($SQL_codes, 'CMS_ACCESS_LeftAndMain', 'ADMIN')");
-
- if(!$subsites && $rolesSubsites) return $rolesSubsites;
-
- $subsites = new ArrayList($subsites->toArray());
-
- if($rolesSubsites) foreach($rolesSubsites as $subsite) {
- if(!$subsites->find('ID', $subsite->ID)) {
- $subsites->push($subsite);
- }
- }
-
- if($includeMainSite) {
- if(!is_array($permCode)) $permCode = array($permCode);
- if(self::hasMainSitePermission($member, $permCode)) {
- $subsites=$subsites->toArray();
-
- $mainSite = new Subsite();
- $mainSite->Title = $mainSiteTitle;
- array_unshift($subsites, $mainSite);
- $subsites=ArrayList::create($subsites);
- }
- }
-
- self::$_cache_accessible_sites[$cacheKey] = $subsites;
-
- return $subsites;
- }
-
- /**
- * Write a host->domain map to subsites/host-map.php
- *
- * This is used primarily when using subsites in conjunction with StaticPublisher
- *
- * @param string $file - filepath of the host map to be written
- * @return void
- */
- public static function writeHostMap($file = null) {
- if (!self::$write_hostmap) return;
-
- if (!$file) $file = Director::baseFolder().'/subsites/host-map.php';
- $hostmap = array();
-
- $subsites = DataObject::get('Subsite');
-
- if ($subsites) foreach($subsites as $subsite) {
- $domains = $subsite->Domains();
- if ($domains) foreach($domains as $domain) {
- $domainStr = $domain->Domain;
- if(!self::$strict_subdomain_matching) $domainStr = preg_replace('/^www\./', '', $domainStr);
- $hostmap[$domainStr] = $subsite->domain();
- }
- if ($subsite->DefaultSite) $hostmap['default'] = $subsite->domain();
- }
-
- $data = "ID;
-
- // Count this user's groups which can access the main site
- $groupCount = DB::query("
+class Subsite extends DataObject
+{
+ /**
+ * @var $use_session_subsiteid Boolean Set to TRUE when using the CMS and FALSE
+ * when browsing the frontend of a website.
+ *
+ * @todo Remove flag once the Subsite CMS works without session state,
+ * similarly to the Translatable module.
+ */
+ public static $use_session_subsiteid = false;
+
+ /**
+ * @var boolean $disable_subsite_filter If enabled, bypasses the query decoration
+ * to limit DataObject::get*() calls to a specific subsite. Useful for debugging.
+ */
+ public static $disable_subsite_filter = false;
+
+ /**
+ * Allows you to force a specific subsite ID, or comma separated list of IDs.
+ * Only works for reading. An object cannot be written to more than 1 subsite.
+ */
+ public static $force_subsite = null;
+
+ /**
+ *
+ * @var boolean
+ */
+ public static $write_hostmap = true;
+
+ /**
+ * Memory cache of accessible sites
+ *
+ * @array
+ */
+ private static $_cache_accessible_sites = array();
+
+ /**
+ * Memory cache of subsite id for domains
+ *
+ * @var array
+ */
+ private static $_cache_subsite_for_domain = array();
+
+ /**
+ * @var array $allowed_themes Numeric array of all themes which are allowed to be selected for all subsites.
+ * Corresponds to subfolder names within the /themes folder. By default, all themes contained in this folder
+ * are listed.
+ */
+ private static $allowed_themes = array();
+
+ /**
+ * @var Boolean If set to TRUE, don't assume 'www.example.com' and 'example.com' are the same.
+ * Doesn't affect wildcard matching, so '*.example.com' will match 'www.example.com' (but not 'example.com')
+ * in both TRUE or FALSE setting.
+ */
+ public static $strict_subdomain_matching = false;
+
+ /**
+ * @var boolean Respects the IsPublic flag when retrieving subsites
+ */
+ public static $check_is_public = true;
+
+ /**
+ * Set allowed themes
+ *
+ * @param array $themes - Numeric array of all themes which are allowed to be selected for all subsites.
+ */
+ public static function set_allowed_themes($themes)
+ {
+ self::$allowed_themes = $themes;
+ }
+
+ /**
+ * Gets the subsite currently set in the session.
+ *
+ * @uses ControllerSubsites->controllerAugmentInit()
+ * @return Subsite
+ */
+ public static function currentSubsite()
+ {
+ // get_by_id handles caching so we don't have to
+ return DataObject::get_by_id('Subsite', self::currentSubsiteID());
+ }
+
+ /**
+ * This function gets the current subsite ID from the session. It used in the backend so Ajax requests
+ * use the correct subsite. The frontend handles subsites differently. It calls getSubsiteIDForDomain
+ * directly from ModelAsController::getNestedController. Only gets Subsite instances which have their
+ * {@link IsPublic} flag set to TRUE.
+ *
+ * You can simulate subsite access without creating virtual hosts by appending ?SubsiteID= to the request.
+ *
+ * @todo Pass $request object from controller so we don't have to rely on $_GET
+ *
+ * @param boolean $cache
+ * @return int ID of the current subsite instance
+ */
+ public static function currentSubsiteID()
+ {
+ $id = null;
+
+ if (isset($_GET['SubsiteID'])) {
+ $id = (int)$_GET['SubsiteID'];
+ } elseif (Subsite::$use_session_subsiteid) {
+ $id = Session::get('SubsiteID');
+ }
+
+ if ($id === null) {
+ $id = self::getSubsiteIDForDomain();
+ }
+
+ return (int)$id;
+ }
+
+ /**
+ * Switch to another subsite through storing the subsite identifier in the current PHP session.
+ * Only takes effect when {@link Subsite::$use_session_subsiteid} is set to TRUE.
+ *
+ * @param int|Subsite $subsite Either the ID of the subsite, or the subsite object itself
+ */
+ public static function changeSubsite($subsite)
+ {
+ // Session subsite change only meaningful if the session is active.
+ // Otherwise we risk setting it to wrong value, e.g. if we rely on currentSubsiteID.
+ if (!Subsite::$use_session_subsiteid) {
+ return;
+ }
+
+ if (is_object($subsite)) {
+ $subsiteID = $subsite->ID;
+ } else {
+ $subsiteID = $subsite;
+ }
+
+ Session::set('SubsiteID', (int)$subsiteID);
+
+ // Set locale
+ if (is_object($subsite) && $subsite->Language != '') {
+ $locale = i18n::get_locale_from_lang($subsite->Language);
+ if ($locale) {
+ i18n::set_locale($locale);
+ }
+ }
+
+ Permission::flush_permission_cache();
+ }
+
+ /**
+ * Get a matching subsite for the given host, or for the current HTTP_HOST.
+ * Supports "fuzzy" matching of domains by placing an asterisk at the start of end of the string,
+ * for example matching all subdomains on *.example.com with one subsite,
+ * and all subdomains on *.example.org on another.
+ *
+ * @param $host The host to find the subsite for. If not specified, $_SERVER['HTTP_HOST'] is used.
+ * @return int Subsite ID
+ */
+ public static function getSubsiteIDForDomain($host = null, $checkPermissions = true)
+ {
+ if ($host == null && isset($_SERVER['HTTP_HOST'])) {
+ $host = $_SERVER['HTTP_HOST'];
+ }
+
+ $matchingDomains = null;
+ $cacheKey = null;
+ if ($host) {
+ if (!self::$strict_subdomain_matching) {
+ $host = preg_replace('/^www\./', '', $host);
+ }
+
+ $cacheKey = implode('_', array($host, Member::currentUserID(), self::$check_is_public));
+ if (isset(self::$_cache_subsite_for_domain[$cacheKey])) {
+ return self::$_cache_subsite_for_domain[$cacheKey];
+ }
+
+ $SQL_host = Convert::raw2sql($host);
+ $matchingDomains = DataObject::get(
+ "SubsiteDomain",
+ "'$SQL_host' LIKE replace(\"SubsiteDomain\".\"Domain\",'*','%')",
+ "\"IsPrimary\" DESC"
+ )->innerJoin('Subsite', "\"Subsite\".\"ID\" = \"SubsiteDomain\".\"SubsiteID\" AND \"Subsite\".\"IsPublic\"=1");
+ }
+
+ if ($matchingDomains && $matchingDomains->Count()) {
+ $subsiteIDs = array_unique($matchingDomains->column('SubsiteID'));
+ $subsiteDomains = array_unique($matchingDomains->column('Domain'));
+ if (sizeof($subsiteIDs) > 1) {
+ throw new UnexpectedValueException(sprintf(
+ "Multiple subsites match on '%s': %s",
+ $host,
+ implode(',', $subsiteDomains)
+ ));
+ }
+
+ $subsiteID = $subsiteIDs[0];
+ } elseif ($default = DataObject::get_one('Subsite', "\"DefaultSite\" = 1")) {
+ // Check for a 'default' subsite
+ $subsiteID = $default->ID;
+ } else {
+ // Default subsite id = 0, the main site
+ $subsiteID = 0;
+ }
+
+ if ($cacheKey) {
+ self::$_cache_subsite_for_domain[$cacheKey] = $subsiteID;
+ }
+
+ return $subsiteID;
+ }
+
+ /**
+ *
+ * @param string $className
+ * @param string $filter
+ * @param string $sort
+ * @param string $join
+ * @param string $limit
+ * @return DataList
+ */
+ public static function get_from_all_subsites($className, $filter = "", $sort = "", $join = "", $limit = "")
+ {
+ $result = DataObject::get($className, $filter, $sort, $join, $limit);
+ $result = $result->setDataQueryParam('Subsite.filter', false);
+ return $result;
+ }
+
+ /**
+ * Disable the sub-site filtering; queries will select from all subsites
+ */
+ public static function disable_subsite_filter($disabled = true)
+ {
+ self::$disable_subsite_filter = $disabled;
+ }
+
+ /**
+ * Flush caches on database reset
+ */
+ public static function on_db_reset()
+ {
+ self::$_cache_accessible_sites = array();
+ self::$_cache_subsite_for_domain = array();
+ }
+
+ /**
+ * Return all subsites, regardless of permissions (augmented with main site).
+ *
+ * @return SS_List List of {@link Subsite} objects (DataList or ArrayList).
+ */
+ public static function all_sites($includeMainSite = true, $mainSiteTitle = "Main site")
+ {
+ $subsites = Subsite::get();
+
+ if ($includeMainSite) {
+ $subsites = $subsites->toArray();
+
+ $mainSite = new Subsite();
+ $mainSite->Title = $mainSiteTitle;
+ array_unshift($subsites, $mainSite);
+
+ $subsites = ArrayList::create($subsites);
+ }
+
+ return $subsites;
+ }
+
+ /*
+ * Returns an ArrayList of the subsites accessible to the current user.
+ * It's enough for any section to be accessible for the site to be included.
+ *
+ * @return ArrayList of {@link Subsite} instances.
+ */
+ public static function all_accessible_sites($includeMainSite = true, $mainSiteTitle = "Main site", $member = null)
+ {
+ // Rationalise member arguments
+ if (!$member) {
+ $member = Member::currentUser();
+ }
+ if (!$member) {
+ return new ArrayList();
+ }
+ if (!is_object($member)) {
+ $member = DataObject::get_by_id('Member', $member);
+ }
+
+ $subsites = new ArrayList();
+
+ // Collect subsites for all sections.
+ $menu = CMSMenu::get_viewable_menu_items();
+ foreach ($menu as $candidate) {
+ if ($candidate->controller) {
+ $accessibleSites = singleton($candidate->controller)->sectionSites(
+ $includeMainSite,
+ $mainSiteTitle,
+ $member
+ );
+
+ // Replace existing keys so no one site appears twice.
+ $subsites->merge($accessibleSites);
+ }
+ }
+
+ $subsites->removeDuplicates();
+
+ return $subsites;
+ }
+
+ /**
+ * Return the subsites that the current user can access by given permission.
+ * Sites will only be included if they have a Title.
+ *
+ * @param $permCode array|string Either a single permission code or an array of permission codes.
+ * @param $includeMainSite If true, the main site will be included if appropriate.
+ * @param $mainSiteTitle The label to give to the main site
+ * @param $member
+ * @return DataList of {@link Subsite} instances
+ */
+ public static function accessible_sites($permCode, $includeMainSite = true, $mainSiteTitle = "Main site", $member = null)
+ {
+ // Rationalise member arguments
+ if (!$member) {
+ $member = Member::currentUser();
+ }
+ if (!$member) {
+ return new ArrayList();
+ }
+ if (!is_object($member)) {
+ $member = DataObject::get_by_id('Member', $member);
+ }
+
+ // Rationalise permCode argument
+ if (is_array($permCode)) {
+ $SQL_codes = "'" . implode("', '", Convert::raw2sql($permCode)) . "'";
+ } else {
+ $SQL_codes = "'" . Convert::raw2sql($permCode) . "'";
+ }
+
+ // Cache handling
+ $cacheKey = $SQL_codes . '-' . $member->ID . '-' . $includeMainSite . '-' . $mainSiteTitle;
+ if (isset(self::$_cache_accessible_sites[$cacheKey])) {
+ return self::$_cache_accessible_sites[$cacheKey];
+ }
+
+ $subsites = DataList::create('Subsite')
+ ->where("\"Subsite\".\"Title\" != ''")
+ ->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
+ ->innerJoin('Group', "\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
+ ->innerJoin('Group_Members', "\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
+ ->innerJoin('Permission', "\"Group\".\"ID\"=\"Permission\".\"GroupID\" AND \"Permission\".\"Code\" IN ($SQL_codes, 'CMS_ACCESS_LeftAndMain', 'ADMIN')");
+
+ if (!$subsites) {
+ $subsites = new ArrayList();
+ }
+
+ $rolesSubsites = DataList::create('Subsite')
+ ->where("\"Subsite\".\"Title\" != ''")
+ ->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
+ ->innerJoin('Group', "\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
+ ->innerJoin('Group_Members', "\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
+ ->innerJoin('Group_Roles', "\"Group_Roles\".\"GroupID\"=\"Group\".\"ID\"")
+ ->innerJoin('PermissionRole', "\"Group_Roles\".\"PermissionRoleID\"=\"PermissionRole\".\"ID\"")
+ ->innerJoin('PermissionRoleCode', "\"PermissionRole\".\"ID\"=\"PermissionRoleCode\".\"RoleID\" AND \"PermissionRoleCode\".\"Code\" IN ($SQL_codes, 'CMS_ACCESS_LeftAndMain', 'ADMIN')");
+
+ if (!$subsites && $rolesSubsites) {
+ return $rolesSubsites;
+ }
+
+ $subsites = new ArrayList($subsites->toArray());
+
+ if ($rolesSubsites) {
+ foreach ($rolesSubsites as $subsite) {
+ if (!$subsites->find('ID', $subsite->ID)) {
+ $subsites->push($subsite);
+ }
+ }
+ }
+
+ if ($includeMainSite) {
+ if (!is_array($permCode)) {
+ $permCode = array($permCode);
+ }
+ if (self::hasMainSitePermission($member, $permCode)) {
+ $subsites=$subsites->toArray();
+
+ $mainSite = new Subsite();
+ $mainSite->Title = $mainSiteTitle;
+ array_unshift($subsites, $mainSite);
+ $subsites=ArrayList::create($subsites);
+ }
+ }
+
+ self::$_cache_accessible_sites[$cacheKey] = $subsites;
+
+ return $subsites;
+ }
+
+ /**
+ * Write a host->domain map to subsites/host-map.php
+ *
+ * This is used primarily when using subsites in conjunction with StaticPublisher
+ *
+ * @param string $file - filepath of the host map to be written
+ * @return void
+ */
+ public static function writeHostMap($file = null)
+ {
+ if (!self::$write_hostmap) {
+ return;
+ }
+
+ if (!$file) {
+ $file = Director::baseFolder().'/subsites/host-map.php';
+ }
+ $hostmap = array();
+
+ $subsites = DataObject::get('Subsite');
+
+ if ($subsites) {
+ foreach ($subsites as $subsite) {
+ $domains = $subsite->Domains();
+ if ($domains) {
+ foreach ($domains as $domain) {
+ $domainStr = $domain->Domain;
+ if (!self::$strict_subdomain_matching) {
+ $domainStr = preg_replace('/^www\./', '', $domainStr);
+ }
+ $hostmap[$domainStr] = $subsite->domain();
+ }
+ }
+ if ($subsite->DefaultSite) {
+ $hostmap['default'] = $subsite->domain();
+ }
+ }
+ }
+
+ $data = "ID;
+
+ // Count this user's groups which can access the main site
+ $groupCount = DB::query("
SELECT COUNT(\"Permission\".\"ID\")
FROM \"Permission\"
INNER JOIN \"Group\" ON \"Group\".\"ID\" = \"Permission\".\"GroupID\" AND \"Group\".\"AccessAllSubsites\" = 1
@@ -428,8 +492,8 @@ public static function hasMainSitePermission($member = null, $permissionCodes =
AND \"MemberID\" = {$memberID}
")->value();
- // Count this user's groups which have a role that can access the main site
- $roleCount = DB::query("
+ // Count this user's groups which have a role that can access the main site
+ $roleCount = DB::query("
SELECT COUNT(\"PermissionRoleCode\".\"ID\")
FROM \"Group\"
INNER JOIN \"Group_Members\" ON \"Group_Members\".\"GroupID\" = \"Group\".\"ID\"
@@ -441,380 +505,398 @@ public static function hasMainSitePermission($member = null, $permissionCodes =
AND \"MemberID\" = {$memberID}
")->value();
- // There has to be at least one that allows access.
- return ($groupCount + $roleCount > 0);
- }
-
- /**
- *
- * @var array
- */
- private static $db = array(
- 'Title' => 'Varchar(255)',
- 'RedirectURL' => 'Varchar(255)',
- 'DefaultSite' => 'Boolean',
- 'Theme' => 'Varchar',
- 'Language' => 'Varchar(6)',
-
- // Used to hide unfinished/private subsites from public view.
- // If unset, will default to true
- 'IsPublic' => 'Boolean',
-
- // Comma-separated list of disallowed page types
- 'PageTypeBlacklist' => 'Text',
- );
-
- /**
- *
- * @var array
- */
- private static $has_many = array(
- 'Domains' => 'SubsiteDomain',
- );
-
- /**
- *
- * @var array
- */
- private static $belongs_many_many = array(
- "Groups" => "Group",
- );
-
- /**
- *
- * @var array
- */
- private static $defaults = array(
- 'IsPublic' => 1
- );
-
- /**
- *
- * @var array
- */
- private static $searchable_fields = array(
- 'Title',
- 'Domains.Domain',
- 'IsPublic',
- );
-
- /**
- *
- * @var string
- */
- private static $default_sort = "\"Title\" ASC";
-
- /**
- * @todo Possible security issue, don't grant edit permissions to everybody.
- * @return boolean
- */
- public function canEdit($member = false) {
- return true;
- }
-
- /**
- * Show the configuration fields for each subsite
- *
- * @return FieldList
- */
- public function getCMSFields() {
- if($this->ID!=0) {
- $domainTable = new GridField(
- "Domains",
- _t('Subsite.DomainsListTitle',"Domains"),
- $this->Domains(),
- GridFieldConfig_RecordEditor::create(10)
- );
- }else {
- $domainTable = new LiteralField(
- 'Domains',
- ''._t('Subsite.DOMAINSAVEFIRST', 'You can only add domains after saving for the first time').'
'
- );
- }
-
- $languageSelector = new DropdownField(
- 'Language',
- $this->fieldLabel('Language'),
- i18n::get_common_locales()
- );
-
- $pageTypeMap = array();
- $pageTypes = SiteTree::page_type_classes();
- foreach($pageTypes as $pageType) {
- $pageTypeMap[$pageType] = singleton($pageType)->i18n_singular_name();
- }
- asort($pageTypeMap);
-
- $fields = new FieldList(
- $subsiteTabs = new TabSet('Root',
- new Tab(
- 'Configuration',
- _t('Subsite.TabTitleConfig', 'Configuration'),
- new HeaderField($this->getClassName() . ' configuration', 2),
- new TextField('Title', $this->fieldLabel('Title'), $this->Title),
-
- new HeaderField(
- _t('Subsite.DomainsHeadline',"Domains for this subsite")
- ),
- $domainTable,
- $languageSelector,
- // new TextField('RedirectURL', 'Redirect to URL', $this->RedirectURL),
- new CheckboxField('DefaultSite', $this->fieldLabel('DefaultSite'), $this->DefaultSite),
- new CheckboxField('IsPublic', $this->fieldLabel('IsPublic'), $this->IsPublic),
-
- new DropdownField('Theme',$this->fieldLabel('Theme'), $this->allowedThemes(), $this->Theme),
-
-
- new LiteralField(
- 'PageTypeBlacklistToggle',
- sprintf(
- '',
- _t('Subsite.PageTypeBlacklistField', 'Disallow page types?')
- )
- ),
- new CheckboxSetField(
- 'PageTypeBlacklist',
- false,
- $pageTypeMap
- )
- )
- ),
- new HiddenField('ID', '', $this->ID),
- new HiddenField('IsSubsite', '', 1)
- );
-
- $subsiteTabs->addExtraClass('subsite-model');
-
- $this->extend('updateCMSFields', $fields);
- return $fields;
- }
-
- /**
- *
- * @param boolean $includerelations
- * @return array
- */
- public function fieldLabels($includerelations = true) {
- $labels = parent::fieldLabels($includerelations);
- $labels['Title'] = _t('Subsites.TitleFieldLabel', 'Subsite Name');
- $labels['RedirectURL'] = _t('Subsites.RedirectURLFieldLabel', 'Redirect URL');
- $labels['DefaultSite'] = _t('Subsites.DefaultSiteFieldLabel', 'Default site');
- $labels['Theme'] = _t('Subsites.ThemeFieldLabel', 'Theme');
- $labels['Language'] = _t('Subsites.LanguageFieldLabel', 'Language');
- $labels['IsPublic'] = _t('Subsites.IsPublicFieldLabel', 'Enable public access');
- $labels['PageTypeBlacklist'] = _t('Subsites.PageTypeBlacklistFieldLabel', 'Page Type Blacklist');
- $labels['Domains.Domain'] = _t('Subsites.DomainFieldLabel', 'Domain');
- $labels['PrimaryDomain'] = _t('Subsites.PrimaryDomainFieldLabel', 'Primary Domain');
-
- return $labels;
- }
-
- /**
- *
- * @return array
- */
- public function summaryFields() {
- return array(
- 'Title' => $this->fieldLabel('Title'),
- 'PrimaryDomain' => $this->fieldLabel('PrimaryDomain'),
- 'IsPublic' => _t('Subsite.IsPublicHeaderField','Active subsite'),
- );
- }
-
- /**
- * Return the themes that can be used with this subsite, as an array of themecode => description
- *
- * @return array
- */
- public function allowedThemes() {
- if($themes = $this->stat('allowed_themes')) {
- return ArrayLib::valuekey($themes);
- } else {
- $themes = array();
- if(is_dir('../themes/')) {
- foreach(scandir('../themes/') as $theme) {
- if($theme[0] == '.') continue;
- $theme = strtok($theme,'_');
- $themes[$theme] = $theme;
- }
- ksort($themes);
- }
- return $themes;
- }
- }
-
- /**
- * @return string Current locale of the subsite
- */
- public function getLanguage() {
- if($this->getField('Language')) {
- return $this->getField('Language');
- } else {
- return i18n::get_locale();
- }
- }
-
- /**
- *
- * @return ValidationResult
- */
- public function validate() {
- $result = parent::validate();
- if(!$this->Title) {
- $result->error(_t('Subsite.ValidateTitle', 'Please add a "Title"'));
- }
- return $result;
- }
-
- /**
- * Whenever a Subsite is written, rewrite the hostmap
- *
- * @return void
- */
- public function onAfterWrite() {
- Subsite::writeHostMap();
- parent::onAfterWrite();
- }
-
- /**
- * Return the primary domain of this site. Tries to "normalize" the domain name,
- * by replacing potential wildcards.
- *
- * @return string The full domain name of this subsite (without protocol prefix)
- */
- public function domain() {
- if($this->ID) {
- $domains = DataObject::get("SubsiteDomain", "\"SubsiteID\" = $this->ID", "\"IsPrimary\" DESC","", 1);
- if($domains && $domains->Count()>0) {
- $domain = $domains->First()->Domain;
- // If there are wildcards in the primary domain (not recommended), make some
- // educated guesses about what to replace them with:
- $domain = preg_replace('/\.\*$/',".$_SERVER[HTTP_HOST]", $domain);
- // Default to "subsite." prefix for first wildcard
- // TODO Whats the significance of "subsite" in this context?!
- $domain = preg_replace('/^\*\./',"subsite.", $domain);
- // *Only* removes "intermediate" subdomains, so 'subdomain.www.domain.com' becomes 'subdomain.domain.com'
- $domain = str_replace('.www.','.', $domain);
-
- return $domain;
- }
-
- // SubsiteID = 0 is often used to refer to the main site, just return $_SERVER['HTTP_HOST']
- } else {
- return $_SERVER['HTTP_HOST'];
- }
- }
-
- /**
- *
- * @return string - The full domain name of this subsite (without protocol prefix)
- */
- public function getPrimaryDomain() {
- return $this->domain();
- }
-
- /**
- *
- * @return string
- */
- public function absoluteBaseURL() {
- return "http://" . $this->domain() . Director::baseURL();
- }
-
- /**
- * @todo getClassName is redundant, already stored as a database field?
- */
- public function getClassName() {
- return $this->class;
- }
-
- /**
- * Javascript admin action to duplicate this subsite
- *
- * @return string - javascript
- */
- public function adminDuplicate() {
- $newItem = $this->duplicate();
- $message = _t(
- 'Subsite.CopyMessage',
- 'Created a copy of {title}',
- array('title' => Convert::raw2js($this->Title))
- );
-
- return << 0);
+ }
+
+ /**
+ *
+ * @var array
+ */
+ private static $db = array(
+ 'Title' => 'Varchar(255)',
+ 'RedirectURL' => 'Varchar(255)',
+ 'DefaultSite' => 'Boolean',
+ 'Theme' => 'Varchar',
+ 'Language' => 'Varchar(6)',
+
+ // Used to hide unfinished/private subsites from public view.
+ // If unset, will default to true
+ 'IsPublic' => 'Boolean',
+
+ // Comma-separated list of disallowed page types
+ 'PageTypeBlacklist' => 'Text',
+ );
+
+ /**
+ *
+ * @var array
+ */
+ private static $has_many = array(
+ 'Domains' => 'SubsiteDomain',
+ );
+
+ /**
+ *
+ * @var array
+ */
+ private static $belongs_many_many = array(
+ "Groups" => "Group",
+ );
+
+ /**
+ *
+ * @var array
+ */
+ private static $defaults = array(
+ 'IsPublic' => 1
+ );
+
+ /**
+ *
+ * @var array
+ */
+ private static $searchable_fields = array(
+ 'Title',
+ 'Domains.Domain',
+ 'IsPublic',
+ );
+
+ /**
+ *
+ * @var string
+ */
+ private static $default_sort = "\"Title\" ASC";
+
+ /**
+ * @todo Possible security issue, don't grant edit permissions to everybody.
+ * @return boolean
+ */
+ public function canEdit($member = false)
+ {
+ return true;
+ }
+
+ /**
+ * Show the configuration fields for each subsite
+ *
+ * @return FieldList
+ */
+ public function getCMSFields()
+ {
+ if ($this->ID!=0) {
+ $domainTable = new GridField(
+ "Domains",
+ _t('Subsite.DomainsListTitle', "Domains"),
+ $this->Domains(),
+ GridFieldConfig_RecordEditor::create(10)
+ );
+ } else {
+ $domainTable = new LiteralField(
+ 'Domains',
+ ''._t('Subsite.DOMAINSAVEFIRST', 'You can only add domains after saving for the first time').'
'
+ );
+ }
+
+ $languageSelector = new DropdownField(
+ 'Language',
+ $this->fieldLabel('Language'),
+ i18n::get_common_locales()
+ );
+
+ $pageTypeMap = array();
+ $pageTypes = SiteTree::page_type_classes();
+ foreach ($pageTypes as $pageType) {
+ $pageTypeMap[$pageType] = singleton($pageType)->i18n_singular_name();
+ }
+ asort($pageTypeMap);
+
+ $fields = new FieldList(
+ $subsiteTabs = new TabSet('Root',
+ new Tab(
+ 'Configuration',
+ _t('Subsite.TabTitleConfig', 'Configuration'),
+ new HeaderField($this->getClassName() . ' configuration', 2),
+ new TextField('Title', $this->fieldLabel('Title'), $this->Title),
+
+ new HeaderField(
+ _t('Subsite.DomainsHeadline', "Domains for this subsite")
+ ),
+ $domainTable,
+ $languageSelector,
+ // new TextField('RedirectURL', 'Redirect to URL', $this->RedirectURL),
+ new CheckboxField('DefaultSite', $this->fieldLabel('DefaultSite'), $this->DefaultSite),
+ new CheckboxField('IsPublic', $this->fieldLabel('IsPublic'), $this->IsPublic),
+
+ new DropdownField('Theme', $this->fieldLabel('Theme'), $this->allowedThemes(), $this->Theme),
+
+
+ new LiteralField(
+ 'PageTypeBlacklistToggle',
+ sprintf(
+ '',
+ _t('Subsite.PageTypeBlacklistField', 'Disallow page types?')
+ )
+ ),
+ new CheckboxSetField(
+ 'PageTypeBlacklist',
+ false,
+ $pageTypeMap
+ )
+ )
+ ),
+ new HiddenField('ID', '', $this->ID),
+ new HiddenField('IsSubsite', '', 1)
+ );
+
+ $subsiteTabs->addExtraClass('subsite-model');
+
+ $this->extend('updateCMSFields', $fields);
+ return $fields;
+ }
+
+ /**
+ *
+ * @param boolean $includerelations
+ * @return array
+ */
+ public function fieldLabels($includerelations = true)
+ {
+ $labels = parent::fieldLabels($includerelations);
+ $labels['Title'] = _t('Subsites.TitleFieldLabel', 'Subsite Name');
+ $labels['RedirectURL'] = _t('Subsites.RedirectURLFieldLabel', 'Redirect URL');
+ $labels['DefaultSite'] = _t('Subsites.DefaultSiteFieldLabel', 'Default site');
+ $labels['Theme'] = _t('Subsites.ThemeFieldLabel', 'Theme');
+ $labels['Language'] = _t('Subsites.LanguageFieldLabel', 'Language');
+ $labels['IsPublic'] = _t('Subsites.IsPublicFieldLabel', 'Enable public access');
+ $labels['PageTypeBlacklist'] = _t('Subsites.PageTypeBlacklistFieldLabel', 'Page Type Blacklist');
+ $labels['Domains.Domain'] = _t('Subsites.DomainFieldLabel', 'Domain');
+ $labels['PrimaryDomain'] = _t('Subsites.PrimaryDomainFieldLabel', 'Primary Domain');
+
+ return $labels;
+ }
+
+ /**
+ *
+ * @return array
+ */
+ public function summaryFields()
+ {
+ return array(
+ 'Title' => $this->fieldLabel('Title'),
+ 'PrimaryDomain' => $this->fieldLabel('PrimaryDomain'),
+ 'IsPublic' => _t('Subsite.IsPublicHeaderField', 'Active subsite'),
+ );
+ }
+
+ /**
+ * Return the themes that can be used with this subsite, as an array of themecode => description
+ *
+ * @return array
+ */
+ public function allowedThemes()
+ {
+ if ($themes = $this->stat('allowed_themes')) {
+ return ArrayLib::valuekey($themes);
+ } else {
+ $themes = array();
+ if (is_dir('../themes/')) {
+ foreach (scandir('../themes/') as $theme) {
+ if ($theme[0] == '.') {
+ continue;
+ }
+ $theme = strtok($theme, '_');
+ $themes[$theme] = $theme;
+ }
+ ksort($themes);
+ }
+ return $themes;
+ }
+ }
+
+ /**
+ * @return string Current locale of the subsite
+ */
+ public function getLanguage()
+ {
+ if ($this->getField('Language')) {
+ return $this->getField('Language');
+ } else {
+ return i18n::get_locale();
+ }
+ }
+
+ /**
+ *
+ * @return ValidationResult
+ */
+ public function validate()
+ {
+ $result = parent::validate();
+ if (!$this->Title) {
+ $result->error(_t('Subsite.ValidateTitle', 'Please add a "Title"'));
+ }
+ return $result;
+ }
+
+ /**
+ * Whenever a Subsite is written, rewrite the hostmap
+ *
+ * @return void
+ */
+ public function onAfterWrite()
+ {
+ Subsite::writeHostMap();
+ parent::onAfterWrite();
+ }
+
+ /**
+ * Return the primary domain of this site. Tries to "normalize" the domain name,
+ * by replacing potential wildcards.
+ *
+ * @return string The full domain name of this subsite (without protocol prefix)
+ */
+ public function domain()
+ {
+ if ($this->ID) {
+ $domains = DataObject::get("SubsiteDomain", "\"SubsiteID\" = $this->ID", "\"IsPrimary\" DESC", "", 1);
+ if ($domains && $domains->Count()>0) {
+ $domain = $domains->First()->Domain;
+ // If there are wildcards in the primary domain (not recommended), make some
+ // educated guesses about what to replace them with:
+ $domain = preg_replace('/\.\*$/', ".$_SERVER[HTTP_HOST]", $domain);
+ // Default to "subsite." prefix for first wildcard
+ // TODO Whats the significance of "subsite" in this context?!
+ $domain = preg_replace('/^\*\./', "subsite.", $domain);
+ // *Only* removes "intermediate" subdomains, so 'subdomain.www.domain.com' becomes 'subdomain.domain.com'
+ $domain = str_replace('.www.', '.', $domain);
+
+ return $domain;
+ }
+
+ // SubsiteID = 0 is often used to refer to the main site, just return $_SERVER['HTTP_HOST']
+ } else {
+ return $_SERVER['HTTP_HOST'];
+ }
+ }
+
+ /**
+ *
+ * @return string - The full domain name of this subsite (without protocol prefix)
+ */
+ public function getPrimaryDomain()
+ {
+ return $this->domain();
+ }
+
+ /**
+ *
+ * @return string
+ */
+ public function absoluteBaseURL()
+ {
+ return "http://" . $this->domain() . Director::baseURL();
+ }
+
+ /**
+ * @todo getClassName is redundant, already stored as a database field?
+ */
+ public function getClassName()
+ {
+ return $this->class;
+ }
+
+ /**
+ * Javascript admin action to duplicate this subsite
+ *
+ * @return string - javascript
+ */
+ public function adminDuplicate()
+ {
+ $newItem = $this->duplicate();
+ $message = _t(
+ 'Subsite.CopyMessage',
+ 'Created a copy of {title}',
+ array('title' => Convert::raw2js($this->Title))
+ );
+
+ return <<ID');
JS;
- }
-
- /**
- * Make this subsite the current one
- */
- public function activate() {
- Subsite::changeSubsite($this);
- }
-
- /**
- *
- * @param array $permissionCodes
- * @return DataList
- */
- public function getMembersByPermission($permissionCodes = array('ADMIN')){
- if(!is_array($permissionCodes))
- user_error('Permissions must be passed to Subsite::getMembersByPermission as an array', E_USER_ERROR);
- $SQL_permissionCodes = Convert::raw2sql($permissionCodes);
-
- $SQL_permissionCodes = join("','", $SQL_permissionCodes);
-
- return DataObject::get(
- 'Member',
- "\"Group\".\"SubsiteID\" = $this->ID AND \"Permission\".\"Code\" IN ('$SQL_permissionCodes')",
- '',
- "LEFT JOIN \"Group_Members\" ON \"Member\".\"ID\" = \"Group_Members\".\"MemberID\"
+ }
+
+ /**
+ * Make this subsite the current one
+ */
+ public function activate()
+ {
+ Subsite::changeSubsite($this);
+ }
+
+ /**
+ *
+ * @param array $permissionCodes
+ * @return DataList
+ */
+ public function getMembersByPermission($permissionCodes = array('ADMIN'))
+ {
+ if (!is_array($permissionCodes)) {
+ user_error('Permissions must be passed to Subsite::getMembersByPermission as an array', E_USER_ERROR);
+ }
+ $SQL_permissionCodes = Convert::raw2sql($permissionCodes);
+
+ $SQL_permissionCodes = join("','", $SQL_permissionCodes);
+
+ return DataObject::get(
+ 'Member',
+ "\"Group\".\"SubsiteID\" = $this->ID AND \"Permission\".\"Code\" IN ('$SQL_permissionCodes')",
+ '',
+ "LEFT JOIN \"Group_Members\" ON \"Member\".\"ID\" = \"Group_Members\".\"MemberID\"
LEFT JOIN \"Group\" ON \"Group\".\"ID\" = \"Group_Members\".\"GroupID\"
LEFT JOIN \"Permission\" ON \"Permission\".\"GroupID\" = \"Group\".\"ID\""
- );
-
- }
-
- /**
- * Duplicate this subsite
- */
- public function duplicate($doWrite = true) {
- $duplicate = parent::duplicate($doWrite);
-
- $oldSubsiteID = Session::get('SubsiteID');
- self::changeSubsite($this->ID);
-
- /*
- * Copy data from this object to the given subsite. Does this using an iterative depth-first search.
- * This will make sure that the new parents on the new subsite are correct, and there are no funny
- * issues with having to check whether or not the new parents have been added to the site tree
- * when a page, etc, is duplicated
- */
- $stack = array(array(0,0));
- while(count($stack) > 0) {
- list($sourceParentID, $destParentID) = array_pop($stack);
- $children = Versioned::get_by_stage('Page', 'Live', "\"ParentID\" = $sourceParentID", '');
-
- if($children) {
- foreach($children as $child) {
- self::changeSubsite($duplicate->ID); //Change to destination subsite
-
- $childClone = $child->duplicateToSubsite($duplicate, false);
- $childClone->ParentID = $destParentID;
- $childClone->writeToStage('Stage');
- $childClone->publish('Stage', 'Live');
-
- self::changeSubsite($this->ID); //Change Back to this subsite
-
- array_push($stack, array($child->ID, $childClone->ID));
- }
- }
- }
-
- self::changeSubsite($oldSubsiteID);
-
- return $duplicate;
- }
+ );
+ }
+
+ /**
+ * Duplicate this subsite
+ */
+ public function duplicate($doWrite = true)
+ {
+ $duplicate = parent::duplicate($doWrite);
+
+ $oldSubsiteID = Session::get('SubsiteID');
+ self::changeSubsite($this->ID);
+
+ /*
+ * Copy data from this object to the given subsite. Does this using an iterative depth-first search.
+ * This will make sure that the new parents on the new subsite are correct, and there are no funny
+ * issues with having to check whether or not the new parents have been added to the site tree
+ * when a page, etc, is duplicated
+ */
+ $stack = array(array(0,0));
+ while (count($stack) > 0) {
+ list($sourceParentID, $destParentID) = array_pop($stack);
+ $children = Versioned::get_by_stage('Page', 'Live', "\"ParentID\" = $sourceParentID", '');
+
+ if ($children) {
+ foreach ($children as $child) {
+ self::changeSubsite($duplicate->ID); //Change to destination subsite
+
+ $childClone = $child->duplicateToSubsite($duplicate, false);
+ $childClone->ParentID = $destParentID;
+ $childClone->writeToStage('Stage');
+ $childClone->publish('Stage', 'Live');
+
+ self::changeSubsite($this->ID); //Change Back to this subsite
+
+ array_push($stack, array($child->ID, $childClone->ID));
+ }
+ }
+ }
+
+ self::changeSubsite($oldSubsiteID);
+
+ return $duplicate;
+ }
}
diff --git a/code/model/SubsiteDomain.php b/code/model/SubsiteDomain.php
index b6af6344..11439e02 100644
--- a/code/model/SubsiteDomain.php
+++ b/code/model/SubsiteDomain.php
@@ -4,78 +4,82 @@
* @property text Domain domain name of this subsite. Do not include the URL scheme here
* @property bool IsPrimary Is this the primary subdomain?
*/
-class SubsiteDomain extends DataObject {
+class SubsiteDomain extends DataObject
+{
+ /**
+ *
+ * @var array
+ */
+ private static $db = array(
+ "Domain" => "Varchar(255)",
+ "IsPrimary" => "Boolean",
+ );
- /**
- *
- * @var array
- */
- private static $db = array(
- "Domain" => "Varchar(255)",
- "IsPrimary" => "Boolean",
- );
+ /**
+ *
+ * @var array
+ */
+ private static $has_one = array(
+ "Subsite" => "Subsite",
+ );
- /**
- *
- * @var array
- */
- private static $has_one = array(
- "Subsite" => "Subsite",
- );
+ /**
+ *
+ * @var array
+ */
+ private static $summary_fields=array(
+ 'Domain',
+ 'IsPrimary',
+ );
- /**
- *
- * @var array
- */
- private static $summary_fields=array(
- 'Domain',
- 'IsPrimary',
- );
+ /**
+ * Whenever a Subsite Domain is written, rewrite the hostmap
+ *
+ * @return void
+ */
+ public function onAfterWrite()
+ {
+ Subsite::writeHostMap();
+ }
+
+ /**
+ *
+ * @return \FieldList
+ */
+ public function getCMSFields()
+ {
+ $fields = new FieldList(
+ new TextField('Domain', $this->fieldLabel('Domain'), null, 255),
+ new CheckboxField('IsPrimary', $this->fieldLabel('IsPrimary'))
+ );
- /**
- * Whenever a Subsite Domain is written, rewrite the hostmap
- *
- * @return void
- */
- public function onAfterWrite() {
- Subsite::writeHostMap();
- }
-
- /**
- *
- * @return \FieldList
- */
- public function getCMSFields() {
- $fields = new FieldList(
- new TextField('Domain', $this->fieldLabel('Domain'), null, 255),
- new CheckboxField('IsPrimary', $this->fieldLabel('IsPrimary'))
- );
+ $this->extend('updateCMSFields', $fields);
+ return $fields;
+ }
- $this->extend('updateCMSFields', $fields);
- return $fields;
- }
+ /**
+ *
+ * @param bool $includerelations
+ * @return array
+ */
+ public function fieldLabels($includerelations = true)
+ {
+ $labels = parent::fieldLabels($includerelations);
+ $labels['Domain'] = _t('SubsiteDomain.DOMAIN', 'Domain');
+ $labels['IsPrimary'] = _t('SubsiteDomain.IS_PRIMARY', 'Is Primary Domain');
- /**
- *
- * @param bool $includerelations
- * @return array
- */
- public function fieldLabels($includerelations = true) {
- $labels = parent::fieldLabels($includerelations);
- $labels['Domain'] = _t('SubsiteDomain.DOMAIN', 'Domain');
- $labels['IsPrimary'] = _t('SubsiteDomain.IS_PRIMARY', 'Is Primary Domain');
+ return $labels;
+ }
- return $labels;
- }
+ /**
+ * Before writing the Subsite Domain, strip out any HTML the user has entered.
+ * @return void
+ */
+ public function onBeforeWrite()
+ {
+ parent::onBeforeWrite();
- /**
- * Before writing the Subsite Domain, strip out any HTML the user has entered.
- * @return void
- */
- public function onBeforeWrite() {
- parent::onBeforeWrite();
-
- //strip out any HTML to avoid XSS attacks
- $this->Domain = Convert::html2raw($this->Domain);
- }
+ //strip out any HTML to avoid XSS attacks
+ $this->Domain = Convert::html2raw($this->Domain);
+ }
}
diff --git a/code/tasks/SubsiteCopyPagesTask.php b/code/tasks/SubsiteCopyPagesTask.php
index 8448beca..ceac4172 100644
--- a/code/tasks/SubsiteCopyPagesTask.php
+++ b/code/tasks/SubsiteCopyPagesTask.php
@@ -6,62 +6,72 @@
*
* Example: sake dev/tasks/SubsiteCopyPagesTask from= to=
*/
-class SubsiteCopyPagesTask extends BuildTask {
+class SubsiteCopyPagesTask extends BuildTask
+{
+ protected $title = 'Copy pages to different subsite';
+
+ protected $description = '';
- protected $title = 'Copy pages to different subsite';
-
- protected $description = '';
+ public function run($request)
+ {
+ $subsiteFromId = $request->getVar('from');
+ if (!is_numeric($subsiteFromId)) {
+ throw new InvalidArgumentException('Missing "from" parameter');
+ }
+ $subsiteFrom = DataObject::get_by_id('Subsite', $subsiteFromId);
+ if (!$subsiteFrom) {
+ throw new InvalidArgumentException('Subsite not found');
+ }
- function run($request) {
- $subsiteFromId = $request->getVar('from');
- if(!is_numeric($subsiteFromId)) throw new InvalidArgumentException('Missing "from" parameter');
- $subsiteFrom = DataObject::get_by_id('Subsite', $subsiteFromId);
- if(!$subsiteFrom) throw new InvalidArgumentException('Subsite not found');
+ $subsiteToId = $request->getVar('to');
+ if (!is_numeric($subsiteToId)) {
+ throw new InvalidArgumentException('Missing "to" parameter');
+ }
+ $subsiteTo = DataObject::get_by_id('Subsite', $subsiteToId);
+ if (!$subsiteTo) {
+ throw new InvalidArgumentException('Subsite not found');
+ }
- $subsiteToId = $request->getVar('to');
- if(!is_numeric($subsiteToId)) throw new InvalidArgumentException('Missing "to" parameter');
- $subsiteTo = DataObject::get_by_id('Subsite', $subsiteToId);
- if(!$subsiteTo) throw new InvalidArgumentException('Subsite not found');
+ $useVirtualPages = (bool)$request->getVar('virtual');
- $useVirtualPages = (bool)$request->getVar('virtual');
+ Subsite::changeSubsite($subsiteFrom);
- Subsite::changeSubsite($subsiteFrom);
+ // Copy data from this template to the given subsite. Does this using an iterative depth-first search.
+ // This will make sure that the new parents on the new subsite are correct, and there are no funny
+ // issues with having to check whether or not the new parents have been added to the site tree
+ // when a page, etc, is duplicated
+ $stack = array(array(0,0));
+ while (count($stack) > 0) {
+ list($sourceParentID, $destParentID) = array_pop($stack);
- // Copy data from this template to the given subsite. Does this using an iterative depth-first search.
- // This will make sure that the new parents on the new subsite are correct, and there are no funny
- // issues with having to check whether or not the new parents have been added to the site tree
- // when a page, etc, is duplicated
- $stack = array(array(0,0));
- while(count($stack) > 0) {
- list($sourceParentID, $destParentID) = array_pop($stack);
+ $children = Versioned::get_by_stage('SiteTree', 'Live', "\"ParentID\" = $sourceParentID", '');
- $children = Versioned::get_by_stage('SiteTree', 'Live', "\"ParentID\" = $sourceParentID", '');
+ if ($children) {
+ foreach ($children as $child) {
+ if ($useVirtualPages) {
+ $childClone = new SubsitesVirtualPage();
+ $childClone->writeToStage('Stage');
+ $childClone->CopyContentFromID = $child->ID;
+ $childClone->SubsiteID = $subsiteTo->ID;
+ } else {
+ $childClone = $child->duplicateToSubsite($subsiteTo->ID, true);
+ }
+
+ $childClone->ParentID = $destParentID;
+ $childClone->writeToStage('Stage');
+ $childClone->publish('Stage', 'Live');
+ array_push($stack, array($child->ID, $childClone->ID));
- if($children) {
- foreach($children as $child) {
- if($useVirtualPages) {
- $childClone = new SubsitesVirtualPage();
- $childClone->writeToStage('Stage');
- $childClone->CopyContentFromID = $child->ID;
- $childClone->SubsiteID = $subsiteTo->ID;
- } else {
- $childClone = $child->duplicateToSubsite($subsiteTo->ID, true);
- }
-
- $childClone->ParentID = $destParentID;
- $childClone->writeToStage('Stage');
- $childClone->publish('Stage', 'Live');
- array_push($stack, array($child->ID, $childClone->ID));
+ $this->log(sprintf('Copied "%s" (#%d, %s)', $child->Title, $child->ID, $child->Link()));
+ }
+ }
- $this->log(sprintf('Copied "%s" (#%d, %s)', $child->Title, $child->ID, $child->Link()));
- }
- }
+ unset($children);
+ }
+ }
- unset($children);
- }
- }
-
- function log($msg) {
- echo $msg . "\n";
- }
-}
\ No newline at end of file
+ public function log($msg)
+ {
+ echo $msg . "\n";
+ }
+}
diff --git a/tests/BaseSubsiteTest.php b/tests/BaseSubsiteTest.php
index de0940e8..657857cd 100644
--- a/tests/BaseSubsiteTest.php
+++ b/tests/BaseSubsiteTest.php
@@ -1,28 +1,30 @@
assertFalse(Subsite::$disable_subsite_filter);
- }
+ return $obj;
+ }
+ /**
+ * Tests the initial state of disable_subsite_filter
+ */
+ public function testDisableSubsiteFilter()
+ {
+ $this->assertFalse(Subsite::$disable_subsite_filter);
+ }
}
diff --git a/tests/FileSubsitesTest.php b/tests/FileSubsitesTest.php
index 943e8cce..a465dee7 100644
--- a/tests/FileSubsitesTest.php
+++ b/tests/FileSubsitesTest.php
@@ -1,76 +1,79 @@
assertTrue(is_array(singleton('FileSubsites')->extraStatics()));
- $file = new File();
- $file->Name = 'FileTitle';
- $file->Title = 'FileTitle';
- $this->assertEquals(' * FileTitle', $file->alternateTreeTitle());
- $file->SubsiteID = $this->objFromFixture('Subsite', 'domaintest1')->ID;
- $this->assertEquals('FileTitle', $file->getTreeTitle());
- $this->assertTrue(singleton('Folder')->getCMSFields() instanceof FieldList);
- Subsite::changeSubsite(1);
- $this->assertEquals($file->cacheKeyComponent(), 'subsite-1');
- }
-
- function testWritingSubsiteID() {
- $this->objFromFixture('Member', 'admin')->logIn();
-
- $subsite = $this->objFromFixture('Subsite', 'domaintest1');
- FileSubsites::$default_root_folders_global = true;
-
- Subsite::changeSubsite(0);
- $file = new File();
- $file->write();
- $file->onAfterUpload();
- $this->assertEquals((int)$file->SubsiteID, 0);
-
- Subsite::changeSubsite($subsite->ID);
- $this->assertTrue($file->canEdit());
-
- $file = new File();
- $file->write();
- $this->assertEquals((int)$file->SubsiteID, 0);
- $this->assertTrue($file->canEdit());
-
- FileSubsites::$default_root_folders_global = false;
-
- Subsite::changeSubsite($subsite->ID);
- $file = new File();
- $file->write();
- $this->assertEquals($file->SubsiteID, $subsite->ID);
-
- // Test inheriting from parent folder
- $folder = new Folder();
- $folder->write();
- $this->assertEquals($folder->SubsiteID, $subsite->ID);
- FileSubsites::$default_root_folders_global = true;
- $file = new File();
- $file->ParentID = $folder->ID;
- $file->onAfterUpload();
- $this->assertEquals($folder->SubsiteID, $file->SubsiteID);
- }
+class FileSubsitesTest extends BaseSubsiteTest
+{
+ public static $fixture_file = 'subsites/tests/SubsiteTest.yml';
+
+ public function testTrivialFeatures()
+ {
+ $this->assertTrue(is_array(singleton('FileSubsites')->extraStatics()));
+ $file = new File();
+ $file->Name = 'FileTitle';
+ $file->Title = 'FileTitle';
+ $this->assertEquals(' * FileTitle', $file->alternateTreeTitle());
+ $file->SubsiteID = $this->objFromFixture('Subsite', 'domaintest1')->ID;
+ $this->assertEquals('FileTitle', $file->getTreeTitle());
+ $this->assertTrue(singleton('Folder')->getCMSFields() instanceof FieldList);
+ Subsite::changeSubsite(1);
+ $this->assertEquals($file->cacheKeyComponent(), 'subsite-1');
+ }
+
+ public function testWritingSubsiteID()
+ {
+ $this->objFromFixture('Member', 'admin')->logIn();
+
+ $subsite = $this->objFromFixture('Subsite', 'domaintest1');
+ FileSubsites::$default_root_folders_global = true;
+
+ Subsite::changeSubsite(0);
+ $file = new File();
+ $file->write();
+ $file->onAfterUpload();
+ $this->assertEquals((int)$file->SubsiteID, 0);
+
+ Subsite::changeSubsite($subsite->ID);
+ $this->assertTrue($file->canEdit());
+
+ $file = new File();
+ $file->write();
+ $this->assertEquals((int)$file->SubsiteID, 0);
+ $this->assertTrue($file->canEdit());
+
+ FileSubsites::$default_root_folders_global = false;
+
+ Subsite::changeSubsite($subsite->ID);
+ $file = new File();
+ $file->write();
+ $this->assertEquals($file->SubsiteID, $subsite->ID);
+
+ // Test inheriting from parent folder
+ $folder = new Folder();
+ $folder->write();
+ $this->assertEquals($folder->SubsiteID, $subsite->ID);
+ FileSubsites::$default_root_folders_global = true;
+ $file = new File();
+ $file->ParentID = $folder->ID;
+ $file->onAfterUpload();
+ $this->assertEquals($folder->SubsiteID, $file->SubsiteID);
+ }
- function testSubsitesFolderDropdown() {
- $this->objFromFixture('Member', 'admin')->logIn();
+ public function testSubsitesFolderDropdown()
+ {
+ $this->objFromFixture('Member', 'admin')->logIn();
- $file = new Folder();
+ $file = new Folder();
- $source = array_values($file->getCMSFields()->dataFieldByName('SubsiteID')->getSource());
- asort($source);
+ $source = array_values($file->getCMSFields()->dataFieldByName('SubsiteID')->getSource());
+ asort($source);
- $this->assertEquals(array(
- 'Main site',
- 'Template',
- 'Subsite1 Template',
- 'Subsite2 Template',
- 'Test 1',
- 'Test 2',
- 'Test 3'
- ), $source);
- }
-
+ $this->assertEquals(array(
+ 'Main site',
+ 'Template',
+ 'Subsite1 Template',
+ 'Subsite2 Template',
+ 'Test 1',
+ 'Test 2',
+ 'Test 3'
+ ), $source);
+ }
}
diff --git a/tests/GroupSubsitesTest.php b/tests/GroupSubsitesTest.php
index 6ab1feca..d9a7feb4 100644
--- a/tests/GroupSubsitesTest.php
+++ b/tests/GroupSubsitesTest.php
@@ -1,25 +1,28 @@
assertTrue(is_array(singleton('GroupSubsites')->extraStatics()));
- $this->assertTrue(is_array(singleton('GroupSubsites')->providePermissions()));
- $this->assertTrue(singleton('Group')->getCMSFields() instanceof FieldList);
- }
-
- function testAlternateTreeTitle() {
- $group = new Group();
- $group->Title = 'The A Team';
- $group->AccessAllSubsites = true;
- $this->assertEquals($group->getTreeTitle(), 'The A Team (global group)');
- $group->AccessAllSubsites = false;
- $group->write();
- $group->Subsites()->add($this->objFromFixture('Subsite', 'domaintest1'));
- $group->Subsites()->add($this->objFromFixture('Subsite', 'domaintest2'));
- $this->assertEquals($group->getTreeTitle(), 'The A Team (Test 1, Test 2)');
- }
-}
\ No newline at end of file
+class GroupSubsitesTest extends BaseSubsiteTest
+{
+ public static $fixture_file = 'subsites/tests/SubsiteTest.yml';
+
+ protected $requireDefaultRecordsFrom = array('GroupSubsites');
+
+ public function testTrivialFeatures()
+ {
+ $this->assertTrue(is_array(singleton('GroupSubsites')->extraStatics()));
+ $this->assertTrue(is_array(singleton('GroupSubsites')->providePermissions()));
+ $this->assertTrue(singleton('Group')->getCMSFields() instanceof FieldList);
+ }
+
+ public function testAlternateTreeTitle()
+ {
+ $group = new Group();
+ $group->Title = 'The A Team';
+ $group->AccessAllSubsites = true;
+ $this->assertEquals($group->getTreeTitle(), 'The A Team (global group)');
+ $group->AccessAllSubsites = false;
+ $group->write();
+ $group->Subsites()->add($this->objFromFixture('Subsite', 'domaintest1'));
+ $group->Subsites()->add($this->objFromFixture('Subsite', 'domaintest2'));
+ $this->assertEquals($group->getTreeTitle(), 'The A Team (Test 1, Test 2)');
+ }
+}
diff --git a/tests/LeftAndMainSubsitesTest.php b/tests/LeftAndMainSubsitesTest.php
index 0b2c6dfb..5a9603ec 100644
--- a/tests/LeftAndMainSubsitesTest.php
+++ b/tests/LeftAndMainSubsitesTest.php
@@ -1,88 +1,90 @@
objFromFixture('Member', 'subsite1member');
-
- $cmsmain = singleton('CMSMain');
- $subsites = $cmsmain->sectionSites(true, "Main site", $member);
- $this->assertDOSEquals(array(
- array('Title' =>'Subsite1 Template')
- ), $subsites, 'Lists member-accessible sites for the accessible controller.');
-
- $assetadmin = singleton('AssetAdmin');
- $subsites = $assetadmin->sectionSites(true, "Main site", $member);
- $this->assertDOSEquals(array(), $subsites, 'Does not list any sites for forbidden controller.');
-
- $member = $this->objFromFixture('Member', 'editor');
-
- $cmsmain = singleton('CMSMain');
- $subsites = $cmsmain->sectionSites(true, "Main site", $member);
- $this->assertDOSContains(array(
- array('Title' =>'Main site')
- ), $subsites, 'Includes the main site for members who can access all sites.');
- }
-
- function testAccessChecksDontChangeCurrentSubsite() {
- $admin = $this->objFromFixture("Member","admin");
- $this->loginAs($admin);
- $ids = array();
-
- $subsite1 = $this->objFromFixture('Subsite', 'domaintest1');
- $subsite2 = $this->objFromFixture('Subsite', 'domaintest2');
- $subsite3 = $this->objFromFixture('Subsite', 'domaintest3');
-
- $ids[] = $subsite1->ID;
- $ids[] = $subsite2->ID;
- $ids[] = $subsite3->ID;
- $ids[] = 0;
-
- // Enable session-based subsite tracking.
- Subsite::$use_session_subsiteid = true;
-
- foreach($ids as $id) {
- Subsite::changeSubsite($id);
- $this->assertEquals($id, Subsite::currentSubsiteID());
-
- $left = new LeftAndMain();
- $this->assertTrue($left->canView(), "Admin user can view subsites LeftAndMain with id = '$id'");
- $this->assertEquals($id, Subsite::currentSubsiteID(),
- "The current subsite has not been changed in the process of checking permissions for admin user.");
- }
-
- }
-
- function testShouldChangeSubsite() {
- $l = new LeftAndMain();
- Config::inst()->nest();
-
- Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', false);
- $this->assertTrue($l->shouldChangeSubsite('CMSPageEditController', 0, 5));
- $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 0, 0));
- $this->assertTrue($l->shouldChangeSubsite('CMSPageEditController', 1, 5));
- $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 1, 1));
-
- Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', true);
- $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 0, 5));
- $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 0, 0));
- $this->assertTrue($l->shouldChangeSubsite('CMSPageEditController', 1, 5));
- $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 1, 1));
-
- Config::inst()->unnest();
- }
-
+class LeftAndMainSubsitesTest extends FunctionalTest
+{
+ public static $fixture_file = 'subsites/tests/SubsiteTest.yml';
+
+ /**
+ * Avoid subsites filtering on fixture fetching.
+ */
+ public function objFromFixture($class, $id)
+ {
+ Subsite::disable_subsite_filter(true);
+ $obj = parent::objFromFixture($class, $id);
+ Subsite::disable_subsite_filter(false);
+
+ return $obj;
+ }
+
+ public function testSectionSites()
+ {
+ $member = $this->objFromFixture('Member', 'subsite1member');
+
+ $cmsmain = singleton('CMSMain');
+ $subsites = $cmsmain->sectionSites(true, "Main site", $member);
+ $this->assertDOSEquals(array(
+ array('Title' =>'Subsite1 Template')
+ ), $subsites, 'Lists member-accessible sites for the accessible controller.');
+
+ $assetadmin = singleton('AssetAdmin');
+ $subsites = $assetadmin->sectionSites(true, "Main site", $member);
+ $this->assertDOSEquals(array(), $subsites, 'Does not list any sites for forbidden controller.');
+
+ $member = $this->objFromFixture('Member', 'editor');
+
+ $cmsmain = singleton('CMSMain');
+ $subsites = $cmsmain->sectionSites(true, "Main site", $member);
+ $this->assertDOSContains(array(
+ array('Title' =>'Main site')
+ ), $subsites, 'Includes the main site for members who can access all sites.');
+ }
+
+ public function testAccessChecksDontChangeCurrentSubsite()
+ {
+ $admin = $this->objFromFixture("Member", "admin");
+ $this->loginAs($admin);
+ $ids = array();
+
+ $subsite1 = $this->objFromFixture('Subsite', 'domaintest1');
+ $subsite2 = $this->objFromFixture('Subsite', 'domaintest2');
+ $subsite3 = $this->objFromFixture('Subsite', 'domaintest3');
+
+ $ids[] = $subsite1->ID;
+ $ids[] = $subsite2->ID;
+ $ids[] = $subsite3->ID;
+ $ids[] = 0;
+
+ // Enable session-based subsite tracking.
+ Subsite::$use_session_subsiteid = true;
+
+ foreach ($ids as $id) {
+ Subsite::changeSubsite($id);
+ $this->assertEquals($id, Subsite::currentSubsiteID());
+
+ $left = new LeftAndMain();
+ $this->assertTrue($left->canView(), "Admin user can view subsites LeftAndMain with id = '$id'");
+ $this->assertEquals($id, Subsite::currentSubsiteID(),
+ "The current subsite has not been changed in the process of checking permissions for admin user.");
+ }
+ }
+
+ public function testShouldChangeSubsite()
+ {
+ $l = new LeftAndMain();
+ Config::inst()->nest();
+
+ Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', false);
+ $this->assertTrue($l->shouldChangeSubsite('CMSPageEditController', 0, 5));
+ $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 0, 0));
+ $this->assertTrue($l->shouldChangeSubsite('CMSPageEditController', 1, 5));
+ $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 1, 1));
+
+ Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', true);
+ $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 0, 5));
+ $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 0, 0));
+ $this->assertTrue($l->shouldChangeSubsite('CMSPageEditController', 1, 5));
+ $this->assertFalse($l->shouldChangeSubsite('CMSPageEditController', 1, 1));
+
+ Config::inst()->unnest();
+ }
}
diff --git a/tests/SiteConfigSubsitesTest.php b/tests/SiteConfigSubsitesTest.php
index 612ac327..336ab366 100644
--- a/tests/SiteConfigSubsitesTest.php
+++ b/tests/SiteConfigSubsitesTest.php
@@ -1,38 +1,39 @@
objFromFixture('Subsite', 'domaintest1');
- $subsite2 = $this->objFromFixture('Subsite', 'domaintest2');
+class SiteConfigSubsitesTest extends BaseSubsiteTest
+{
+ public static $fixture_file = 'subsites/tests/SubsiteTest.yml';
+
+ public function testEachSubsiteHasAUniqueSiteConfig()
+ {
+ $subsite1 = $this->objFromFixture('Subsite', 'domaintest1');
+ $subsite2 = $this->objFromFixture('Subsite', 'domaintest2');
- $this->assertTrue(is_array(singleton('SiteConfigSubsites')->extraStatics()));
-
- Subsite::changeSubsite(0);
- $sc = SiteConfig::current_site_config();
- $sc->Title = 'RootSite';
- $sc->write();
-
- Subsite::changeSubsite($subsite1->ID);
- $sc = SiteConfig::current_site_config();
- $sc->Title = 'Subsite1';
- $sc->write();
-
- Subsite::changeSubsite($subsite2->ID);
- $sc = SiteConfig::current_site_config();
- $sc->Title = 'Subsite2';
- $sc->write();
-
- Subsite::changeSubsite(0);
- $this->assertEquals(SiteConfig::current_site_config()->Title, 'RootSite');
- Subsite::changeSubsite($subsite1->ID);
- $this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite1');
- Subsite::changeSubsite($subsite2->ID);
- $this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite2');
-
- $keys = SiteConfig::current_site_config()->extend('cacheKeyComponent');
- $this->assertContains('subsite-' . $subsite2->ID, $keys);
- }
+ $this->assertTrue(is_array(singleton('SiteConfigSubsites')->extraStatics()));
+
+ Subsite::changeSubsite(0);
+ $sc = SiteConfig::current_site_config();
+ $sc->Title = 'RootSite';
+ $sc->write();
+
+ Subsite::changeSubsite($subsite1->ID);
+ $sc = SiteConfig::current_site_config();
+ $sc->Title = 'Subsite1';
+ $sc->write();
+
+ Subsite::changeSubsite($subsite2->ID);
+ $sc = SiteConfig::current_site_config();
+ $sc->Title = 'Subsite2';
+ $sc->write();
+
+ Subsite::changeSubsite(0);
+ $this->assertEquals(SiteConfig::current_site_config()->Title, 'RootSite');
+ Subsite::changeSubsite($subsite1->ID);
+ $this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite1');
+ Subsite::changeSubsite($subsite2->ID);
+ $this->assertEquals(SiteConfig::current_site_config()->Title, 'Subsite2');
+ $keys = SiteConfig::current_site_config()->extend('cacheKeyComponent');
+ $this->assertContains('subsite-' . $subsite2->ID, $keys);
+ }
}
diff --git a/tests/SiteTreeSubsitesTest.php b/tests/SiteTreeSubsitesTest.php
index 1ea82026..f5edef45 100644
--- a/tests/SiteTreeSubsitesTest.php
+++ b/tests/SiteTreeSubsitesTest.php
@@ -1,203 +1,213 @@
array('Translatable')
+ );
+
+ public function testPagesInDifferentSubsitesCanShareURLSegment()
+ {
+ $subsiteMain = $this->objFromFixture('Subsite', 'main');
+ $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
+
+ $pageMain = new SiteTree();
+ $pageMain->URLSegment = 'testpage';
+ $pageMain->write();
+ $pageMain->publish('Stage', 'Live');
+
+ $pageMainOther = new SiteTree();
+ $pageMainOther->URLSegment = 'testpage';
+ $pageMainOther->write();
+ $pageMainOther->publish('Stage', 'Live');
+
+ $this->assertNotEquals($pageMain->URLSegment, $pageMainOther->URLSegment,
+ 'Pages in same subsite cant share the same URL'
+ );
+
+ Subsite::changeSubsite($subsite1->ID);
+
+ $pageSubsite1 = new SiteTree();
+ $pageSubsite1->URLSegment = 'testpage';
+ $pageSubsite1->write();
+ $pageSubsite1->publish('Stage', 'Live');
+
+ $this->assertEquals($pageMain->URLSegment, $pageSubsite1->URLSegment,
+ 'Pages in different subsites can share the same URL'
+ );
+ }
+
+ public function testBasicSanity()
+ {
+ $this->assertTrue(singleton('SiteTree')->getSiteConfig() instanceof SiteConfig);
+ // The following assert is breaking in Translatable.
+ $this->assertTrue(singleton('SiteTree')->getCMSFields() instanceof FieldList);
+ $this->assertTrue(singleton('SubsitesVirtualPage')->getCMSFields() instanceof FieldList);
+ $this->assertTrue(is_array(singleton('SiteTreeSubsites')->extraStatics()));
+ }
+
+ public function testErrorPageLocations()
+ {
+ $subsite1 = $this->objFromFixture('Subsite', 'domaintest1');
+
+ Subsite::changeSubsite($subsite1->ID);
+ $path = ErrorPage::get_filepath_for_errorcode(500);
+
+ $static_path = Config::inst()->get('ErrorPage', 'static_filepath');
+ $expected_path = $static_path . '/error-500-'.$subsite1->domain().'.html';
+ $this->assertEquals($expected_path, $path);
+ }
+
+ public function testCanEditSiteTree()
+ {
+ $admin = $this->objFromFixture('Member', 'admin');
+ $subsite1member = $this->objFromFixture('Member', 'subsite1member');
+ $subsite2member = $this->objFromFixture('Member', 'subsite2member');
+ $mainpage = $this->objFromFixture('Page', 'home');
+ $subsite1page = $this->objFromFixture('Page', 'subsite1_home');
+ $subsite2page = $this->objFromFixture('Page', 'subsite2_home');
+ $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
+ $subsite2 = $this->objFromFixture('Subsite', 'subsite2');
+
+ // Cant pass member as arguments to canEdit() because of GroupSubsites
+ Session::set("loggedInAs", $admin->ID);
+ $this->assertTrue(
+ (bool)$subsite1page->canEdit(),
+ 'Administrators can edit all subsites'
+ );
+
+ // @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
+ Subsite::changeSubsite($subsite1);
+
+ Session::set("loggedInAs", $subsite1member->ID);
+ $this->assertTrue(
+ (bool)$subsite1page->canEdit(),
+ 'Members can edit pages on a subsite if they are in a group belonging to this subsite'
+ );
+
+ Session::set("loggedInAs", $subsite2member->ID);
+ $this->assertFalse(
+ (bool)$subsite1page->canEdit(),
+ 'Members cant edit pages on a subsite if they are not in a group belonging to this subsite'
+ );
+
+ // @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
+ Subsite::changeSubsite(0);
+ $this->assertFalse(
+ $mainpage->canEdit(),
+ 'Members cant edit pages on the main site if they are not in a group allowing this'
+ );
+ }
+
+ /**
+ * Similar to {@link SubsitesVirtualPageTest->testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite()}.
+ */
+ public function testTwoPagesWithSameURLOnDifferentSubsites()
+ {
+ // Set up a couple of pages with the same URL on different subsites
+ $s1 = $this->objFromFixture('Subsite', 'domaintest1');
+ $s2 = $this->objFromFixture('Subsite', 'domaintest2');
+
+ $p1 = new SiteTree();
+ $p1->Title = $p1->URLSegment = "test-page";
+ $p1->SubsiteID = $s1->ID;
+ $p1->write();
- protected $illegalExtensions = array(
- 'SiteTree' => array('Translatable')
- );
-
- function testPagesInDifferentSubsitesCanShareURLSegment() {
- $subsiteMain = $this->objFromFixture('Subsite', 'main');
- $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
-
- $pageMain = new SiteTree();
- $pageMain->URLSegment = 'testpage';
- $pageMain->write();
- $pageMain->publish('Stage', 'Live');
-
- $pageMainOther = new SiteTree();
- $pageMainOther->URLSegment = 'testpage';
- $pageMainOther->write();
- $pageMainOther->publish('Stage', 'Live');
-
- $this->assertNotEquals($pageMain->URLSegment, $pageMainOther->URLSegment,
- 'Pages in same subsite cant share the same URL'
- );
-
- Subsite::changeSubsite($subsite1->ID);
-
- $pageSubsite1 = new SiteTree();
- $pageSubsite1->URLSegment = 'testpage';
- $pageSubsite1->write();
- $pageSubsite1->publish('Stage', 'Live');
-
- $this->assertEquals($pageMain->URLSegment, $pageSubsite1->URLSegment,
- 'Pages in different subsites can share the same URL'
- );
- }
-
- function testBasicSanity() {
- $this->assertTrue(singleton('SiteTree')->getSiteConfig() instanceof SiteConfig);
- // The following assert is breaking in Translatable.
- $this->assertTrue(singleton('SiteTree')->getCMSFields() instanceof FieldList);
- $this->assertTrue(singleton('SubsitesVirtualPage')->getCMSFields() instanceof FieldList);
- $this->assertTrue(is_array(singleton('SiteTreeSubsites')->extraStatics()));
- }
-
- function testErrorPageLocations() {
- $subsite1 = $this->objFromFixture('Subsite', 'domaintest1');
-
- Subsite::changeSubsite($subsite1->ID);
- $path = ErrorPage::get_filepath_for_errorcode(500);
-
- $static_path = Config::inst()->get('ErrorPage', 'static_filepath');
- $expected_path = $static_path . '/error-500-'.$subsite1->domain().'.html';
- $this->assertEquals($expected_path, $path);
- }
-
- function testCanEditSiteTree() {
- $admin = $this->objFromFixture('Member', 'admin');
- $subsite1member = $this->objFromFixture('Member', 'subsite1member');
- $subsite2member = $this->objFromFixture('Member', 'subsite2member');
- $mainpage = $this->objFromFixture('Page', 'home');
- $subsite1page = $this->objFromFixture('Page', 'subsite1_home');
- $subsite2page = $this->objFromFixture('Page', 'subsite2_home');
- $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
- $subsite2 = $this->objFromFixture('Subsite', 'subsite2');
-
- // Cant pass member as arguments to canEdit() because of GroupSubsites
- Session::set("loggedInAs", $admin->ID);
- $this->assertTrue(
- (bool)$subsite1page->canEdit(),
- 'Administrators can edit all subsites'
- );
-
- // @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
- Subsite::changeSubsite($subsite1);
-
- Session::set("loggedInAs", $subsite1member->ID);
- $this->assertTrue(
- (bool)$subsite1page->canEdit(),
- 'Members can edit pages on a subsite if they are in a group belonging to this subsite'
- );
-
- Session::set("loggedInAs", $subsite2member->ID);
- $this->assertFalse(
- (bool)$subsite1page->canEdit(),
- 'Members cant edit pages on a subsite if they are not in a group belonging to this subsite'
- );
-
- // @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
- Subsite::changeSubsite(0);
- $this->assertFalse(
- $mainpage->canEdit(),
- 'Members cant edit pages on the main site if they are not in a group allowing this'
- );
- }
-
- /**
- * Similar to {@link SubsitesVirtualPageTest->testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite()}.
- */
- function testTwoPagesWithSameURLOnDifferentSubsites() {
- // Set up a couple of pages with the same URL on different subsites
- $s1 = $this->objFromFixture('Subsite','domaintest1');
- $s2 = $this->objFromFixture('Subsite','domaintest2');
-
- $p1 = new SiteTree();
- $p1->Title = $p1->URLSegment = "test-page";
- $p1->SubsiteID = $s1->ID;
- $p1->write();
+ $p2 = new SiteTree();
+ $p2->Title = $p1->URLSegment = "test-page";
+ $p2->SubsiteID = $s2->ID;
+ $p2->write();
- $p2 = new SiteTree();
- $p2->Title = $p1->URLSegment = "test-page";
- $p2->SubsiteID = $s2->ID;
- $p2->write();
+ // Check that the URLs weren't modified in our set-up
+ $this->assertEquals($p1->URLSegment, 'test-page');
+ $this->assertEquals($p2->URLSegment, 'test-page');
+
+ // Check that if we switch between the different subsites, we receive the correct pages
+ Subsite::changeSubsite($s1);
+ $this->assertEquals($p1->ID, SiteTree::get_by_link('test-page')->ID);
- // Check that the URLs weren't modified in our set-up
- $this->assertEquals($p1->URLSegment, 'test-page');
- $this->assertEquals($p2->URLSegment, 'test-page');
-
- // Check that if we switch between the different subsites, we receive the correct pages
- Subsite::changeSubsite($s1);
- $this->assertEquals($p1->ID, SiteTree::get_by_link('test-page')->ID);
+ Subsite::changeSubsite($s2);
+ $this->assertEquals($p2->ID, SiteTree::get_by_link('test-page')->ID);
+ }
+
+ public function testPageTypesBlacklistInClassDropdown()
+ {
+ $editor = $this->objFromFixture('Member', 'editor');
+ Session::set("loggedInAs", $editor->ID);
+
+ $s1 = $this->objFromFixture('Subsite', 'domaintest1');
+ $s2 = $this->objFromFixture('Subsite', 'domaintest2');
+ $page = singleton('SiteTree');
+
+ $s1->PageTypeBlacklist = 'SiteTreeSubsitesTest_ClassA,ErrorPage';
+ $s1->write();
+
+ Subsite::changeSubsite($s1);
+ $settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource();
+
+ $this->assertArrayNotHasKey('ErrorPage',
+ $settingsFields
+ );
+ $this->assertArrayNotHasKey('SiteTreeSubsitesTest_ClassA',
+ $settingsFields
+ );
+ $this->assertArrayHasKey('SiteTreeSubsitesTest_ClassB',
+ $settingsFields
+ );
- Subsite::changeSubsite($s2);
- $this->assertEquals($p2->ID, SiteTree::get_by_link('test-page')->ID);
- }
-
- function testPageTypesBlacklistInClassDropdown() {
- $editor = $this->objFromFixture('Member', 'editor');
- Session::set("loggedInAs", $editor->ID);
-
- $s1 = $this->objFromFixture('Subsite','domaintest1');
- $s2 = $this->objFromFixture('Subsite','domaintest2');
- $page = singleton('SiteTree');
-
- $s1->PageTypeBlacklist = 'SiteTreeSubsitesTest_ClassA,ErrorPage';
- $s1->write();
-
- Subsite::changeSubsite($s1);
- $settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource();
-
- $this->assertArrayNotHasKey('ErrorPage',
- $settingsFields
- );
- $this->assertArrayNotHasKey('SiteTreeSubsitesTest_ClassA',
- $settingsFields
- );
- $this->assertArrayHasKey('SiteTreeSubsitesTest_ClassB',
- $settingsFields
- );
+ Subsite::changeSubsite($s2);
+ $settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource();
+ $this->assertArrayHasKey('ErrorPage',
+ $settingsFields
+ );
+ $this->assertArrayHasKey('SiteTreeSubsitesTest_ClassA',
+ $settingsFields
+ );
+ $this->assertArrayHasKey('SiteTreeSubsitesTest_ClassB',
+ $settingsFields
+ );
+ }
+
+ public function testPageTypesBlacklistInCMSMain()
+ {
+ $editor = $this->objFromFixture('Member', 'editor');
+ Session::set("loggedInAs", $editor->ID);
+
+ $cmsmain = new CMSMain();
+
+ $s1 = $this->objFromFixture('Subsite', 'domaintest1');
+ $s2 = $this->objFromFixture('Subsite', 'domaintest2');
+
+ $s1->PageTypeBlacklist = 'SiteTreeSubsitesTest_ClassA,ErrorPage';
+ $s1->write();
- Subsite::changeSubsite($s2);
- $settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource();
- $this->assertArrayHasKey('ErrorPage',
- $settingsFields
- );
- $this->assertArrayHasKey('SiteTreeSubsitesTest_ClassA',
- $settingsFields
- );
- $this->assertArrayHasKey('SiteTreeSubsitesTest_ClassB',
- $settingsFields
- );
- }
-
- function testPageTypesBlacklistInCMSMain() {
- $editor = $this->objFromFixture('Member', 'editor');
- Session::set("loggedInAs", $editor->ID);
-
- $cmsmain = new CMSMain();
-
- $s1 = $this->objFromFixture('Subsite','domaintest1');
- $s2 = $this->objFromFixture('Subsite','domaintest2');
-
- $s1->PageTypeBlacklist = 'SiteTreeSubsitesTest_ClassA,ErrorPage';
- $s1->write();
+ Subsite::changeSubsite($s1);
+ $hints = Convert::json2array($cmsmain->SiteTreeHints());
+ $classes = $hints['Root']['disallowedChildren'];
+ $this->assertContains('ErrorPage', $classes);
+ $this->assertContains('SiteTreeSubsitesTest_ClassA', $classes);
+ $this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
- Subsite::changeSubsite($s1);
- $hints = Convert::json2array($cmsmain->SiteTreeHints());
- $classes = $hints['Root']['disallowedChildren'];
- $this->assertContains('ErrorPage', $classes);
- $this->assertContains('SiteTreeSubsitesTest_ClassA', $classes);
- $this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
-
- Subsite::changeSubsite($s2);
- $hints = Convert::json2array($cmsmain->SiteTreeHints());
- $classes = $hints['Root']['disallowedChildren'];
- $this->assertNotContains('ErrorPage', $classes);
- $this->assertNotContains('SiteTreeSubsitesTest_ClassA', $classes);
- $this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
- }
-
+ Subsite::changeSubsite($s2);
+ $hints = Convert::json2array($cmsmain->SiteTreeHints());
+ $classes = $hints['Root']['disallowedChildren'];
+ $this->assertNotContains('ErrorPage', $classes);
+ $this->assertNotContains('SiteTreeSubsitesTest_ClassA', $classes);
+ $this->assertNotContains('SiteTreeSubsitesTest_ClassB', $classes);
+ }
}
-class SiteTreeSubsitesTest_ClassA extends SiteTree implements TestOnly {}
+class SiteTreeSubsitesTest_ClassA extends SiteTree implements TestOnly
+{
+}
-class SiteTreeSubsitesTest_ClassB extends SiteTree implements TestOnly {}
+class SiteTreeSubsitesTest_ClassB extends SiteTree implements TestOnly
+{
+}
diff --git a/tests/SubsiteAdminFunctionalTest.php b/tests/SubsiteAdminFunctionalTest.php
index 02f393fa..16c626d6 100644
--- a/tests/SubsiteAdminFunctionalTest.php
+++ b/tests/SubsiteAdminFunctionalTest.php
@@ -1,143 +1,150 @@
get($url);
- while ($location = $response->getHeader('Location')) {
- $response = $this->mainSession->followRedirection();
- }
- echo $response->getHeader('Location');
-
- return $response;
- }
-
- /**
- * Anonymous user cannot access anything.
- */
- function testAnonymousIsForbiddenAdminAccess() {
- $response = $this->getAndFollowAll('admin/pages/?SubsiteID=0');
- $this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Admin is disallowed');
-
- $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
- $response = $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
- $this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Admin is disallowed');
-
- $response = $this->getAndFollowAll('SubsiteXHRController');
- $this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
- 'SubsiteXHRController is disallowed');
- }
-
- /**
- * Admin should be able to access all subsites and the main site
- */
- function testAdminCanAccessAllSubsites() {
- $member = $this->objFromFixture('Member', 'admin');
- Session::set("loggedInAs", $member->ID);
-
- $this->getAndFollowAll('admin/pages/?SubsiteID=0');
- $this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.');
- $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
-
- $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
- $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
- $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.');
- $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
-
- $response = $this->getAndFollowAll('SubsiteXHRController');
- $this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
- 'SubsiteXHRController is reachable');
- }
-
- function testAdminIsRedirectedToObjectsSubsite() {
- $member = $this->objFromFixture('Member', 'admin');
- Session::set("loggedInAs", $member->ID);
-
- $mainSubsitePage = $this->objFromFixture('Page', 'mainSubsitePage');
- $subsite1Home = $this->objFromFixture('Page', 'subsite1_home');
-
- Config::inst()->nest();
-
- Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', false);
- Subsite::changeSubsite(0);
- $this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
- $this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID, 'Loading an object switches the subsite');
- $this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
-
- Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', true);
- Subsite::changeSubsite(0);
- $this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
- $this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID, 'Loading a non-main-site object still switches the subsite if configured with treats_subsite_0_as_global');
- $this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
-
- $this->getAndFollowAll("admin/pages/edit/show/$mainSubsitePage->ID");
- $this->assertNotEquals(Subsite::currentSubsiteID(), $mainSubsitePage->SubsiteID, 'Loading a main-site object does not change the subsite if configured with treats_subsite_0_as_global');
- $this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
-
- Config::inst()->unnest();
- }
-
- /**
- * User which has AccessAllSubsites set to 1 should be able to access all subsites and main site,
- * even though he does not have the ADMIN permission.
- */
- function testEditorCanAccessAllSubsites() {
- $member = $this->objFromFixture('Member', 'editor');
- Session::set("loggedInAs", $member->ID);
-
- $this->getAndFollowAll('admin/pages/?SubsiteID=0');
- $this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.');
- $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
-
- $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
- $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
- $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.');
- $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
-
- $response = $this->getAndFollowAll('SubsiteXHRController');
- $this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
- 'SubsiteXHRController is reachable');
- }
-
- /**
- * Test a member who only has access to one subsite (subsite1) and only some sections (pages and security).
- */
- function testSubsiteAdmin() {
- $member = $this->objFromFixture('Member', 'subsite1member');
- Session::set("loggedInAs", $member->ID);
-
- $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
-
- // Check allowed URL.
- $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
- $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access own subsite.');
- $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Can access permitted section.');
-
- // Check forbidden section in allowed subsite.
- $this->getAndFollowAll("admin/assets/?SubsiteID={$subsite1->ID}");
- $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected within subsite.');
- $this->assertNotRegExp('#^admin/assets/.*#', $this->mainSession->lastUrl(),
- 'Is redirected away from forbidden section');
-
- // Check forbidden site, on a section that's allowed on another subsite
- $this->getAndFollowAll("admin/pages/?SubsiteID=0");
- $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to permitted subsite.');
-
- // Check forbidden site, on a section that's not allowed on any other subsite
- $this->getAndFollowAll("admin/assets/?SubsiteID=0");
- $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to first permitted subsite.');
- $this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Is not denied access');
-
- // Check the standalone XHR controller.
- $response = $this->getAndFollowAll('SubsiteXHRController');
- $this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
- 'SubsiteXHRController is reachable');
- }
+class SubsiteAdminFunctionalTest extends FunctionalTest
+{
+ public static $fixture_file = 'subsites/tests/SubsiteTest.yml';
+ public static $use_draft_site = true;
+
+ protected $autoFollowRedirection = false;
+
+ /**
+ * Helper: FunctionalTest is only able to follow redirection once, we want to go all the way.
+ */
+ public function getAndFollowAll($url)
+ {
+ $response = $this->get($url);
+ while ($location = $response->getHeader('Location')) {
+ $response = $this->mainSession->followRedirection();
+ }
+ echo $response->getHeader('Location');
+
+ return $response;
+ }
+
+ /**
+ * Anonymous user cannot access anything.
+ */
+ public function testAnonymousIsForbiddenAdminAccess()
+ {
+ $response = $this->getAndFollowAll('admin/pages/?SubsiteID=0');
+ $this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Admin is disallowed');
+
+ $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
+ $response = $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
+ $this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Admin is disallowed');
+
+ $response = $this->getAndFollowAll('SubsiteXHRController');
+ $this->assertRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
+ 'SubsiteXHRController is disallowed');
+ }
+
+ /**
+ * Admin should be able to access all subsites and the main site
+ */
+ public function testAdminCanAccessAllSubsites()
+ {
+ $member = $this->objFromFixture('Member', 'admin');
+ Session::set("loggedInAs", $member->ID);
+
+ $this->getAndFollowAll('admin/pages/?SubsiteID=0');
+ $this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.');
+ $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
+
+ $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
+ $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
+ $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.');
+ $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
+
+ $response = $this->getAndFollowAll('SubsiteXHRController');
+ $this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
+ 'SubsiteXHRController is reachable');
+ }
+
+ public function testAdminIsRedirectedToObjectsSubsite()
+ {
+ $member = $this->objFromFixture('Member', 'admin');
+ Session::set("loggedInAs", $member->ID);
+
+ $mainSubsitePage = $this->objFromFixture('Page', 'mainSubsitePage');
+ $subsite1Home = $this->objFromFixture('Page', 'subsite1_home');
+
+ Config::inst()->nest();
+
+ Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', false);
+ Subsite::changeSubsite(0);
+ $this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
+ $this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID, 'Loading an object switches the subsite');
+ $this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
+
+ Config::inst()->update('CMSPageEditController', 'treats_subsite_0_as_global', true);
+ Subsite::changeSubsite(0);
+ $this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
+ $this->assertEquals(Subsite::currentSubsiteID(), $subsite1Home->SubsiteID, 'Loading a non-main-site object still switches the subsite if configured with treats_subsite_0_as_global');
+ $this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
+
+ $this->getAndFollowAll("admin/pages/edit/show/$mainSubsitePage->ID");
+ $this->assertNotEquals(Subsite::currentSubsiteID(), $mainSubsitePage->SubsiteID, 'Loading a main-site object does not change the subsite if configured with treats_subsite_0_as_global');
+ $this->assertRegExp("#^admin/pages.*#", $this->mainSession->lastUrl(), 'Lands on the correct section');
+
+ Config::inst()->unnest();
+ }
+
+ /**
+ * User which has AccessAllSubsites set to 1 should be able to access all subsites and main site,
+ * even though he does not have the ADMIN permission.
+ */
+ public function testEditorCanAccessAllSubsites()
+ {
+ $member = $this->objFromFixture('Member', 'editor');
+ Session::set("loggedInAs", $member->ID);
+
+ $this->getAndFollowAll('admin/pages/?SubsiteID=0');
+ $this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.');
+ $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
+
+ $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
+ $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
+ $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.');
+ $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
+
+ $response = $this->getAndFollowAll('SubsiteXHRController');
+ $this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
+ 'SubsiteXHRController is reachable');
+ }
+
+ /**
+ * Test a member who only has access to one subsite (subsite1) and only some sections (pages and security).
+ */
+ public function testSubsiteAdmin()
+ {
+ $member = $this->objFromFixture('Member', 'subsite1member');
+ Session::set("loggedInAs", $member->ID);
+
+ $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
+
+ // Check allowed URL.
+ $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
+ $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access own subsite.');
+ $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Can access permitted section.');
+
+ // Check forbidden section in allowed subsite.
+ $this->getAndFollowAll("admin/assets/?SubsiteID={$subsite1->ID}");
+ $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected within subsite.');
+ $this->assertNotRegExp('#^admin/assets/.*#', $this->mainSession->lastUrl(),
+ 'Is redirected away from forbidden section');
+
+ // Check forbidden site, on a section that's allowed on another subsite
+ $this->getAndFollowAll("admin/pages/?SubsiteID=0");
+ $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to permitted subsite.');
+
+ // Check forbidden site, on a section that's not allowed on any other subsite
+ $this->getAndFollowAll("admin/assets/?SubsiteID=0");
+ $this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to first permitted subsite.');
+ $this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Is not denied access');
+
+ // Check the standalone XHR controller.
+ $response = $this->getAndFollowAll('SubsiteXHRController');
+ $this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(),
+ 'SubsiteXHRController is reachable');
+ }
}
diff --git a/tests/SubsiteAdminTest.php b/tests/SubsiteAdminTest.php
index 3b9fb0f5..a9f29d03 100644
--- a/tests/SubsiteAdminTest.php
+++ b/tests/SubsiteAdminTest.php
@@ -1,9 +1,11 @@
$this->idFromFixture('Member', 'admin')
));
@@ -12,39 +14,38 @@ function adminLoggedInSession() {
/**
* Test generation of the view
*/
- function testBasicView() {
- Subsite::$write_hostmap = false;
- $subsite1ID = $this->objFromFixture('Subsite','domaintest1')->ID;
+ public function testBasicView()
+ {
+ Subsite::$write_hostmap = false;
+ $subsite1ID = $this->objFromFixture('Subsite', 'domaintest1')->ID;
// Open the admin area logged in as admin
$response1 = Director::test('admin/subsites/', null, $this->adminLoggedInSession());
// Confirm that this URL gets you the entire page, with the edit form loaded
- $response2 = Director::test("admin/subsites/Subsite/EditForm/field/Subsite/item/$subsite1ID/edit", null, $this->adminLoggedInSession());
- $this->assertTrue(strpos($response2->getBody(), 'id="Form_ItemEditForm_ID"') !== false, "Testing Form_ItemEditForm_ID exists");
+ $response2 = Director::test("admin/subsites/Subsite/EditForm/field/Subsite/item/$subsite1ID/edit", null, $this->adminLoggedInSession());
+ $this->assertTrue(strpos($response2->getBody(), 'id="Form_ItemEditForm_ID"') !== false, "Testing Form_ItemEditForm_ID exists");
$this->assertTrue(strpos($response2->getBody(), ' exists");
}
-
- /**
- * Test that the main-site user with ADMIN permissions can access all subsites, regardless
- * of whether he is in a subsite-specific group or not.
- */
- function testMainsiteAdminCanAccessAllSubsites() {
- $member = $this->objFromFixture('Member', 'admin');
- Session::set("loggedInAs", $member->ID);
-
- $cmsMain = new CMSMain();
- foreach($cmsMain->Subsites() as $subsite) {
- $ids[$subsite->ID] = true;
- }
-
- $this->assertArrayHasKey(0, $ids, "Main site accessible");
- $this->assertArrayHasKey($this->idFromFixture('Subsite','main'), $ids, "Site with no groups inaccesible");
- $this->assertArrayHasKey($this->idFromFixture('Subsite','subsite1'), $ids, "Subsite1 Template inaccessible");
- $this->assertArrayHasKey($this->idFromFixture('Subsite','subsite2'), $ids, "Subsite2 Template inaccessible");
- }
-
-
+
+ /**
+ * Test that the main-site user with ADMIN permissions can access all subsites, regardless
+ * of whether he is in a subsite-specific group or not.
+ */
+ public function testMainsiteAdminCanAccessAllSubsites()
+ {
+ $member = $this->objFromFixture('Member', 'admin');
+ Session::set("loggedInAs", $member->ID);
+
+ $cmsMain = new CMSMain();
+ foreach ($cmsMain->Subsites() as $subsite) {
+ $ids[$subsite->ID] = true;
+ }
+
+ $this->assertArrayHasKey(0, $ids, "Main site accessible");
+ $this->assertArrayHasKey($this->idFromFixture('Subsite', 'main'), $ids, "Site with no groups inaccesible");
+ $this->assertArrayHasKey($this->idFromFixture('Subsite', 'subsite1'), $ids, "Subsite1 Template inaccessible");
+ $this->assertArrayHasKey($this->idFromFixture('Subsite', 'subsite2'), $ids, "Subsite2 Template inaccessible");
+ }
}
-
diff --git a/tests/SubsiteTest.php b/tests/SubsiteTest.php
index 16ee4935..fd128e99 100644
--- a/tests/SubsiteTest.php
+++ b/tests/SubsiteTest.php
@@ -1,362 +1,380 @@
origStrictSubdomainMatching = Subsite::$strict_subdomain_matching;
+ Subsite::$strict_subdomain_matching = false;
+ }
+
+ public function tearDown()
+ {
+ parent::tearDown();
+
+ Subsite::$strict_subdomain_matching = $this->origStrictSubdomainMatching;
+ }
- static $fixture_file = 'subsites/tests/SubsiteTest.yml';
-
- function setUp() {
- parent::setUp();
-
- $this->origStrictSubdomainMatching = Subsite::$strict_subdomain_matching;
- Subsite::$strict_subdomain_matching = false;
- }
-
- function tearDown() {
- parent::tearDown();
-
- Subsite::$strict_subdomain_matching = $this->origStrictSubdomainMatching;
- }
+ /**
+ * Create a new subsite from the template and verify that all the template's pages are copied
+ */
+ public function testSubsiteCreation()
+ {
+ Subsite::$write_hostmap = false;
+
+ // Create the instance
+ $template = $this->objFromFixture('Subsite', 'main');
+
+ // Test that changeSubsite is working
+ Subsite::changeSubsite($template->ID);
+ $tmplStaff = $this->objFromFixture('Page', 'staff');
+ $tmplHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
+
+ // Publish all the pages in the template, testing that DataObject::get only returns pages from the chosen subsite
+ $pages = DataObject::get("SiteTree");
+ $totalPages = $pages->Count();
+ foreach ($pages as $page) {
+ $this->assertEquals($template->ID, $page->SubsiteID);
+ $page->publish('Stage', 'Live');
+ }
- /**
- * Create a new subsite from the template and verify that all the template's pages are copied
- */
- function testSubsiteCreation() {
- Subsite::$write_hostmap = false;
-
- // Create the instance
- $template = $this->objFromFixture('Subsite', 'main');
-
- // Test that changeSubsite is working
- Subsite::changeSubsite($template->ID);
- $tmplStaff = $this->objFromFixture('Page','staff');
- $tmplHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
-
- // Publish all the pages in the template, testing that DataObject::get only returns pages from the chosen subsite
- $pages = DataObject::get("SiteTree");
- $totalPages = $pages->Count();
- foreach($pages as $page) {
- $this->assertEquals($template->ID, $page->SubsiteID);
- $page->publish('Stage', 'Live');
- }
+ // Create a new site
+ $subsite = $template->duplicate();
+
+ // Check title
+ $this->assertEquals($subsite->Title, $template->Title);
+
+ // Another test that changeSubsite is working
+ $subsite->activate();
+
+ $siteHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
+ $this->assertNotEquals($siteHome, false, 'Home Page for subsite not found');
+ $this->assertEquals($subsite->ID, $siteHome->SubsiteID,
+ 'createInstance() copies existing pages retaining the same URLSegment'
+ );
+
+ Subsite::changeSubsite(0);
+ }
+
+ /**
+ * Confirm that domain lookup is working
+ */
+ public function testDomainLookup()
+ {
+ // Clear existing fixtures
+ foreach (DataObject::get('Subsite') as $subsite) {
+ $subsite->delete();
+ }
+ foreach (DataObject::get('SubsiteDomain') as $domain) {
+ $domain->delete();
+ }
+
+ // Much more expressive than YML in this case
+ $subsite1 = $this->createSubsiteWithDomains(array(
+ 'one.example.org' => true,
+ 'one.*' => false,
+ ));
+ $subsite2 = $this->createSubsiteWithDomains(array(
+ 'two.mysite.com' => true,
+ '*.mysite.com' => false,
+ 'subdomain.onmultiplesubsites.com' => false,
+ ));
+ $subsite3 = $this->createSubsiteWithDomains(array(
+ 'three.*' => true, // wildcards in primary domain are not recommended
+ 'subdomain.unique.com' => false,
+ '*.onmultiplesubsites.com' => false,
+ ));
+
+ $this->assertEquals(
+ $subsite3->ID,
+ Subsite::getSubsiteIDForDomain('subdomain.unique.com'),
+ 'Full unique match'
+ );
+
+ $this->assertEquals(
+ $subsite1->ID,
+ Subsite::getSubsiteIDForDomain('one.example.org'),
+ 'Full match, doesn\'t complain about multiple matches within a single subsite'
+ );
+
+ $failed = false;
+ try {
+ Subsite::getSubsiteIDForDomain('subdomain.onmultiplesubsites.com');
+ } catch (UnexpectedValueException $e) {
+ $failed = true;
+ }
+ $this->assertTrue(
+ $failed,
+ 'Fails on multiple matches with wildcard vs. www across multiple subsites'
+ );
+
+ $this->assertEquals(
+ $subsite1->ID,
+ Subsite::getSubsiteIDForDomain('one.unique.com'),
+ 'Fuzzy match suffixed with wildcard (rule "one.*")'
+ );
+
+ $this->assertEquals(
+ $subsite2->ID,
+ Subsite::getSubsiteIDForDomain('two.mysite.com'),
+ 'Matches correct subsite for rule'
+ );
+
+ $this->assertEquals(
+ $subsite2->ID,
+ Subsite::getSubsiteIDForDomain('other.mysite.com'),
+ 'Fuzzy match prefixed with wildcard (rule "*.mysite.com")'
+ );
- // Create a new site
- $subsite = $template->duplicate();
-
- // Check title
- $this->assertEquals($subsite->Title, $template->Title);
-
- // Another test that changeSubsite is working
- $subsite->activate();
-
- $siteHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
- $this->assertNotEquals($siteHome, false, 'Home Page for subsite not found');
- $this->assertEquals($subsite->ID, $siteHome->SubsiteID,
- 'createInstance() copies existing pages retaining the same URLSegment'
- );
-
- Subsite::changeSubsite(0);
- }
-
- /**
- * Confirm that domain lookup is working
- */
- function testDomainLookup() {
- // Clear existing fixtures
- foreach(DataObject::get('Subsite') as $subsite) $subsite->delete();
- foreach(DataObject::get('SubsiteDomain') as $domain) $domain->delete();
-
- // Much more expressive than YML in this case
- $subsite1 = $this->createSubsiteWithDomains(array(
- 'one.example.org' => true,
- 'one.*' => false,
- ));
- $subsite2 = $this->createSubsiteWithDomains(array(
- 'two.mysite.com' => true,
- '*.mysite.com' => false,
- 'subdomain.onmultiplesubsites.com' => false,
- ));
- $subsite3 = $this->createSubsiteWithDomains(array(
- 'three.*' => true, // wildcards in primary domain are not recommended
- 'subdomain.unique.com' => false,
- '*.onmultiplesubsites.com' => false,
- ));
-
- $this->assertEquals(
- $subsite3->ID,
- Subsite::getSubsiteIDForDomain('subdomain.unique.com'),
- 'Full unique match'
- );
-
- $this->assertEquals(
- $subsite1->ID,
- Subsite::getSubsiteIDForDomain('one.example.org'),
- 'Full match, doesn\'t complain about multiple matches within a single subsite'
- );
-
- $failed = false;
- try {
- Subsite::getSubsiteIDForDomain('subdomain.onmultiplesubsites.com');
- } catch(UnexpectedValueException $e) {
- $failed = true;
- }
- $this->assertTrue(
- $failed,
- 'Fails on multiple matches with wildcard vs. www across multiple subsites'
- );
-
- $this->assertEquals(
- $subsite1->ID,
- Subsite::getSubsiteIDForDomain('one.unique.com'),
- 'Fuzzy match suffixed with wildcard (rule "one.*")'
- );
-
- $this->assertEquals(
- $subsite2->ID,
- Subsite::getSubsiteIDForDomain('two.mysite.com'),
- 'Matches correct subsite for rule'
- );
-
- $this->assertEquals(
- $subsite2->ID,
- Subsite::getSubsiteIDForDomain('other.mysite.com'),
- 'Fuzzy match prefixed with wildcard (rule "*.mysite.com")'
- );
+ $this->assertEquals(
+ 0,
+ Subsite::getSubsiteIDForDomain('unknown.madeup.com'),
+ "Doesn't match unknown subsite"
+ );
+ }
+
+ public function testStrictSubdomainMatching()
+ {
+ // Clear existing fixtures
+ foreach (DataObject::get('Subsite') as $subsite) {
+ $subsite->delete();
+ }
+ foreach (DataObject::get('SubsiteDomain') as $domain) {
+ $domain->delete();
+ }
+
+ // Much more expressive than YML in this case
+ $subsite1 = $this->createSubsiteWithDomains(array(
+ 'example.org' => true,
+ 'example.com' => false,
+ '*.wildcard.com' => false,
+ ));
+ $subsite2 = $this->createSubsiteWithDomains(array(
+ 'www.example.org' => true,
+ 'www.wildcard.com' => false,
+ ));
- $this->assertEquals(
- 0,
- Subsite::getSubsiteIDForDomain('unknown.madeup.com'),
- "Doesn't match unknown subsite"
- );
-
- }
-
- function testStrictSubdomainMatching() {
- // Clear existing fixtures
- foreach(DataObject::get('Subsite') as $subsite) $subsite->delete();
- foreach(DataObject::get('SubsiteDomain') as $domain) $domain->delete();
-
- // Much more expressive than YML in this case
- $subsite1 = $this->createSubsiteWithDomains(array(
- 'example.org' => true,
- 'example.com' => false,
- '*.wildcard.com' => false,
- ));
- $subsite2 = $this->createSubsiteWithDomains(array(
- 'www.example.org' => true,
- 'www.wildcard.com' => false,
- ));
+ Subsite::$strict_subdomain_matching = false;
+
+ $this->assertEquals(
+ $subsite1->ID,
+ Subsite::getSubsiteIDForDomain('example.org'),
+ 'Exact matches without strict checking when not using www prefix'
+ );
+ $this->assertEquals(
+ $subsite1->ID,
+ Subsite::getSubsiteIDForDomain('www.example.org'),
+ 'Matches without strict checking when using www prefix, still matching first domain regardless of www prefix (falling back to subsite primary key ordering)'
+ );
+ $this->assertEquals(
+ $subsite1->ID,
+ Subsite::getSubsiteIDForDomain('www.example.com'),
+ 'Fuzzy matches without strict checking with www prefix'
+ );
+ $this->assertEquals(
+ 0,
+ Subsite::getSubsiteIDForDomain('www.wildcard.com'),
+ 'Doesn\'t match www prefix without strict check, even if a wildcard subdomain is in place'
+ );
+
+ Subsite::$strict_subdomain_matching = true;
+
+ $this->assertEquals(
+ $subsite1->ID,
+ Subsite::getSubsiteIDForDomain('example.org'),
+ 'Matches with strict checking when not using www prefix'
+ );
+ $this->assertEquals(
+ $subsite2->ID, // not 1
+ Subsite::getSubsiteIDForDomain('www.example.org'),
+ 'Matches with strict checking when using www prefix'
+ );
+ $this->assertEquals(
+ 0,
+ Subsite::getSubsiteIDForDomain('www.example.com'),
+ 'Doesn\'t fuzzy match with strict checking when using www prefix'
+ );
+ $failed = false;
+ try {
+ Subsite::getSubsiteIDForDomain('www.wildcard.com');
+ } catch (UnexpectedValueException $e) {
+ $failed = true;
+ }
+ $this->assertTrue(
+ $failed,
+ 'Fails on multiple matches with strict checking and wildcard vs. www'
+ );
+ }
+
+ protected function createSubsiteWithDomains($domains)
+ {
+ $subsite = new Subsite(array(
+ 'Title' => 'My Subsite'
+ ));
+ $subsite->write();
+ foreach ($domains as $domainStr => $isPrimary) {
+ $domain = new SubsiteDomain(array(
+ 'Domain' => $domainStr,
+ 'IsPrimary' => $isPrimary,
+ 'SubsiteID' => $subsite->ID
+ ));
+ $domain->write();
+ }
+
+ return $subsite;
+ }
- Subsite::$strict_subdomain_matching = false;
-
- $this->assertEquals(
- $subsite1->ID,
- Subsite::getSubsiteIDForDomain('example.org'),
- 'Exact matches without strict checking when not using www prefix'
- );
- $this->assertEquals(
- $subsite1->ID,
- Subsite::getSubsiteIDForDomain('www.example.org'),
- 'Matches without strict checking when using www prefix, still matching first domain regardless of www prefix (falling back to subsite primary key ordering)'
- );
- $this->assertEquals(
- $subsite1->ID,
- Subsite::getSubsiteIDForDomain('www.example.com'),
- 'Fuzzy matches without strict checking with www prefix'
- );
- $this->assertEquals(
- 0,
- Subsite::getSubsiteIDForDomain('www.wildcard.com'),
- 'Doesn\'t match www prefix without strict check, even if a wildcard subdomain is in place'
- );
-
- Subsite::$strict_subdomain_matching = true;
-
- $this->assertEquals(
- $subsite1->ID,
- Subsite::getSubsiteIDForDomain('example.org'),
- 'Matches with strict checking when not using www prefix'
- );
- $this->assertEquals(
- $subsite2->ID, // not 1
- Subsite::getSubsiteIDForDomain('www.example.org'),
- 'Matches with strict checking when using www prefix'
- );
- $this->assertEquals(
- 0,
- Subsite::getSubsiteIDForDomain('www.example.com'),
- 'Doesn\'t fuzzy match with strict checking when using www prefix'
- );
- $failed = false;
- try {
- Subsite::getSubsiteIDForDomain('www.wildcard.com');
- } catch(UnexpectedValueException $e) {
- $failed = true;
- }
- $this->assertTrue(
- $failed,
- 'Fails on multiple matches with strict checking and wildcard vs. www'
- );
-
- }
-
- protected function createSubsiteWithDomains($domains) {
- $subsite = new Subsite(array(
- 'Title' => 'My Subsite'
- ));
- $subsite->write();
- foreach($domains as $domainStr => $isPrimary) {
- $domain = new SubsiteDomain(array(
- 'Domain' => $domainStr,
- 'IsPrimary' => $isPrimary,
- 'SubsiteID' => $subsite->ID
- ));
- $domain->write();
- }
-
- return $subsite;
- }
+ /**
+ * Test the Subsite->domain() method
+ */
+ public function testDefaultDomain()
+ {
+ $this->assertEquals('one.example.org',
+ $this->objFromFixture('Subsite', 'domaintest1')->domain());
- /**
- * Test the Subsite->domain() method
- */
- function testDefaultDomain() {
- $this->assertEquals('one.example.org',
- $this->objFromFixture('Subsite','domaintest1')->domain());
+ $this->assertEquals('two.mysite.com',
+ $this->objFromFixture('Subsite', 'domaintest2')->domain());
+
+ $originalHTTPHost = $_SERVER['HTTP_HOST'];
+
+ $_SERVER['HTTP_HOST'] = "www.example.org";
+ $this->assertEquals('three.example.org',
+ $this->objFromFixture('Subsite', 'domaintest3')->domain());
- $this->assertEquals('two.mysite.com',
- $this->objFromFixture('Subsite','domaintest2')->domain());
-
- $originalHTTPHost = $_SERVER['HTTP_HOST'];
-
- $_SERVER['HTTP_HOST'] = "www.example.org";
- $this->assertEquals('three.example.org',
- $this->objFromFixture('Subsite','domaintest3')->domain());
+ $_SERVER['HTTP_HOST'] = "mysite.example.org";
+ $this->assertEquals('three.mysite.example.org',
+ $this->objFromFixture('Subsite', 'domaintest3')->domain());
- $_SERVER['HTTP_HOST'] = "mysite.example.org";
- $this->assertEquals('three.mysite.example.org',
- $this->objFromFixture('Subsite','domaintest3')->domain());
+ $this->assertEquals($_SERVER['HTTP_HOST'], singleton('Subsite')->PrimaryDomain);
+ $this->assertEquals('http://'.$_SERVER['HTTP_HOST'].Director::baseURL(), singleton('Subsite')->absoluteBaseURL());
- $this->assertEquals($_SERVER['HTTP_HOST'], singleton('Subsite')->PrimaryDomain);
- $this->assertEquals('http://'.$_SERVER['HTTP_HOST'].Director::baseURL(), singleton('Subsite')->absoluteBaseURL());
+ $_SERVER['HTTP_HOST'] = $originalHTTPHost;
+ }
- $_SERVER['HTTP_HOST'] = $originalHTTPHost;
- }
+ public function testAllSites()
+ {
+ $subsites = Subsite::all_sites();
+ $this->assertDOSEquals(array(
+ array('Title' =>'Main site'),
+ array('Title' =>'Template'),
+ array('Title' =>'Subsite1 Template'),
+ array('Title' =>'Subsite2 Template'),
+ array('Title' =>'Test 1'),
+ array('Title' =>'Test 2'),
+ array('Title' =>'Test 3')
+ ), $subsites, 'Lists all subsites');
+ }
- function testAllSites() {
- $subsites = Subsite::all_sites();
- $this->assertDOSEquals(array(
- array('Title' =>'Main site'),
- array('Title' =>'Template'),
- array('Title' =>'Subsite1 Template'),
- array('Title' =>'Subsite2 Template'),
- array('Title' =>'Test 1'),
- array('Title' =>'Test 2'),
- array('Title' =>'Test 3')
- ), $subsites, 'Lists all subsites');
- }
+ public function testAllAccessibleSites()
+ {
+ $member = $this->objFromFixture('Member', 'subsite1member');
- function testAllAccessibleSites() {
- $member = $this->objFromFixture('Member', 'subsite1member');
+ $subsites = Subsite::all_accessible_sites(true, 'Main site', $member);
+ $this->assertDOSEquals(array(
+ array('Title' =>'Subsite1 Template')
+ ), $subsites, 'Lists member-accessible sites.');
+ }
- $subsites = Subsite::all_accessible_sites(true, 'Main site', $member);
- $this->assertDOSEquals(array(
- array('Title' =>'Subsite1 Template')
- ), $subsites, 'Lists member-accessible sites.');
- }
+ /**
+ * Test Subsite::accessible_sites()
+ */
+ public function testAccessibleSites()
+ {
+ $member1Sites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
+ $this->objFromFixture('Member', 'subsite1member'));
+ $member1SiteTitles = $member1Sites->column("Title");
+ sort($member1SiteTitles);
+ $this->assertEquals('Subsite1 Template', $member1SiteTitles[0], 'Member can get to a subsite via a group');
- /**
- * Test Subsite::accessible_sites()
- */
- function testAccessibleSites() {
- $member1Sites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
- $this->objFromFixture('Member', 'subsite1member'));
- $member1SiteTitles = $member1Sites->column("Title");
- sort($member1SiteTitles);
- $this->assertEquals('Subsite1 Template', $member1SiteTitles[0], 'Member can get to a subsite via a group');
+ $adminSites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
+ $this->objFromFixture('Member', 'admin'));
+ $adminSiteTitles = $adminSites->column("Title");
+ sort($adminSiteTitles);
+ $this->assertEquals(array(
+ 'Subsite1 Template',
+ 'Subsite2 Template',
+ 'Template',
+ 'Test 1',
+ 'Test 2',
+ 'Test 3',
+ ), $adminSiteTitles);
- $adminSites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
- $this->objFromFixture('Member', 'admin'));
- $adminSiteTitles = $adminSites->column("Title");
- sort($adminSiteTitles);
- $this->assertEquals(array(
- 'Subsite1 Template',
- 'Subsite2 Template',
- 'Template',
- 'Test 1',
- 'Test 2',
- 'Test 3',
- ), $adminSiteTitles);
+ $member2Sites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
+ $this->objFromFixture('Member', 'subsite1member2'));
+ $member2SiteTitles = $member2Sites->column("Title");
+ sort($member2SiteTitles);
+ $this->assertEquals('Subsite1 Template', $member2SiteTitles[0], 'Member can get to subsite via a group role');
+ }
+
+ public function testhasMainSitePermission()
+ {
+ $admin = $this->objFromFixture('Member', 'admin');
+ $subsite1member = $this->objFromFixture('Member', 'subsite1member');
+ $subsite1admin = $this->objFromFixture('Member', 'subsite1admin');
+ $allsubsitesauthor = $this->objFromFixture('Member', 'allsubsitesauthor');
+
+ $this->assertTrue(
+ Subsite::hasMainSitePermission($admin),
+ 'Default permissions granted for super-admin'
+ );
+ $this->assertTrue(
+ Subsite::hasMainSitePermission($admin, array("ADMIN")),
+ 'ADMIN permissions granted for super-admin'
+ );
+ $this->assertFalse(
+ Subsite::hasMainSitePermission($subsite1admin, array("ADMIN")),
+ 'ADMIN permissions (on main site) denied for subsite1 admin'
+ );
+ $this->assertFalse(
+ Subsite::hasMainSitePermission($subsite1admin, array("CMS_ACCESS_CMSMain")),
+ 'CMS_ACCESS_CMSMain (on main site) denied for subsite1 admin'
+ );
+ $this->assertFalse(
+ Subsite::hasMainSitePermission($allsubsitesauthor, array("ADMIN")),
+ 'ADMIN permissions (on main site) denied for CMS author with edit rights on all subsites'
+ );
+ $this->assertTrue(
+ Subsite::hasMainSitePermission($allsubsitesauthor, array("CMS_ACCESS_CMSMain")),
+ 'CMS_ACCESS_CMSMain (on main site) granted for CMS author with edit rights on all subsites'
+ );
+ $this->assertFalse(
+ Subsite::hasMainSitePermission($subsite1member, array("ADMIN")),
+ 'ADMIN (on main site) denied for subsite1 subsite1 cms author'
+ );
+ $this->assertFalse(
+ Subsite::hasMainSitePermission($subsite1member, array("CMS_ACCESS_CMSMain")),
+ 'CMS_ACCESS_CMSMain (on main site) denied for subsite1 cms author'
+ );
+ }
- $member2Sites = Subsite::accessible_sites("CMS_ACCESS_CMSMain", false, null,
- $this->objFromFixture('Member', 'subsite1member2'));
- $member2SiteTitles = $member2Sites->column("Title");
- sort($member2SiteTitles);
- $this->assertEquals('Subsite1 Template', $member2SiteTitles[0], 'Member can get to subsite via a group role');
- }
-
- function testhasMainSitePermission() {
- $admin = $this->objFromFixture('Member', 'admin');
- $subsite1member = $this->objFromFixture('Member', 'subsite1member');
- $subsite1admin = $this->objFromFixture('Member', 'subsite1admin');
- $allsubsitesauthor = $this->objFromFixture('Member', 'allsubsitesauthor');
-
- $this->assertTrue(
- Subsite::hasMainSitePermission($admin),
- 'Default permissions granted for super-admin'
- );
- $this->assertTrue(
- Subsite::hasMainSitePermission($admin, array("ADMIN")),
- 'ADMIN permissions granted for super-admin'
- );
- $this->assertFalse(
- Subsite::hasMainSitePermission($subsite1admin, array("ADMIN")),
- 'ADMIN permissions (on main site) denied for subsite1 admin'
- );
- $this->assertFalse(
- Subsite::hasMainSitePermission($subsite1admin, array("CMS_ACCESS_CMSMain")),
- 'CMS_ACCESS_CMSMain (on main site) denied for subsite1 admin'
- );
- $this->assertFalse(
- Subsite::hasMainSitePermission($allsubsitesauthor, array("ADMIN")),
- 'ADMIN permissions (on main site) denied for CMS author with edit rights on all subsites'
- );
- $this->assertTrue(
- Subsite::hasMainSitePermission($allsubsitesauthor, array("CMS_ACCESS_CMSMain")),
- 'CMS_ACCESS_CMSMain (on main site) granted for CMS author with edit rights on all subsites'
- );
- $this->assertFalse(
- Subsite::hasMainSitePermission($subsite1member, array("ADMIN")),
- 'ADMIN (on main site) denied for subsite1 subsite1 cms author'
- );
- $this->assertFalse(
- Subsite::hasMainSitePermission($subsite1member, array("CMS_ACCESS_CMSMain")),
- 'CMS_ACCESS_CMSMain (on main site) denied for subsite1 cms author'
- );
- }
-
- function testDuplicateSubsite() {
- // get subsite1 & create page
- $subsite1 = $this->objFromFixture('Subsite','domaintest1');
- $subsite1->activate();
- $page1 = new Page();
- $page1->Title = 'MyAwesomePage';
- $page1->write();
- $page1->doPublish();
- $this->assertEquals($page1->SubsiteID, $subsite1->ID);
-
- // duplicate
- $subsite2 = $subsite1->duplicate();
- $subsite2->activate();
- // change content on dupe
- $page2 = DataObject::get_one('Page', "\"Title\" = 'MyAwesomePage'");
- $page2->Title = 'MyNewAwesomePage';
- $page2->write();
- $page2->doPublish();
-
- // check change & check change has not affected subiste1
- $subsite1->activate();
- $this->assertEquals('MyAwesomePage', DataObject::get_by_id('Page', $page1->ID)->Title);
- $subsite2->activate();
- $this->assertEquals('MyNewAwesomePage', DataObject::get_by_id('Page', $page2->ID)->Title);
- }
+ public function testDuplicateSubsite()
+ {
+ // get subsite1 & create page
+ $subsite1 = $this->objFromFixture('Subsite', 'domaintest1');
+ $subsite1->activate();
+ $page1 = new Page();
+ $page1->Title = 'MyAwesomePage';
+ $page1->write();
+ $page1->doPublish();
+ $this->assertEquals($page1->SubsiteID, $subsite1->ID);
+
+ // duplicate
+ $subsite2 = $subsite1->duplicate();
+ $subsite2->activate();
+ // change content on dupe
+ $page2 = DataObject::get_one('Page', "\"Title\" = 'MyAwesomePage'");
+ $page2->Title = 'MyNewAwesomePage';
+ $page2->write();
+ $page2->doPublish();
+
+ // check change & check change has not affected subiste1
+ $subsite1->activate();
+ $this->assertEquals('MyAwesomePage', DataObject::get_by_id('Page', $page1->ID)->Title);
+ $subsite2->activate();
+ $this->assertEquals('MyNewAwesomePage', DataObject::get_by_id('Page', $page2->ID)->Title);
+ }
}
diff --git a/tests/SubsitesVirtualPageTest.php b/tests/SubsitesVirtualPageTest.php
index 1822b516..92f289bb 100644
--- a/tests/SubsitesVirtualPageTest.php
+++ b/tests/SubsitesVirtualPageTest.php
@@ -1,276 +1,288 @@
logInWithPermission('ADMIN');
-
- $fh = fopen(Director::baseFolder() . '/assets/testscript-test-file.pdf', "w");
- fwrite($fh, str_repeat('x',1000000));
- fclose($fh);
- }
+class SubsitesVirtualPageTest extends BaseSubsiteTest
+{
+ public static $fixture_file = array(
+ 'subsites/tests/SubsiteTest.yml',
+ 'subsites/tests/SubsitesVirtualPageTest.yml',
+ );
+
+ public function setUp()
+ {
+ parent::setUp();
+ $this->logInWithPermission('ADMIN');
+
+ $fh = fopen(Director::baseFolder() . '/assets/testscript-test-file.pdf', "w");
+ fwrite($fh, str_repeat('x', 1000000));
+ fclose($fh);
+ }
- function tearDown() {
- parent::tearDown();
- $testFiles = array(
- '/assets/testscript-test-file.pdf',
- '/assets/renamed-test-file.pdf',
- '/assets/renamed-test-file-second-time.pdf',
- );
- foreach($testFiles as $file) {
- if(file_exists(Director::baseFolder().$file)) unlink(Director::baseFolder().$file);
- }
- }
-
- // Attempt to bring main:linky to subsite2:linky
- function testVirtualPageFromAnotherSubsite() {
- Subsite::$write_hostmap = false;
-
- $subsite = $this->objFromFixture('Subsite', 'subsite2');
-
- Subsite::changeSubsite($subsite->ID);
- Subsite::$disable_subsite_filter = false;
-
- $linky = $this->objFromFixture('Page', 'linky');
-
- $svp = new SubsitesVirtualPage();
- $svp->CopyContentFromID = $linky->ID;
- $svp->SubsiteID = $subsite->ID;
- $svp->URLSegment = 'linky';
-
- $svp->write();
-
- $this->assertEquals($svp->SubsiteID, $subsite->ID);
- $this->assertEquals($svp->Title, $linky->Title);
- }
+ public function tearDown()
+ {
+ parent::tearDown();
+ $testFiles = array(
+ '/assets/testscript-test-file.pdf',
+ '/assets/renamed-test-file.pdf',
+ '/assets/renamed-test-file-second-time.pdf',
+ );
+ foreach ($testFiles as $file) {
+ if (file_exists(Director::baseFolder().$file)) {
+ unlink(Director::baseFolder().$file);
+ }
+ }
+ }
+
+ // Attempt to bring main:linky to subsite2:linky
+ public function testVirtualPageFromAnotherSubsite()
+ {
+ Subsite::$write_hostmap = false;
+
+ $subsite = $this->objFromFixture('Subsite', 'subsite2');
+
+ Subsite::changeSubsite($subsite->ID);
+ Subsite::$disable_subsite_filter = false;
+
+ $linky = $this->objFromFixture('Page', 'linky');
+
+ $svp = new SubsitesVirtualPage();
+ $svp->CopyContentFromID = $linky->ID;
+ $svp->SubsiteID = $subsite->ID;
+ $svp->URLSegment = 'linky';
+
+ $svp->write();
+
+ $this->assertEquals($svp->SubsiteID, $subsite->ID);
+ $this->assertEquals($svp->Title, $linky->Title);
+ }
- function testFileLinkRewritingOnVirtualPages() {
- // File setup
- $this->logInWithPermission('ADMIN');
- touch(Director::baseFolder() . '/assets/testscript-test-file.pdf');
+ public function testFileLinkRewritingOnVirtualPages()
+ {
+ // File setup
+ $this->logInWithPermission('ADMIN');
+ touch(Director::baseFolder() . '/assets/testscript-test-file.pdf');
- // Publish the source page
- $page = $this->objFromFixture('SiteTree', 'page1');
- $this->assertTrue($page->doPublish());
+ // Publish the source page
+ $page = $this->objFromFixture('SiteTree', 'page1');
+ $this->assertTrue($page->doPublish());
- // Create a virtual page from it, and publish that
- $svp = new SubsitesVirtualPage();
- $svp->CopyContentFromID = $page->ID;
- $svp->write();
- $svp->doPublish();
-
- // Rename the file
- $file = $this->objFromFixture('File', 'file1');
- $file->Name = 'renamed-test-file.pdf';
- $file->write();
-
- // Verify that the draft and publish virtual pages both have the corrected link
- $this->assertContains('ID")->value());
- $this->assertContains('ID")->value());
+ // Create a virtual page from it, and publish that
+ $svp = new SubsitesVirtualPage();
+ $svp->CopyContentFromID = $page->ID;
+ $svp->write();
+ $svp->doPublish();
+
+ // Rename the file
+ $file = $this->objFromFixture('File', 'file1');
+ $file->Name = 'renamed-test-file.pdf';
+ $file->write();
+
+ // Verify that the draft and publish virtual pages both have the corrected link
+ $this->assertContains('ID")->value());
+ $this->assertContains('ID")->value());
- // File teardown
- $testFiles = array(
- '/assets/testscript-test-file.pdf',
- '/assets/renamed-test-file.pdf',
- );
- foreach($testFiles as $file) {
- if(file_exists(Director::baseFolder().$file)) unlink(Director::baseFolder().$file);
- }
- }
+ // File teardown
+ $testFiles = array(
+ '/assets/testscript-test-file.pdf',
+ '/assets/renamed-test-file.pdf',
+ );
+ foreach ($testFiles as $file) {
+ if (file_exists(Director::baseFolder().$file)) {
+ unlink(Director::baseFolder().$file);
+ }
+ }
+ }
- function testSubsiteVirtualPagesArentInappropriatelyPublished() {
- // Fixture
- $p = new Page();
- $p->Content = "test content";
- $p->write();
- $vp = new SubsitesVirtualPage();
- $vp->CopyContentFromID = $p->ID;
- $vp->write();
+ public function testSubsiteVirtualPagesArentInappropriatelyPublished()
+ {
+ // Fixture
+ $p = new Page();
+ $p->Content = "test content";
+ $p->write();
+ $vp = new SubsitesVirtualPage();
+ $vp->CopyContentFromID = $p->ID;
+ $vp->write();
- // VP is oragne
- $this->assertTrue($vp->IsAddedToStage);
+ // VP is oragne
+ $this->assertTrue($vp->IsAddedToStage);
- // VP is still orange after we publish
- $p->doPublish();
- $this->fixVersionNumberCache($vp);
- $this->assertTrue($vp->IsAddedToStage);
-
- // A new VP created after P's initial construction
- $vp2 = new SubsitesVirtualPage();
- $vp2->CopyContentFromID = $p->ID;
- $vp2->write();
- $this->assertTrue($vp2->IsAddedToStage);
-
- // Also remains orange after a republish
- $p->Content = "new content";
- $p->write();
- $p->doPublish();
- $this->fixVersionNumberCache($vp2);
- $this->assertTrue($vp2->IsAddedToStage);
-
- // VP is now published
- $vp->doPublish();
+ // VP is still orange after we publish
+ $p->doPublish();
+ $this->fixVersionNumberCache($vp);
+ $this->assertTrue($vp->IsAddedToStage);
+
+ // A new VP created after P's initial construction
+ $vp2 = new SubsitesVirtualPage();
+ $vp2->CopyContentFromID = $p->ID;
+ $vp2->write();
+ $this->assertTrue($vp2->IsAddedToStage);
+
+ // Also remains orange after a republish
+ $p->Content = "new content";
+ $p->write();
+ $p->doPublish();
+ $this->fixVersionNumberCache($vp2);
+ $this->assertTrue($vp2->IsAddedToStage);
+
+ // VP is now published
+ $vp->doPublish();
- $this->fixVersionNumberCache($vp);
- $this->assertTrue($vp->ExistsOnLive);
- $this->assertFalse($vp->IsModifiedOnStage);
-
- // P edited, VP and P both go green
- $p->Content = "third content";
- $p->write();
+ $this->fixVersionNumberCache($vp);
+ $this->assertTrue($vp->ExistsOnLive);
+ $this->assertFalse($vp->IsModifiedOnStage);
+
+ // 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->fixVersionNumberCache($vp, $p);
+ $this->assertTrue($p->IsModifiedOnStage);
+ $this->assertTrue($vp->IsModifiedOnStage);
- // Publish, VP goes black
- $p->doPublish();
- $this->fixVersionNumberCache($vp);
- $this->assertTrue($vp->ExistsOnLive);
- $this->assertFalse($vp->IsModifiedOnStage);
- }
-
- /**
- * This test ensures published Subsites Virtual Pages immediately reflect updates
- * to their published target pages. Note - this has to happen when the virtual page
- * is in a different subsite to the page you are editing and republishing,
- * otherwise the test will pass falsely due to current subsite ID being the same.
- */
- function testPublishedSubsiteVirtualPagesUpdateIfTargetPageUpdates()
- {
- // create page
- $p = new Page();
- $p->Content = 'Content';
- $p->Title = 'Title';
- $p->writeToStage('Stage');
- $p->publish('Stage', 'Live');
- $this->assertTrue($p->ExistsOnLive);
-
- // change to subsite
- $subsite = $this->objFromFixture('Subsite', 'subsite2');
- Subsite::changeSubsite($subsite->ID);
- Subsite::$disable_subsite_filter = false;
-
- // create svp in subsite
- $svp = new SubsitesVirtualPage();
- $svp->CopyContentFromID = $p->ID;
- $svp->write();
- $svp->writeToStage('Stage');
- $svp->publish('Stage', 'Live');
- $this->assertEquals($svp->SubsiteID, $subsite->ID);
- $this->assertTrue($svp->ExistsOnLive);
-
- // change back to original subsite ("Main site")
- Subsite::changeSubsite(0);
-
- // update original page
- $p->Title = 'New Title';
- // "save & publish"
- $p->writeToStage('Stage');
- $p->publish('Stage', 'Live');
- $this->assertNotEquals($p->SubsiteID, $subsite->ID);
-
- // reload SVP from database
- // can't use DO::get by id because caches.
- $svpdb = $svp->get()->byID($svp->ID);
-
- // ensure title changed
- $this->assertEquals($svpdb->Title, $p->Title);
- }
-
- function testUnpublishingParentPageUnpublishesSubsiteVirtualPages() {
- Config::inst()->update('StaticPublisher', 'disable_realtime', true);
-
- // Go to main site, get parent page
- $subsite = $this->objFromFixture('Subsite', 'main');
- Subsite::changeSubsite($subsite->ID);
- $page = $this->objFromFixture('Page', 'importantpage');
-
- // Create two SVPs on other subsites
- $subsite = $this->objFromFixture('Subsite', 'subsite1');
- Subsite::changeSubsite($subsite->ID);
- $vp1 = new SubsitesVirtualPage();
- $vp1->CopyContentFromID = $page->ID;
- $vp1->write();
- $vp1->doPublish();
-
- $subsite = $this->objFromFixture('Subsite', 'subsite2');
- Subsite::changeSubsite($subsite->ID);
- $vp2 = new SubsitesVirtualPage();
- $vp2->CopyContentFromID = $page->ID;
- $vp2->write();
- $vp2->doPublish();
-
- // Switch back to main site, unpublish source
- $subsite = $this->objFromFixture('Subsite', 'main');
- Subsite::changeSubsite($subsite->ID);
- $page = $this->objFromFixture('Page', 'importantpage');
- $page->doUnpublish();
-
- Subsite::changeSubsite($vp1->SubsiteID);
- $onLive = Versioned::get_one_by_stage('SubsitesVirtualPage', 'Live', "\"SiteTree_Live\".\"ID\" = ".$vp1->ID);
- $this->assertNull($onLive, 'SVP has been removed from live');
-
- $subsite = $this->objFromFixture('Subsite', 'subsite2');
- Subsite::changeSubsite($vp2->SubsiteID);
- $onLive = Versioned::get_one_by_stage('SubsitesVirtualPage', 'Live', "\"SiteTree_Live\".\"ID\" = ".$vp2->ID);
- $this->assertNull($onLive, 'SVP has been removed from live');
- }
-
- /**
- * Similar to {@link SiteTreeSubsitesTest->testTwoPagesWithSameURLOnDifferentSubsites()}
- * and {@link SiteTreeSubsitesTest->testPagesInDifferentSubsitesCanShareURLSegment()}.
- */
- function testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite() {
- Subsite::$write_hostmap = false;
- $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
- $subsite2 = $this->objFromFixture('Subsite', 'subsite2');
- Subsite::changeSubsite($subsite1->ID);
-
- $subsite1Page = $this->objFromFixture('Page', 'subsite1_staff');
- $subsite1Page->URLSegment = 'staff';
- $subsite1Page->write();
-
- // saving on subsite1, and linking to subsite1
- $subsite1Vp = new SubsitesVirtualPage();
- $subsite1Vp->CopyContentFromID = $subsite1Page->ID;
- $subsite1Vp->SubsiteID = $subsite1->ID;
- $subsite1Vp->write();
- $this->assertNotEquals(
- $subsite1Vp->URLSegment,
- $subsite1Page->URLSegment,
- "Doesn't allow explicit URLSegment overrides when already existing in same subsite"
- );
-
- //Change to subsite 2
- Subsite::changeSubsite($subsite2->ID);
+ // Publish, VP goes black
+ $p->doPublish();
+ $this->fixVersionNumberCache($vp);
+ $this->assertTrue($vp->ExistsOnLive);
+ $this->assertFalse($vp->IsModifiedOnStage);
+ }
+
+ /**
+ * This test ensures published Subsites Virtual Pages immediately reflect updates
+ * to their published target pages. Note - this has to happen when the virtual page
+ * is in a different subsite to the page you are editing and republishing,
+ * otherwise the test will pass falsely due to current subsite ID being the same.
+ */
+ public function testPublishedSubsiteVirtualPagesUpdateIfTargetPageUpdates()
+ {
+ // create page
+ $p = new Page();
+ $p->Content = 'Content';
+ $p->Title = 'Title';
+ $p->writeToStage('Stage');
+ $p->publish('Stage', 'Live');
+ $this->assertTrue($p->ExistsOnLive);
+
+ // change to subsite
+ $subsite = $this->objFromFixture('Subsite', 'subsite2');
+ Subsite::changeSubsite($subsite->ID);
+ Subsite::$disable_subsite_filter = false;
+
+ // create svp in subsite
+ $svp = new SubsitesVirtualPage();
+ $svp->CopyContentFromID = $p->ID;
+ $svp->write();
+ $svp->writeToStage('Stage');
+ $svp->publish('Stage', 'Live');
+ $this->assertEquals($svp->SubsiteID, $subsite->ID);
+ $this->assertTrue($svp->ExistsOnLive);
+
+ // change back to original subsite ("Main site")
+ Subsite::changeSubsite(0);
+
+ // update original page
+ $p->Title = 'New Title';
+ // "save & publish"
+ $p->writeToStage('Stage');
+ $p->publish('Stage', 'Live');
+ $this->assertNotEquals($p->SubsiteID, $subsite->ID);
+
+ // reload SVP from database
+ // can't use DO::get by id because caches.
+ $svpdb = $svp->get()->byID($svp->ID);
+
+ // ensure title changed
+ $this->assertEquals($svpdb->Title, $p->Title);
+ }
+
+ public function testUnpublishingParentPageUnpublishesSubsiteVirtualPages()
+ {
+ Config::inst()->update('StaticPublisher', 'disable_realtime', true);
+
+ // Go to main site, get parent page
+ $subsite = $this->objFromFixture('Subsite', 'main');
+ Subsite::changeSubsite($subsite->ID);
+ $page = $this->objFromFixture('Page', 'importantpage');
+
+ // Create two SVPs on other subsites
+ $subsite = $this->objFromFixture('Subsite', 'subsite1');
+ Subsite::changeSubsite($subsite->ID);
+ $vp1 = new SubsitesVirtualPage();
+ $vp1->CopyContentFromID = $page->ID;
+ $vp1->write();
+ $vp1->doPublish();
+
+ $subsite = $this->objFromFixture('Subsite', 'subsite2');
+ Subsite::changeSubsite($subsite->ID);
+ $vp2 = new SubsitesVirtualPage();
+ $vp2->CopyContentFromID = $page->ID;
+ $vp2->write();
+ $vp2->doPublish();
+
+ // Switch back to main site, unpublish source
+ $subsite = $this->objFromFixture('Subsite', 'main');
+ Subsite::changeSubsite($subsite->ID);
+ $page = $this->objFromFixture('Page', 'importantpage');
+ $page->doUnpublish();
+
+ Subsite::changeSubsite($vp1->SubsiteID);
+ $onLive = Versioned::get_one_by_stage('SubsitesVirtualPage', 'Live', "\"SiteTree_Live\".\"ID\" = ".$vp1->ID);
+ $this->assertNull($onLive, 'SVP has been removed from live');
+
+ $subsite = $this->objFromFixture('Subsite', 'subsite2');
+ Subsite::changeSubsite($vp2->SubsiteID);
+ $onLive = Versioned::get_one_by_stage('SubsitesVirtualPage', 'Live', "\"SiteTree_Live\".\"ID\" = ".$vp2->ID);
+ $this->assertNull($onLive, 'SVP has been removed from live');
+ }
+
+ /**
+ * Similar to {@link SiteTreeSubsitesTest->testTwoPagesWithSameURLOnDifferentSubsites()}
+ * and {@link SiteTreeSubsitesTest->testPagesInDifferentSubsitesCanShareURLSegment()}.
+ */
+ public function testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite()
+ {
+ Subsite::$write_hostmap = false;
+ $subsite1 = $this->objFromFixture('Subsite', 'subsite1');
+ $subsite2 = $this->objFromFixture('Subsite', 'subsite2');
+ Subsite::changeSubsite($subsite1->ID);
+
+ $subsite1Page = $this->objFromFixture('Page', 'subsite1_staff');
+ $subsite1Page->URLSegment = 'staff';
+ $subsite1Page->write();
+
+ // saving on subsite1, and linking to subsite1
+ $subsite1Vp = new SubsitesVirtualPage();
+ $subsite1Vp->CopyContentFromID = $subsite1Page->ID;
+ $subsite1Vp->SubsiteID = $subsite1->ID;
+ $subsite1Vp->write();
+ $this->assertNotEquals(
+ $subsite1Vp->URLSegment,
+ $subsite1Page->URLSegment,
+ "Doesn't allow explicit URLSegment overrides when already existing in same subsite"
+ );
+
+ //Change to subsite 2
+ Subsite::changeSubsite($subsite2->ID);
- // saving in subsite2 (which already has a page with URLSegment 'contact-us'),
- // but linking to a page in subsite1
- $subsite2Vp = new SubsitesVirtualPage();
- $subsite2Vp->CopyContentFromID = $subsite1Page->ID;
- $subsite2Vp->SubsiteID = $subsite2->ID;
- $subsite2Vp->write();
- $this->assertEquals(
- $subsite2Vp->URLSegment,
- $subsite1Page->URLSegment,
- "Does allow explicit URLSegment overrides when only existing in a different subsite"
- );
- }
-
- function fixVersionNumberCache($page) {
- $pages = func_get_args();
- foreach($pages as $p) {
- Versioned::prepopulate_versionnumber_cache('SiteTree', 'Stage', array($p->ID));
- Versioned::prepopulate_versionnumber_cache('SiteTree', 'Live', array($p->ID));
- }
- }
+ // saving in subsite2 (which already has a page with URLSegment 'contact-us'),
+ // but linking to a page in subsite1
+ $subsite2Vp = new SubsitesVirtualPage();
+ $subsite2Vp->CopyContentFromID = $subsite1Page->ID;
+ $subsite2Vp->SubsiteID = $subsite2->ID;
+ $subsite2Vp->write();
+ $this->assertEquals(
+ $subsite2Vp->URLSegment,
+ $subsite1Page->URLSegment,
+ "Does allow explicit URLSegment overrides when only existing in a different subsite"
+ );
+ }
+ public function fixVersionNumberCache($page)
+ {
+ $pages = func_get_args();
+ foreach ($pages as $p) {
+ Versioned::prepopulate_versionnumber_cache('SiteTree', 'Stage', array($p->ID));
+ Versioned::prepopulate_versionnumber_cache('SiteTree', 'Live', array($p->ID));
+ }
+ }
}
diff --git a/tests/behat/features/bootstrap/Context/FeatureContext.php b/tests/behat/features/bootstrap/Context/FeatureContext.php
index 1ac5c27c..ae49f741 100644
--- a/tests/behat/features/bootstrap/Context/FeatureContext.php
+++ b/tests/behat/features/bootstrap/Context/FeatureContext.php
@@ -2,15 +2,17 @@
namespace Subsites\Test\Behaviour;
-if(!class_exists('SilverStripe\BehatExtension\Context\SilverStripeContext')) return;
+if (!class_exists('SilverStripe\BehatExtension\Context\SilverStripeContext')) {
+ return;
+}
-use SilverStripe\BehatExtension\Context\SilverStripeContext,
- SilverStripe\BehatExtension\Context\BasicContext,
- SilverStripe\BehatExtension\Context\LoginContext,
- SilverStripe\BehatExtension\Context\FixtureContext,
- SilverStripe\Framework\Test\Behaviour\CmsFormsContext,
- SilverStripe\Framework\Test\Behaviour\CmsUiContext,
- SilverStripe\Cms\Test\Behaviour;
+use SilverStripe\BehatExtension\Context\SilverStripeContext;
+use SilverStripe\BehatExtension\Context\BasicContext;
+use SilverStripe\BehatExtension\Context\LoginContext;
+use SilverStripe\BehatExtension\Context\FixtureContext;
+use SilverStripe\Framework\Test\Behaviour\CmsFormsContext;
+use SilverStripe\Framework\Test\Behaviour\CmsUiContext;
+use SilverStripe\Cms\Test\Behaviour;
// PHPUnit
require_once 'PHPUnit/Autoload.php';
@@ -22,8 +24,8 @@
* Context automatically loaded by Behat.
* Uses subcontexts to extend functionality.
*/
-class FeatureContext extends SilverStripeContext {
-
+class FeatureContext extends SilverStripeContext
+{
/**
* @var FixtureFactory
*/
@@ -35,7 +37,8 @@ class FeatureContext extends SilverStripeContext {
*
* @param array $parameters context parameters (set them up through behat.yml)
*/
- public function __construct(array $parameters) {
+ public function __construct(array $parameters)
+ {
parent::__construct($parameters);
$this->useContext('BasicContext', new BasicContext($parameters));
@@ -50,41 +53,46 @@ public function __construct(array $parameters) {
// Use blueprints to set user name from identifier
$factory = $fixtureContext->getFixtureFactory();
$blueprint = \Injector::inst()->create('FixtureBlueprint', 'Member');
- $blueprint->addCallback('beforeCreate', function($identifier, &$data, &$fixtures) {
- if(!isset($data['FirstName'])) $data['FirstName'] = $identifier;
+ $blueprint->addCallback('beforeCreate', function ($identifier, &$data, &$fixtures) {
+ if (!isset($data['FirstName'])) {
+ $data['FirstName'] = $identifier;
+ }
});
$factory->define('Member', $blueprint);
// Auto-publish pages
- foreach(\ClassInfo::subclassesFor('SiteTree') as $id => $class) {
+ foreach (\ClassInfo::subclassesFor('SiteTree') as $id => $class) {
$blueprint = \Injector::inst()->create('FixtureBlueprint', $class);
- $blueprint->addCallback('afterCreate', function($obj, $identifier, &$data, &$fixtures) {
+ $blueprint->addCallback('afterCreate', function ($obj, $identifier, &$data, &$fixtures) {
$obj->publish('Stage', 'Live');
});
$factory->define($class, $blueprint);
- }
+ }
}
- public function setMinkParameters(array $parameters) {
+ public function setMinkParameters(array $parameters)
+ {
parent::setMinkParameters($parameters);
- if(isset($parameters['files_path'])) {
- $this->getSubcontext('FixtureContext')->setFilesPath($parameters['files_path']);
+ if (isset($parameters['files_path'])) {
+ $this->getSubcontext('FixtureContext')->setFilesPath($parameters['files_path']);
}
}
/**
* @return FixtureFactory
*/
- public function getFixtureFactory() {
- if(!$this->fixtureFactory) {
+ public function getFixtureFactory()
+ {
+ if (!$this->fixtureFactory) {
$this->fixtureFactory = \Injector::inst()->create('BehatFixtureFactory');
}
return $this->fixtureFactory;
}
- public function setFixtureFactory(FixtureFactory $factory) {
+ public function setFixtureFactory(FixtureFactory $factory)
+ {
$this->fixtureFactory = $factory;
}