diff --git a/_config.php b/_config.php index c58d0e2..f19682b 100644 --- a/_config.php +++ b/_config.php @@ -16,7 +16,7 @@ Director::addRules(100, array( 'admin/subsites/$Action/$ID/$OtherID' => 'SubsiteAdmin', )); Object::addStaticVars( 'LeftAndMain', array( 'extra_menu_items' => array( - 'Sub-sites' => array("intranets", "admin/subsites/") + 'Sub-sites' => array("intranets", "admin/subsites/", 'SubsiteAdmin') ))); ?> diff --git a/code/GroupSubsites.php b/code/GroupSubsites.php index 2d2b768..14e5e01 100644 --- a/code/GroupSubsites.php +++ b/code/GroupSubsites.php @@ -16,22 +16,33 @@ class GroupSubsites extends DataObjectDecorator { } } - + function alternateTreeTitle() { + if($this->owner->SubsiteID == 0) return " * " . $this->owner->Title; + else return $this->owner->Title; + } + /** * Update any requests to limit the results to the current site */ function augmentSQL(SQLQuery &$query) { - return; - // The foreach is an ugly way of getting the first key :-) - foreach($query->from as $tableName => $info) { - $query->where[] = "`$tableName`.SubsiteID = " . Subsite::currentSubsiteID(); - break; + // If you're querying by ID, ignore the sub-site - this is a bit ugly... + if(strpos($query->where[0], ".`ID` = ") === false && strpos($query->where[0], ".ID = ") === false) { + + 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->from as $tableName => $info) { + $query->where[] = "`$tableName`.SubsiteID IN (0, $subsiteID)"; + break; + } + + $query->orderby = 'SubsiteID' . ($query->orderby ? ', ' : '') . $query->orderby; } - } function augmentBeforeWrite() { - if(!is_numeric($this->owner->ID)) $this->owner->SubsiteID = Subsite::currentSubsiteID(); + if(!is_numeric($this->owner->ID) && !$this->owner->SubsiteID) $this->owner->SubsiteID = Subsite::currentSubsiteID(); } } diff --git a/code/LeftAndMainSubsites.php b/code/LeftAndMainSubsites.php index c3b8f3b..877d5ee 100644 --- a/code/LeftAndMainSubsites.php +++ b/code/LeftAndMainSubsites.php @@ -55,11 +55,10 @@ class LeftAndMainSubsites extends Extension { } public function Subsites() { - $subsites = Subsite::getSubsitesForMember(Member::currentUser(), array('CMS_ACCESS_CMSMain', 'ADMIN')); - $siteList = new DataObjectSet(); - - if(Subsite::hasMainSitePermission(Member::currentUser(), array('CMS_ACCESS_CMSMain', 'ADMIN'))) + $subsites = Subsite::accessible_sites('CMS_ACCESS_' . $this->owner->class); + + if(Subsite::hasMainSitePermission(Member::currentUser(), array('CMS_ACCESS_' . $this->owner->class, 'ADMIN'))) $siteList->push(new ArrayData(array('Title' => 'Main site', 'ID' => 0))); if($subsites) @@ -90,6 +89,38 @@ class LeftAndMainSubsites extends Extension { public function CanAddSubsites() { return Permission::check("ADMIN", "any", null, "all"); - }} + } + + /** + * Alternative security checker for LeftAndMain. + * If security isn't found, then it will switch to a subsite where we do have access. + */ + public function alternateAccessCheck() { + $className = $this->owner->class; + + if($result = Permission::check("CMS_ACCESS_$className")) { + return $result; + } else { + if($className == 'CMSMain') { + // When access /admin/, we should try a redirect to another part of the admin rather than be locked out + $menu = $this->owner->MainMenu(); + if(($first = $menu->First()) && $first->Link) { + Director::redirect($first->Link); + return; + } + } + + $otherSites = Subsite::accessible_sites("CMS_ACCESS_$className"); + if($otherSites && $otherSites->TotalItems() > 0) { + $otherSites->First()->activate(); + return Permission::check("CMS_ACCESS_$className"); + } + } + + return null; + } +} + + ?> \ No newline at end of file diff --git a/code/Subsite.php b/code/Subsite.php index 132b262..a866c8d 100644 --- a/code/Subsite.php +++ b/code/Subsite.php @@ -158,6 +158,13 @@ JS; } + /** + * Make this subsite the current one + */ + public function activate() { + Subsite::changeSubsite($this); + } + function canEdit() { return true; } @@ -170,9 +177,11 @@ JS; $SQL_subdomain = Convert::raw2sql(array_shift($domainNameParts)); $SQL_domain = join('.', Convert::raw2sql($domainNameParts)); // $_REQUEST['showqueries'] = 1; + $subsite = null; if(self::$use_domain) { $subsite = DataObject::get_one('Subsite',"`Subdomain` = '$SQL_subdomain' AND `Domain`='$SQL_domain' AND `IsPublic`=1"); - } else { + } + if(!$subsite) { $subsite = DataObject::get_one('Subsite',"`Subdomain` = '$SQL_subdomain' AND `IsPublic`=1"); } @@ -271,7 +280,31 @@ SQL; self::changeSubsite($oldSubsiteID); return $newTemplate; - } + } + + + /** + * Return the subsites that the current user can access. + * Look for one of the given permission codes on the site. + * + * @param $permCode array|string Either a single permission code or an array of permission codes. + */ + function accessible_sites($permCode) { + $member = Member::currentUser(); + + if(is_array($permCode)) $SQL_codes = "'" . implode("', '", Convert::raw2sql($permCode)) . "'"; + else $SQL_codes = "'" . Convert::raw2sql($permCode) . "'"; + + if(!$member) return new DataObjectSet(); + + $subsites = DataObject::get('Subsite', + "`Group_Members`.`MemberID` = $member->ID AND `Permission`.`Code` IN ($SQL_codes, 'ADMIN')", '', + "LEFT JOIN `Group` ON (`SubsiteID`=`Subsite`.`ID` OR `SubsiteID` = 0) LEFT JOIN `Group_Members` ON `Group_Members`.`GroupID`=`Group`.`ID` + LEFT JOIN `Permission` ON `Group`.`ID`=`Permission`.`GroupID`"); + + return $subsites; + } + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // CMS ADMINISTRATION HELPERS ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/javascript/LeftAndMain_Subsites.js b/javascript/LeftAndMain_Subsites.js index 9a0635a..5190428 100644 --- a/javascript/LeftAndMain_Subsites.js +++ b/javascript/LeftAndMain_Subsites.js @@ -1,7 +1,7 @@ Behaviour.register({ '#SubsiteActions select' : { onchange: function() { - var request = new Ajax.Request('admin/changesubsite?ID=' + this.value + '&ajax=1', { + var request = new Ajax.Request('admin/security/changesubsite?ID=' + this.value + '&ajax=1', { onSuccess: function(response) { $('sitetree').innerHTML = response.responseText; SiteTree.applyTo($('sitetree'));