Merged from branches/0.1

This commit is contained in:
Sam Minnee 2009-05-04 05:03:44 +00:00
parent 6037ec56e5
commit b646a104f1
11 changed files with 239 additions and 187 deletions

View File

@ -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')
)));
}

View File

@ -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;
}
}
}
}

View File

@ -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) {

View File

@ -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
View 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 ) ;
}
}

View File

@ -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;
}
}

View File

@ -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:')*/
),

View File

@ -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

View File

@ -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) {

View File

@ -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'
);

View File

@ -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