Skip to content

Commit

Permalink
fix(ModelAdmin): Workaround for silverstripe-recipe 4.3.0
Browse files Browse the repository at this point in the history
- Primary takeaway: this allows a site to use multisites with
  silverstripe-recipe 4.3.0
- Silverstripe-recipe 4.3.0 introduced changes that broke the previous
  approach to retrieving the model class.
- This will be fixed in silverstripe-recipe 4.3.1 (really
  silverstripe-admin 1.3.1).
- Don't want to require a specific version of ss-admin as it will create
  composer conflicts.
- This commit changes multisites to only work with ss-recipe >= 4.3.0
- When using ss-recipe 4.3.0:
  - An error will be thrown if you use the MultisitesAware extension.
  - Else MultisitesAware will be bypassed.
- Will work with ss-recipe >= 4.3.1 (other potential issues aside).
  • Loading branch information
jcarter committed Feb 11, 2019
1 parent 7b4c52e commit 1d080da
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 35 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"require":
{
"silverstripe/cms": "~4.0",
"silverstripe/admin": "^4.3",
"symbiote/silverstripe-multivaluefield": "~5.0"
},
"require-dev": {
Expand All @@ -24,7 +25,7 @@
],
"installer-name": "multisites",
"branch-alias": {
"dev-master": "5.0.x-dev"
"dev-master": "5.2.x-dev"
}
},
"replace": {
Expand Down
106 changes: 72 additions & 34 deletions src/Admin/MultisitesModelAdminExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
use SilverStripe\Core\Extension;
use Symbiote\Multisites\Multisites;
use Symbiote\Multisites\Model\Site;
use Symbiote\Multisites\Extension\MultisitesAware;

/**
* MultisitesModelAdminExtension
*
* @package silverstripe-multisites
*/
class MultisitesModelAdminExtension extends Extension {

private static $allowed_actions = array(
'updateSiteFilter'
);
Expand All @@ -27,24 +28,26 @@ class MultisitesModelAdminExtension extends Extension {
* @var DataObject
**/
private $listDataClass;

/**
* If this dataClass is MultisitesAware, set the Multisites_ActiveSite
* session variable to one of the follwing:
* a) The SiteID passed in the request params, if it exists
* b) The current site, if the current member is a manager of that site
* c) The first site that the current member is a manager of
**/
public function onAfterInit(){
if($this->modelIsMultiSitesAware()) {
public function onAfterInit(){
// throws exception if using ss-recipe <= 4.3.0 and using MultiSitesAware
$this->checkMultisitesAware();

if($this->modelIsMultiSitesAware()) {
if($siteID = $this->owner->getRequest()->requestVar('SiteID')){
$this->setActiveSite($siteID);
}

if(!$this->getActiveSite()){
$managedByMember = Multisites::inst()->sitesManagedByMember();

if(count($managedByMember)){
$currentSiteID = Multisites::inst()->getCurrentSiteId();
if(in_array($currentSiteID, $managedByMember)){
Expand All @@ -58,7 +61,27 @@ public function onAfterInit(){
}
}


/**
* Prevents use of MultisitesAware extension when using
* silvestripe-recipe <= 4.3.0
*
* @return void
*/
public function checkMultisitesAware() {
// only true if using silverstripe-recipe <= 4.3.0
if (!$this->owner->hasMethod('getModelClass')) {
$models = $this->owner->getManagedModels();
// throw error if any models use MultisitesAware extension
foreach ($models as $model => $val) {
if($model::has_extension(MultisitesAware::class)) {
throw new \Exception(
'`ModelAdmin::getModelClass()` missing. You are likely using `silverstripe-recipe:4.3.0` which introduced this bug. This can be fixed by updating to `silverstripe-recipe:4.3.1` or greater.'
);
}
}
}
}

/**
* If this dataClass is MultisitesAware, filter the list by the current Multisites_ActiveSite
**/
Expand All @@ -71,7 +94,6 @@ public function updateList(&$list){
}
}


/**
* If the current member is not a "Manager" of any sites, they shouldn't be able to manage MultisitesAware DataObjects.
**/
Expand All @@ -88,7 +110,6 @@ public function updateEditForm($form){
}
}


/**
* Provide a Site filter
**/
Expand All @@ -110,7 +131,6 @@ public function updateSearchForm($form){
}
}


/**
* get the active site for this model admin
*
Expand All @@ -128,7 +148,6 @@ public function getActiveSite() {
}
}


/**
* Set the active site for this model admin
*
Expand All @@ -143,7 +162,6 @@ public function setActiveSite($siteID) {
}
}


/**
* Get the key used to store this model admin active site Session to
*
Expand All @@ -153,27 +171,47 @@ public function getActiveSiteSessionKey() {
return 'Multisites_ActiveSite_For_' . get_class($this->owner);
}


/**
* Get and cache an instance of the data class currently being listed
*
* @return DataObject
**/
private function getListDataClass() {
if(!$this->listDataClass) {
$this->listDataClass = singleton($this->owner->getSearchContext()->getResults(array())->dataClass());
}
return $this->listDataClass;
}


/**
* Determines whether the current model being managed is MultiSitesAware
*
* @return boolean
**/
private function modelIsMultiSitesAware() {
$model = $this->getListDataClass();
return $model->hasExtension('MultisitesAware') || $model instanceof SiteTree;
}
/**
* Get and cache an instance of the data class currently being listed
*
* @return DataObject
**/
private function getListDataClass() {
/**
* Silverstripe-recipe 4.3.0 introduces changes that broke the
* previous approach to retrieving the model class.
*
* This is/will be fixed in silverstripe-recipe 4.3.1
*
* We've taken this approach so that Multisites can work with
* SS 4.3.0 so long as you don't use the MultisitesAware extension.
*/
if ($this->listDataClass === null) {
// only true if silverstripe-recipe > 4.3.0
if ($this->owner->hasMethod('getModelClass')) {
$this->listDataClass = $this->owner->getModelClass();
}
// else false to bypass the MultisitesAware extension
else {
$this->listDataClass = false;
}
}
return $this->listDataClass;
}

/**
* Determines whether the current model being managed is MultiSitesAware
*
* @return boolean
**/
private function modelIsMultiSitesAware() {
$model = $this->getListDataClass();
// always false if using silverstripe-recipe <= 4.3.0
if ($model) {
$isAware = $model::has_extension(MultisitesAware::class);
$isSiteTree = in_array(SiteTree::class, ClassInfo::ancestry($model));
return $isAware || $isSiteTree;
}
return false;
}
}

0 comments on commit 1d080da

Please sign in to comment.