NEW Add SubsiteState and initialisation middleware, replace Subsite::currentSubsiteID use

This commit is contained in:
Robbie Averill 2017-08-30 11:06:07 +12:00
parent ce360aa383
commit e129cafa94
16 changed files with 232 additions and 103 deletions

View File

@ -1 +1,5 @@
<?php <?php
use SilverStripe\Dev\Deprecation;
Deprecation::notification_version('2.0', 'subsites');

10
_config/middleware.yml Normal file
View File

@ -0,0 +1,10 @@
---
Name: subsitesmiddleware
After:
- requestprocessors
---
SilverStripe\Core\Injector\Injector:
SilverStripe\Control\Director:
properties:
Middlewares:
SubsitesStateMiddleware: %$SilverStripe\Subsites\Middleware\InitStateMiddleware

View File

@ -0,0 +1,47 @@
<?php
namespace SilverStripe\Subsites\Middleware;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\Middleware\HTTPMiddleware;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;
class InitStateMiddleware implements HTTPMiddleware
{
public function process(HTTPRequest $request, callable $delegate)
{
$state = SubsiteState::create();
Injector::inst()->registerService($state);
$state->setSubsiteId($this->detectSubsiteId($request));
return $delegate($request);
}
/**
* Use the given request to detect the current subsite ID
*
* @param HTTPRequest $request
* @return int
*/
protected function detectSubsiteId(HTTPRequest $request)
{
$id = null;
if ($request->getVar('SubsiteID')) {
$id = (int) $request->getVar('SubsiteID');
}
if (Subsite::$use_session_subsiteid) {
$id = $request->getSession()->get('SubsiteID');
}
if ($id === null) {
$id = Subsite::getSubsiteIDForDomain();
}
return (int) $id;
}
}

View File

@ -0,0 +1,60 @@
<?php
namespace SilverStripe\Subsites\State;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\Core\Injector\Injector;
/**
* SubsiteState provides static access to the current state for subsite related data during a request
*/
class SubsiteState
{
use Injectable;
/**
* @var int|null
*/
protected $subsiteId;
/**
* Get the current subsite ID
*
* @return int|null
*/
public function getSubsiteId()
{
return $this->subsiteId;
}
/**
* Set the current subsite ID
*
* @param int $id
* @return $this
*/
public function setSubsiteId($id)
{
$this->subsiteId = (int) $id;
return $this;
}
/**
* Perform a given action within the context of a new, isolated state. Modifications are temporary
* and the existing state will be restored afterwards.
*
* @param callable $callback Callback to run. Will be passed the nested state as a parameter
* @return mixed Result of callback
*/
public function withState(callable $callback)
{
$newState = clone $this;
try {
Injector::inst()->registerService($newState);
return $callback($newState);
} finally {
Injector::inst()->registerService($this);
}
}
}

View File

@ -3,14 +3,14 @@
namespace SilverStripe\Subsites\Extensions; namespace SilverStripe\Subsites\Extensions;
use SilverStripe\Core\Extension; use SilverStripe\Core\Extension;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\HiddenField; use SilverStripe\Forms\HiddenField;
use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\State\SubsiteState;
class CMSPageAddControllerExtension extends Extension class CMSPageAddControllerExtension extends Extension
{ {
public function updatePageOptions(FieldList $fields)
public function updatePageOptions(&$fields)
{ {
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID())); $fields->push(HiddenField::create('SubsiteID', 'SubsiteID', SubsiteState::singleton()->getSubsiteId()));
} }
} }

View File

@ -3,7 +3,6 @@
namespace SilverStripe\Subsites\Extensions; namespace SilverStripe\Subsites\Extensions;
use SilverStripe\Assets\Folder; use SilverStripe\Assets\Folder;
use SilverStripe\Control\Session;
use SilverStripe\Forms\DropdownField; use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\FieldList; use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\LiteralField; use SilverStripe\Forms\LiteralField;
@ -12,6 +11,7 @@ use SilverStripe\ORM\DataQuery;
use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\Security\Permission; use SilverStripe\Security\Permission;
use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;
/** /**
* Extension for the File object to add subsites support * Extension for the File object to add subsites support
@ -96,7 +96,10 @@ class FileSubsites extends DataExtension
return; return;
} }
$subsiteID = (int)Subsite::currentSubsiteID(); $subsiteID = SubsiteState::singleton()->getSubsiteId();
if ($subsiteID === null) {
return;
}
// The foreach is an ugly way of getting the first key :-) // The foreach is an ugly way of getting the first key :-)
foreach ($query->getFrom() as $tableName => $info) { foreach ($query->getFrom() as $tableName => $info) {
@ -120,7 +123,7 @@ class FileSubsites extends DataExtension
if (self::$default_root_folders_global) { if (self::$default_root_folders_global) {
$this->owner->SubsiteID = 0; $this->owner->SubsiteID = 0;
} else { } else {
$this->owner->SubsiteID = Subsite::currentSubsiteID(); $this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
} }
} }
} }
@ -131,7 +134,7 @@ class FileSubsites extends DataExtension
if ($this->owner->Parent()) { if ($this->owner->Parent()) {
$this->owner->SubsiteID = $this->owner->Parent()->SubsiteID; $this->owner->SubsiteID = $this->owner->Parent()->SubsiteID;
} else { } else {
$this->owner->SubsiteID = Subsite::currentSubsiteID(); $this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
} }
$this->owner->write(); $this->owner->write();
} }
@ -139,16 +142,16 @@ class FileSubsites extends DataExtension
public function canEdit($member = null) public function canEdit($member = null)
{ {
// Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group // Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group
$subsiteID = Session::get('SubsiteID'); $subsiteID = SubsiteState::singleton()->getSubsiteId();
if ($subsiteID && $subsiteID == $this->owner->SubsiteID) { if ($subsiteID && $subsiteID == $this->owner->SubsiteID) {
return true; return true;
} }
Session::set('SubsiteID', $this->owner->SubsiteID); return SubsiteState::singleton()->withState(function ($newState) {
$access = Permission::check(['CMS_ACCESS_AssetAdmin', 'CMS_ACCESS_LeftAndMain']); $newState->setSubsiteId($this->owner->SubsiteID);
Session::set('SubsiteID', $subsiteID);
return $access; return Permission::check(['CMS_ACCESS_AssetAdmin', 'CMS_ACCESS_LeftAndMain']);
});
} }
/** /**
@ -158,6 +161,6 @@ class FileSubsites extends DataExtension
*/ */
public function cacheKeyComponent() public function cacheKeyComponent()
{ {
return 'subsite-' . Subsite::currentSubsiteID(); return 'subsite-' . SubsiteState::singleton()->getSubsiteId();
} }
} }

View File

@ -15,6 +15,7 @@ use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\Security\Group; use SilverStripe\Security\Group;
use SilverStripe\Security\PermissionProvider; use SilverStripe\Security\PermissionProvider;
use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;
/** /**
* Extension for the Group object to add subsites support * Extension for the Group object to add subsites support
@ -154,10 +155,10 @@ class GroupSubsites extends DataExtension implements PermissionProvider
// If you're querying by ID, ignore the sub-site - this is a bit ugly... // If you're querying by ID, ignore the sub-site - this is a bit ugly...
if (!$query->filtersOnID()) { if (!$query->filtersOnID()) {
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID; $subsiteID = SubsiteState::singleton()->getSubsiteId();
if ($subsiteID === null) {
else */ return;
$subsiteID = (int)Subsite::currentSubsiteID(); }
// Don't filter by Group_Subsites if we've already done that // Don't filter by Group_Subsites if we've already done that
$hasGroupSubsites = false; $hasGroupSubsites = false;
@ -198,7 +199,7 @@ class GroupSubsites extends DataExtension implements PermissionProvider
{ {
// New record test approximated by checking whether the ID has changed. // 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 // Note also that the after write test is only used when we're *not* on a subsite
if ($this->owner->isChanged('ID') && !Subsite::currentSubsiteID()) { if ($this->owner->isChanged('ID') && !SubsiteState::singleton()->getSubsiteId()) {
$this->owner->AccessAllSubsites = 1; $this->owner->AccessAllSubsites = 1;
} }
} }
@ -207,7 +208,7 @@ class GroupSubsites extends DataExtension implements PermissionProvider
{ {
// New record test approximated by checking whether the ID has changed. // 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 // Note also that the after write test is only used when we're on a subsite
if ($this->owner->isChanged('ID') && $currentSubsiteID = Subsite::currentSubsiteID()) { if ($this->owner->isChanged('ID') && $currentSubsiteID = SubsiteState::singleton()->getSubsiteId()) {
$subsites = $this->owner->Subsites(); $subsites = $this->owner->Subsites();
$subsites->add($currentSubsiteID); $subsites->add($currentSubsiteID);
} }

View File

@ -3,12 +3,12 @@
namespace SilverStripe\Subsites\Extensions; namespace SilverStripe\Subsites\Extensions;
use SilverStripe\Admin\CMSMenu; use SilverStripe\Admin\CMSMenu;
use SilverStripe\Admin\LeftAndMainExtension;
use SilverStripe\CMS\Model\SiteTree; use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\Controller; use SilverStripe\Control\Controller;
use SilverStripe\Control\Session;
use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Convert; use SilverStripe\Core\Convert;
use SilverStripe\Core\Extension; use SilverStripe\Core\Manifest\ModuleLoader;
use SilverStripe\Forms\HiddenField; use SilverStripe\Forms\HiddenField;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DataObject;
@ -17,6 +17,7 @@ use SilverStripe\Security\Permission;
use SilverStripe\Security\Security; use SilverStripe\Security\Security;
use SilverStripe\Subsites\Controller\SubsiteXHRController; use SilverStripe\Subsites\Controller\SubsiteXHRController;
use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;
use SilverStripe\View\ArrayData; use SilverStripe\View\ArrayData;
use SilverStripe\View\Requirements; use SilverStripe\View\Requirements;
@ -25,7 +26,7 @@ use SilverStripe\View\Requirements;
* *
* @package subsites * @package subsites
*/ */
class LeftAndMainSubsites extends Extension class LeftAndMainSubsites extends LeftAndMainExtension
{ {
private static $allowed_actions = ['CopyToSubsite']; private static $allowed_actions = ['CopyToSubsite'];
@ -38,9 +39,11 @@ class LeftAndMainSubsites extends Extension
public function init() public function init()
{ {
Requirements::css('subsites/css/LeftAndMain_Subsites.css'); $module = ModuleLoader::getModule('silverstripe/subsites');
Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
Requirements::javascript('subsites/javascript/VirtualPage_Subsites.js'); Requirements::css($module->getRelativeResourcePath('css/LeftAndMain_Subsites.css'));
Requirements::javascript($module->getRelativeResourcePath('javascript/LeftAndMain_Subsites.js'));
Requirements::javascript($module->getRelativeResourcePath('javascript/VirtualPage_Subsites.js'));
} }
/** /**
@ -54,7 +57,7 @@ class LeftAndMainSubsites extends Extension
public function updatePageOptions(&$fields) public function updatePageOptions(&$fields)
{ {
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID())); $fields->push(HiddenField::create('SubsiteID', 'SubsiteID', SubsiteState::singleton()->getSubsiteId()));
} }
/** /**
@ -141,13 +144,14 @@ class LeftAndMainSubsites extends Extension
public function ListSubsites() public function ListSubsites()
{ {
$list = $this->Subsites(); $list = $this->Subsites();
$currentSubsiteID = Subsite::currentSubsiteID(); $currentSubsiteID = SubsiteState::singleton()->getSubsiteId();
if ($list == null || $list->count() == 1 && $list->first()->DefaultSite == true) { if ($list == null || $list->count() == 1 && $list->first()->DefaultSite == true) {
return false; return false;
} }
Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js'); $module = ModuleLoader::getModule('silverstripe/subsites');
Requirements::javascript($module->getRelativeResourcePath('javascript/LeftAndMain_Subsites.js'));
$output = new ArrayList(); $output = new ArrayList();
@ -176,7 +180,7 @@ class LeftAndMainSubsites extends Extension
} }
// Check subsite support. // Check subsite support.
if (Subsite::currentSubsiteID() == 0) { if (SubsiteState::singleton()->getSubsiteId() == 0) {
// Main site always supports everything. // Main site always supports everything.
return true; return true;
} }
@ -194,9 +198,9 @@ class LeftAndMainSubsites extends Extension
/** /**
* Helper for testing if the subsite should be adjusted. * Helper for testing if the subsite should be adjusted.
* @param $adminClass * @param string $adminClass
* @param $recordSubsiteID * @param int $recordSubsiteID
* @param $currentSubsiteID * @param int $currentSubsiteID
* @return bool * @return bool
*/ */
public function shouldChangeSubsite($adminClass, $recordSubsiteID, $currentSubsiteID) public function shouldChangeSubsite($adminClass, $recordSubsiteID, $currentSubsiteID)
@ -227,7 +231,7 @@ class LeftAndMainSubsites extends Extension
// Check if we have access to current section on the current subsite. // Check if we have access to current section on the current subsite.
$accessibleSites = $this->owner->sectionSites(true, 'Main site', $member); $accessibleSites = $this->owner->sectionSites(true, 'Main site', $member);
return $accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID()); return $accessibleSites->count() && $accessibleSites->find('ID', SubsiteState::singleton()->getSubsiteId());
} }
/** /**
@ -283,7 +287,11 @@ class LeftAndMainSubsites extends Extension
if ($record if ($record
&& isset($record->SubsiteID, $this->owner->urlParams['ID']) && isset($record->SubsiteID, $this->owner->urlParams['ID'])
&& is_numeric($record->SubsiteID) && is_numeric($record->SubsiteID)
&& $this->shouldChangeSubsite($this->owner->class, $record->SubsiteID, Subsite::currentSubsiteID()) && $this->shouldChangeSubsite(
$this->owner->class,
$record->SubsiteID,
SubsiteState::singleton()->getSubsiteId()
)
) { ) {
// Update current subsite in session // Update current subsite in session
Subsite::changeSubsite($record->SubsiteID); Subsite::changeSubsite($record->SubsiteID);
@ -306,7 +314,9 @@ class LeftAndMainSubsites extends Extension
foreach ($menu as $candidate) { foreach ($menu as $candidate) {
if ($candidate->controller && $candidate->controller != $this->owner->class) { if ($candidate->controller && $candidate->controller != $this->owner->class) {
$accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member); $accessibleSites = singleton($candidate->controller)->sectionSites(true, 'Main site', $member);
if ($accessibleSites->count() && $accessibleSites->find('ID', Subsite::currentSubsiteID())) { if ($accessibleSites->count()
&& $accessibleSites->find('ID', SubsiteState::singleton()->getSubsiteId())
) {
// Section is accessible, redirect there. // Section is accessible, redirect there.
return $this->owner->redirect(singleton($candidate->controller)->Link()); return $this->owner->redirect(singleton($candidate->controller)->Link());
} }
@ -334,7 +344,7 @@ class LeftAndMainSubsites extends Extension
public function augmentNewSiteTreeItem(&$item) public function augmentNewSiteTreeItem(&$item)
{ {
$item->SubsiteID = isset($_POST['SubsiteID']) ? $_POST['SubsiteID'] : Subsite::currentSubsiteID(); $item->SubsiteID = isset($_POST['SubsiteID']) ? $_POST['SubsiteID'] : SubsiteState::singleton()->getSubsiteId();
} }
public function onAfterSave($record) public function onAfterSave($record)

View File

@ -9,6 +9,7 @@ use SilverStripe\ORM\DataQuery;
use SilverStripe\ORM\Queries\SQLSelect; use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\SiteConfig\SiteConfig; use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;
/** /**
* Extension for the SiteConfig object to add subsites support * Extension for the SiteConfig object to add subsites support
@ -41,7 +42,10 @@ class SiteConfigSubsites extends DataExtension
} }
} }
$subsiteID = (int)Subsite::currentSubsiteID(); $subsiteID = SubsiteState::singleton()->getSubsiteId();
if ($subsiteID === null) {
return;
}
$froms = $query->getFrom(); $froms = $query->getFrom();
$froms = array_keys($froms); $froms = array_keys($froms);
@ -55,7 +59,7 @@ class SiteConfigSubsites extends DataExtension
public function onBeforeWrite() public function onBeforeWrite()
{ {
if ((!is_numeric($this->owner->ID) || !$this->owner->ID) && !$this->owner->SubsiteID) { if ((!is_numeric($this->owner->ID) || !$this->owner->ID) && !$this->owner->SubsiteID) {
$this->owner->SubsiteID = Subsite::currentSubsiteID(); $this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
} }
} }
@ -64,11 +68,11 @@ class SiteConfigSubsites extends DataExtension
*/ */
public function cacheKeyComponent() public function cacheKeyComponent()
{ {
return 'subsite-' . Subsite::currentSubsiteID(); return 'subsite-' . SubsiteState::singleton()->getSubsiteId();
} }
public function updateCMSFields(FieldList $fields) public function updateCMSFields(FieldList $fields)
{ {
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID())); $fields->push(HiddenField::create('SubsiteID', 'SubsiteID', SubsiteState::singleton()->getSubsiteId()));
} }
} }

View File

@ -2,6 +2,7 @@
namespace SilverStripe\Subsites\Extensions; namespace SilverStripe\Subsites\Extensions;
use Page;
use SilverStripe\CMS\Model\SiteTree; use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\Controller; use SilverStripe\Control\Controller;
use SilverStripe\Control\Director; use SilverStripe\Control\Director;
@ -20,6 +21,7 @@ use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\Security\Member; use SilverStripe\Security\Member;
use SilverStripe\SiteConfig\SiteConfig; use SilverStripe\SiteConfig\SiteConfig;
use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;
use SilverStripe\View\SSViewer; use SilverStripe\View\SSViewer;
/** /**
@ -64,12 +66,15 @@ class SiteTreeSubsites extends DataExtension
return; return;
} }
$subsiteID = null;
if (Subsite::$force_subsite) { if (Subsite::$force_subsite) {
$subsiteID = Subsite::$force_subsite; $subsiteID = Subsite::$force_subsite;
} else { } else {
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID; $subsiteID = SubsiteState::singleton()->getSubsiteId();
else */ }
$subsiteID = (int)Subsite::currentSubsiteID();
if ($subsiteID === null) {
return;
} }
// The foreach is an ugly way of getting the first key :-) // The foreach is an ugly way of getting the first key :-)
@ -87,7 +92,7 @@ class SiteTreeSubsites extends DataExtension
public function onBeforeWrite() public function onBeforeWrite()
{ {
if (!$this->owner->ID && !$this->owner->SubsiteID) { if (!$this->owner->ID && !$this->owner->SubsiteID) {
$this->owner->SubsiteID = Subsite::currentSubsiteID(); $this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
} }
parent::onBeforeWrite(); parent::onBeforeWrite();
@ -128,7 +133,7 @@ class SiteTreeSubsites extends DataExtension
)->setHeadingLevel(4) )->setHeadingLevel(4)
); );
// @todo check if this needs re-implementation
// $copyAction->includeDefaultJS(false); // $copyAction->includeDefaultJS(false);
} }
@ -163,7 +168,7 @@ class SiteTreeSubsites extends DataExtension
$subsiteID = $subsiteID->ID; $subsiteID = $subsiteID->ID;
} }
$oldSubsite = Subsite::currentSubsiteID(); $oldSubsite = SubsiteState::singleton()->getSubsiteId();
if ($subsiteID) { if ($subsiteID) {
Subsite::changeSubsite($subsiteID); Subsite::changeSubsite($subsiteID);
} else { } else {
@ -276,7 +281,7 @@ class SiteTreeSubsites extends DataExtension
// //
// We do the second best: fetch the likely SubsiteID from the session. The drawback is this might // 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. // make it possible to force relations to point to other (forbidden) subsites.
$subsiteID = Subsite::currentSubsiteID(); $subsiteID = SubsiteState::singleton()->getSubsiteId();
} }
// Return true if they have access to this object's site // Return true if they have access to this object's site
@ -427,7 +432,7 @@ class SiteTreeSubsites extends DataExtension
public function augmentValidURLSegment() public function augmentValidURLSegment()
{ {
// If this page is being filtered in the current subsite, then no custom validation query is required. // If this page is being filtered in the current subsite, then no custom validation query is required.
$subsite = Subsite::$force_subsite ?: Subsite::currentSubsiteID(); $subsite = Subsite::$force_subsite ?: SubsiteState::singleton()->getSubsiteId();
if (empty($this->owner->SubsiteID) || $subsite == $this->owner->SubsiteID) { if (empty($this->owner->SubsiteID) || $subsite == $this->owner->SubsiteID) {
return null; return null;
} }
@ -450,7 +455,7 @@ class SiteTreeSubsites extends DataExtension
*/ */
public function cacheKeyComponent() public function cacheKeyComponent()
{ {
return 'subsite-' . Subsite::currentSubsiteID(); return 'subsite-' . SubsiteState::singleton()->getSubsiteId();
} }
/** /**

View File

@ -4,7 +4,6 @@ namespace SilverStripe\Subsites\Model;
use SilverStripe\Admin\CMSMenu; use SilverStripe\Admin\CMSMenu;
use SilverStripe\CMS\Model\SiteTree; use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director; use SilverStripe\Control\Director;
use SilverStripe\Control\Session; use SilverStripe\Control\Session;
use SilverStripe\Core\Convert; use SilverStripe\Core\Convert;
@ -32,6 +31,7 @@ use SilverStripe\ORM\SS_List;
use SilverStripe\Security\Group; use SilverStripe\Security\Group;
use SilverStripe\Security\Member; use SilverStripe\Security\Member;
use SilverStripe\Security\Permission; use SilverStripe\Security\Permission;
use SilverStripe\Subsites\State\SubsiteState;
use SilverStripe\Versioned\Versioned; use SilverStripe\Versioned\Versioned;
use UnexpectedValueException; use UnexpectedValueException;
@ -132,7 +132,7 @@ class Subsite extends DataObject
*/ */
public static function currentSubsite() public static function currentSubsite()
{ {
return Subsite::get()->byID(self::currentSubsiteID()); return Subsite::get()->byID(SubsiteState::singleton()->getSubsiteId());
} }
/** /**
@ -143,25 +143,14 @@ class Subsite extends DataObject
* *
* You can simulate subsite access without creating virtual hosts by appending ?SubsiteID=<ID> to the request. * You can simulate subsite access without creating virtual hosts by appending ?SubsiteID=<ID> to the request.
* *
* @todo Pass $request object from controller so we don't have to rely on $_GET
*
* @return int ID of the current subsite instance * @return int ID of the current subsite instance
*
* @deprecated 2.0..3.0 Use SubsiteState::singleton()->getSubsiteId() instead
*/ */
public static function currentSubsiteID() public static function currentSubsiteID()
{ {
$id = null; Deprecation::notice('3.0', 'Use SubsiteState::singleton()->getSubsiteId() instead');
return SubsiteState::singleton()->getSubsiteId();
if (isset($_GET['SubsiteID'])) {
$id = (int)$_GET['SubsiteID'];
} elseif (Subsite::$use_session_subsiteid) {
$id = Controller::curr()->getRequest()->getSession()->get('SubsiteID');
}
if ($id === null) {
$id = self::getSubsiteIDForDomain();
}
return (int)$id;
} }
/** /**
@ -184,7 +173,7 @@ class Subsite extends DataObject
$subsiteID = $subsite; $subsiteID = $subsite;
} }
Controller::curr()->getRequest()->getSession()->set('SubsiteID', (int)$subsiteID); SubsiteState::singleton()->setSubsiteId($subsiteID);
// Set locale // Set locale
if (is_object($subsite) && $subsite->Language !== '') { if (is_object($subsite) && $subsite->Language !== '') {
@ -381,7 +370,7 @@ class Subsite extends DataObject
$mainSiteTitle = 'Main site', $mainSiteTitle = 'Main site',
$member = null $member = null
) { ) {
// Rationalise member arguments // Rationalise member arguments
if (!$member) { if (!$member) {
$member = Member::currentUser(); $member = Member::currentUser();
@ -940,7 +929,7 @@ JS;
{ {
$duplicate = parent::duplicate($doWrite); $duplicate = parent::duplicate($doWrite);
$oldSubsiteID = Session::get('SubsiteID'); $oldSubsiteID = SubsiteState::singleton()->getSubsiteId();
self::changeSubsite($this->ID); self::changeSubsite($this->ID);
/* /*

View File

@ -10,6 +10,7 @@ use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\FunctionalTest; use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Security\Member; use SilverStripe\Security\Member;
use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;
class LeftAndMainSubsitesTest extends FunctionalTest class LeftAndMainSubsitesTest extends FunctionalTest
{ {
@ -24,7 +25,7 @@ class LeftAndMainSubsitesTest extends FunctionalTest
protected function objFromFixture($className, $identifier) protected function objFromFixture($className, $identifier)
{ {
Subsite::disable_subsite_filter(true); Subsite::disable_subsite_filter(true);
$obj = parent::objFromFixture($classname, $identifier); $obj = parent::objFromFixture($className, $identifier);
Subsite::disable_subsite_filter(false); Subsite::disable_subsite_filter(false);
return $obj; return $obj;
@ -71,13 +72,13 @@ class LeftAndMainSubsitesTest extends FunctionalTest
foreach ($ids as $id) { foreach ($ids as $id) {
Subsite::changeSubsite($id); Subsite::changeSubsite($id);
$this->assertEquals($id, Subsite::currentSubsiteID()); $this->assertEquals($id, SubsiteState::singleton()->getSubsiteId());
$left = new LeftAndMain(); $left = new LeftAndMain();
$this->assertTrue($left->canView(), "Admin user can view subsites LeftAndMain with id = '$id'"); $this->assertTrue($left->canView(), "Admin user can view subsites LeftAndMain with id = '$id'");
$this->assertEquals( $this->assertEquals(
$id, $id,
Subsite::currentSubsiteID(), SubsiteState::singleton()->getSubsiteId(),
'The current subsite has not been changed in the process of checking permissions for admin user.' 'The current subsite has not been changed in the process of checking permissions for admin user.'
); );
} }
@ -86,7 +87,6 @@ class LeftAndMainSubsitesTest extends FunctionalTest
public function testShouldChangeSubsite() public function testShouldChangeSubsite()
{ {
$l = new LeftAndMain(); $l = new LeftAndMain();
Config::nest();
Config::modify()->set(CMSPageEditController::class, 'treats_subsite_0_as_global', false); Config::modify()->set(CMSPageEditController::class, 'treats_subsite_0_as_global', false);
$this->assertTrue($l->shouldChangeSubsite(CMSPageEditController::class, 0, 5)); $this->assertTrue($l->shouldChangeSubsite(CMSPageEditController::class, 0, 5));
@ -99,7 +99,5 @@ class LeftAndMainSubsitesTest extends FunctionalTest
$this->assertFalse($l->shouldChangeSubsite(CMSPageEditController::class, 0, 0)); $this->assertFalse($l->shouldChangeSubsite(CMSPageEditController::class, 0, 0));
$this->assertTrue($l->shouldChangeSubsite(CMSPageEditController::class, 1, 5)); $this->assertTrue($l->shouldChangeSubsite(CMSPageEditController::class, 1, 5));
$this->assertFalse($l->shouldChangeSubsite(CMSPageEditController::class, 1, 1)); $this->assertFalse($l->shouldChangeSubsite(CMSPageEditController::class, 1, 1));
Config::unnest();
} }
} }

View File

@ -8,7 +8,6 @@ use SilverStripe\CMS\Controllers\ModelAsController;
use SilverStripe\ErrorPage\ErrorPage; use SilverStripe\ErrorPage\ErrorPage;
use SilverStripe\CMS\Model\SiteTree; use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\Director; use SilverStripe\Control\Director;
use SilverStripe\Control\Session;
use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Convert; use SilverStripe\Core\Convert;
use SilverStripe\Forms\FieldList; use SilverStripe\Forms\FieldList;
@ -107,7 +106,8 @@ class SiteTreeSubsitesTest extends BaseSubsiteTest
$subsite2 = $this->objFromFixture(Subsite::class, 'subsite2'); $subsite2 = $this->objFromFixture(Subsite::class, 'subsite2');
// Cant pass member as arguments to canEdit() because of GroupSubsites // Cant pass member as arguments to canEdit() because of GroupSubsites
Session::set('loggedInAs', $admin->ID); $this->logInAs($admin);
$this->assertTrue( $this->assertTrue(
(bool)$subsite1page->canEdit(), (bool)$subsite1page->canEdit(),
'Administrators can edit all subsites' 'Administrators can edit all subsites'
@ -116,13 +116,13 @@ class SiteTreeSubsitesTest extends BaseSubsiteTest
// @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state // @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
Subsite::changeSubsite($subsite1); Subsite::changeSubsite($subsite1);
Session::set('loggedInAs', $subsite1member->ID); $this->logInAs($subsite1member->ID);
$this->assertTrue( $this->assertTrue(
(bool)$subsite1page->canEdit(), (bool)$subsite1page->canEdit(),
'Members can edit pages on a subsite if they are in a group belonging to this subsite' 'Members can edit pages on a subsite if they are in a group belonging to this subsite'
); );
Session::set('loggedInAs', $subsite2member->ID); $this->logInAs($subsite2member->ID);
$this->assertFalse( $this->assertFalse(
(bool)$subsite1page->canEdit(), (bool)$subsite1page->canEdit(),
'Members cant edit pages on a subsite if they are not in a group belonging to this subsite' 'Members cant edit pages on a subsite if they are not in a group belonging to this subsite'
@ -169,8 +169,7 @@ class SiteTreeSubsitesTest extends BaseSubsiteTest
public function testPageTypesBlacklistInClassDropdown() public function testPageTypesBlacklistInClassDropdown()
{ {
$editor = $this->objFromFixture(Member::class, 'editor'); $this->logInAs('editor');
Session::set('loggedInAs', $editor->ID);
$s1 = $this->objFromFixture(Subsite::class, 'domaintest1'); $s1 = $this->objFromFixture(Subsite::class, 'domaintest1');
$s2 = $this->objFromFixture(Subsite::class, 'domaintest2'); $s2 = $this->objFromFixture(Subsite::class, 'domaintest2');
@ -241,8 +240,7 @@ class SiteTreeSubsitesTest extends BaseSubsiteTest
public function testPageTypesBlacklistInCMSMain() public function testPageTypesBlacklistInCMSMain()
{ {
$editor = $this->objFromFixture(Member::class, 'editor'); $this->logInAs('editor');
Session::set('loggedInAs', $editor->ID);
$cmsmain = new CMSMain(); $cmsmain = new CMSMain();

View File

@ -3,12 +3,11 @@
namespace SilverStripe\Subsites\Tests; namespace SilverStripe\Subsites\Tests;
use SilverStripe\CMS\Controllers\CMSPageEditController; use SilverStripe\CMS\Controllers\CMSPageEditController;
use SilverStripe\Control\Session;
use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Config;
use SilverStripe\Dev\FunctionalTest; use SilverStripe\Dev\FunctionalTest;
use SilverStripe\Security\Member;
use SilverStripe\Subsites\Controller\SubsiteXHRController; use SilverStripe\Subsites\Controller\SubsiteXHRController;
use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;
class SubsiteAdminFunctionalTest extends FunctionalTest class SubsiteAdminFunctionalTest extends FunctionalTest
{ {
@ -61,12 +60,12 @@ class SubsiteAdminFunctionalTest extends FunctionalTest
$this->logInAs('admin'); $this->logInAs('admin');
$this->getAndFollowAll('admin/pages/?SubsiteID=0'); $this->getAndFollowAll('admin/pages/?SubsiteID=0');
$this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.'); $this->assertEquals(SubsiteState::singleton()->getSubsiteId(), '0', 'Can access main site.');
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section'); $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
$this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}"); $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.'); $this->assertEquals(SubsiteState::singleton()->getSubsiteId(), $subsite1->ID, 'Can access other subsite.');
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section'); $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
$response = $this->getAndFollowAll(SubsiteXHRController::class); $response = $this->getAndFollowAll(SubsiteXHRController::class);
@ -90,7 +89,7 @@ class SubsiteAdminFunctionalTest extends FunctionalTest
Subsite::changeSubsite(0); Subsite::changeSubsite(0);
$this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID"); $this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
$this->assertEquals( $this->assertEquals(
Subsite::currentSubsiteID(), SubsiteState::singleton()->getSubsiteId(),
$subsite1Home->SubsiteID, $subsite1Home->SubsiteID,
'Loading an object switches the subsite' 'Loading an object switches the subsite'
); );
@ -100,7 +99,7 @@ class SubsiteAdminFunctionalTest extends FunctionalTest
Subsite::changeSubsite(0); Subsite::changeSubsite(0);
$this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID"); $this->getAndFollowAll("admin/pages/edit/show/$subsite1Home->ID");
$this->assertEquals( $this->assertEquals(
Subsite::currentSubsiteID(), SubsiteState::singleton()->getSubsiteId(),
$subsite1Home->SubsiteID, $subsite1Home->SubsiteID,
'Loading a non-main-site object still switches the subsite if configured with treats_subsite_0_as_global' 'Loading a non-main-site object still switches the subsite if configured with treats_subsite_0_as_global'
); );
@ -108,7 +107,7 @@ class SubsiteAdminFunctionalTest extends FunctionalTest
$this->getAndFollowAll("admin/pages/edit/show/$mainSubsitePage->ID"); $this->getAndFollowAll("admin/pages/edit/show/$mainSubsitePage->ID");
$this->assertNotEquals( $this->assertNotEquals(
Subsite::currentSubsiteID(), SubsiteState::singleton()->getSubsiteId(),
$mainSubsitePage->SubsiteID, $mainSubsitePage->SubsiteID,
'Loading a main-site object does not change the subsite if configured with treats_subsite_0_as_global' 'Loading a main-site object does not change the subsite if configured with treats_subsite_0_as_global'
); );
@ -126,12 +125,12 @@ class SubsiteAdminFunctionalTest extends FunctionalTest
$this->logInAs('editor'); $this->logInAs('editor');
$this->getAndFollowAll('admin/pages/?SubsiteID=0'); $this->getAndFollowAll('admin/pages/?SubsiteID=0');
$this->assertEquals(Subsite::currentSubsiteID(), '0', 'Can access main site.'); $this->assertEquals(SubsiteState::singleton()->getSubsiteId(), '0', 'Can access main site.');
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section'); $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
$this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}"); $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access other subsite.'); $this->assertEquals(SubsiteState::singleton()->getSubsiteId(), $subsite1->ID, 'Can access other subsite.');
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section'); $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Lands on the correct section');
$response = $this->getAndFollowAll('SubsiteXHRController'); $response = $this->getAndFollowAll('SubsiteXHRController');
@ -147,19 +146,18 @@ class SubsiteAdminFunctionalTest extends FunctionalTest
*/ */
public function testSubsiteAdmin() public function testSubsiteAdmin()
{ {
$member = $this->objFromFixture(Member::class, 'subsite1member'); $this->logInAs('subsite1member');
Session::set('loggedInAs', $member->ID);
$subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1');
// Check allowed URL. // Check allowed URL.
$this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}"); $this->getAndFollowAll("admin/pages/?SubsiteID={$subsite1->ID}");
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Can access own subsite.'); $this->assertEquals(SubsiteState::singleton()->getSubsiteId(), $subsite1->ID, 'Can access own subsite.');
$this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Can access permitted section.'); $this->assertRegExp('#^admin/pages.*#', $this->mainSession->lastUrl(), 'Can access permitted section.');
// Check forbidden section in allowed subsite. // Check forbidden section in allowed subsite.
$this->getAndFollowAll("admin/assets/?SubsiteID={$subsite1->ID}"); $this->getAndFollowAll("admin/assets/?SubsiteID={$subsite1->ID}");
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected within subsite.'); $this->assertEquals(SubsiteState::singleton()->getSubsiteId(), $subsite1->ID, 'Is redirected within subsite.');
$this->assertNotRegExp( $this->assertNotRegExp(
'#^admin/assets/.*#', '#^admin/assets/.*#',
$this->mainSession->lastUrl(), $this->mainSession->lastUrl(),
@ -168,11 +166,11 @@ class SubsiteAdminFunctionalTest extends FunctionalTest
// Check forbidden site, on a section that's allowed on another subsite // Check forbidden site, on a section that's allowed on another subsite
$this->getAndFollowAll('admin/pages/?SubsiteID=0'); $this->getAndFollowAll('admin/pages/?SubsiteID=0');
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to permitted subsite.'); $this->assertEquals(SubsiteState::singleton()->getSubsiteId(), $subsite1->ID, 'Is redirected to permitted subsite.');
// Check forbidden site, on a section that's not allowed on any other subsite // Check forbidden site, on a section that's not allowed on any other subsite
$this->getAndFollowAll('admin/assets/?SubsiteID=0'); $this->getAndFollowAll('admin/assets/?SubsiteID=0');
$this->assertEquals(Subsite::currentSubsiteID(), $subsite1->ID, 'Is redirected to first permitted subsite.'); $this->assertEquals(SubsiteState::singleton()->getSubsiteId(), $subsite1->ID, 'Is redirected to first permitted subsite.');
$this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Is not denied access'); $this->assertNotRegExp('#^Security/login.*#', $this->mainSession->lastUrl(), 'Is not denied access');
// Check the standalone XHR controller. // Check the standalone XHR controller.

View File

@ -1,6 +1,6 @@
<?php <?php
namespace subsites\tests\php; namespace SilverStripe\Subsites\Tests;
use Page; use Page;
use SilverStripe\Dev\FunctionalTest; use SilverStripe\Dev\FunctionalTest;
@ -22,7 +22,7 @@ class SubsiteFunctionalTest extends FunctionalTest
$subsitePage = $this->objFromFixture(Page::class, 'contact'); $subsitePage = $this->objFromFixture(Page::class, 'contact');
$this->get($subsitePage->AbsoluteLink()); $this->get($subsitePage->AbsoluteLink());
$this->assertEquals($subsitePage->SubsiteID, Subsite::currentSubsiteID(), 'Subsite should be changed'); $this->assertEquals($subsitePage->SubsiteID, SubsiteState::singleton()->getSubsiteId(), 'Subsite should be changed');
$this->assertEquals( $this->assertEquals(
SSViewer::get_themes(), SSViewer::get_themes(),
$defaultThemes, $defaultThemes,
@ -32,7 +32,7 @@ class SubsiteFunctionalTest extends FunctionalTest
$pageWithTheme = $this->objFromFixture(Page::class, 'subsite1_contactus'); $pageWithTheme = $this->objFromFixture(Page::class, 'subsite1_contactus');
$this->get($pageWithTheme->AbsoluteLink()); $this->get($pageWithTheme->AbsoluteLink());
$subsiteTheme = $pageWithTheme->Subsite()->Theme; $subsiteTheme = $pageWithTheme->Subsite()->Theme;
$this->assertEquals($pageWithTheme->SubsiteID, Subsite::currentSubsiteID(), 'Subsite should be changed'); $this->assertEquals($pageWithTheme->SubsiteID, SubsiteState::singleton()->getSubsiteId(), 'Subsite should be changed');
$this->assertEquals( $this->assertEquals(
SSViewer::get_themes(), SSViewer::get_themes(),
array_merge([$subsiteTheme], $defaultThemes), array_merge([$subsiteTheme], $defaultThemes),

View File

@ -10,6 +10,8 @@ use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member; use SilverStripe\Security\Member;
use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\Model\SubsiteDomain; use SilverStripe\Subsites\Model\SubsiteDomain;
use SilverStripe\Subsites\State\SubsiteState;
use UnexpectedValueException;
class SubsiteTest extends BaseSubsiteTest class SubsiteTest extends BaseSubsiteTest
{ {
@ -59,7 +61,7 @@ class SubsiteTest extends BaseSubsiteTest
// Test that changeSubsite is working // Test that changeSubsite is working
Subsite::changeSubsite($template->ID); Subsite::changeSubsite($template->ID);
$this->assertEquals($template->ID, Subsite::currentSubsiteID()); $this->assertEquals($template->ID, SubsiteState::singleton()->getSubsiteId());
$tmplStaff = $this->objFromFixture('Page', 'staff'); $tmplStaff = $this->objFromFixture('Page', 'staff');
$tmplHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'"); $tmplHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");