silverstripe-subsites/code/extensions/GroupSubsites.php

209 lines
7.2 KiB
PHP
Raw Normal View History

<?php
2016-09-22 16:38:29 +02:00
2017-05-24 12:32:05 +02:00
namespace SilverStripe\Subsites\Extensions;
2016-09-22 16:38:29 +02:00
use SilverStripe\ORM\DB;
use SilverStripe\Forms\FieldList;
use SilverStripe\Core\Convert;
use SilverStripe\Forms\OptionsetField;
use SilverStripe\Forms\CheckboxSetField;
use SilverStripe\Forms\ReadonlyField;
use SilverStripe\ORM\Queries\SQLSelect;
use SilverStripe\ORM\DataQuery;
use SilverStripe\Control\Cookie;
use SilverStripe\ORM\DataExtension;
use SilverStripe\Security\PermissionProvider;
2017-05-24 12:32:05 +02:00
use SilverStripe\Subsites\Model\Subsite;
2017-05-24 13:36:04 +02:00
use SilverStripe\Security\Group;
2017-05-24 12:32:05 +02:00
/**
* Extension for the Group object to add subsites support
2009-05-04 07:03:44 +02:00
*
* @package subsites
*/
BUG: Modifying the module to work with SS 3.0 Replaced deprecated DataObjectDecorator with DataExtension Fixed hard crashes in the cms Updated to support new LeftAndMain template structure Made the subsites model admin functional Moved the LeftAndMain_Menu template up a directory so it overrides the core Fixed some errors caused by changes to the framework Re-organized the code folder Fixed permission issue causing to default to first subsite regardless if it is the default or not Fixed crashes on the subsite virtual page when creating/editing Removed toDropdownMap() calls replacing with map() Fixed the URLSegment field on subsites Fixed error when detecting subsite for a domain Improved styles on the subsite dropdown Updated LeftAndMain_Subsites.js to work with jQuery entwine Started porting the SubsitesTreeDropdownField.js to use jQuery entwine and work with the new TreeDropdownField.js Fixed issue causing crash when viewing a page who is linked to by a subsite virtual page Removed unused methods on SubsitesTreeDropdownField.js Re-added classes that were moved Fixed hard crash after saving caused by the many_many definition on SiteTreeSubsites Replaced deprecated DataObjectSet creation with ArrayList Compatibility fixes with SS 3.0 beta 2 Fixed crash in cms caused by no parameter being passed to the SubsiteReportWrapper constructor Proper fix for report wrapper Removed table list field in favor of a basic grid field Fixed updateCMSFields() for file subsites Migrated translations to yml Fixed issue causing the current page to not get cleared when changing subsites in the cms Fixed virtual page icon Fixed language files issue
2012-03-25 18:35:01 +02:00
class GroupSubsites extends DataExtension implements PermissionProvider {
2009-05-04 07:03:44 +02:00
private static $db = array(
2012-07-10 15:43:53 +02:00
'AccessAllSubsites' => 'Boolean'
);
private static $many_many = array(
2017-05-24 13:36:04 +02:00
'Subsites' => Subsite::class
2012-07-10 15:43:53 +02:00
);
private static $defaults = array(
2012-07-10 15:43:53 +02:00
'AccessAllSubsites' => true
);
/**
* Migrations for GroupSubsites data.
*/
function requireDefaultRecords() {
// Migration for Group.SubsiteID data from when Groups only had a single subsite
2017-05-24 14:55:03 +02:00
$schema = $this->owner->getSchema();
$groupFields = DB::field_list($schema->tableName(Group::class));
2016-09-22 16:38:29 +02:00
// Detection of SubsiteID field is the trigger for old-style-subsiteID migration
if(isset($groupFields['SubsiteID'])) {
// Migrate subsite-specific data
DB::query('INSERT INTO "Group_Subsites" ("GroupID", "SubsiteID")
SELECT "ID", "SubsiteID" FROM "Group" WHERE "SubsiteID" > 0');
2016-09-22 16:38:29 +02:00
// Migrate global-access data
DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1 WHERE "SubsiteID" = 0');
2016-09-22 16:38:29 +02:00
// Move the field out of the way so that this migration doesn't get executed again
2017-05-24 13:36:04 +02:00
DB::get_schema()->renameField(Group::class, 'SubsiteID', '_obsolete_SubsiteID');
2016-09-22 16:38:29 +02:00
// No subsite access on anything means that we've just installed the subsites module.
// Make all previous groups global-access groups
2016-09-22 16:38:29 +02:00
} else if(!DB::query('SELECT "Group"."ID" FROM "Group"
LEFT JOIN "Group_Subsites" ON "Group_Subsites"."GroupID" = "Group"."ID" AND "Group_Subsites"."SubsiteID" > 0
WHERE "AccessAllSubsites" = 1
OR "Group_Subsites"."GroupID" IS NOT NULL ')->value()) {
2016-09-22 16:38:29 +02:00
DB::query('UPDATE "Group" SET "AccessAllSubsites" = 1');
}
}
2016-09-22 16:38:29 +02:00
function updateCMSFields(FieldList $fields) {
if($this->owner->canEdit() ){
// i18n tab
$fields->findOrMakeTab('Root.Subsites',_t('GroupSubsites.SECURITYTABTITLE','Subsites'));
$subsites = Subsite::accessible_sites(array('ADMIN', 'SECURITY_SUBSITE_GROUP'), true);
BUG: Modifying the module to work with SS 3.0 Replaced deprecated DataObjectDecorator with DataExtension Fixed hard crashes in the cms Updated to support new LeftAndMain template structure Made the subsites model admin functional Moved the LeftAndMain_Menu template up a directory so it overrides the core Fixed some errors caused by changes to the framework Re-organized the code folder Fixed permission issue causing to default to first subsite regardless if it is the default or not Fixed crashes on the subsite virtual page when creating/editing Removed toDropdownMap() calls replacing with map() Fixed the URLSegment field on subsites Fixed error when detecting subsite for a domain Improved styles on the subsite dropdown Updated LeftAndMain_Subsites.js to work with jQuery entwine Started porting the SubsitesTreeDropdownField.js to use jQuery entwine and work with the new TreeDropdownField.js Fixed issue causing crash when viewing a page who is linked to by a subsite virtual page Removed unused methods on SubsitesTreeDropdownField.js Re-added classes that were moved Fixed hard crash after saving caused by the many_many definition on SiteTreeSubsites Replaced deprecated DataObjectSet creation with ArrayList Compatibility fixes with SS 3.0 beta 2 Fixed crash in cms caused by no parameter being passed to the SubsiteReportWrapper constructor Proper fix for report wrapper Removed table list field in favor of a basic grid field Fixed updateCMSFields() for file subsites Migrated translations to yml Fixed issue causing the current page to not get cleared when changing subsites in the cms Fixed virtual page icon Fixed language files issue
2012-03-25 18:35:01 +02:00
$subsiteMap = $subsites->map();
// Prevent XSS injection
$subsiteMap = Convert::raw2xml($subsiteMap);
2016-09-22 16:38:29 +02:00
// Interface is different if you have the rights to modify subsite group values on
// all subsites
if(isset($subsiteMap[0])) {
2016-09-22 16:38:29 +02:00
$fields->addFieldToTab("Root.Subsites", new OptionsetField("AccessAllSubsites",
_t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
array(
1 => _t('GroupSubsites.ACCESSALL', "All subsites"),
0 => _t('GroupSubsites.ACCESSONLY', "Only these subsites"),
)
));
unset($subsiteMap[0]);
$fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites", "",
$subsiteMap));
} else {
if (sizeof($subsiteMap) <= 1) {
2016-09-22 16:38:29 +02:00
$fields->addFieldToTab("Root.Subsites", new ReadonlyField("SubsitesHuman",
_t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
reset($subsiteMap)));
} else {
2016-09-22 16:38:29 +02:00
$fields->addFieldToTab("Root.Subsites", new CheckboxSetField("Subsites",
_t('GroupSubsites.ACCESSRADIOTITLE', 'Give this group access to'),
$subsiteMap));
}
2009-05-04 07:03:44 +02:00
}
}
}
2009-05-04 07:03:44 +02:00
/**
* If this group belongs to a subsite,
* append the subsites title to the group title
* to make it easy to distinguish in the tree-view
* of the security admin interface.
*/
2009-05-04 07:03:44 +02:00
function alternateTreeTitle() {
if($this->owner->AccessAllSubsites) {
2013-10-30 13:43:59 +01:00
$title = _t('GroupSubsites.GlobalGroup', 'global group');
return htmlspecialchars($this->owner->Title, ENT_QUOTES) . ' <i>(' . $title . ')</i>';
} else {
$subsites = Convert::raw2xml(implode(", ", $this->owner->Subsites()->column('Title')));
return htmlspecialchars($this->owner->Title) . " <i>($subsites)</i>";
}
2009-05-04 07:03:44 +02:00
}
/**
* Update any requests to limit the results to the current site
*/
public function augmentSQL(SQLSelect $query, DataQuery $dataQuery = null) {
if(Subsite::$disable_subsite_filter) return;
if(Cookie::get('noSubsiteFilter') == 'true') return;
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
if(!$query->filtersOnID()) {
2009-05-04 07:03:44 +02:00
BUG: Modifying the module to work with SS 3.0 Replaced deprecated DataObjectDecorator with DataExtension Fixed hard crashes in the cms Updated to support new LeftAndMain template structure Made the subsites model admin functional Moved the LeftAndMain_Menu template up a directory so it overrides the core Fixed some errors caused by changes to the framework Re-organized the code folder Fixed permission issue causing to default to first subsite regardless if it is the default or not Fixed crashes on the subsite virtual page when creating/editing Removed toDropdownMap() calls replacing with map() Fixed the URLSegment field on subsites Fixed error when detecting subsite for a domain Improved styles on the subsite dropdown Updated LeftAndMain_Subsites.js to work with jQuery entwine Started porting the SubsitesTreeDropdownField.js to use jQuery entwine and work with the new TreeDropdownField.js Fixed issue causing crash when viewing a page who is linked to by a subsite virtual page Removed unused methods on SubsitesTreeDropdownField.js Re-added classes that were moved Fixed hard crash after saving caused by the many_many definition on SiteTreeSubsites Replaced deprecated DataObjectSet creation with ArrayList Compatibility fixes with SS 3.0 beta 2 Fixed crash in cms caused by no parameter being passed to the SubsiteReportWrapper constructor Proper fix for report wrapper Removed table list field in favor of a basic grid field Fixed updateCMSFields() for file subsites Migrated translations to yml Fixed issue causing the current page to not get cleared when changing subsites in the cms Fixed virtual page icon Fixed language files issue
2012-03-25 18:35:01 +02:00
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
else */$subsiteID = (int)Subsite::currentSubsiteID();
2016-09-22 16:38:29 +02:00
// Don't filter by Group_Subsites if we've already done that
$hasGroupSubsites = false;
foreach($query->getFrom() as $item) {
2012-07-10 15:43:53 +02:00
if((is_array($item) && strpos($item['table'], 'Group_Subsites')!==false) || (!is_array($item) && strpos($item, 'Group_Subsites')!==false)) {
$hasGroupSubsites = true;
break;
}
}
2016-09-22 16:38:29 +02:00
if(!$hasGroupSubsites) {
if($subsiteID) {
2016-09-22 16:38:29 +02:00
$query->addLeftJoin("Group_Subsites", "\"Group_Subsites\".\"GroupID\"
= \"Group\".\"ID\" AND \"Group_Subsites\".\"SubsiteID\" = $subsiteID");
$query->addWhere("(\"Group_Subsites\".\"SubsiteID\" IS NOT NULL OR
\"Group\".\"AccessAllSubsites\" = 1)");
} else {
$query->addWhere("\"Group\".\"AccessAllSubsites\" = 1");
}
}
2016-09-22 16:38:29 +02:00
// WORKAROUND for databases that complain about an ORDER BY when the column wasn't selected (e.g. SQL Server)
2012-07-10 15:43:53 +02:00
$select=$query->getSelect();
if(isset($select[0]) && !$select[0] == 'COUNT(*)') {
$query->orderby = "\"AccessAllSubsites\" DESC" . ($query->orderby ? ', ' : '') . $query->orderby;
}
}
}
2009-05-04 07:03:44 +02:00
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()) {
$this->owner->AccessAllSubsites = 1;
}
}
2016-09-22 16:38:29 +02:00
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()) {
$subsites = $this->owner->Subsites();
$subsites->add($currentSubsiteID);
}
}
2009-05-04 07:03:44 +02:00
function alternateCanEdit() {
// Find the sites that this group belongs to and the sites where we have appropriate perm.
$accessibleSites = Subsite::accessible_sites('CMS_ACCESS_SecurityAdmin')->column('ID');
$linkedSites = $this->owner->Subsites()->column('ID');
2016-09-22 16:38:29 +02:00
// We are allowed to access this site if at we have CMS_ACCESS_SecurityAdmin permission on
// at least one of the sites
return (bool)array_intersect($accessibleSites, $linkedSites);
}
function providePermissions() {
return array(
'SECURITY_SUBSITE_GROUP' => array(
'name' => _t('GroupSubsites.MANAGE_SUBSITES', 'Manage subsites for groups'),
'category' => _t('Permissions.PERMISSIONS_CATEGORY', 'Roles and access permissions'),
'help' => _t('GroupSubsites.MANAGE_SUBSITES_HELP', 'Ability to limit the permissions for a group to one or more subsites.'),
'sort' => 200
)
);
}
}
?>