From b646a104f1b08c13ae6762910a92de4f19c47a35 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Mon, 4 May 2009 05:03:44 +0000 Subject: [PATCH] Merged from branches/0.1 --- _config.php | 11 +- code/FileSubsites.php | 29 ++-- code/GroupSubsites.php | 80 +++++---- code/LeftAndMainSubsites.php | 5 +- code/MemberSubsites.php | 20 +++ code/Subsite.php | 221 ++++++++++++------------ code/SubsiteAdmin.php | 2 +- templates/Includes/SubsiteAdmin_left.ss | 4 +- tests/SubsiteAdminTest.php | 4 +- tests/SubsiteTest.php | 22 ++- tests/SubsiteTest.yml | 28 +-- 11 files changed, 239 insertions(+), 187 deletions(-) create mode 100644 code/MemberSubsites.php diff --git a/_config.php b/_config.php index 012ba4d..820266e 100644 --- a/_config.php +++ b/_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') ))); } diff --git a/code/FileSubsites.php b/code/FileSubsites.php index 891bce3..e82e68f 100755 --- a/code/FileSubsites.php +++ b/code/FileSubsites.php @@ -1,7 +1,7 @@ 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; } - } + } } diff --git a/code/GroupSubsites.php b/code/GroupSubsites.php index bab50b8..89998d9 100644 --- a/code/GroupSubsites.php +++ b/code/GroupSubsites.php @@ -1,14 +1,14 @@ 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 . ' (global group)'; } else { return $this->owner->Title; // . ' (' . $this->owner->Subsite()->Title . ')'; } - } - + } + /** * 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) { diff --git a/code/LeftAndMainSubsites.php b/code/LeftAndMainSubsites.php index 31bbf7a..7559769 100644 --- a/code/LeftAndMainSubsites.php +++ b/code/LeftAndMainSubsites.php @@ -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 { -?> \ No newline at end of file +?> diff --git a/code/MemberSubsites.php b/code/MemberSubsites.php new file mode 100644 index 0000000..aeac4f7 --- /dev/null +++ b/code/MemberSubsites.php @@ -0,0 +1,20 @@ +canEdit() ) $filtered[] = $groupID ; + } + $this->owner->Groups()->setByIDList( $filtered ) ; + } + +} \ No newline at end of file diff --git a/code/Subsite.php b/code/Subsite.php index 5f1e77c..0e66978 100644 --- a/code/Subsite.php +++ b/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= 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= 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; } } diff --git a/code/SubsiteAdmin.php b/code/SubsiteAdmin.php index d7c166d..ff32b58 100644 --- a/code/SubsiteAdmin.php +++ b/code/SubsiteAdmin.php @@ -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:')*/ ), diff --git a/templates/Includes/SubsiteAdmin_left.ss b/templates/Includes/SubsiteAdmin_left.ss index 25eb6eb..41a025c 100644 --- a/templates/Includes/SubsiteAdmin_left.ss +++ b/templates/Includes/SubsiteAdmin_left.ss @@ -1,9 +1,9 @@
-

Create Intranet

+

Create Sub-site

$AddSubsiteForm
-

Search for Intranets

+

Search for Sub-sites

$SearchForm diff --git a/tests/SubsiteAdminTest.php b/tests/SubsiteAdminTest.php index 13136f4..bf42dc3 100644 --- a/tests/SubsiteAdminTest.php +++ b/tests/SubsiteAdminTest.php @@ -1,4 +1,4 @@ -objFromFixture('Member', 'admin'); - $member->logIn(); + Session::set("loggedInAs", $member->ID); $cmsMain = new CMSMain(); foreach($cmsMain->Subsites() as $subsite) { diff --git a/tests/SubsiteTest.php b/tests/SubsiteTest.php index 68c90fe..feeae2c 100644 --- a/tests/SubsiteTest.php +++ b/tests/SubsiteTest.php @@ -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' ); diff --git a/tests/SubsiteTest.yml b/tests/SubsiteTest.yml index 7c85bc7..4f13228 100644 --- a/tests/SubsiteTest.yml +++ b/tests/SubsiteTest.yml @@ -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