Skip to content

Commit

Permalink
Merge pull request #293 from creative-commoners/pulls/2.0/add-subsite…
Browse files Browse the repository at this point in the history
…-state

NEW Add SubsiteState and initialisation middleware
  • Loading branch information
Damian Mooyman committed Aug 30, 2017
2 parents 5cf2d87 + e129caf commit 46bcffa
Show file tree
Hide file tree
Showing 16 changed files with 232 additions and 103 deletions.
4 changes: 4 additions & 0 deletions _config.php
@@ -1 +1,5 @@
<?php

use SilverStripe\Dev\Deprecation;

Deprecation::notification_version('2.0', 'subsites');
10 changes: 10 additions & 0 deletions _config/middleware.yml
@@ -0,0 +1,10 @@
---
Name: subsitesmiddleware
After:
- requestprocessors
---
SilverStripe\Core\Injector\Injector:
SilverStripe\Control\Director:
properties:
Middlewares:
SubsitesStateMiddleware: %$SilverStripe\Subsites\Middleware\InitStateMiddleware
47 changes: 47 additions & 0 deletions code/Middleware/InitStateMiddleware.php
@@ -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;
}
}
60 changes: 60 additions & 0 deletions code/State/SubsiteState.php
@@ -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);
}
}
}
8 changes: 4 additions & 4 deletions code/extensions/CMSPageAddControllerExtension.php
Expand Up @@ -3,14 +3,14 @@
namespace SilverStripe\Subsites\Extensions;

use SilverStripe\Core\Extension;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\HiddenField;
use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;

class CMSPageAddControllerExtension extends Extension
{

public function updatePageOptions(&$fields)
public function updatePageOptions(FieldList $fields)
{
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
$fields->push(HiddenField::create('SubsiteID', 'SubsiteID', SubsiteState::singleton()->getSubsiteId()));
}
}
23 changes: 13 additions & 10 deletions code/extensions/FileSubsites.php
Expand Up @@ -3,7 +3,6 @@
namespace SilverStripe\Subsites\Extensions;

use SilverStripe\Assets\Folder;
use SilverStripe\Control\Session;
use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\LiteralField;
Expand All @@ -12,6 +11,7 @@
use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\Security\Permission;
use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;

/**
* Extension for the File object to add subsites support
Expand Down Expand Up @@ -96,7 +96,10 @@ public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)
return;
}

$subsiteID = (int)Subsite::currentSubsiteID();
$subsiteID = SubsiteState::singleton()->getSubsiteId();
if ($subsiteID === null) {
return;
}

// The foreach is an ugly way of getting the first key :-)
foreach ($query->getFrom() as $tableName => $info) {
Expand All @@ -120,7 +123,7 @@ public function onBeforeWrite()
if (self::$default_root_folders_global) {
$this->owner->SubsiteID = 0;
} else {
$this->owner->SubsiteID = Subsite::currentSubsiteID();
$this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
}
}
}
Expand All @@ -131,24 +134,24 @@ public function onAfterUpload()
if ($this->owner->Parent()) {
$this->owner->SubsiteID = $this->owner->Parent()->SubsiteID;
} else {
$this->owner->SubsiteID = Subsite::currentSubsiteID();
$this->owner->SubsiteID = SubsiteState::singleton()->getSubsiteId();
}
$this->owner->write();
}

public function canEdit($member = null)
{
// 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) {
return true;
}

Session::set('SubsiteID', $this->owner->SubsiteID);
$access = Permission::check(['CMS_ACCESS_AssetAdmin', 'CMS_ACCESS_LeftAndMain']);
Session::set('SubsiteID', $subsiteID);
return SubsiteState::singleton()->withState(function ($newState) {
$newState->setSubsiteId($this->owner->SubsiteID);

return $access;
return Permission::check(['CMS_ACCESS_AssetAdmin', 'CMS_ACCESS_LeftAndMain']);
});
}

/**
Expand All @@ -158,6 +161,6 @@ public function canEdit($member = null)
*/
public function cacheKeyComponent()
{
return 'subsite-' . Subsite::currentSubsiteID();
return 'subsite-' . SubsiteState::singleton()->getSubsiteId();
}
}
13 changes: 7 additions & 6 deletions code/extensions/GroupSubsites.php
Expand Up @@ -15,6 +15,7 @@
use SilverStripe\Security\Group;
use SilverStripe\Security\PermissionProvider;
use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;

/**
* Extension for the Group object to add subsites support
Expand Down Expand Up @@ -154,10 +155,10 @@ public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null)

// 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();
$subsiteID = SubsiteState::singleton()->getSubsiteId();
if ($subsiteID === null) {
return;
}

// Don't filter by Group_Subsites if we've already done that
$hasGroupSubsites = false;
Expand Down Expand Up @@ -198,7 +199,7 @@ 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()) {
if ($this->owner->isChanged('ID') && !SubsiteState::singleton()->getSubsiteId()) {
$this->owner->AccessAllSubsites = 1;
}
}
Expand All @@ -207,7 +208,7 @@ 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()) {
if ($this->owner->isChanged('ID') && $currentSubsiteID = SubsiteState::singleton()->getSubsiteId()) {
$subsites = $this->owner->Subsites();
$subsites->add($currentSubsiteID);
}
Expand Down
44 changes: 27 additions & 17 deletions code/extensions/LeftAndMainSubsites.php
Expand Up @@ -3,12 +3,12 @@
namespace SilverStripe\Subsites\Extensions;

use SilverStripe\Admin\CMSMenu;
use SilverStripe\Admin\LeftAndMainExtension;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Session;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Convert;
use SilverStripe\Core\Extension;
use SilverStripe\Core\Manifest\ModuleLoader;
use SilverStripe\Forms\HiddenField;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
Expand All @@ -17,6 +17,7 @@
use SilverStripe\Security\Security;
use SilverStripe\Subsites\Controller\SubsiteXHRController;
use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\State\SubsiteState;
use SilverStripe\View\ArrayData;
use SilverStripe\View\Requirements;

Expand All @@ -25,7 +26,7 @@
*
* @package subsites
*/
class LeftAndMainSubsites extends Extension
class LeftAndMainSubsites extends LeftAndMainExtension
{
private static $allowed_actions = ['CopyToSubsite'];

Expand All @@ -38,9 +39,11 @@ class LeftAndMainSubsites extends Extension

public function init()
{
Requirements::css('subsites/css/LeftAndMain_Subsites.css');
Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
Requirements::javascript('subsites/javascript/VirtualPage_Subsites.js');
$module = ModuleLoader::getModule('silverstripe/subsites');

Requirements::css($module->getRelativeResourcePath('css/LeftAndMain_Subsites.css'));
Requirements::javascript($module->getRelativeResourcePath('javascript/LeftAndMain_Subsites.js'));
Requirements::javascript($module->getRelativeResourcePath('javascript/VirtualPage_Subsites.js'));
}

/**
Expand All @@ -54,7 +57,7 @@ public function getCMSTreeTitle()

public function updatePageOptions(&$fields)
{
$fields->push(new HiddenField('SubsiteID', 'SubsiteID', Subsite::currentSubsiteID()));
$fields->push(HiddenField::create('SubsiteID', 'SubsiteID', SubsiteState::singleton()->getSubsiteId()));
}

/**
Expand Down Expand Up @@ -141,13 +144,14 @@ public function Subsites()
public function ListSubsites()
{
$list = $this->Subsites();
$currentSubsiteID = Subsite::currentSubsiteID();
$currentSubsiteID = SubsiteState::singleton()->getSubsiteId();

if ($list == null || $list->count() == 1 && $list->first()->DefaultSite == true) {
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();

Expand Down Expand Up @@ -176,7 +180,7 @@ public function alternateMenuDisplayCheck($controllerName)
}

// Check subsite support.
if (Subsite::currentSubsiteID() == 0) {
if (SubsiteState::singleton()->getSubsiteId() == 0) {
// Main site always supports everything.
return true;
}
Expand All @@ -194,9 +198,9 @@ public function CanAddSubsites()

/**
* Helper for testing if the subsite should be adjusted.
* @param $adminClass
* @param $recordSubsiteID
* @param $currentSubsiteID
* @param string $adminClass
* @param int $recordSubsiteID
* @param int $currentSubsiteID
* @return bool
*/
public function shouldChangeSubsite($adminClass, $recordSubsiteID, $currentSubsiteID)
Expand Down Expand Up @@ -227,7 +231,7 @@ public function canAccess()

// Check if we have access to current section on the current subsite.
$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());
}

/**
Expand Down Expand Up @@ -283,7 +287,11 @@ public function onBeforeInit()
if ($record
&& isset($record->SubsiteID, $this->owner->urlParams['ID'])
&& 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
Subsite::changeSubsite($record->SubsiteID);
Expand All @@ -306,7 +314,9 @@ public function onBeforeInit()
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())) {
if ($accessibleSites->count()
&& $accessibleSites->find('ID', SubsiteState::singleton()->getSubsiteId())
) {
// Section is accessible, redirect there.
return $this->owner->redirect(singleton($candidate->controller)->Link());
}
Expand Down Expand Up @@ -334,7 +344,7 @@ public function onBeforeInit()

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)
Expand Down

0 comments on commit 46bcffa

Please sign in to comment.