mirror of
https://github.com/silverstripe/silverstripe-subsites
synced 2024-10-22 11:05:55 +02:00
Merged from branches/0.1
This commit is contained in:
parent
6037ec56e5
commit
b646a104f1
11
_config.php
11
_config.php
@ -13,15 +13,16 @@ Object::add_extension('LeftAndMain', 'LeftAndMainSubsites');
|
||||
Object::add_extension('LeftAndMain', 'ControllerSubsites');
|
||||
|
||||
Object::add_extension('Group', 'GroupSubsites');
|
||||
Object::add_extension('Member', 'MemberSubsites');
|
||||
Object::add_extension('File', 'FileSubsites');
|
||||
|
||||
// Backwards compatibility with SilverStripe 2.2
|
||||
if(!class_exists('CMSMenu')) {
|
||||
Director::addRules(100, array(
|
||||
'admin/subsites/$Action/$ID/$OtherID' => 'SubsiteAdmin',
|
||||
));
|
||||
Object::addStaticVars( 'LeftAndMain', array( 'extra_menu_items' => array(
|
||||
'Sub-sites' => array("intranets", "admin/subsites/", 'SubsiteAdmin')
|
||||
Director::addRules(100, array(
|
||||
'admin/subsites/$Action/$ID/$OtherID' => 'SubsiteAdmin',
|
||||
));
|
||||
Object::addStaticVars( 'LeftAndMain', array( 'extra_menu_items' => array(
|
||||
'Sub-sites' => array("intranets", "admin/subsites/", 'SubsiteAdmin')
|
||||
)));
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* Extension for the File object to add subsites support
|
||||
*
|
||||
*
|
||||
* @package subsites
|
||||
*/
|
||||
class FileSubsites extends DataObjectDecorator {
|
||||
@ -14,17 +14,17 @@ class FileSubsites extends DataObjectDecorator {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Amends the CMS tree title for folders in the Files & Images section.
|
||||
* Prefixes a '* ' to the folders that are accessible from all subsites.
|
||||
* Prefixes a '* ' to the folders that are accessible from all subsites.
|
||||
*/
|
||||
function alternateTreeTitle() {
|
||||
if($this->owner->SubsiteID == 0) return " * " . $this->owner->Title;
|
||||
else return $this->owner->Title;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add subsites-specific fields to the folder editor.
|
||||
*/
|
||||
@ -33,10 +33,10 @@ class FileSubsites extends DataObjectDecorator {
|
||||
$sites = Subsite::accessible_sites('CMS_ACCESS_AssetAdmin');
|
||||
if($sites)$fields->addFieldToTab('Root.Details', new DropdownField("SubsiteID", "Subsite", $sites->toDropdownMap('ID', 'Title', "(Public)")));
|
||||
}
|
||||
|
||||
if($this->owner->SubsiteID == 0&&!Permission::check('EDIT_PERMISSIONS')){
|
||||
|
||||
if($this->owner->SubsiteID == 0 && !Permission::check('EDIT_PERMISSIONS') && !Permission::check('SUBSITE_ASSETS_EDIT')){
|
||||
$fields->removeFieldFromTab("Root", "Upload");
|
||||
$fields->transform(new ReadonlyTransformation());
|
||||
$fields = $fields->transform(new ReadonlyTransformation());
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ class FileSubsites extends DataObjectDecorator {
|
||||
|
||||
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)";
|
||||
@ -59,11 +59,16 @@ class FileSubsites extends DataObjectDecorator {
|
||||
$query->orderby = 'SubsiteID' . ($query->orderby ? ', ' : '') . $query->orderby;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function augmentBeforeWrite() {
|
||||
if(!$this->owner->ID && !$this->owner->SubsiteID) $this->owner->SubsiteID = Subsite::currentSubsiteID();
|
||||
}
|
||||
|
||||
|
||||
function onAfterUpload() {
|
||||
$this->owner->SubsiteID = Subsite::currentSubsiteID();
|
||||
$this->owner->write();
|
||||
}
|
||||
|
||||
function alternateCanEdit() {
|
||||
// Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group
|
||||
$subsiteID = Session::get('SubsiteID');
|
||||
@ -73,9 +78,9 @@ class FileSubsites extends DataObjectDecorator {
|
||||
Session::set('SubsiteID', $this->owner->SubsiteID);
|
||||
$access = Permission::check('CMS_ACCESS_AssetAdmin');
|
||||
Session::set('SubsiteID', $subsiteID);
|
||||
|
||||
|
||||
return $access;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* Extension for the Group object to add subsites support
|
||||
*
|
||||
*
|
||||
* @package subsites
|
||||
*/
|
||||
class GroupSubsites extends DataObjectDecorator {
|
||||
|
||||
|
||||
function extraDBFields() {
|
||||
// This is hard-coded to be applied to SiteTree, unfortunately
|
||||
if($this->owner->class == 'Group') {
|
||||
if($this->owner->class == 'Group') {
|
||||
return array(
|
||||
'has_one' => array(
|
||||
'Subsite' => 'Subsite',
|
||||
@ -16,38 +16,53 @@ class GroupSubsites extends DataObjectDecorator {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function updateCMSFields(&$fields) {
|
||||
$subsites = DataObject::get('Subsite');
|
||||
$tab = $fields->findOrMakeTab(
|
||||
'Root.Subsites',
|
||||
_t('GroupSubsites.SECURITYTABTITLE', 'Subsites')
|
||||
);
|
||||
$tab->push(new DropdownField(
|
||||
'SubsiteID',
|
||||
_t('GroupSubsites.SECURITYACCESS', 'Limit CMS access to subsites', PR_MEDIUM, 'Dropdown listing existing subsites which this group has access to'),
|
||||
($subsites) ? $subsites->toDropDownMap() : null,
|
||||
null,
|
||||
null,
|
||||
''
|
||||
));
|
||||
|
||||
function updateCMSFields(&$fields) {
|
||||
|
||||
if( $this->owner->SubsiteID == 0 || $this->owner->canEdit() ){
|
||||
$subsites = DataObject::get('Subsite');
|
||||
if ( $subsites && $subsites->exists() ) {
|
||||
$oldSubsiteID = Session::get('SubsiteID');
|
||||
foreach( $subsites as $subsite ) {
|
||||
Subsite::changeSubsite($subsite->ID);
|
||||
if ( !Permission::check('CL_Admin') ) { $subsites->remove( $subsite ) ; }
|
||||
}
|
||||
Subsite::changeSubsite($oldSubsiteID);
|
||||
|
||||
$tab = $fields->findOrMakeTab(
|
||||
'Root.Subsites',
|
||||
_t('GroupSubsites.SECURITYTABTITLE', 'Subsites')
|
||||
);
|
||||
|
||||
$dropdown = new DropdownField(
|
||||
'SubsiteID',
|
||||
_t('GroupSubsites.SECURITYACCESS', 'Limit CMS access to subsites', PR_MEDIUM, 'Dropdown listing existing subsites which this group has access to'),
|
||||
$subsites->toDropDownMap(),
|
||||
null,
|
||||
null,
|
||||
''
|
||||
);
|
||||
if ( $subsites->Count() == 1 ) $dropdown = $dropdown->transform(new ReadonlyTransformation()) ;
|
||||
|
||||
$tab->push($dropdown) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function alternateTreeTitle() {
|
||||
if($this->owner->SubsiteID == 0) {
|
||||
function alternateTreeTitle() {
|
||||
if($this->owner->SubsiteID == 0) {
|
||||
return $this->owner->Title . ' <i>(global group)</i>';
|
||||
} else {
|
||||
return $this->owner->Title; // . ' <i>(' . $this->owner->Subsite()->Title . ')</i>';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update any requests to limit the results to the current site
|
||||
*/
|
||||
@ -59,33 +74,32 @@ class GroupSubsites extends DataObjectDecorator {
|
||||
|
||||
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;
|
||||
$query->orderby = 'SubsiteID' . ($query->orderby ? ', ' : '') . $query->orderby;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function augmentBeforeWrite() {
|
||||
if(!is_numeric($this->owner->ID) && !$this->owner->SubsiteID) $this->owner->SubsiteID = Subsite::currentSubsiteID();
|
||||
}
|
||||
|
||||
|
||||
function alternateCanEdit() {
|
||||
// Check the CMS_ACCESS_SecurityAdmin privileges on the subsite that owns this group
|
||||
$oldSubsiteID = Session::get('SubsiteID');
|
||||
|
||||
Session::set('SubsiteID', $this->owner->SubsiteID);
|
||||
Subsite::changeSubsite($this->owner->SubsiteID) ;
|
||||
$access = Permission::check('CMS_ACCESS_SecurityAdmin');
|
||||
Session::set('SubsiteID', $oldSubsiteID);
|
||||
|
||||
Subsite::changeSubsite($oldSubsiteID) ;
|
||||
|
||||
return $access;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a duplicate of this group and save it to another subsite.
|
||||
* The group and permissions will be duplicated, but not the members.
|
||||
@ -98,13 +112,13 @@ class GroupSubsites extends DataObjectDecorator {
|
||||
} else {
|
||||
$subsite = DataObject::get_by_id('Subsite', $subsiteID);
|
||||
}
|
||||
|
||||
|
||||
$group = $this->owner->duplicate(false);
|
||||
|
||||
$subsiteID = ($subsiteID ? $subsiteID : Subsite::currentSubsiteID());
|
||||
$group->SubsiteID = $subsiteID;
|
||||
$group->write();
|
||||
|
||||
|
||||
// Duplicate permissions
|
||||
$permissions = $this->owner->Permissions();
|
||||
foreach($permissions as $permission) {
|
||||
|
@ -78,6 +78,9 @@ class LeftAndMainSubsites extends Extension {
|
||||
$mainSiteTitle = "Main site";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$mainSiteTitle = "Main site";
|
||||
break;
|
||||
}
|
||||
|
||||
if($mainSiteTitle && Subsite::hasMainSitePermission(Member::currentUser(), array('CMS_ACCESS_' . $this->owner->class, 'ADMIN')))
|
||||
@ -145,4 +148,4 @@ class LeftAndMainSubsites extends Extension {
|
||||
|
||||
|
||||
|
||||
?>
|
||||
?>
|
||||
|
20
code/MemberSubsites.php
Normal file
20
code/MemberSubsites.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Extension for the Group object to add subsites support
|
||||
*
|
||||
* @package subsites
|
||||
*/
|
||||
class MemberSubsites extends DataObjectDecorator {
|
||||
|
||||
/* Only allow adding to groups we can edit */
|
||||
public function saveGroups( $groups ) {
|
||||
$groups = explode( ',', $groups ) ;
|
||||
$filtered = array() ;
|
||||
foreach( $groups as $groupID ) {
|
||||
$group = DataObject::get_by_id('Group', $groupID) ;
|
||||
if ( $group && $group->canEdit() ) $filtered[] = $groupID ;
|
||||
}
|
||||
$this->owner->Groups()->setByIDList( $filtered ) ;
|
||||
}
|
||||
|
||||
}
|
221
code/Subsite.php
221
code/Subsite.php
@ -2,7 +2,7 @@
|
||||
/**
|
||||
* A dynamically created subdomain. SiteTree objects can now belong to a subdomain.
|
||||
* You can simulate subsite access without creating subdomains by appending ?SubsiteID=<ID> to the request.
|
||||
*
|
||||
*
|
||||
* @package subsites
|
||||
*/
|
||||
class Subsite extends DataObject implements PermissionProvider {
|
||||
@ -12,16 +12,16 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
* to limit DataObject::get*() calls to a specific subsite. Useful for debugging.
|
||||
*/
|
||||
static $disable_subsite_filter = false;
|
||||
|
||||
|
||||
static $default_sort = 'Title';
|
||||
|
||||
|
||||
/**
|
||||
* @var boolean $use_domain Checks for valid domain in addition to subdomain
|
||||
* when searching for a matching page with {@link getSubsiteIDForDomain()}.
|
||||
* By default, only the subdomain has to match.
|
||||
*/
|
||||
static $use_domain = false;
|
||||
|
||||
|
||||
static $db = array(
|
||||
'Subdomain' => 'Varchar',
|
||||
'Title' => 'Varchar(255)',
|
||||
@ -30,13 +30,13 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
'Theme' => 'Varchar',
|
||||
'Domain' => 'Varchar',
|
||||
// Used to hide unfinished/private subsites from public view.
|
||||
// If unset, will default to
|
||||
// If unset, will default to
|
||||
'IsPublic' => 'Boolean'
|
||||
);
|
||||
|
||||
|
||||
static $has_one = array(
|
||||
);
|
||||
|
||||
|
||||
static $indexes = array(
|
||||
'Subdomain' => true,
|
||||
'Domain' => true
|
||||
@ -45,13 +45,13 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
static $defaults = array(
|
||||
'IsPublic' => 1,
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @var string $base_domain If {@link Domain} is not set for this subsite instance,
|
||||
* default to this domain (without subdomain or protocol prefix).
|
||||
*/
|
||||
static $base_domain;
|
||||
|
||||
|
||||
/**
|
||||
* @var string $default_subdomain If {@link Subdomain} is not set for this subsite instance,
|
||||
* default to this domain (without domain or protocol prefix).
|
||||
@ -62,19 +62,19 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
* @var Subsite $cached_subsite Internal cache used by {@link currentSubsite()}.
|
||||
*/
|
||||
protected static $cached_subsite = null;
|
||||
|
||||
|
||||
/**
|
||||
* @var array $allowed_domains Numeric array of all domains which are selectable for (without their subdomain-parts or http:// prefix)
|
||||
*/
|
||||
public static $allowed_domains = array();
|
||||
|
||||
|
||||
/**
|
||||
* @var array $allowed_themes Numeric array of all themes which are allowed to be selected for all subsites.
|
||||
* Corresponds to subfolder names within the /themes folder. By default, all themes contained in this folder
|
||||
* are listed.
|
||||
*/
|
||||
protected static $allowed_themes = array();
|
||||
|
||||
protected static $allowed_themes = array();
|
||||
|
||||
static function set_allowed_domains($domain){
|
||||
if(is_array($domain)){
|
||||
foreach($domain as $do){
|
||||
@ -84,13 +84,13 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
self::$allowed_domains[] = $domain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all domains (without their subdomain parts)
|
||||
* which are allowed to be combined to the full URL
|
||||
* (subdomain.domain). If no custom domains are set through
|
||||
* {@link set_allowed_domains()}, will fall back to the {@link base_domain()}.
|
||||
*
|
||||
* {@link set_allowed_domains()}, will fall back to the {@link base_domain()}.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static function allowed_domains() {
|
||||
@ -100,11 +100,11 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
return array(self::base_domain());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static function set_allowed_themes($themes) {
|
||||
self::$allowed_themes = $themes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the themes that can be used with this subsite, as an array of themecode => description
|
||||
*/
|
||||
@ -124,38 +124,38 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
return $themes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the base domain for this set of subsites.
|
||||
* You can set this by setting Subsite::$base_domain, otherwise it defaults to HTTP_HOST
|
||||
*
|
||||
*
|
||||
* @return string Domain name (without protocol prefix).
|
||||
*/
|
||||
static function base_domain() {
|
||||
if(self::$base_domain) return self::$base_domain;
|
||||
else return $_SERVER['HTTP_HOST'];
|
||||
else return $_SERVER['HTTP_HOST'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the default domain of this set of subsites. Generally this will be the base domain,
|
||||
* but you can also set Subsite::$default_subdomain to add a default prefix to this.
|
||||
*
|
||||
*
|
||||
* @return string Domain name (without protocol prefix).
|
||||
*/
|
||||
static function default_domain() {
|
||||
if(self::$default_subdomain) return self::$default_subdomain . '.' . self::base_domain();
|
||||
else return self::base_domain();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the domain of this site
|
||||
*
|
||||
*
|
||||
* @return string Domain name including subdomain (without protocol prefix)
|
||||
*/
|
||||
function domain() {
|
||||
$base = $this->Domain ? $this->Domain : self::base_domain();
|
||||
$sub = $this->Subdomain ? $this->Subdomain : self::$default_subdomain;
|
||||
|
||||
|
||||
if($sub) return "$sub.$base";
|
||||
else return $base;
|
||||
}
|
||||
@ -163,7 +163,7 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
function absoluteBaseURL() {
|
||||
return "http://" . $this->domain() . Director::baseURL();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the configuration fields for each subsite
|
||||
*/
|
||||
@ -196,20 +196,20 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
$this->extend('updateCMSFields', $fields);
|
||||
return $fields;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo getClassName is redundant, already stored as a database field?
|
||||
*/
|
||||
function getClassName() {
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
|
||||
function getCMSActions() {
|
||||
return new FieldSet(
|
||||
new FormAction('callPageMethod', "Create copy", null, 'adminDuplicate')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function adminDuplicate() {
|
||||
$newItem = $this->duplicate();
|
||||
$JS_title = Convert::raw2js($this->Title);
|
||||
@ -218,12 +218,12 @@ class Subsite extends DataObject implements PermissionProvider {
|
||||
$('Form_EditForm').loadURLFromServer('admin/subsites/show/$newItem->ID');
|
||||
JS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the subsite currently set in the session.
|
||||
*
|
||||
*
|
||||
* @uses ControllerSubsites->controllerAugmentInit()
|
||||
*
|
||||
*
|
||||
* @param boolean $cache
|
||||
* @return Subsite
|
||||
*/
|
||||
@ -231,17 +231,17 @@ JS;
|
||||
if(!self::$cached_subsite || !$cache) self::$cached_subsite = DataObject::get_by_id('Subsite', self::currentSubsiteID());
|
||||
return self::$cached_subsite;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function gets the current subsite ID from the session. It used in the backend so Ajax requests
|
||||
* use the correct subsite. The frontend handles subsites differently. It calls getSubsiteIDForDomain
|
||||
* directly from ModelAsController::getNestedController. Only gets Subsite instances which have their
|
||||
* {@link IsPublic} flag set to TRUE.
|
||||
*
|
||||
*
|
||||
* You can simulate subsite access without creating subdomains by appending ?SubsiteID=<ID> to the request.
|
||||
*
|
||||
*
|
||||
* @todo Pass $request object from controller so we don't have to rely on $_REQUEST
|
||||
*
|
||||
*
|
||||
* @param boolean $cache
|
||||
* @return int ID of the current subsite instance
|
||||
*/
|
||||
@ -251,15 +251,15 @@ JS;
|
||||
} else if(Session::get('SubsiteID')) {
|
||||
$id = Session::get('SubsiteID');
|
||||
}
|
||||
|
||||
|
||||
if(!isset($id) || $id === NULL) {
|
||||
$id = self::getSubsiteIDForDomain($cache);
|
||||
Session::set('SubsiteID', $id);
|
||||
}
|
||||
|
||||
|
||||
return (int)$id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo Object::create() shoudln't be overloaded with different parameters.
|
||||
*/
|
||||
@ -271,43 +271,47 @@ JS;
|
||||
$newSubsite->createInitialRecords();
|
||||
return $newSubsite;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Switch to another subsite.
|
||||
*
|
||||
*
|
||||
* @param int|Subsite $subsite Either the ID of the subsite, or the subsite object itself
|
||||
*/
|
||||
static function changeSubsite($subsite) {
|
||||
if(is_object($subsite)) $subsiteID = $subsite->ID;
|
||||
else $subsiteID = $subsite;
|
||||
|
||||
|
||||
Session::set('SubsiteID', $subsiteID);
|
||||
|
||||
// And clear caches
|
||||
self::$cached_subsite = NULL ;
|
||||
Permission::flush_permission_cache() ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make this subsite the current one
|
||||
*/
|
||||
public function activate() {
|
||||
Subsite::changeSubsite($this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo Possible security issue, don't grant edit permissions to everybody.
|
||||
*/
|
||||
function canEdit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a matching subsite for the domain defined in HTTP_HOST.
|
||||
*
|
||||
*
|
||||
* @return int Subsite ID
|
||||
*/
|
||||
static function getSubsiteIDForDomain() {
|
||||
$domainNameParts = explode('.', $_SERVER['HTTP_HOST']);
|
||||
|
||||
|
||||
if($domainNameParts[0] == 'www') array_shift($domainNameParts);
|
||||
|
||||
|
||||
$SQL_subdomain = Convert::raw2sql(array_shift($domainNameParts));
|
||||
$SQL_domain = join('.', Convert::raw2sql($domainNameParts));
|
||||
|
||||
@ -321,39 +325,39 @@ JS;
|
||||
if(!$subsite) {
|
||||
$subsite = DataObject::get_one('Subsite',"`DefaultSite` AND `IsPublic`");
|
||||
}
|
||||
|
||||
|
||||
if($subsite) {
|
||||
// This will need to be updated to use the current theme system
|
||||
// SSViewer::setCurrentTheme($subsite->Theme);
|
||||
return $subsite->ID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getMembersByPermission($permissionCodes = array('ADMIN')){
|
||||
if(!is_array($permissionCodes))
|
||||
user_error('Permissions must be passed to Subsite::getMembersByPermission as an array', E_USER_ERROR);
|
||||
$SQL_permissionCodes = Convert::raw2sql($permissionCodes);
|
||||
|
||||
|
||||
$SQL_permissionCodes = join("','", $SQL_permissionCodes);
|
||||
|
||||
|
||||
return DataObject::get(
|
||||
'Member',
|
||||
"`Group`.`SubsiteID` = $this->ID AND `Permission`.`Code` IN ('$SQL_permissionCodes')",
|
||||
'',
|
||||
'Member',
|
||||
"`Group`.`SubsiteID` = $this->ID AND `Permission`.`Code` IN ('$SQL_permissionCodes')",
|
||||
'',
|
||||
"LEFT JOIN `Group_Members` ON `Member`.`ID` = `Group_Members`.`MemberID`
|
||||
LEFT JOIN `Group` ON `Group`.`ID` = `Group_Members`.`GroupID`
|
||||
LEFT JOIN `Permission` ON `Permission`.`GroupID` = `Group`.`ID`"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all subsites.
|
||||
*
|
||||
*
|
||||
* @return DataObjectSet Subsite instances
|
||||
*/
|
||||
static function getSubsitesForMember( $member = null) {
|
||||
if(!$member && $member !== FALSE) $member = Member::currentMember();
|
||||
|
||||
|
||||
if(!$member) return false;
|
||||
|
||||
if(self::hasMainSitePermission($member)) {
|
||||
@ -361,46 +365,46 @@ JS;
|
||||
} else {
|
||||
return DataObject::get(
|
||||
'Subsite',
|
||||
"`MemberID` = {$member->ID}",
|
||||
"`MemberID` = {$member->ID}",
|
||||
'',
|
||||
"LEFT JOIN `Group` ON `Subsite`.`ID` = `SubsiteID`
|
||||
LEFT JOIN `Group_Members` ON `Group`.`ID` = `Group_Members`.`GroupID`"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static function hasMainSitePermission($member = null, $permissionCodes = array('ADMIN')) {
|
||||
if(!is_array($permissionCodes))
|
||||
user_error('Permissions must be passed to Subsite::hasMainSitePermission as an array', E_USER_ERROR);
|
||||
|
||||
if(!$member && $member !== FALSE) $member = Member::currentMember();
|
||||
|
||||
|
||||
if(!$member) return false;
|
||||
|
||||
|
||||
if(Permission::checkMember($member->ID, "ADMIN")) return true;
|
||||
|
||||
if(Permission::checkMember($member, "SUBSITE_ACCESS_ALL")) return true;
|
||||
|
||||
$SQLa_perm = Convert::raw2sql($permissionCodes);
|
||||
$SQL_perms = join("','", $SQLa_perm);
|
||||
$SQL_perms = join("','", $SQLa_perm);
|
||||
$memberID = (int)$member->ID;
|
||||
|
||||
|
||||
$groupCount = DB::query("
|
||||
SELECT COUNT(`Permission`.`ID`)
|
||||
FROM `Permission`
|
||||
INNER JOIN `Group` ON `Group`.`ID` = `Permission`.`GroupID` AND `Group`.`SubsiteID` = 0
|
||||
INNER JOIN `Group_Members` USING(`GroupID`)
|
||||
WHERE
|
||||
`Permission`.`Code` IN ('$SQL_perms')
|
||||
SELECT COUNT(`Permission`.`ID`)
|
||||
FROM `Permission`
|
||||
INNER JOIN `Group` ON `Group`.`ID` = `Permission`.`GroupID` AND `Group`.`SubsiteID` = 0
|
||||
INNER JOIN `Group_Members` USING(`GroupID`)
|
||||
WHERE
|
||||
`Permission`.`Code` IN ('$SQL_perms')
|
||||
AND `MemberID` = {$memberID}
|
||||
")->value();
|
||||
|
||||
return ($groupCount > 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function createInitialRecords() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -408,10 +412,10 @@ JS;
|
||||
*/
|
||||
function duplicate() {
|
||||
$newTemplate = parent::duplicate();
|
||||
|
||||
|
||||
$oldSubsiteID = Session::get('SubsiteID');
|
||||
self::changeSubsite($this->ID);
|
||||
|
||||
|
||||
/*
|
||||
* Copy data from this template to the given subsite. Does this using an iterative depth-first search.
|
||||
* This will make sure that the new parents on the new subsite are correct, and there are no funny
|
||||
@ -419,11 +423,11 @@ JS;
|
||||
* when a page, etc, is duplicated
|
||||
*/
|
||||
$stack = array(array(0,0));
|
||||
while(count($stack) > 0) {
|
||||
while(count($stack) > 0) {
|
||||
list($sourceParentID, $destParentID) = array_pop($stack);
|
||||
|
||||
|
||||
$children = Versioned::get_by_stage('Page', 'Live', "`ParentID`=$sourceParentID", '');
|
||||
|
||||
|
||||
if($children) {
|
||||
foreach($children as $child) {
|
||||
$childClone = $child->duplicateToSubsite($newTemplate, false);
|
||||
@ -436,61 +440,62 @@ JS;
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
*
|
||||
* Sites will only be included if they have a Title and a Subdomain.
|
||||
* Templates will only be included if they have a Title.
|
||||
*
|
||||
*
|
||||
* @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();
|
||||
|
||||
|
||||
$templateClassList = "'" . implode("', '", ClassInfo::subclassesFor("Subsite_Template")) . "'";
|
||||
|
||||
$subsites = DataObject::get(
|
||||
'Subsite',
|
||||
"`Group_Members`.`MemberID` = $member->ID
|
||||
AND `Permission`.`Code` IN ($SQL_codes, 'ADMIN')
|
||||
AND (Subdomain IS NOT NULL OR `Subsite`.ClassName IN ($templateClassList)) AND `Subsite`.Title != ''",
|
||||
"`Group_Members`.`MemberID` = $member->ID
|
||||
AND `Permission`.`Code` IN ($SQL_codes, 'ADMIN')
|
||||
AND (Subdomain IS NOT NULL OR `Subsite`.ClassName IN ($templateClassList)) AND `Subsite`.Title != ''",
|
||||
'',
|
||||
"LEFT JOIN `Group` ON (`SubsiteID`=`Subsite`.`ID` OR `SubsiteID` = 0)
|
||||
"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
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Return the FieldSet that will build the search form in the CMS
|
||||
*/
|
||||
function adminSearchFields() {
|
||||
return new FieldSet(
|
||||
new TextField('Name', 'Sub-site name')
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function providePermissions() {
|
||||
return array(
|
||||
'SUBSITE_EDIT' => 'Edit Sub-site Details',
|
||||
'SUBSITE_ACCESS_ALL' => 'Access all subsites',
|
||||
'SUBSITE_ASSETS_EDIT' => 'Edit Sub-site Assets Admin'
|
||||
);
|
||||
}
|
||||
|
||||
@ -500,10 +505,10 @@ JS;
|
||||
self::$disable_subsite_filter = false;
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disable the sub-site filtering; queries will select from all subsites
|
||||
*/
|
||||
*/
|
||||
static function disable_subsite_filter($disabled = true) {
|
||||
self::$disable_subsite_filter = $disabled;
|
||||
}
|
||||
@ -511,7 +516,7 @@ JS;
|
||||
|
||||
/**
|
||||
* An instance of subsite that can be duplicated to provide a quick way to create new subsites.
|
||||
*
|
||||
*
|
||||
* @package subsites
|
||||
*/
|
||||
class Subsite_Template extends Subsite {
|
||||
@ -525,11 +530,11 @@ class Subsite_Template extends Subsite {
|
||||
$intranet->Subdomain = $subdomain;
|
||||
$intranet->TemplateID = $this->ID;
|
||||
$intranet->write();
|
||||
|
||||
|
||||
|
||||
|
||||
$oldSubsiteID = Session::get('SubsiteID');
|
||||
self::changeSubsite($this->ID);
|
||||
|
||||
|
||||
/*
|
||||
* Copy site content from this template to the given subsite. Does this using an iterative depth-first search.
|
||||
* This will make sure that the new parents on the new subsite are correct, and there are no funny
|
||||
@ -537,11 +542,11 @@ class Subsite_Template extends Subsite {
|
||||
* when a page, etc, is duplicated
|
||||
*/
|
||||
$stack = array(array(0,0));
|
||||
while(count($stack) > 0) {
|
||||
while(count($stack) > 0) {
|
||||
list($sourceParentID, $destParentID) = array_pop($stack);
|
||||
|
||||
$children = Versioned::get_by_stage('Page', 'Live', "`ParentID`=$sourceParentID", '');
|
||||
|
||||
|
||||
$children = Versioned::get_by_stage('SiteTree', 'Live', "`ParentID`=$sourceParentID", '');
|
||||
|
||||
if($children) {
|
||||
foreach($children as $child) {
|
||||
$childClone = $child->duplicateToSubsite($intranet);
|
||||
@ -552,7 +557,7 @@ class Subsite_Template extends Subsite {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy groups from the template to the given subsites. Each of the groups will be created and left
|
||||
* empty.
|
||||
@ -563,7 +568,7 @@ class Subsite_Template extends Subsite {
|
||||
}
|
||||
|
||||
self::changeSubsite($oldSubsiteID);
|
||||
|
||||
|
||||
return $intranet;
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ class SubsiteAdmin extends GenericDataAdmin {
|
||||
'subsite' => 'New site',
|
||||
'template' => 'New template',
|
||||
)),
|
||||
new DropdownField('TemplateID', 'Use template:', $templateArray)//,
|
||||
new DropdownField('TemplateID', 'Copy structure from:', $templateArray)//,
|
||||
/*new TextField('AdminName', 'Admin name:'),
|
||||
new EmailField('AdminEmail', 'Admin email:')*/
|
||||
),
|
||||
|
@ -1,9 +1,9 @@
|
||||
<div id="LeftPane">
|
||||
<h2>Create Intranet</h2>
|
||||
<h2>Create Sub-site</h2>
|
||||
<div id="AddIntranetForm_holder" style="overflow:auto">
|
||||
$AddSubsiteForm
|
||||
</div>
|
||||
<h2>Search for Intranets</h2>
|
||||
<h2>Search for Sub-sites</h2>
|
||||
<div id="Search_holder" style="overflow: auto;">
|
||||
<div id="SearchForm_holder" style="overflow:auto">
|
||||
$SearchForm
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
class SubsiteAdminTest extends SapphireTest {
|
||||
static $fixture_file = 'subsites/tests/SubsiteTest.yml';
|
||||
@ -99,7 +99,7 @@ class SubsiteAdminTest extends SapphireTest {
|
||||
*/
|
||||
function testMainsiteAdminCanAccessAllSubsites() {
|
||||
$member = $this->objFromFixture('Member', 'admin');
|
||||
$member->logIn();
|
||||
Session::set("loggedInAs", $member->ID);
|
||||
|
||||
$cmsMain = new CMSMain();
|
||||
foreach($cmsMain->Subsites() as $subsite) {
|
||||
|
@ -35,7 +35,7 @@ class SubsiteTest extends SapphireTest {
|
||||
// Another test that changeSubsite is working
|
||||
Subsite::changeSubsite($subsite->ID);
|
||||
$pages = DataObject::get("SiteTree");
|
||||
|
||||
|
||||
$siteHome = DataObject::get_one('SiteTree', "URLSegment = 'home'");
|
||||
$this->assertEquals($subsite->ID, $siteHome->SubsiteID);
|
||||
|
||||
@ -43,7 +43,7 @@ class SubsiteTest extends SapphireTest {
|
||||
$this->assertEquals($siteHome->MasterPageID, $tmplHome->ID);
|
||||
|
||||
// Check linking of child pages
|
||||
$tmplStaff = $this->objFromFixture('Page','staff');
|
||||
$tmplStaff = $this->objFromFixture('SiteTree','staff');
|
||||
$siteStaff = DataObject::get_one('SiteTree', "URLSegment = '" . Convert::raw2sql($tmplStaff->URLSegment) . "'");
|
||||
$this->assertEquals($siteStaff->MasterPageID, $tmplStaff->ID);
|
||||
|
||||
@ -77,33 +77,37 @@ class SubsiteTest extends SapphireTest {
|
||||
$admin = $this->objFromFixture('Member', 'admin');
|
||||
$subsite1member = $this->objFromFixture('Member', 'subsite1member');
|
||||
$subsite2member = $this->objFromFixture('Member', 'subsite2member');
|
||||
$mainpage = $this->objFromFixture('Page', 'home');
|
||||
$subsite1page = $this->objFromFixture('Page', 'subsite1_home');
|
||||
$subsite2page = $this->objFromFixture('Page', 'subsite2_home');
|
||||
$mainpage = $this->objFromFixture('SiteTree', 'home');
|
||||
$subsite1page = $this->objFromFixture('SiteTree', 'subsite1_home');
|
||||
$subsite2page = $this->objFromFixture('SiteTree', 'subsite2_home');
|
||||
$subsite1 = $this->objFromFixture('Subsite_Template', 'subsite1');
|
||||
$subsite2 = $this->objFromFixture('Subsite_Template', 'subsite2');
|
||||
|
||||
Session::set("loggedInAs", $admin->ID);
|
||||
$this->assertTrue(
|
||||
$subsite1page->canEdit($admin),
|
||||
(bool)$subsite1page->canEdit(),
|
||||
'Administrators can edit all subsites'
|
||||
);
|
||||
|
||||
// @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
|
||||
Subsite::changeSubsite($subsite1);
|
||||
|
||||
Session::set("loggedInAs", $subsite1member->ID);
|
||||
$this->assertTrue(
|
||||
$subsite1page->canEdit($subsite1member),
|
||||
(bool)$subsite1page->canEdit(),
|
||||
'Members can edit pages on a subsite if they are in a group belonging to this subsite'
|
||||
);
|
||||
|
||||
Session::set("loggedInAs", $subsite2member->ID);
|
||||
$this->assertFalse(
|
||||
$subsite1page->canEdit($subsite2member),
|
||||
(bool)$subsite1page->canEdit(),
|
||||
'Members cant edit pages on a subsite if they are not in a group belonging to this subsite'
|
||||
);
|
||||
|
||||
// @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state
|
||||
Subsite::changeSubsite($subsite2);
|
||||
$this->assertFalse(
|
||||
$mainpage->canEdit($subsite2member),
|
||||
$mainpage->canEdit(),
|
||||
'Members cant edit pages on the main site if they are not in a group allowing this'
|
||||
);
|
||||
|
||||
|
@ -8,7 +8,7 @@ Subsite_Template:
|
||||
subsite2:
|
||||
Title: Subsite2 Template
|
||||
Subdomain: subsite2
|
||||
Page:
|
||||
SiteTree:
|
||||
home:
|
||||
Title: Home
|
||||
SubsiteID: =>Subsite_Template.main
|
||||
@ -17,7 +17,7 @@ Page:
|
||||
SubsiteID: =>Subsite_Template.main
|
||||
staff:
|
||||
Title: Staff
|
||||
ParentID: =>Page.about
|
||||
ParentID: =>SiteTree.about
|
||||
SubsiteID: =>Subsite_Template.main
|
||||
contact:
|
||||
Title: Contact Us
|
||||
@ -34,28 +34,28 @@ Page:
|
||||
subsite2_contactus:
|
||||
Title: Contact Us (Subsite 2)
|
||||
SubsiteID: =>Subsite_Template.subsite2
|
||||
Permission:
|
||||
admin:
|
||||
Code: ADMIN
|
||||
accesscmsmain1:
|
||||
Code: CMS_ACCESS_CMSMain
|
||||
accesscmsmain2:
|
||||
Code: CMS_ACCESS_CMSMain
|
||||
Group:
|
||||
admin:
|
||||
Title: Admin
|
||||
Code: admin
|
||||
Permissions: =>Permission.admin
|
||||
subsite1_group:
|
||||
Title: subsite1_group
|
||||
Code: subsite1_group
|
||||
Subsite: =>Subsite_Template.subsite1
|
||||
Permissions: =>Permission.accesscmsmain1
|
||||
SubsiteID: =>Subsite_Template.subsite1
|
||||
subsite2_group:
|
||||
Title: subsite2_group
|
||||
Code: subsite2_group
|
||||
Subsite: =>Subsite_Template.subsite2
|
||||
Permissions: =>Permission.accesscmsmain2
|
||||
SubsiteID: =>Subsite_Template.subsite2
|
||||
Permission:
|
||||
admin:
|
||||
Code: ADMIN
|
||||
GroupID: =>Group.admin
|
||||
accesscmsmain1:
|
||||
Code: CMS_ACCESS_CMSMain
|
||||
GroupID: =>Group.subsite1_group
|
||||
accesscmsmain2:
|
||||
Code: CMS_ACCESS_CMSMain
|
||||
GroupID: =>Group.subsite2_group
|
||||
Member:
|
||||
admin:
|
||||
FirstName: Admin
|
||||
|
Loading…
Reference in New Issue
Block a user