diff --git a/code/LeftAndMainSubsites.php b/code/LeftAndMainSubsites.php index 9d467f2..24740b5 100644 --- a/code/LeftAndMainSubsites.php +++ b/code/LeftAndMainSubsites.php @@ -127,7 +127,8 @@ class LeftAndMainSubsites extends Extension { $member = Member::currentUser(); if ($member && $member->isAdmin()) return true; //admin can access all subsites - $sites = Subsite::accessible_sites("CMS_ACCESS_{$this->owner->class}")->toDropdownMap(); + $sites = Subsite::accessible_sites("CMS_ACCESS_{$this->owner->class}", true)->toDropdownMap(); + if($sites && !isset($sites[Subsite::currentSubsiteID()])) { $siteIDs = array_keys($sites); Subsite::changeSubsite($siteIDs[0]); @@ -139,7 +140,7 @@ class LeftAndMainSubsites extends Extension { foreach($menu as $candidate) { if($candidate->controller != $this->owner->class) { - $sites = Subsite::accessible_sites("CMS_ACCESS_{$candidate->controller}")->toDropdownMap(); + $sites = Subsite::accessible_sites("CMS_ACCESS_{$candidate->controller}", true)->toDropdownMap(); if($sites && !isset($sites[Subsite::currentSubsiteID()])) { $siteIDs = array_keys($sites); Subsite::changeSubsite($siteIDs[0]); diff --git a/code/Subsite.php b/code/Subsite.php index 88bed05..49b32f0 100644 --- a/code/Subsite.php +++ b/code/Subsite.php @@ -347,6 +347,7 @@ JS; $SQL_perms = join("','", $SQLa_perm); $memberID = (int)$member->ID; + // Count this user's groups which can access the main site $groupCount = DB::query(" SELECT COUNT(\"Permission\".\"ID\") FROM \"Permission\" @@ -356,8 +357,21 @@ JS; AND \"MemberID\" = {$memberID} ")->value(); - return ($groupCount > 0); - + // 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\" + INNER JOIN \"Group_Roles\" ON \"Group_Roles\".\"GroupID\"=\"Group\".\"ID\" + INNER JOIN \"PermissionRole\" ON \"Group_Roles\".\"PermissionRoleID\"=\"PermissionRole\".\"ID\" + INNER JOIN \"PermissionRoleCode\" ON \"PermissionRole\".\"ID\"=\"PermissionRoleCode\".\"RoleID\" + WHERE \"PermissionRoleCode\".\"Code\" IN ('$SQL_perms') + AND \"Group\".\"AccessAllSubsites\" = 1 + AND \"MemberID\" = {$memberID} + ")->value(); + + // There has to be at least one that allows access. + return ($groupCount + $roleCount > 0); } /** @@ -419,6 +433,7 @@ JS; $templateClassList = "'" . implode("', '", ClassInfo::subclassesFor("Subsite_Template")) . "'"; + // Get all subsites accessible via a group $subsites = DataObject::get( 'Subsite', "\"Subsite\".\"Title\" != ''", @@ -434,7 +449,9 @@ JS; ON \"Group\".\"ID\"=\"Permission\".\"GroupID\" AND \"Permission\".\"Code\" IN ($SQL_codes, 'ADMIN')" ); + if (!$subsites) $subsites = new DataObjectSet(); + // Get all subsites accessible via a role $rolesSubsites = DataObject::get( 'Subsite', "\"Subsite\".\"Title\" != ''", @@ -454,17 +471,17 @@ JS; ON \"PermissionRole\".\"ID\"=\"PermissionRoleCode\".\"RoleID\" AND \"PermissionRoleCode\".\"Code\" IN ($SQL_codes, 'ADMIN')" ); - - if(!$subsites && $rolesSubsites) return $rolesSubsites; - - if($rolesSubsites) foreach($rolesSubsites as $subsite) { - if(!$subsites->containsIDs(array($subsite->ID))) { - $subsites->push($subsite); + + // Merge subsites + if($rolesSubsites) { + if($rolesSubsites) foreach($rolesSubsites as $subsite) { + if(!$subsites->containsIDs(array($subsite->ID))) { + $subsites->push($subsite); + } } } - // Include the main site - if(!$subsites) $subsites = new DataObjectSet(); + // Include the main site, if requested if($includeMainSite) { if(!is_array($permCode)) $permCode = array($permCode); if(self::hasMainSitePermission($member, $permCode)) { diff --git a/tests/SubsiteTest.php b/tests/SubsiteTest.php index 9faa80e..92314f8 100644 --- a/tests/SubsiteTest.php +++ b/tests/SubsiteTest.php @@ -109,7 +109,7 @@ class SubsiteTest extends SapphireTest { $this->objFromFixture('Member', 'subsite1member')); $member1SiteTitles = $member1Sites->column("Title"); sort($member1SiteTitles); - $this->assertEquals(array('Subsite1 Template'), $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')); @@ -123,6 +123,20 @@ class SubsiteTest extends SapphireTest { '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'); + } + + function testHasMainSitePermission() { + $canAccess = Subsite::hasMainSitePermission($this->objFromFixture('Member', 'subsite1member'), array("CMS_ACCESS_CMSMain")); + $this->assertTrue($canAccess, 'Member has access to Main site via a group'); + + $canAccess = Subsite::hasMainSitePermission($this->objFromFixture('Member', 'subsite1member2'), array("CMS_ACCESS_CMSMain")); + $this->assertTrue($canAccess, 'Member has access to Main site via a group role'); } function testDuplicateSubsite() { @@ -150,4 +164,4 @@ class SubsiteTest extends SapphireTest { $subsite2->activate(); $this->assertEquals('MyNewAwesomePage', DataObject::get_by_id('Page', $page2->ID)->Title); } -} \ No newline at end of file +} diff --git a/tests/SubsiteTest.yml b/tests/SubsiteTest.yml index 6caed8c..33bb00c 100644 --- a/tests/SubsiteTest.yml +++ b/tests/SubsiteTest.yml @@ -75,6 +75,13 @@ SiteTree: Title: Contact Us (Subsite 2) SubsiteID: =>Subsite_Template.subsite2 +PermissionRoleCode: + roleCode1: + Code: CMS_ACCESS_CMSMain +PermissionRole: + role1: + Title: role1 + Codes: =>PermissionRoleCode.roleCode1 Group: admin: Title: Admin @@ -87,13 +94,18 @@ Group: subsite1_group: Title: subsite1_group Code: subsite1_group - AccessAllSubsites: 0 + AccessAllSubsites: 1 Subsites: =>Subsite_Template.subsite1 subsite2_group: Title: subsite2_group Code: subsite2_group AccessAllSubsites: 0 Subsites: =>Subsite_Template.subsite2 + subsite1_group_via_role: + Title: subsite1_group_via_role + Code: subsite1_group_via_role + AccessAllSubsites: 1 + Roles: =>PermissionRole.role1 Permission: admin: Code: ADMIN @@ -139,3 +151,6 @@ Member: subsite2member: Email: subsite2member@test.com Groups: =>Group.subsite2_group + subsite1member2: + Email: subsite1member2@test.com + Groups: =>Group.subsite1_group_via_role