BUG: Modifying the module to work with SS 3.0

Replaced deprecated DataObjectDecorator with DataExtension

Fixed hard crashes in the cms

Updated to support new LeftAndMain template structure

Made the subsites model admin functional

Moved the LeftAndMain_Menu template up a directory so it overrides the core

Fixed some errors caused by changes to the framework

Re-organized the code folder

Fixed permission issue causing to default to first subsite regardless if it is the default or not

Fixed crashes on the subsite virtual page when creating/editing

Removed toDropdownMap() calls replacing with map()

Fixed the URLSegment field on subsites

Fixed error when detecting subsite for a domain

Improved styles on the subsite dropdown

Updated LeftAndMain_Subsites.js to work with jQuery entwine

Started porting the SubsitesTreeDropdownField.js to use jQuery entwine and work with the new TreeDropdownField.js

Fixed issue causing crash when viewing a page who is linked to by a subsite virtual page

Removed unused methods on SubsitesTreeDropdownField.js

Re-added classes that were moved

Fixed hard crash after saving caused by the many_many definition on SiteTreeSubsites

Replaced deprecated DataObjectSet creation with ArrayList

Compatibility fixes with SS 3.0 beta 2

Fixed crash in cms caused by no parameter being passed to the SubsiteReportWrapper constructor

Proper fix for report wrapper

Removed table list field in favor of a basic grid field

Fixed updateCMSFields() for file subsites

Migrated translations to yml

Fixed issue causing the current page to not get cleared when changing subsites in the cms

Fixed virtual page icon

Fixed language files issue
This commit is contained in:
Ed 2012-03-25 13:35:01 -03:00 committed by Kirk Mayo
parent a6bb5a3fb7
commit 2ef72b374c
36 changed files with 670 additions and 632 deletions

View File

@ -15,6 +15,8 @@ Object::add_extension('LeftAndMain', 'ControllerSubsites');
Object::add_extension('Group', 'GroupSubsites');
Object::add_extension('File', 'FileSubsites');
Object::add_extension('ErrorPage', 'ErrorPageSubsite');
if (class_exists('SiteConfig')) Object::add_extension('SiteConfig', 'SiteConfigSubsites');
Object::add_extension('SiteConfig', 'SiteConfigSubsites');
SS_Report::add_excluded_reports('SubsiteReportWrapper');
?>

View File

@ -6,83 +6,26 @@
*/
class SubsiteAdmin extends ModelAdmin {
static $managed_models = array('Subsite');
static $managed_models = array('Subsite', 'Subsite_Template');
static $url_segment = 'subsites';
static $menu_title = "Subsites";
public $showImportForm=false;
static $collection_controller_class = "SubsiteAdmin_CollectionController";
}
class SubsiteAdmin_CollectionController extends ModelAdmin_CollectionController {
function AddForm() {
$form = parent::AddForm();
$templates = DataObject::get('Subsite_Template', '', 'Title');
$templateArray = array('' => "(No template)");
if($templates) {
$templateArray = $templateArray + $templates->map('ID', 'Title');
}
$form->Fields()->addFieldsToTab('Root.Configuration', array(
new DropdownField('Type', 'Type', array(
'subsite' => 'New site',
'template' => 'New template',
)),
new DropdownField('TemplateID', 'Copy structure from:', $templateArray)
));
public function getEditForm($id = null) {
$form = parent::getEditForm($id);
if($this->modelClass=='Subsite') {
$grid=$form->Fields()->dataFieldByName('Subsite');
if($grid) {
$grid->getConfig()->addComponent(new GridFieldAddFromTemplateButton('toolbar-header-right'));
$grid->getConfig()->addComponent(new GridFieldAddFromTemplate());
}
}
return $form;
}
function doCreate($data, $form, $request) {
if(isset($data['TemplateID']) && $data['TemplateID']) {
$template = DataObject::get_by_id('Subsite_Template', $data['TemplateID']);
} else {
$template = null;
}
// Create subsite from existing template
switch($data['Type']) {
case 'template':
if($template) $subsite = $template->duplicate();
else {
$subsite = new Subsite_Template();
$subsite->write();
}
break;
case 'subsite':
default:
if($template) $subsite = $template->createInstance($data['Title']);
else {
$subsite = new Subsite();
$subsite->Title = $data['Title'];
$subsite->write();
}
break;
}
$form->dataFieldByName('Domains')->setExtraData(array(
"SubsiteID" => $subsite->ID,
));
$form->saveInto($subsite);
$subsite->write();
if(Director::is_ajax()) {
$recordController = new ModelAdmin_RecordController($this, $request, $subsite->ID);
return new SS_HTTPResponse(
$recordController->EditForm()->forAjaxTemplate(),
200,
sprintf(
_t('ModelAdmin.LOADEDFOREDITING', "Loaded '%s' for editing."),
$subsite->Title
)
);
} else {
Director::redirect(Controller::join_links($this->Link(), $subsitess->ID , 'edit'));
}
}
}
?>

View File

@ -1,20 +0,0 @@
<?php
class SubsiteDomain extends DataObject {
static $db = array(
"Domain" => "Varchar(255)",
"IsPrimary" => "Boolean",
);
static $has_one = array(
"Subsite" => "Subsite",
);
/**
* Whenever a Subsite Domain is written, rewrite the hostmap
*
* @return void
*/
public function onAfterWrite() {
Subsite::writeHostMap();
}
}

View File

@ -24,7 +24,7 @@ class SubsiteReportWrapper extends SS_ReportWrapper {
if($fields) {
$fields->insertBefore($subsiteField, $fields->First()->Name());
} else {
$fields = new FieldSet($subsiteField);
$fields = new FieldList($subsiteField);
}
return $fields;
}

View File

@ -1,60 +0,0 @@
<?php
/**
* Wraps around a TreedropdownField to add ability for temporary
* switching of subsite sessions.
*
* @package subsites
*/
class SubsitesTreeDropdownField extends TreeDropdownField {
protected $subsiteID = 0;
protected $extraClasses = array('SubsitesTreeDropdownField');
function Field() {
$html = parent::Field();
Requirements::javascript('subsites/javascript/SubsitesTreeDropdownField.js');
return $html;
}
function setSubsiteID($id) {
$this->subsiteID = $id;
}
function getSubsiteID() {
return $this->subsiteID;
}
function gettree(SS_HTTPRequest $request) {
$oldSubsiteID = Session::get('SubsiteID');
Session::set('SubsiteID', $this->subsiteID);
$results = parent::tree($request);
Session::set('SubsiteID', $oldSubsiteID);
return $results;
}
public function getsubtree(SS_HTTPRequest $request) {
$oldSubsiteID = Session::get('SubsiteID');
Session::set('SubsiteID', $this->subsiteID);
$obj = $this->objectForKey($_REQUEST['SubtreeRootID']);
if(!$obj) user_error("Can't find database record $this->sourceObject with $this->keyField = $_REQUEST[SubtreeRootID]", E_USER_ERROR);
if($this->filterFunc) $obj->setMarkingFilterFunction($this->filterFunc);
else if($this->sourceObject == 'Folder') $obj->setMarkingFilter('ClassName', 'Folder');
$obj->markPartialTree();
$eval = '"<li id=\"selector-' . $this->name . '-$child->' . $this->keyField . '\" class=\"$child->class" . $child->markingClasses() . "\"><a>" . $child->' . $this->labelField . ' . "</a>"';
$tree = $obj->getChildrenAsUL("", $eval, null, true);
echo substr(trim($tree), 4,-5);
Session::set('SubsiteID', $oldSubsiteID);
}
}

View File

@ -1,27 +1,32 @@
<?php
class SubsitesVirtualPage extends VirtualPage {
static $db = array(
public static $db = array(
'CustomMetaTitle' => 'Varchar(255)',
'CustomMetaKeywords' => 'Varchar(255)',
'CustomMetaDescription' => 'Text',
'CustomExtraMeta' => 'HTMLText'
);
function getCMSFields() {
public function getCMSFields() {
$fields = parent::getCMSFields();
$subsites = DataObject::get('Subsite');
if(!$subsites) $subsites = new DataObjectSet();
if(!$subsites) {
$subsites = new ArrayList();
}else {
$subsites=ArrayList::create($subsites->toArray());
}
$subsites->push(new ArrayData(array('Title' => 'Main site', 'ID' => 0)));
$subsiteSelectionField = new DropdownField(
"CopyContentFromID_SubsiteID",
"Subsite",
$subsites->toDropdownMap('ID', 'Title'),
$subsites->map('ID', 'Title'),
($this->CopyContentFromID) ? $this->CopyContentFrom()->SubsiteID : Session::get('SubsiteID')
);
$fields->addFieldToTab(
'Root.Content.Main',
'Root.Main',
$subsiteSelectionField,
'CopyContentFromID'
);
@ -36,36 +41,37 @@ class SubsitesVirtualPage extends VirtualPage {
);
if(Controller::has_curr() && Controller::curr()->getRequest()) {
$subsiteID = Controller::curr()->getRequest()->getVar('CopyContentFromID_SubsiteID');
$subsiteID = Controller::curr()->getRequest()->postVar('CopyContentFromID_SubsiteID');
$pageSelectionField->setSubsiteID($subsiteID);
}
$fields->replaceField('CopyContentFromID', $pageSelectionField);
// Create links back to the original object in the CMS
if($this->CopyContentFromID) {
$editLink = "admin/show/$this->CopyContentFromID/?SubsiteID=" . $this->CopyContentFrom()->SubsiteID;
$editLink = "admin/page/edit/show/$this->CopyContentFromID/?SubsiteID=" . $this->CopyContentFrom()->SubsiteID;
$linkToContent = "
<a class=\"cmsEditlink\" href=\"$editLink\">" .
_t('VirtualPage.EDITCONTENT', 'Click here to edit the content') .
"</a>";
$fields->removeByName("VirtualPageContentLinkLabel");
$fields->addFieldToTab(
"Root.Content.Main",
"Root.Main",
$linkToContentLabelField = new LabelField('VirtualPageContentLinkLabel', $linkToContent),
'Title'
);
$linkToContentLabelField->setAllowHTML(true);
}
$fields->addFieldToTab('Root.Content.Metadata', new TextField('CustomMetaTitle', 'Title (overrides inherited value from the source)'), 'MetaTitle');
$fields->addFieldToTab('Root.Content.Metadata', new TextareaField('CustomMetaKeywords', 'Keywords (overrides inherited value from the source)'), 'MetaKeywords');
$fields->addFieldToTab('Root.Content.Metadata', new TextareaField('CustomMetaDescription', 'Description (overrides inherited value from the source)'), 'MetaDescription');
$fields->addFieldToTab('Root.Content.Metadata', new TextField('CustomExtraMeta', 'Custom Meta Tags (overrides inherited value from the source)'), 'ExtraMeta');
$fields->addFieldToTab('Root.Metadata', new TextField('CustomMetaTitle', 'Title (overrides inherited value from the source)'), 'MetaTitle');
$fields->addFieldToTab('Root.Metadata', new TextareaField('CustomMetaKeywords', 'Keywords (overrides inherited value from the source)'), 'MetaKeywords');
$fields->addFieldToTab('Root.Metadata', new TextareaField('CustomMetaDescription', 'Description (overrides inherited value from the source)'), 'MetaDescription');
$fields->addFieldToTab('Root.Metadata', new TextField('CustomExtraMeta', 'Custom Meta Tags (overrides inherited value from the source)'), 'ExtraMeta');
return $fields;
}
function getVirtualFields() {
public function getVirtualFields() {
$fields = parent::getVirtualFields();
foreach($fields as $k => $v) {
if($v == 'SubsiteID') unset($fields[$k]);
@ -76,14 +82,14 @@ class SubsitesVirtualPage extends VirtualPage {
return $fields;
}
function syncLinkTracking() {
public function syncLinkTracking() {
$oldState = Subsite::$disable_subsite_filter;
Subsite::$disable_subsite_filter = true;
if ($this->CopyContentFromID) $this->HasBrokenLink = DataObject::get_by_id('SiteTree', $this->CopyContentFromID) ? false : true;
Subsite::$disable_subsite_filter = $oldState;
}
function onBeforeWrite() {
public function onBeforeWrite() {
parent::onBeforeWrite();
if($this->CustomMetaTitle) $this->MetaTitle = $this->CustomMetaTitle;
@ -104,7 +110,7 @@ class SubsitesVirtualPage extends VirtualPage {
}
}
function validURLSegment() {
public function validURLSegment() {
$isValid = parent::validURLSegment();
// Veto the validation rules if its false. In this case, some logic
@ -146,13 +152,13 @@ class SubsitesVirtualPage extends VirtualPage {
class SubsitesVirtualPage_Controller extends VirtualPage_Controller {
function reloadContent() {
public function reloadContent() {
$this->failover->copyFrom($this->failover->CopyContentFrom());
$this->failover->write();
return;
}
function init(){
public function init(){
$origDisableSubsiteFilter = Subsite::$disable_subsite_filter;
Subsite::$disable_subsite_filter = true;

View File

@ -1,20 +1,20 @@
<?php
/**
* @package subsites
*/
class ControllerSubsites extends Extension {
function controllerAugmentInit(){
if($subsite = Subsite::currentSubsite()){
if($theme = $subsite->Theme)
SSViewer::set_theme($theme);
}
}
function CurrentSubsite(){
if($subsite = Subsite::currentSubsite()){
return $subsite;
}
}
}
<?php
/**
* @package subsites
*/
class ControllerSubsites extends Extension {
function controllerAugmentInit(){
if($subsite = Subsite::currentSubsite()){
if($theme = $subsite->Theme)
SSViewer::set_theme($theme);
}
}
function CurrentSubsite(){
if($subsite = Subsite::currentSubsite()){
return $subsite;
}
}
}
?>

View File

@ -1,5 +1,5 @@
<?php
class ErrorPageSubsite extends DataObjectDecorator {
class ErrorPageSubsite extends DataExtension {
/**
* Alter file path to generated a static (static) error page file to handle error page template on different sub-sites

View File

@ -4,19 +4,18 @@
*
* @package subsites
*/
class FileSubsites extends DataObjectDecorator {
class FileSubsites extends DataExtension {
// If this is set to true, all folders created will be default be
// considered 'global', unless set otherwise
static $default_root_folders_global = false;
function extraStatics() {
if(!method_exists('DataObjectDecorator', 'load_extra_statics') && $this->owner->class != 'File') return null;
return array(
'has_one' => array(
'Subsite' => 'Subsite',
),
);
'has_one' => array(
'Subsite' => 'Subsite',
)
);
}
/**
@ -31,13 +30,13 @@ class FileSubsites extends DataObjectDecorator {
/**
* Add subsites-specific fields to the folder editor.
*/
function updateCMSFields(FieldSet &$fields) {
function updateCMSFields(FieldList $fields) {
if($this->owner instanceof Folder) {
$sites = Subsite::accessible_sites('CMS_ACCESS_AssetAdmin');
$dropdownValues = ($sites) ? $sites->toDropdownMap() : array();
$dropdownValues = ($sites) ? $sites->map()->toArray() : array();
$dropdownValues[0] = 'All sites';
ksort($dropdownValues);
if($sites)$fields->addFieldToTab('Root.Details', new DropdownField("SubsiteID", "Subsite", $dropdownValues));
if($sites)$fields->push(new DropdownField("SubsiteID", "Subsite", $dropdownValues));
}
}
@ -47,14 +46,14 @@ class FileSubsites extends DataObjectDecorator {
function augmentSQL(SQLQuery &$query) {
// If you're querying by ID, ignore the sub-site - this is a bit ugly... (but it was WAYYYYYYYYY worse)
if(!$query->where || !preg_match('/\.(\'|"|`|)ID(\'|"|`|)/', $query->where[0])) {
if($context = DataObject::context_obj()) $subsiteID = (int) $context->SubsiteID;
else $subsiteID = (int) Subsite::currentSubsiteID();
/*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) {
$where = "\"$tableName\".\"SubsiteID\" IN (0, $subsiteID)";
$query->where[] = $where;
break;
$where = "\"$tableName\".\"SubsiteID\" IN (0, $subsiteID)";
$query->where[] = $where;
break;
}
$isCounting = strpos($query->select[0], 'COUNT') !== false;

View File

@ -4,12 +4,9 @@
*
* @package subsites
*/
class GroupSubsites extends DataObjectDecorator implements PermissionProvider {
class GroupSubsites extends DataExtension implements PermissionProvider {
function extraStatics() {
if(!method_exists('DataObjectDecorator', 'load_extra_statics')) {
if($this->owner->class != 'Group') return null;
}
return array(
'db' => array(
'AccessAllSubsites' => 'Boolean',
@ -60,7 +57,7 @@ class GroupSubsites extends DataObjectDecorator implements PermissionProvider {
$fields->findOrMakeTab('Root.Subsites',_t('GroupSubsites.SECURITYTABTITLE','Subsites'));
$subsites = Subsite::accessible_sites(array('ADMIN', 'SECURITY_SUBSITE_GROUP'), true);
$subsiteMap = $subsites->toDropdownMap();
$subsiteMap = $subsites->map();
// Interface is different if you have the rights to modify subsite group values on
// all subsites
@ -116,16 +113,18 @@ class GroupSubsites extends DataObjectDecorator implements PermissionProvider {
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
if(!$query->filtersOnID()) {
if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
else $subsiteID = (int)Subsite::currentSubsiteID();
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
else */$subsiteID = (int)Subsite::currentSubsiteID();
// Don't filter by Group_Subsites if we've already done that
$hasGroupSubsites = false;
foreach($query->from as $item) if(strpos($item, 'Group_Subsites') !== false) {
$hasGroupSubsites = true;
break;
foreach($query->from as $item) {
if((is_array($item) && strpos($item['table'], 'Group_Subsites')!==false) || (!is_array($item) && strpos($item, 'Group_Subsites')!==false)) {
$hasGroupSubsites = true;
break;
}
}
if(!$hasGroupSubsites) {
if($subsiteID) {
$query->leftJoin("Group_Subsites", "\"Group_Subsites\".\"GroupID\"

View File

@ -16,9 +16,12 @@ class LeftAndMainSubsites extends Extension {
if(!Session::get('SubsiteID') || $_REQUEST['SubsiteID'] != Session::get('SubsiteID')) {
Session::clear("{$this->owner->class}.currentPage");
}
// Update current subsite in session
Subsite::changeSubsite($_REQUEST['SubsiteID']);
//Redirect to clear the current page
$this->owner->redirect('admin/pages');
}
}
@ -35,54 +38,10 @@ class LeftAndMainSubsites extends Extension {
}
public function Subsites() {
$accessPerm = 'CMS_ACCESS_'. $this->owner->class;
switch($this->owner->class) {
case "AssetAdmin":
$subsites = Subsite::accessible_sites($accessPerm, true, "Shared files & images");
break;
case "SecurityAdmin":
$subsites = Subsite::accessible_sites($accessPerm, true, "Groups accessing all sites");
if($subsites->find('ID',0)) {
$subsites->push(new ArrayData(array('Title' => 'All groups', 'ID' => -1)));
}
break;
case "CMSMain":
// If there's a default site then main site has no meaning
$showMainSite = !DataObject::get_one('Subsite',"\"DefaultSite\"=1 AND \"IsPublic\"=1");
$subsites = Subsite::accessible_sites($accessPerm, $showMainSite);
break;
default:
$subsites = Subsite::accessible_sites($accessPerm);
break;
}
return $subsites;
return Subsite::accessible_sites('ADMIN');
}
public function SubsiteList() {
if ($this->owner->class == 'AssetAdmin') {
// See if the right decorator is there....
$file = new File();
if (!$file->hasExtension('FileSubsites')) {
return false;
}
}
// Whitelist for admin sections which are subsite aware.
// For example, don't show subsite list in reports section, it doesn't have
// any effect there - subsites are filtered through a custom dropdown there, see SubsiteReportWrapper.
if(!(
$this->owner instanceof AssetAdmin
|| $this->owner instanceof SecurityAdmin
|| $this->owner instanceof CMSMain)
) {
return false;
}
$list = $this->Subsites();
$currentSubsiteID = Subsite::currentSubsiteID();
@ -101,7 +60,22 @@ class LeftAndMainSubsites extends Extension {
Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
return $output;
} else if($list->Count() == 1) {
return $list->First()->Title;
if($list->First()->DefaultSite==false) {
$output = '<select id="SubsitesSelect">';
$output .= "\n<option value=\"0\">". _t('LeftAndMainSubsites.DEFAULT_SITE', '_Default Site') . "</option>";
foreach($list as $subsite) {
$selected = $subsite->ID == $currentSubsiteID ? ' selected="selected"' : '';
$output .= "\n<option value=\"{$subsite->ID}\"$selected>". Convert::raw2xml($subsite->Title) . "</option>";
}
$output .= '</select>';
Requirements::javascript('subsites/javascript/LeftAndMain_Subsites.js');
return $output;
}else {
return '<span>'.$list->First()->Title.'</span>';
}
}
}
@ -125,9 +99,11 @@ class LeftAndMainSubsites extends Extension {
// Switch to a subsite that this user can actually access.
$member = Member::currentUser();
if ($member && $member->isAdmin()) return true; //admin can access all subsites
$sites = Subsite::accessible_sites("CMS_ACCESS_{$this->owner->class}")->toDropdownMap();
if ($member && Permission::check('ADMIN')) {
return true; //admin can access all subsites
}
$sites = Subsite::accessible_sites("CMS_ACCESS_{$this->owner->class}")->map('ID', 'Title')->toArray();
if($sites && !isset($sites[Subsite::currentSubsiteID()])) {
$siteIDs = array_keys($sites);
Subsite::changeSubsite($siteIDs[0]);
@ -139,7 +115,7 @@ class LeftAndMainSubsites extends Extension {
foreach($menu as $candidate) {
if($candidate->controller != $this->owner->class) {
$sites = Subsite::accessible_sites("CMS_ACCESS_{$candidate->controller}")->toDropdownMap();
$sites = Subsite::accessible_sites("CMS_ACCESS_{$candidate->controller}")->map('ID', 'Title')->toArray();
if($sites && !isset($sites[Subsite::currentSubsiteID()])) {
$siteIDs = array_keys($sites);
Subsite::changeSubsite($siteIDs[0]);

View File

@ -3,7 +3,7 @@
/**
* Extension for the SiteConfig object to add subsites support
*/
class SiteConfigSubsites extends DataObjectDecorator {
class SiteConfigSubsites extends DataExtension {
function extraStatics() {
return array(
'has_one' => array(
@ -20,8 +20,8 @@ class SiteConfigSubsites extends DataObjectDecorator {
// If you're querying by ID, ignore the sub-site - this is a bit ugly...
if (!$query->where || (!preg_match('/\.(\'|"|`|)ID(\'|"|`|)( ?)=/', $query->where[0]) && !preg_match('/\.?(\'|"|`|)SubsiteID(\'|"|`|)( ?)=/', $query->where[0]))) {
if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
else $subsiteID = (int)Subsite::currentSubsiteID();
/*if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
else */$subsiteID = (int)Subsite::currentSubsiteID();
$tableName = array_shift(array_keys($query->from));
if($tableName != 'SiteConfig') return;

View File

@ -3,7 +3,7 @@
/**
* Extension for the SiteTree object to add subsites support
*/
class SiteTreeSubsites extends SiteTreeDecorator {
class SiteTreeSubsites extends DataExtension {
static $template_variables = array(
'((Company Name))' => 'Title'
);
@ -28,7 +28,6 @@ class SiteTreeSubsites extends SiteTreeDecorator {
function extraStatics() {
if(!method_exists('DataObjectDecorator', 'load_extra_statics') && $this->owner->class != 'SiteTree') return null;
return array(
'has_one' => array(
'Subsite' => 'Subsite', // The subsite that this page belongs to
@ -67,8 +66,8 @@ class SiteTreeSubsites extends SiteTreeDecorator {
if (Subsite::$force_subsite) $subsiteID = Subsite::$force_subsite;
else {
if($context = DataObject::context_obj()) $subsiteID = (int)$context->SubsiteID;
else $subsiteID = (int)Subsite::currentSubsiteID();
/*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 :-)
@ -94,12 +93,18 @@ class SiteTreeSubsites extends SiteTreeDecorator {
$subsite = $this->owner->Subsite();
if($subsite && $subsite->ID) {
$baseUrl = 'http://' . $subsite->domain() . '/';
$fields->removeByName('BaseUrlLabel');
$fields->addFieldToTab(
'Root.Content.Metadata',
new LabelField('BaseUrlLabel',$baseUrl),
'URLSegment'
);
$fields->removeByName('URLSegment');
$baseLink = Controller::join_links (
$baseUrl,
(SiteTree::nested_urls() && $this->ParentID ? $this->owner->Parent()->RelativeLink(true) : null)
);
$url = (strlen($baseLink) > 36) ? "..." .substr($baseLink, -32) : $baseLink;
$urlsegment = new SiteTreeURLSegmentField("URLSegment", $this->owner->fieldLabel('URLSegment'));
$urlsegment->setURLPrefix($url);
$urlsegment->setHelpText(SiteTree::nested_urls() && count($this->owner->Children()) ? $this->owner->fieldLabel('LinkChangeNote'): false);
$fields->addFieldToTab('Root.Metadata', $urlsegment, 'MetaTitle');
}
$relatedCount = 0;
@ -113,19 +118,13 @@ class SiteTreeSubsites extends SiteTreeDecorator {
// Related pages
$tab->push(new LiteralField('RelatedNote', '<p>You can list pages here that are related to this page.<br />When this page is updated, you will get a reminder to check whether these related pages need to be updated as well.</p>'));
$tab->push(
$related = new ComplexTableField(
$this,
'RelatedPages',
'RelatedPageLink',
array(
'RelatedPageAdminLink' => 'Page',
'AbsoluteLink' => 'URL',
)
)
$related=new GridField('RelatedPages', 'Related Pages', $this->owner->RelatedPages(), GridFieldConfig_Base::create())
);
$related->setModelClass('RelatedPageLink');
// The 'show' link doesn't provide any useful info
$related->setPermissions(array('add', 'edit', 'delete'));
//$related->setPermissions(array('add', 'edit', 'delete'));
if($reverse) {
$text = '<p>In addition, this page is marked as related by the following pages: </p><p>';
@ -144,16 +143,13 @@ class SiteTreeSubsites extends SiteTreeDecorator {
*/
function ReverseRelated() {
return DataObject::get('RelatedPageLink', "\"RelatedPageLink\".\"RelatedPageID\" = {$this->owner->ID}
AND R2.\"ID\" IS NULL", '',
"INNER JOIN \"SiteTree\" ON \"SiteTree\".\"ID\" = \"RelatedPageLink\".\"MasterPageID\"
LEFT JOIN \"RelatedPageLink\" AS R2 ON R2.\"MasterPageID\" = {$this->owner->ID}
AND R2.\"RelatedPageID\" = \"RelatedPageLink\".\"MasterPageID\"
"
);
AND R2.\"ID\" IS NULL", '')
->innerJoin('SiteTree', "\"SiteTree\".\"ID\" = \"RelatedPageLink\".\"MasterPageID\"")
->leftJoin('RelatedPageLink', "R2.\"MasterPageID\" = {$this->owner->ID} AND R2.\"RelatedPageID\" = \"RelatedPageLink\".\"MasterPageID\"", 'R2');
}
function NormalRelated() {
$return = new DataObjectSet();
$return = new ArrayList();
$links = DataObject::get('RelatedPageLink', '"MasterPageID" = ' . $this->owner->ID);
if($links) foreach($links as $link) {
if($link->RelatedPage()->exists()) {

View File

@ -0,0 +1,148 @@
<?php
class GridFieldAddFromTemplateButton implements GridField_HTMLProvider {
protected $targetFragment;
public function __construct($targetFragment = 'before') {
$this->targetFragment = $targetFragment;
}
public function getHTMLFragments($gridField) {
$data = new ArrayData(array(
'NewFromTemplateLink' => $gridField->Link('newFromTemplate'),
));
return array(
$this->targetFragment => $data->renderWith('GridFieldAddFromTemplateButton'),
);
}
}
class GridFieldAddFromTemplate extends GridFieldDetailForm {
public function getURLHandlers($gridField) {
return array(
'newFromTemplate'=>'newFromTemplate',
);
}
public function newFromTemplate($gridField, $request) {
$controller = $gridField->getForm()->Controller();
if(is_numeric($request->param('ID'))) {
$record = $gridField->getList()->byId($request->param("ID"));
} else {
$record = Object::create($gridField->getModelClass());
}
$handler = Object::create('GridFieldAddFromTemplate_ItemRequest', $gridField, $this, $record, $controller, $this->name);
$handler->setTemplate($this->template);
return $handler->handleRequest($request, DataModel::inst());
}
}
class GridFieldAddFromTemplate_ItemRequest extends GridFieldDetailForm_ItemRequest {
public function Link($action = null) {
return $this->gridField->Link('newFromTemplate');
}
function edit($request) {
$controller = $this->getToplevelController();
$form = $this->NewFromTemplateForm($this->gridField, $request);
$return = $this->customise(array(
'Backlink' => $controller->Link(),
'ItemEditForm' => $form,
))->renderWith($this->template);
if($controller->isAjax()) {
return $return;
} else {
// If not requested by ajax, we need to render it within the controller context+template
return $controller->customise(array(
// TODO CMS coupling
'Content' => $return,
));
}
}
public function NewFromTemplateForm() {
$templates=DataObject::get('Subsite_Template');
$fields=new FieldList(
new DropdownField('TemplateID', _t('GridFieldAddFromTemplate.TEMPLATE', '_Template'), $templates->map('ID', 'Name'))
);
$actions=new FieldList(
FormAction::create('doCreateFromTemplate', _t('GridFieldDetailsForm.Create', 'Create'))->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'add')
);
// Add a Cancel link which is a button-like link and link back to one level up.
$curmbs = $this->Breadcrumbs();
if($curmbs && $curmbs->count()>=2){
$one_level_up = $curmbs->offsetGet($curmbs->count()-2);
$text = "
<a class=\"crumb ss-ui-button ss-ui-action-destructive cms-panel-link ui-corner-all\" href=\"".$one_level_up->Link."\">
Cancel
</a>";
$actions->push(new LiteralField('cancelbutton', $text));
}
$validator=new RequiredFields('TemplateID');
$form=new Form($this, 'NewFromTemplateForm', $fields, $actions, $validator);
// TODO Coupling with CMS
$toplevelController = $this->getToplevelController();
if($toplevelController && $toplevelController instanceof LeftAndMain) {
// Always show with base template (full width, no other panels),
// regardless of overloaded CMS controller templates.
// TODO Allow customization, e.g. to display an edit form alongside a search form from the CMS controller
$form->setTemplate('LeftAndMain_EditForm');
$form->addExtraClass('cms-content cms-edit-form center ss-tabset');
if($form->Fields()->hasTabset()) $form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet');
// TODO Link back to controller action (and edited root record) rather than index,
// which requires more URL knowledge than the current link to this field gives us.
// The current root record is held in session only,
// e.g. page/edit/show/6/ vs. page/edit/EditForm/field/MyGridField/....
$form->Backlink = $toplevelController->Link();
}
return $form;
}
public function doCreateFromTemplate($data, Form $form) {
$template=DataObject::get_by_id('Subsite_Template', intval($data['TemplateID']));
if($template) {
$subsite=$template->createInstance($data['Title']);
$subsite->write();
$this->record($subsite);
return $this->redirect(parent::Link());
}else {
$form->sessionMessage(_t('GridFieldAddFromTemplate.TEMPLATE_NOT_FOUND', '_The selected template could not be found'), 'bad');
return $this->redirectBack();
}
}
/**
* CMS-specific functionality: Passes through navigation breadcrumbs
* to the template, and includes the currently edited record (if any).
* see {@link LeftAndMain->Breadcrumbs()} for details.
*
* @param boolean $unlinked
* @return ArrayData
*/
function Breadcrumbs($unlinked = false) {
if(!$this->popupController->hasMethod('Breadcrumbs')) return;
$items = $this->popupController->Breadcrumbs($unlinked);
$items->push(new ArrayData(array(
'Title' => sprintf(_t('GridFieldAddFromTemplate.NewFromTemplate', 'New %s from template'), $this->record->singular_name()),
'Link' => false
)));
return $items;
}
}

View File

@ -0,0 +1,40 @@
<?php
/**
* Wraps around a TreedropdownField to add ability for temporary
* switching of subsite sessions.
*
* @package subsites
*/
class SubsitesTreeDropdownField extends TreeDropdownField {
protected $subsiteID = 0;
protected $extraClasses = array('SubsitesTreeDropdownField');
function Field() {
$html = parent::Field();
Requirements::javascript('subsites/javascript/SubsitesTreeDropdownField.js');
return $html;
}
function setSubsiteID($id) {
$this->subsiteID = $id;
}
function getSubsiteID() {
return $this->subsiteID;
}
function tree(SS_HTTPRequest $request) {
$oldSubsiteID = Session::get('SubsiteID');
Session::set('SubsiteID', $this->subsiteID);
$results = parent::tree($request);
Session::set('SubsiteID', $oldSubsiteID);
return $results;
}
}

View File

@ -16,10 +16,15 @@ class RelatedPageLink extends DataObject {
// bind a has_many to.
'MasterPage' => 'SiteTree',
);
public static $summary_fields=array(
'RelatedPageAdminLink' => 'Page',
'AbsoluteLink' => 'URL',
);
function getCMSFields() {
$subsites = Subsite::accessible_sites("CMS_ACCESS_CMSMain");
if(!$subsites) $subsites = new DataObjectSet();
if(!$subsites) $subsites = new ArrayList();
if(Subsite::hasMainSitePermission(null, array("CMS_ACCESS_CMSMain"))) {
$subsites->push(new ArrayData(array('Title' => 'Main site', "\"ID\"" => 0)));
@ -47,8 +52,8 @@ class RelatedPageLink extends DataObject {
$pageSelectionField->setFilterFunction(create_function('$item', 'return $item->ClassName != "VirtualPage";'));
if($subsites->Count()) $fields = new FieldSet($subsiteSelectionField, $pageSelectionField);
else $fields = new FieldSet($pageSelectionField);
if($subsites->Count()) $fields = new FieldList($subsiteSelectionField, $pageSelectionField);
else $fields = new FieldList($pageSelectionField);
return $fields;
}

View File

@ -146,7 +146,7 @@ class Subsite extends DataObject implements PermissionProvider {
function domain() {
if($this->ID) {
$domains = DataObject::get("SubsiteDomain", "\"SubsiteID\" = $this->ID", "\"IsPrimary\" DESC","", 1);
if($domains) {
if($domains && $domains->Count()>0) {
$domain = $domains->First()->Domain;
// If there are wildcards in the primary domain (not recommended), make some
// educated guesses about what to replace them with:
@ -178,10 +178,7 @@ class Subsite extends DataObject implements PermissionProvider {
* Show the configuration fields for each subsite
*/
function getCMSFields() {
$domainTable = new TableField("Domains", "SubsiteDomain",
array("Domain" => "Domain <small>(use * as a wildcard)</small>", "IsPrimary" => "Primary domain?"),
array("Domain" => "TextField", "IsPrimary" => "CheckboxField"),
"SubsiteID", $this->ID);
$domainTable = new GridField("Domains", "Domains", $this->Domains(), GridFieldConfig_RecordEditor::create(10));
$languageSelector = new DropdownField('Language', 'Language', i18n::get_common_locales());
@ -192,7 +189,7 @@ class Subsite extends DataObject implements PermissionProvider {
}
asort($pageTypeMap);
$fields = new FieldSet(
$fields = new FieldList(
new TabSet('Root',
new Tab('Configuration',
new HeaderField($this->getClassName() . ' configuration', 2),
@ -238,7 +235,7 @@ class Subsite extends DataObject implements PermissionProvider {
}
function getCMSActions() {
return new FieldSet(
return new FieldList(
new FormAction('callPageMethod', "Create copy", null, 'adminDuplicate')
);
}
@ -285,7 +282,7 @@ JS;
$id = self::getSubsiteIDForDomain();
Session::set('SubsiteID', $id);
}
return (int)$id;
}
@ -341,12 +338,12 @@ JS;
$SQL_host = Convert::raw2sql($host);
$matchingDomains = DataObject::get("SubsiteDomain", "'$SQL_host' LIKE replace(\"SubsiteDomain\".\"Domain\",'*','%')",
"\"IsPrimary\" DESC", "INNER JOIN \"Subsite\" ON \"Subsite\".\"ID\" = \"SubsiteDomain\".\"SubsiteID\" AND
"\"IsPrimary\" DESC")->innerJoin('Subsite', "\"Subsite\".\"ID\" = \"SubsiteDomain\".\"SubsiteID\" AND
\"Subsite\".\"IsPublic\"=1");
if($matchingDomains) {
$subsiteIDs = array_unique($matchingDomains->column('SubsiteID'));
$subsiteDomains = array_unique($matchingDomains->column('Domain'));
if($matchingDomains && $matchingDomains->Count()>0) {
$subsiteIDs = array_unique($matchingDomains->map('SubsiteID')->keys());
$subsiteDomains = array_unique($matchingDomains->map('Domain')->keys());
if(sizeof($subsiteIDs) > 1) {
throw new UnexpectedValueException(sprintf(
"Multiple subsites match on '%s': %s",
@ -473,12 +470,12 @@ JS;
* @param $includeMainSite If true, the main site will be included if appropriate.
* @param $mainSiteTitle The label to give to the main site
* @param $member
* @return DataObjectSet of {@link Subsite} instances
* @return DataList of {@link Subsite} instances
*/
function accessible_sites($permCode, $includeMainSite = false, $mainSiteTitle = "Main site", $member = null) {
// Rationalise member arguments
if(!$member) $member = Member::currentUser();
if(!$member) return new DataObjectSet();
if(!$member) return new ArrayList();
if(!is_object($member)) $member = DataObject::get_by_id('Member', $member);
// Rationalise permCode argument
@ -496,39 +493,22 @@ JS;
$subsites = DataObject::get(
'Subsite',
"\"Subsite\".\"Title\" != ''",
'',
"LEFT JOIN \"Group_Subsites\"
ON \"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"
INNER JOIN \"Group\" ON \"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\"
OR \"Group\".\"AccessAllSubsites\" = 1
INNER JOIN \"Group_Members\"
ON \"Group_Members\".\"GroupID\"=\"Group\".\"ID\"
AND \"Group_Members\".\"MemberID\" = $member->ID
INNER JOIN \"Permission\"
ON \"Group\".\"ID\"=\"Permission\".\"GroupID\"
AND \"Permission\".\"Code\" IN ($SQL_codes, 'ADMIN')"
);
if(!$subsites) $subsites = new DataObjectSet();
'')->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
->innerJoin('Group', "\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
->innerJoin('Group_Members', "\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
->innerJoin('Permission', "\"Group\".\"ID\"=\"Permission\".\"GroupID\" AND \"Permission\".\"Code\" IN ($SQL_codes, 'ADMIN')");
if(!$subsites) $subsites = new ArrayList();
$rolesSubsites = DataObject::get(
'Subsite',
"\"Subsite\".\"Title\" != ''",
'',
"LEFT JOIN \"Group_Subsites\"
ON \"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"
INNER JOIN \"Group\" ON \"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\"
OR \"Group\".\"AccessAllSubsites\" = 1
INNER JOIN \"Group_Members\"
ON \"Group_Members\".\"GroupID\"=\"Group\".\"ID\"
AND \"Group_Members\".\"MemberID\" = $member->ID
INNER JOIN \"Group_Roles\"
ON \"Group_Roles\".\"GroupID\"=\"Group\".\"ID\"
INNER JOIN \"PermissionRole\"
ON \"Group_Roles\".\"PermissionRoleID\"=\"PermissionRole\".\"ID\"
INNER JOIN \"PermissionRoleCode\"
ON \"PermissionRole\".\"ID\"=\"PermissionRoleCode\".\"RoleID\"
AND \"PermissionRoleCode\".\"Code\" IN ($SQL_codes, 'ADMIN')"
);
'')->leftJoin('Group_Subsites', "\"Group_Subsites\".\"SubsiteID\" = \"Subsite\".\"ID\"")
->innerJoin('Group', "\"Group\".\"ID\" = \"Group_Subsites\".\"GroupID\" OR \"Group\".\"AccessAllSubsites\" = 1")
->innerJoin('Group_Members', "\"Group_Members\".\"GroupID\"=\"Group\".\"ID\" AND \"Group_Members\".\"MemberID\" = $member->ID")
->innerJoin('Group_Roles', "\"Group_Roles\".\"GroupID\"=\"Group\".\"ID\"")
->innerJoin('PermissionRole', "\"Group_Roles\".\"PermissionRoleID\"=\"PermissionRole\".\"ID\"")
->innerJoin('PermissionRoleCode', "\"PermissionRole\".\"ID\"=\"PermissionRoleCode\".\"RoleID\" AND \"PermissionRoleCode\".\"Code\" IN ($SQL_codes, 'ADMIN')");
if(!$subsites && $rolesSubsites) return $rolesSubsites;
@ -539,13 +519,16 @@ JS;
}
// Include the main site
if(!$subsites) $subsites = new DataObjectSet();
if(!$subsites) $subsites = new ArrayList();
if($includeMainSite) {
if(!is_array($permCode)) $permCode = array($permCode);
if(self::hasMainSitePermission($member, $permCode)) {
$subsites=$subsites->toArray();
$mainSite = new Subsite();
$mainSite->Title = $mainSiteTitle;
$subsites->insertFirst($mainSite);
array_unshift($subsites, $mainSite);
$subsites=ArrayList::create($subsites);
}
}
@ -593,10 +576,10 @@ JS;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Return the FieldSet that will build the search form in the CMS
* Return the FieldList that will build the search form in the CMS
*/
function adminSearchFields() {
return new FieldSet(
return new FieldList(
new TextField('Name', 'Sub-site name')
);
}

View File

@ -0,0 +1,32 @@
<?php
class SubsiteDomain extends DataObject {
static $db = array(
"Domain" => "Varchar(255)",
"IsPrimary" => "Boolean",
);
static $has_one = array(
"Subsite" => "Subsite",
);
public static $summary_fields=array(
'Domain'=>'Domain',
'IsPrimary'=>'Is Primary Domain'
);
/**
* Whenever a Subsite Domain is written, rewrite the hostmap
*
* @return void
*/
public function onAfterWrite() {
Subsite::writeHostMap();
}
public function getCMSFields() {
return new FieldList(
new TextField('Domain', _t('SubsiteDomain.DOMAIN', '_Domain'), null, 255),
new CheckboxField('IsPrimary', _t('SubsiteDomain.IS_PRIMARY', '_Is Primary Domain'))
);
}
}

View File

@ -24,19 +24,19 @@
padding: 3px;
}
.cms-login-status.subsites {
padding-bottom: 7px;
}
#SubsitesSelect,
#SubsitesSelect option {
font-size: 12px;
}
#SubsitesSelect {
max-width: 200px;
width: 171px;
padding: 3px;
}
#top #MainMenu #Menu-help {
margin-right: 260px;
}
#AddSubsiteLink {
display: block;
font-size: 80%;
@ -55,4 +55,8 @@
body.SubsiteAdmin .right form #URL .fieldgroup * {
font-size: 11px;
}
.cms-add-form #PageType li .class-SubsitesVirtualPage, .class-SubsitesVirtualPage a .jstree-pageicon {
background-position: 0 -32px !important;
}

View File

@ -1,53 +1,53 @@
Behaviour.register({
'#SubsiteActions select' : {
onchange: function() {
document.location.href = SiteTreeHandlers.controller_url + '?SubsiteID=' + this.value;
}
},
// Subsite tab of Group editor
'#Form_EditForm_AccessAllSubsites' : {
initialize: function () {
this.showHideSubsiteList();
var i=0,items=this.getElementsByTagName('input');
for(i=0;i<items.length;i++) {
items[i].onchange = this.showHideSubsiteList;
}
},
showHideSubsiteList : function () {
$('Form_EditForm_Subsites').parentNode.style.display =
Form.Element.getValue($('Form_EditForm').AccessAllSubsites)==1 ? 'none' : '';
}
},
/**
* Binding a visibility toggle anchor to a longer list of checkboxes.
* Hidden by default, unless either the toggle checkbox, or any of the
* actual value checkboxes are selected.
*/
'a#PageTypeBlacklistToggle': {
onclick: function(e) {
jQuery('#PageTypeBlacklist').toggle();
return false;
}
},
'#PageTypeBlacklist': {
initialize: function() {
var hasLimits = Boolean(jQuery(this).find('input:checked').length);
jQuery(this).toggle(hasLimits);
}
}
});
// Add an item to fieldsToIgnore
Behaviour.register({
'#Form_EditForm' : {
initialize: function () {
this.changeDetection_fieldsToIgnore.IsSubsite = true;
}
}
});
fitToParent('ResultTable_holder');
(function($) {
$.entwine('ss', function($) {
$('#SubsitesSelect').live('change', function() {
window.location.search=$.query.set('SubsiteID', $(this).val());
});
// Subsite tab of Group editor
$('#Form_ItemEditForm_AccessAllSubsites').entwine({
/**
* Constructor: onmatch
*/
onmatch: function () {
this.showHideSubsiteList();
var ref=this;
$('#Form_ItemEditForm_AccessAllSubsites input').change(function() {
ref.showHideSubsiteList();
});
},
showHideSubsiteList: function () {
$('#Form_ItemEditForm_Subsites').parent().parent().css('display', ($('#Form_ItemEditForm_AccessAllSubsites_1').is(':checked') ? 'none':''));
}
});
$('.cms-edit-form').entwine({
getChangeTrackerOptions: function() {
this.ChangeTrackerOptions.ignoreFieldSelector+=', input[name=IsSubsite]';
}
});
/**
* Binding a visibility toggle anchor to a longer list of checkboxes.
* Hidden by default, unless either the toggle checkbox, or any of the
* actual value checkboxes are selected.
*/
$('#PageTypeBlacklist').entwine({
onmatch: function() {
var hasLimits=Boolean($('#PageTypeBlacklist').find('input:checked').length);
jQuery('#PageTypeBlacklist').toggle(hasLimits);
//Bind listener
$('a#PageTypeBlacklistToggle').click(function(e) {
jQuery('#PageTypeBlacklist').toggle();
e.stopPropagation();
return false;
});
}
});
});
})(jQuery);

View File

@ -1,54 +1,26 @@
SubsitesTreeDropdownField = Class.extend('TreeDropdownField');
SubsitesTreeDropdownField.prototype = {
subsiteID: function() {
var subsiteSel = $$('#CopyContentFromID_SubsiteID select')[0];
subsiteSel.onchange = (function() {
this.createTreeNode(true);
this.ajaxGetTree((function(response) {
this.newTreeReady(response, true);
this.updateTreeLabel();
}).bind(this));
}).bind(this);
return subsiteSel.options[subsiteSel.selectedIndex].value;
},
ajaxGetTree: function(after) {
// Can't force value because it might be on a different subsite!
var ajaxURL = this.buildURL('gettree?forceValues=' + 0); //this.inputTag.value;
// Customised: Append subsiteid (evaluated in SubsitesVirtualPage.php)
ajaxURL += '&' + this.inputTag.name + '_SubsiteID=' + parseInt(this.subsiteID());
ajaxURL += $('SecurityID') ? '&SecurityID=' + $('SecurityID').value : '';
new Ajax.Request(ajaxURL, {
method : 'get',
onSuccess : after,
onFailure : function(response) { errorMessage("Error getting data", response); }
})
},
// This ajaxExpansion function is actually attached as a method on the tree object; therefore, this.getIdx() is a method
// note also this.tree.options.dropdownField.subsiteID() must be called, not this.subsiteID()
ajaxExpansion: function() {
this.addNodeClass('loading');
var ul = this.treeNodeHolder();
ul.innerHTML = ss.i18n._t('LOADING');
var ajaxURL = this.options.dropdownField.buildURL('getsubtree?SubtreeRootID=' + this.getIdx());
// Find the root of the tree - this points to a list item in the tree, not the root div we actually want
// @todo: We should be using framework API calls to find the tree
var tree = this;
while (tree && !tree.className.match(/(^| )SubsitesTreeDropdownField( |$)/)) tree = tree.parentNode;
// Customized: Append subsiteid (evaluated in SubsitesVirtualPage.php)
ajaxURL += '&' + this.options.dropdownField.inputTag.name + '_SubsiteID=' + parseInt(this.options.dropdownField.subsiteID());
new Ajax.Request(ajaxURL, {
onSuccess : this.installSubtree.bind(this),
onFailure : function(response) { errorMessage('error loading subtree', response); }
});
}
}
SubsitesTreeDropdownField.applyTo('div.SubsitesTreeDropdownField');
(function($) {
$.entwine('ss', function($) {
$('.TreeDropdownField').entwine({
subsiteID: function() {
var subsiteSel = $$('#CopyContentFromID_SubsiteID select')[0];
subsiteSel.onchange = (function() {
this.createTreeNode(true);
this.ajaxGetTree((function(response) {
this.newTreeReady(response, true);
this.updateTreeLabel();
}).bind(this));
}).bind(this);
return subsiteSel.options[subsiteSel.selectedIndex].value;
},
getRequestParams: function() {
var name=this.find(':input:hidden').attr('name');
var obj={};
obj[name+'_SubsiteID']=parseInt(this.subsiteID());
return obj;
}
});
});
})(jQuery);

View File

@ -1,79 +0,0 @@
<?php
global $lang;
$lang['en_US']['SubsiteAdmin']['MENUTITLE'] = array(
'Subsites',
100,
'Menu title'
);
$lang['en_US']['GroupSubsites']['ACCESSALL'] = 'All subsites';
$lang['en_US']['GroupSubsites']['ACCESSONLY'] = 'Only these subsites';
$lang['en_US']['GroupSubsites']['ACCESSRADIOTITLE'] = 'Give this group access to';
$lang['en_US']['GroupSubsites']['SECURITYTABTITLE'] = 'Subsites';
$lang['en_US']['ModelAdmin']['LOADEDFOREDITING'] = 'Loaded \'%s\' for editing.';
$lang['en_US']['RelatedPageLink']['PLURALNAME'] = array(
'Related Page Links',
50,
'Pural name of the object, used in dropdowns and to generally identify a collection of this object in the interface'
);
$lang['en_US']['RelatedPageLink']['SINGULARNAME'] = array(
'Related Page Link',
50,
'Singular name of the object, used in dropdowns and to generally identify a single object in the interface'
);
$lang['en_US']['ModelAdmin']['LOADEDFOREDITING'] = 'Loaded \'%s\' for editing.';
$lang['en_US']['RelatedPageLink']['PLURALNAME'] = array(
'Related Page Links',
50,
'Pural name of the object, used in dropdowns and to generally identify a collection of this object in the interface'
);
$lang['en_US']['RelatedPageLink']['SINGULARNAME'] = array(
'Related Page Link',
50,
'Singular name of the object, used in dropdowns and to generally identify a single object in the interface'
);
$lang['en_US']['Subsite']['PLURALNAME'] = array(
'Subsits',
50,
'Pural name of the object, used in dropdowns and to generally identify a collection of this object in the interface'
);
$lang['en_US']['Subsite']['SINGULARNAME'] = array(
'Subsite',
50,
'Singular name of the object, used in dropdowns and to generally identify a single object in the interface'
);
$lang['en_US']['SubsiteDomain']['PLURALNAME'] = array(
'Subsite Domains',
50,
'Pural name of the object, used in dropdowns and to generally identify a collection of this object in the interface'
);
$lang['en_US']['SubsiteDomain']['SINGULARNAME'] = array(
'Subsite Domain',
50,
'Singular name of the object, used in dropdowns and to generally identify a single object in the interface'
);
$lang['en_US']['Subsite_Template']['PLURALNAME'] = array(
'Subsite Templats',
50,
'Pural name of the object, used in dropdowns and to generally identify a collection of this object in the interface'
);
$lang['en_US']['Subsite_Template']['SINGULARNAME'] = array(
'Subsite Template',
50,
'Singular name of the object, used in dropdowns and to generally identify a single object in the interface'
);
$lang['en_US']['SubsitesVirtualPage']['PLURALNAME'] = array(
'Subsites Virtual Pags',
50,
'Pural name of the object, used in dropdowns and to generally identify a collection of this object in the interface'
);
$lang['en_US']['SubsitesVirtualPage']['SINGULARNAME'] = array(
'Subsites Virtual Page',
50,
'Singular name of the object, used in dropdowns and to generally identify a single object in the interface'
);
$lang['en_US']['VirtualPage']['CHOOSE'] = 'Choose a page to link to';
$lang['en_US']['VirtualPage']['EDITCONTENT'] = 'Click here to edit the content';
?>

38
lang/en_US.yml Normal file
View File

@ -0,0 +1,38 @@
en_US:
SubsiteAdmin:
MENUTITLE: "Subsites"
GroupSubsites:
ACCESSALL: "All subsites"
ACCESSONLY: "Only these subsites"
ACCESSRADIOTITLE: "Give this group access to"
SECURITYTABTITLE: "Subsites"
ModelAdmin:
LOADEDFOREDITING: "Loaded \'%s\' for editing."
RelatedPageLink:
PLURALNAME: "Related Page Links"
SINGULARNAME: "Related Page Link"
Subsite:
PLURALNAME: "Subsits"
SINGULARNAME: "Subsite"
SubsiteDomain:
PLURALNAME: "Subsite Domains"
SINGULARNAME: "Subsite Domain"
DOMAIN: "Domain"
IS_PRIMARY: "Is Primary Domain"
Subsite_Template:
PLURALNAME: "Subsite Templats"
SINGULARNAME: "Subsite Template"
SubsitesVirtualPage:
PLURALNAME: "Subsites Virtual Pags"
SINGULARNAME: "Subsites Virtual Page"
VirtualPage:
CHOOSE: "Choose a page to link to"
EDITCONTENT: "Click here to edit the content"
GridFieldAddFromTemplateButton:
AddFromTemplate: "Add New from Template"
GridFieldAddFromTemplate:
NewFromTemplate: "New %s from template"
TEMPLATE_NOT_FOUND: "The selected template could not be found"
TEMPLATE: "Template"
LeftAndMainSubsites:
DEFAULT_SITE: "Default Site"

View File

@ -1,29 +0,0 @@
<?php
/**
* Norwegian Bokmal (Norway) language pack
* @package subsites
* @subpackage i18n
*/
i18n::include_locale_file('subsites', 'en_US');
global $lang;
if(array_key_exists('nb_NO', $lang) && is_array($lang['nb_NO'])) {
$lang['nb_NO'] = array_merge($lang['en_US'], $lang['nb_NO']);
} else {
$lang['nb_NO'] = $lang['en_US'];
}
$lang['nb_NO']['GroupSubsites']['SECURITYACCESS'] = 'Begrens CMS tilgang til Subdomener';
$lang['nb_NO']['GroupSubsites']['SECURITYTABTITLE'] = 'subdomener';
$lang['nb_NO']['Subsite']['PLURALNAME'] = 'Subdomener';
$lang['nb_NO']['Subsite']['SINGULARNAME'] = 'Subdomene';
$lang['nb_NO']['SubsiteAdmin']['MENUTITLE'] = 'Underdomener';
$lang['nb_NO']['SubsitesVirtualPage']['PLURALNAME'] = 'Subdomeners Virtuelle Sider';
$lang['nb_NO']['SubsitesVirtualPage']['SINGULARNAME'] = 'Subdomeners Virtuelle Side';
$lang['nb_NO']['VirtualPage']['CHOOSE'] = 'Velg en side å lenke til';
$lang['nb_NO']['VirtualPage']['EDITCONTENT'] = 'klikk her for å endre dette innholdet';
?>

39
lang/nb_NO.yml Normal file
View File

@ -0,0 +1,39 @@
nb_NO:
SubsiteAdmin:
MENUTITLE: "Underdomener"
GroupSubsites:
ACCESSALL: "All subsites"
ACCESSONLY: "Only these subsites"
ACCESSRADIOTITLE: "Give this group access to"
SECURITYTABTITLE: "subdomener"
SECURITYACCESS: "Begrens CMS tilgang til Subdomener"
ModelAdmin:
LOADEDFOREDITING: "Loaded \'%s\' for editing."
RelatedPageLink:
PLURALNAME: "Related Page Links"
SINGULARNAME: "Related Page Link"
Subsite:
PLURALNAME: "Subdomener"
SINGULARNAME: "Subdomene"
SubsiteDomain:
PLURALNAME: "Subsite Domains"
SINGULARNAME: "Subsite Domain"
DOMAIN: "Domain"
IS_PRIMARY: "Is Primary Domain"
Subsite_Template:
PLURALNAME: "Subsite Templats"
SINGULARNAME: "Subsite Template"
SubsitesVirtualPage:
PLURALNAME: "Subdomeners Virtuelle Sider"
SINGULARNAME: "Subdomeners Virtuelle Side"
VirtualPage:
CHOOSE: "Velg en side å lenke til"
EDITCONTENT: "klikk her for å endre dette innholdet"
GridFieldAddFromTemplateButton:
AddFromTemplate: "Add New from Template"
GridFieldAddFromTemplate:
NewFromTemplate: "New %s from template"
TEMPLATE_NOT_FOUND: "The selected template could not be found"
TEMPLATE: "Template"
LeftAndMainSubsites:
DEFAULT_SITE: "Default Site"

View File

@ -1,29 +0,0 @@
<?php
/**
* Turkish (Turkey) language pack
* @package subsites
* @subpackage i18n
*/
i18n::include_locale_file('subsites', 'en_US');
global $lang;
if(array_key_exists('tr_TR', $lang) && is_array($lang['tr_TR'])) {
$lang['tr_TR'] = array_merge($lang['en_US'], $lang['tr_TR']);
} else {
$lang['tr_TR'] = $lang['en_US'];
}
$lang['tr_TR']['GroupSubsites']['SECURITYACCESS'] = 'Alt sitelere İYS erişimini kısıtla';
$lang['tr_TR']['GroupSubsites']['SECURITYTABTITLE'] = 'Alt Siteler';
$lang['tr_TR']['Subsite']['PLURALNAME'] = 'Alt Siteler';
$lang['tr_TR']['Subsite']['SINGULARNAME'] = 'Alt Site';
$lang['tr_TR']['SubsiteAdmin']['MENUTITLE'] = 'Alt Siteler';
$lang['tr_TR']['SubsitesVirtualPage']['PLURALNAME'] = 'Alt Site Sanal Sayfalar';
$lang['tr_TR']['SubsitesVirtualPage']['SINGULARNAME'] = 'Alt Site Sanal Sayfa';
$lang['tr_TR']['VirtualPage']['CHOOSE'] = 'İzleyene bağlantı vermek için bir sayfa seçiniz: ';
$lang['tr_TR']['VirtualPage']['EDITCONTENT'] = 'İçeriği düzenlemek için tıklayınız';
?>

39
lang/tr_TR.yml Normal file
View File

@ -0,0 +1,39 @@
tr_TR:
SubsiteAdmin:
MENUTITLE: "Alt Siteler"
GroupSubsites:
ACCESSALL: "All subsites"
ACCESSONLY: "Only these subsites"
ACCESSRADIOTITLE: "Give this group access to"
SECURITYTABTITLE: "Alt Siteler"
SECURITYACCESS: "Alt sitelere İYS erişimini kısıtla"
ModelAdmin:
LOADEDFOREDITING: "Loaded \'%s\' for editing."
RelatedPageLink:
PLURALNAME: "Related Page Links"
SINGULARNAME: "Related Page Link"
Subsite:
PLURALNAME: "Alt Siteler"
SINGULARNAME: "Alt Site"
SubsiteDomain:
PLURALNAME: "Subsite Domains"
SINGULARNAME: "Subsite Domain"
DOMAIN: "Domain"
IS_PRIMARY: "Is Primary Domain"
Subsite_Template:
PLURALNAME: "Subsite Templats"
SINGULARNAME: "Subsite Template"
SubsitesVirtualPage:
PLURALNAME: "Alt Site Sanal Sayfalar"
SINGULARNAME: "Alt Site Sanal Sayfa"
VirtualPage:
CHOOSE: "İzleyene bağlantı vermek için bir sayfa seçiniz: "
EDITCONTENT: "İçeriği düzenlemek için tıklayınız"
GridFieldAddFromTemplateButton:
AddFromTemplate: "Add New from Template"
GridFieldAddFromTemplate:
NewFromTemplate: "New %s from template"
TEMPLATE_NOT_FOUND: "The selected template could not be found"
TEMPLATE: "Template"
LeftAndMainSubsites:
DEFAULT_SITE: "Default Site"

View File

@ -1,11 +0,0 @@
<ul id="MainMenu">
<% control MainMenu %>
<li class="$LinkingMode" id="Menu-$Code"><a href="$Link">$Title</a></li>
<% end_control %>
</ul>
<form id="SubsiteActions">
<fieldset>
$SubsiteList
<span>$ApplicationLogoText</span>
</fieldset>
</form>

View File

@ -1,15 +0,0 @@
<div id="Logo" style="$LogoStyle">
<% if ApplicationLogoText %>
<a href="$ApplicationLink">$ApplicationLogoText</a><br />
<% end_if %>
</div>
<ul id="MainMenu">
<% control MainMenu %>
<li class="$LinkingMode" id="Menu-$Code"><a href="$Link">$Title</a></li>
<% end_control %>
</ul>
<form id="SubsiteActions">
<fieldset>
$SubsiteList
</fieldset>
</form>

View File

@ -0,0 +1 @@
<a href="$NewFromTemplateLink" class="action ss-ui-action-constructive ss-ui-button ui-button ui-widget ui-state-default ui-corner-all new new-link" data-icon="add"><% _t('GridFieldAddFromTemplateButton.AddFromTemplate', '_Add New from Template') %></a>

View File

@ -0,0 +1,59 @@
<div class="cms-menu cms-panel cms-panel-layout west" id="cms-menu" data-layout-type="border">
<div class="cms-logo-header north">
<div class="cms-logo">
<a href="http://www.silverstripe.org/" target="_blank" title="SilverStripe (Version - $CMSVersion)">
SilverStripe <% if CMSVersion %><abbr class="version">$CMSVersion</abbr><% end_if %>
</a>
<span><% if SiteConfig %>$SiteConfig.Title<% else %>$ApplicationName<% end_if %></span>
</div>
<div class="cms-login-status">
<a href="Security/logout" class="logout-link" title="<% _t('LOGOUT','Log out') %>"><% _t('LOGOUT','Log out') %></a>
<% control CurrentMember %>
<span>
<% _t('Hello','Hi') %>
<a href="{$AbsoluteBaseURL}admin/myprofile" class="profile-link ss-ui-dialog-link" data-popupclass="edit-profile-popup">
<% if FirstName && Surname %>$FirstName $Surname<% else_if FirstName %>$FirstName<% else %>$Email<% end_if %>
</a>
</span>
<% end_control %>
</div>
<div class="cms-login-status subsites">
$SubsiteList
</div>
</div>
<div class="cms-panel-content center">
<ul class="cms-menu-list">
<% control MainMenu %>
<li class="$LinkingMode $FirstLast <% if LinkingMode == 'link' %><% else %>opened<% end_if %>" id="Menu-$Code">
<a href="$Link" <% if Code == 'Help' %>target="_blank"<% end_if%>>
<span class="icon icon-16 icon-{$Code.LowerCase}">&nbsp;</span>
<span class="text">$Title</span>
</a>
<% if Code == 'AssetAdmin' %>
<ul>
<li class="first <% if Top.class == 'AssetAdmin' %>current<% end_if %>" id="Menu-AssetAdmin">
<a href="admin/assets/">
<span class="text">Edit &amp; organize</span>
</a>
</li>
<li class="last <% if Top.class == 'CMSFileAddController' %>current<% end_if %>" id="Menu-CMSFileAddController">
<a href="admin/assets/add">
<span class="text">Add files</span>
</a>
</li>
</ul>
<% end_if %>
</li>
<% end_control %>
</ul>
</div>
<div class="cms-panel-toggle south">
<a class="toggle-expand" href="#"><span>&raquo;</span></a>
<a class="toggle-collapse" href="#"><span>&laquo;</span></a>
</div>
</div>

View File

@ -11,7 +11,7 @@ class FileSubsitesTest extends SapphireTest {
$this->assertEquals(' * FileTitle', $file->alternateTreeTitle());
$file->SubsiteID = $this->objFromFixture('Subsite', 'domaintest1')->ID;
$this->assertEquals('FileTitle', $file->TreeTitle());
$this->assertTrue(singleton('Folder')->getCMSFields() instanceof FieldSet);
$this->assertTrue(singleton('Folder')->getCMSFields() instanceof FieldList);
Subsite::changeSubsite(1);
$this->assertEquals($file->cacheKeyComponent(), 'subsite-1');
}

View File

@ -8,7 +8,7 @@ class GroupSubsitesTest extends SapphireTest {
function testTrivialFeatures() {
$this->assertTrue(is_array(singleton('GroupSubsites')->extraStatics()));
$this->assertTrue(is_array(singleton('GroupSubsites')->providePermissions()));
$this->assertTrue(singleton('Group')->getCMSFields() instanceof FieldSet);
$this->assertTrue(singleton('Group')->getCMSFields() instanceof FieldList);
}
function testAlternateTreeTitle() {

View File

@ -41,8 +41,8 @@ class SiteTreeSubsitesTest extends SapphireTest {
function testBasicSanity() {
$this->assertTrue(singleton('SiteTree')->getSiteConfig() instanceof SiteConfig);
$this->assertTrue(singleton('SiteTree')->getCMSFields() instanceof FieldSet);
$this->assertTrue(singleton('SubsitesVirtualPage')->getCMSFields() instanceof FieldSet);
$this->assertTrue(singleton('SiteTree')->getCMSFields() instanceof FieldList);
$this->assertTrue(singleton('SubsitesVirtualPage')->getCMSFields() instanceof FieldList);
$this->assertTrue(is_array(singleton('SiteTreeSubsites')->extraStatics()));
}
@ -58,7 +58,7 @@ class SiteTreeSubsitesTest extends SapphireTest {
}
function testRelatedPages() {
$this->assertTrue(singleton('RelatedPageLink')->getCMSFields() instanceof FieldSet);
$this->assertTrue(singleton('RelatedPageLink')->getCMSFields() instanceof FieldList);
$importantpage = $this->objFromFixture('SiteTree', 'importantpage');
$contact = $this->objFromFixture('SiteTree', 'contact');
@ -68,13 +68,13 @@ class SiteTreeSubsitesTest extends SapphireTest {
$link->RelatedPageID = $contact->ID;
$link->write();
$importantpage->RelatedPages()->add($link);
$this->assertTrue(singleton('SiteTree')->getCMSFields() instanceof FieldSet);
$this->assertTrue(singleton('SiteTree')->getCMSFields() instanceof FieldList);
$this->assertEquals($importantpage->NormalRelated()->Count(), 1);
$this->assertEquals($contact->ReverseRelated()->Count(), 1);
$this->assertTrue($importantpage->getCMSFields() instanceof FieldSet);
$this->assertTrue($contact->getCMSFields() instanceof FieldSet);
$this->assertTrue($importantpage->getCMSFields() instanceof FieldList);
$this->assertTrue($contact->getCMSFields() instanceof FieldList);
$this->assertEquals($importantpage->canView(), $link->canView());
$this->assertEquals($importantpage->canEdit(), $link->canEdit());

View File

@ -102,7 +102,7 @@ class SubsiteAdminTest extends SapphireTest {
$ids[$subsite->ID] = true;
}
$this->assertTrue($subsite->adminSearchFields() instanceof FieldSet);
$this->assertTrue($subsite->adminSearchFields() instanceof FieldList);
$this->assertArrayHasKey(0, $ids, "Main site accessible");
$this->assertArrayHasKey($this->idFromFixture('Subsite_Template','main'), $ids, "Site with no groups inaccesible");
$this->assertArrayHasKey($this->idFromFixture('Subsite_Template','subsite1'), $ids, "Subsite1 Template inaccessible");