From 3c8e45f65a69783e568cdf88695a9c77b2a6d02b Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 4 Dec 2008 22:38:58 +0000 Subject: [PATCH] MINOR merged branches/2.3 into trunk git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@67466 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- _config.php | 59 ----- code/AssetAdmin.php | 243 ++++++++++--------- code/AssetTableField.php | 3 +- code/CMSMain.php | 27 +-- code/ImageEditor.php | 26 +- code/LeftAndMain.php | 70 +++++- code/ModelAdmin.php | 91 +++++-- code/SecurityAdmin.php | 35 +-- code/StaticExporter.php | 91 +++---- code/staticpublisher/FilesystemPublisher.php | 2 + code/staticpublisher/StaticPublisher.php | 2 + css/cms_right.css | 56 ----- css/layout.css | 14 +- javascript/LeftAndMain.js | 34 +-- javascript/LeftAndMain_right.js | 2 +- javascript/ModelAdmin.js | 2 +- javascript/WidgetAreaEditor.js | 18 +- javascript/tinymce.template.js | 11 +- templates/Includes/MemberTableField.ss | 2 + templates/Includes/ModelAdmin_left.ss | 11 +- templates/LeftAndMain.ss | 7 - templates/TaskList.ss | 10 - 22 files changed, 373 insertions(+), 443 deletions(-) delete mode 100755 templates/TaskList.ss diff --git a/_config.php b/_config.php index 6f8f5b47..dea406da 100644 --- a/_config.php +++ b/_config.php @@ -20,65 +20,6 @@ Director::addRules(50, array( CMSMenu::populate_menu(); -// Javascript combined files -Requirements::combine_files( - 'assets/base.js', - array( - 'jsparty/prototype.js', - 'jsparty/behaviour.js', - 'jsparty/prototype_improvements.js', - 'jsparty/jquery/jquery.js', - 'jsparty/jquery/plugins/livequery/jquery.livequery.js', - 'jsparty/jquery/plugins/effen/jquery.fn.js', - 'sapphire/javascript/core/jquery.ondemand.js', - 'jsparty/jquery/jquery_improvements.js', - 'jsparty/firebug/firebugx.js', - 'sapphire/javascript/i18n.js', - ) -); - -Requirements::combine_files( - 'assets/leftandmain.js', - array( - 'jsparty/loader.js', - 'jsparty/hover.js', - 'jsparty/layout_helpers.js', - 'jsparty/scriptaculous/effects.js', - 'jsparty/scriptaculous/dragdrop.js', - 'jsparty/scriptaculous/controls.js', - 'jsparty/greybox/AmiJS.js', - 'jsparty/greybox/greybox.js', - 'cms/javascript/LeftAndMain.js', - 'cms/javascript/LeftAndMain_left.js', - 'cms/javascript/LeftAndMain_right.js', - //'jsparty/tiny_mce2/tiny_mce_src.js', - 'jsparty/tree/tree.js', - 'jsparty/tabstrip/tabstrip.js', - 'cms/javascript/TinyMCEImageEnhancement.js', - 'jsparty/SWFUpload/SWFUpload.js', - 'cms/javascript/Upload.js', - 'sapphire/javascript/TreeSelectorField.js', - 'cms/javascript/ThumbnailStripField.js', - ) -); - -Requirements::combine_files( - 'assets/cmsmain.js', - array( - 'cms/javascript/CMSMain.js', - 'cms/javascript/CMSMain_left.js', - 'cms/javascript/CMSMain_right.js', - 'cms/javascript/SideTabs.js', - 'cms/javascript/TaskList.js', - 'cms/javascript/SideReports.js', - 'cms/javascript/LangSelector.js', - 'cms/javascript/TranslationTab.js', - 'jsparty/calendar/calendar.js', - 'jsparty/calendar/lang/calendar-en.js', - 'jsparty/calendar/calendar-setup.js', - ) -); - CMSMenu::add_link( 'Help', _t('LeftAndMain.HELP', 'Help', PR_HIGH, 'Menu title'), diff --git a/code/AssetAdmin.php b/code/AssetAdmin.php index f3e21864..0de1f122 100755 --- a/code/AssetAdmin.php +++ b/code/AssetAdmin.php @@ -14,7 +14,7 @@ class AssetAdmin extends LeftAndMain { static $menu_title = 'Files & Images'; - public static $tree_class = "File"; + public static $tree_class = 'File'; /** * @see Upload->allowedMaxFileSize @@ -164,7 +164,6 @@ JS $form->disableSecurityToken(); return $form; - } /** @@ -232,7 +231,6 @@ JS $status = ""; } - $fileIDs = array(); $fileNames = array(); foreach($newFiles as $newFile) { @@ -258,11 +256,6 @@ JS HTML; } - /** - * Needs to be overridden to make sure an ID with value "0" is still valid (rootfolder) - */ - - /** * Return the form that displays the details of a folder, including a file list and fields for editing the folder name. */ @@ -275,11 +268,10 @@ HTML; if($record) { $fields = $record->getCMSFields(); - $actions = new FieldSet(); // Only show save button if not 'assets' folder - if( $record->canEdit() && $id != "root") { + if($record->canEdit() && $id != 'root') { $actions = new FieldSet( new FormAction('save',_t('AssetAdmin.SAVEFOLDERNAME','Save folder name')) ); @@ -295,11 +287,11 @@ HTML; )); } - if( !$record->canEdit() ) + if(!$record->canEdit()) { $form->makeReadonly(); + } return $form; - } } @@ -318,8 +310,8 @@ HTML; if($files) { foreach($files as $file) { if($file instanceof Image) { - $file->deleteFormattedImages(); - } + $file->deleteFormattedImages(); + } $file->ParentID = $destFolderID; $file->write(); $numFiles++; @@ -330,11 +322,13 @@ HTML; } $message = sprintf(_t('AssetAdmin.MOVEDX','Moved %s files'),$numFiles); + FormResponse::status_message($message, "good"); FormResponse::add("$('Form_EditForm').getPageFromServer($('Form_EditForm_ID').value)"); + return FormResponse::respond(); } else { - user_error("Bad data: $_REQUEST[DestFolderID]", E_USER_ERROR); + user_error('Bad data:' . $_REQUEST['DestFolderID'], E_USER_ERROR); } } @@ -343,54 +337,53 @@ HTML; * Called and returns in same way as 'save' function */ public function deletemarked($urlParams, $form) { - $fileList = "'" . ereg_replace(' *, *',"','",trim(addslashes($_REQUEST['FileIDs']))) . "'"; - $numFiles = 0; - $folderID = 0; - $deleteList = ''; - $brokenPageList = ''; - - if($fileList != "''") { - $files = DataObject::get("File", "\"File\".\"ID\" IN ($fileList)"); - if($files) { - foreach($files as $file) { - if($file instanceof Image) { - $file->deleteFormattedImages(); - } - if( !$folderID ) - $folderID = $file->ParentID; - - // $deleteList .= "\$('Form_EditForm_Files').removeById($file->ID);\n"; - $file->delete(); - $numFiles++; + $fileList = "'" . ereg_replace(' *, *',"','",trim(addslashes($_REQUEST['FileIDs']))) . "'"; + $numFiles = 0; + $folderID = 0; + $deleteList = ''; + $brokenPageList = ''; + + if($fileList != "''") { + $files = DataObject::get("File", "\"File\".\"ID\" IN ($fileList)"); + if($files) { + foreach($files as $file) { + if($file instanceof Image) { + $file->deleteFormattedImages(); } - if($brokenPages = Notifications::getItems("BrokenLink")) { - $brokenPageList = " ". _t('AssetAdmin.NOWBROKEN',"These pages now have broken links:").""; - foreach($brokenPages as $brokenPage) { - $brokenPageList .= "
  • " . $brokenPage->Breadcrumbs(3, true) . "
  • "; - } - $brokenPageList .= ""; - Notifications::notifyByEmail("BrokenLink", "Page_BrokenLinkEmail"); - } else { - $brokenPageList = ''; + if(!$folderID) { + $folderID = $file->ParentID; } - - $deleteList = ''; - if( $folderID ) { - $remaining = DB::query("SELECT COUNT(*) FROM \"File\" WHERE \"ParentID\" = $folderID")->value(); - - if( !$remaining ) - $deleteList .= "Element.removeClassName(\$('sitetree').getTreeNodeByIdx( '$folderID' ).getElementsByTagName('a')[0],'contents');"; - } - - } else { - user_error("No files in $fileList could be found!", E_USER_ERROR); + $file->delete(); + $numFiles++; } + if($brokenPages = Notifications::getItems('BrokenLink')) { + $brokenPageList = " ". _t('AssetAdmin.NOWBROKEN', 'These pages now have broken links:') . ''; + foreach($brokenPages as $brokenPage) { + $brokenPageList .= "
  • " . $brokenPage->Breadcrumbs(3, true) . '
  • '; + } + $brokenPageList .= ''; + Notifications::notifyByEmail("BrokenLink", "Page_BrokenLinkEmail"); + } else { + $brokenPageList = ''; + } + + $deleteList = ''; + if($folderID) { + $remaining = DB::query("SELECT COUNT(*) FROM \"File\" WHERE \"ParentID\" = $folderID")->value(); + if(!$remaining) $deleteList .= "Element.removeClassName(\$('sitetree').getTreeNodeByIdx('$folderID').getElementsByTagName('a')[0],'contents');"; + } + } else { + user_error("No files in $fileList could be found!", E_USER_ERROR); } - $message = sprintf(_t('AssetAdmin.DELETEDX',"Deleted %s files.%s"),$numFiles,$brokenPageList) ; - FormResponse::add($deleteList); - FormResponse::status_message($message, "good"); - FormResponse::add("$('Form_EditForm').getPageFromServer($('Form_EditForm_ID').value)"); - return FormResponse::respond(); + } + + $message = sprintf(_t('AssetAdmin.DELETEDX',"Deleted %s files.%s"),$numFiles,$brokenPageList) ; + + FormResponse::add($deleteList); + FormResponse::status_message($message, "good"); + FormResponse::add("$('Form_EditForm').getPageFromServer($('Form_EditForm_ID').value)"); + + return FormResponse::respond(); } @@ -532,7 +525,7 @@ JS; */ public function returnItemToUser($p) { if(!empty($_REQUEST['ajax'])) { - $parentID = (int)$p->ParentID; + $parentID = (int) $p->ParentID; return <<ID, "$p->Title", "$p->class"); @@ -555,17 +548,24 @@ JS; if(!$ids) return false; foreach($ids as $id) { - $record = DataObject::get_by_id($this->stat('tree_class'), (int) $id); - if($record) { + if(is_numeric($id)) { + $record = DataObject::get_by_id($this->stat('tree_class'), $id); + if(!$record) { + Debug::message( "Record appears to be null" ); + } $record->delete(); $record->destroy(); + $script .= $this->deleteTreeNodeJS($record); } } $size = sizeof($ids); - if($size > 1) $message = $size . ' ' . _t('AssetAdmin.FOLDERSDELETED', 'folders deleted.'); - else $message = $size . ' ' . _t('AssetAdmin.FOLDERDELETED', 'folder deleted.'); + if($size > 1) { + $message = $size.' '._t('AssetAdmin.FOLDERSDELETED', 'folders deleted.'); + } else { + $message = $size.' '._t('AssetAdmin.FOLDERDELETED', 'folder deleted.'); + } if(isset($brokenPageList)) { $message .= ' '._t('AssetAdmin.NOWBROKEN', 'The following pages now have broken links:').''. @@ -577,7 +577,7 @@ JS; } public function removefile(){ - if($fileID = $this->urlParams['ID']){ + if($fileID = $this->urlParams['ID']) { $file = DataObject::get_by_id('File', $fileID); // Delete the temp verions of this file in assets/_resampled if($file instanceof Image) { @@ -591,10 +591,10 @@ JS; $('Form_EditForm_Files').removeFile($fileID); statusMessage('removed file', 'good'); JS; - }else{ + } else { Director::redirectBack(); } - }else{ + } else { user_error("AssetAdmin::removefile: Bad parameters: File=$fileID", E_USER_ERROR); } } @@ -602,11 +602,10 @@ JS; public function save($urlParams, $form) { // Don't save the root folder - there's no database record if($_REQUEST['ID'] == 'root') { - FormResponse::status_message("Saved", "good"); + FormResponse::status_message('Saved', 'good'); return FormResponse::respond(); } - $form->dataFieldByName('Title')->value = $form->dataFieldByName('Name')->value; return parent::save($urlParams, $form); @@ -619,11 +618,8 @@ JS; */ /** - * Removes all unused thumbnails, and echos status message to user. - * - * @returns null - */ - + * Removes all unused thumbnails, and echos status message to user. + */ public function deleteUnusedThumbnails() { foreach($this->getUnusedThumbnailsArray() as $file) { unlink(ASSETS_PATH . "/" . $file); @@ -632,50 +628,57 @@ JS; } /** - * Creates array containg all unused thumbnails. - * Array is created in three steps: - * 1.Scan assets folder and retrieve all thumbnails - * 2.Scan all HTMLField in system and retrieve thumbnails from them. - * 3.Count difference between two sets (array_diff) - * - * @returns Array - */ - - private function getUnusedThumbnailsArray() { - $allThumbnails = array(); - $dirIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(ASSETS_PATH)); - foreach ($dirIterator as $file) { - if($file->isFile()) { - if(strpos($file->getPathname(),"_resampled") !== false) { - $pathInfo = pathinfo($file->getPathname()); - if(in_array(strtolower($pathInfo['extension']),array('jpeg','jpg','jpe','png','gif'))) { - $path = str_replace('\\','/',$file->getPathname()); - $allThumbnails[] = substr($path,strpos($path,'/assets/')+8); - } - } - } - } - $classes = ClassInfo::subclassesFor('SiteTree'); - $usedThumbnails = array(); - foreach($classes as $className) { - $sng = singleton($className); - $objects = DataObject::get($className); - if($objects !== NULL) { - foreach($objects as $object) { - foreach($sng->db() as $fieldName => $fieldType) { - if($fieldType == 'HTMLText') { - $url1 = HTTP::findByTagAndAttribute($object->$fieldName,array("img" => "src")); - if($url1 != NULL) $usedThumbnails[] = substr($url1[0],strpos($url1[0],'/assets/')+8); - if($object->latestPublished > 0) { - $object = Versioned::get_latest_version($className, $object->ID); - $url2 = HTTP::findByTagAndAttribute($object->$fieldName,array("img" => "src")); - if($url2 != NULL) $usedThumbnails[] = substr($url2[0],strpos($url2[0],'/assets/')+8); - } - } - } - } - } - } - return array_diff($allThumbnails,$usedThumbnails); - } + * Creates array containg all unused thumbnails. + * + * Array is created in three steps: + * 1.Scan assets folder and retrieve all thumbnails + * 2.Scan all HTMLField in system and retrieve thumbnails from them. + * 3.Count difference between two sets (array_diff) + * + * @return array + */ + private function getUnusedThumbnailsArray() { + $allThumbnails = array(); + $usedThumbnails = array(); + $dirIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(ASSETS_PATH)); + + foreach($dirIterator as $file) { + if($file->isFile()) { + if(strpos($file->getPathname(),"_resampled") !== false) { + $pathInfo = pathinfo($file->getPathname()); + if(in_array(strtolower($pathInfo['extension']), array('jpeg', 'jpg', 'jpe', 'png', 'gif'))) { + $path = str_replace('\\','/', $file->getPathname()); + $allThumbnails[] = substr($path, strpos($path, '/assets/') + 8); + } + } + } + } + + $classes = ClassInfo::subclassesFor('SiteTree'); + + foreach($classes as $className) { + $sng = singleton($className); + $objects = DataObject::get($className); + if($objects !== NULL) { + foreach($objects as $object) { + foreach($sng->db() as $fieldName => $fieldType) { + if($fieldType == 'HTMLText') { + $url1 = HTTP::findByTagAndAttribute($object->$fieldName,array("img" => "src")); + if($url1 != NULL) $usedThumbnails[] = substr($url1[0],strpos($url1[0],'/assets/')+8); + if($object->latestPublished > 0) { + $object = Versioned::get_latest_version($className, $object->ID); + $url2 = HTTP::findByTagAndAttribute($object->$fieldName,array("img" => "src")); + if($url2 != NULL) $usedThumbnails[] = substr($url2[0],strpos($url2[0],'/assets/')+8); + } + } + } + } + } + } + + return array_diff($allThumbnails,$usedThumbnails); + } + } + +?> \ No newline at end of file diff --git a/code/AssetTableField.php b/code/AssetTableField.php index 0ec46d73..58eadb13 100755 --- a/code/AssetTableField.php +++ b/code/AssetTableField.php @@ -193,4 +193,5 @@ class AssetTableField extends ComplexTableField { } } -?> + +?> \ No newline at end of file diff --git a/code/CMSMain.php b/code/CMSMain.php index e098ce35..8facfbe7 100644 --- a/code/CMSMain.php +++ b/code/CMSMain.php @@ -51,10 +51,8 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr 'sidereport', 'submit', 'switchlanguage', - 'tasklist', 'unpublish', 'versions', - 'waitingon', 'EditForm', 'AddPageOptionsForm', 'SiteTreeAsUL', @@ -412,26 +410,13 @@ JS; if($record->hasMethod('getAllCMSActions')) { $actions = $record->getAllCMSActions(); } else { - $actions = new FieldSet(); - - if($record->DeletedFromStage) { - if($record->can('CMSEdit')) { - $actions->push(new FormAction('revert',_t('CMSMain.RESTORE','Restore'))); - $actions->push(new FormAction('deletefromlive',_t('CMSMain.DELETEFP','Delete from the published site'))); - } - } else { - if($record->canEdit()) { - $actions->push($deleteAction = new FormAction('delete',_t('CMSMain.DELETE','Delete from the draft site'))); - $deleteAction->addExtraClass('delete'); - } - - if($record->hasMethod('getCMSActions')) { - $extraActions = $record->getCMSActions(); - if($extraActions) foreach($extraActions as $action) $actions->push($action); - } - + $actions = $record->getCMSActions(); + // add default actions if none are defined + if(!$actions || !$actions->Count()) { if($record->canEdit()) { $actions->push(new FormAction('save',_t('CMSMain.SAVE','Save'))); + $actions->push($deleteAction = new FormAction('delete',_t('CMSMain.DELETE','Delete from the draft site'))); + $deleteAction->addExtraClass('delete'); } } } @@ -579,6 +564,8 @@ JS; public function revert($urlParams, $form) { $id = $_REQUEST['ID']; $record = DataObject::get_by_id("SiteTree", $id); + + // if the user can't publish, he shouldn't be able to revert a page (and hence copy the last stored revision to the live site) if(isset($record) && $record && !$record->canEdit()) return Security::permissionFailure($this); $record->doRevertToLive(); diff --git a/code/ImageEditor.php b/code/ImageEditor.php index 7edc2d3d..e3e264f2 100644 --- a/code/ImageEditor.php +++ b/code/ImageEditor.php @@ -20,18 +20,18 @@ class ImageEditor extends Controller { Requirements::clear(); Requirements::javascript(THIRDPARTY_DIR . '/prototype.js'); Requirements::javascript(THIRDPARTY_DIR . '/scriptaculous/scriptaculous.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Utils.js'); - //Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageHistory.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Image.js'); - //Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageTransformation.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Resizeable.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Effects.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Environment.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Crop.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Resize.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageBox.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageEditor.js'); - Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/DocumentBody.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Utils.js'); + //Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageHistory.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Image.js'); + //Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageTransformation.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Resizeable.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Effects.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Environment.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Crop.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/Resize.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageBox.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/ImageEditor.js'); + Requirements::javascript(CMS_DIR . '/javascript/ImageEditor/DocumentBody.js'); Requirements::javascript(THIRDPARTY_DIR . '/loader.js'); Requirements::javascript(THIRDPARTY_DIR . '/behaviour.js'); @@ -257,3 +257,5 @@ class ImageEditor extends Controller { return $path['filename'] . "." . substr($path['extension'],0,strpos($path['extension'],'?')); } } + +?> \ No newline at end of file diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index a153bf01..2145719a 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -22,7 +22,7 @@ class LeftAndMain extends Controller { static $url_segment; - static $url_rule; + static $url_rule = '/$Action/$ID/$OtherID'; static $menu_title; @@ -137,6 +137,7 @@ class LeftAndMain extends Controller { Requirements::javascript(THIRDPARTY_DIR . '/prototype.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js'); + Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery_improvements.js'); Requirements::javascript(THIRDPARTY_DIR . '/behaviour.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/livequery/jquery.livequery.js'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/core/jquery.ondemand.js'); @@ -182,6 +183,64 @@ class LeftAndMain extends Controller { Requirements::customScript('Behaviour.addLoader(hideLoading);'); + // Javascript combined files + Requirements::combine_files( + 'assets/base.js', + array( + 'jsparty/prototype.js', + 'jsparty/behaviour.js', + 'jsparty/prototype_improvements.js', + 'jsparty/jquery/jquery.js', + 'jsparty/jquery/plugins/livequery/jquery.livequery.js', + 'jsparty/jquery/plugins/effen/jquery.fn.js', + 'sapphire/javascript/core/jquery.ondemand.js', + 'jsparty/jquery/jquery_improvements.js', + 'jsparty/firebug/firebugx.js', + 'sapphire/javascript/i18n.js', + ) + ); + + Requirements::combine_files( + 'assets/leftandmain.js', + array( + 'jsparty/loader.js', + 'jsparty/hover.js', + 'jsparty/layout_helpers.js', + 'jsparty/scriptaculous/effects.js', + 'jsparty/scriptaculous/dragdrop.js', + 'jsparty/scriptaculous/controls.js', + 'jsparty/greybox/AmiJS.js', + 'jsparty/greybox/greybox.js', + 'cms/javascript/LeftAndMain.js', + 'cms/javascript/LeftAndMain_left.js', + 'cms/javascript/LeftAndMain_right.js', + //'jsparty/tiny_mce2/tiny_mce_src.js', + 'jsparty/tree/tree.js', + 'jsparty/tabstrip/tabstrip.js', + 'cms/javascript/TinyMCEImageEnhancement.js', + 'jsparty/SWFUpload/SWFUpload.js', + 'cms/javascript/Upload.js', + 'sapphire/javascript/TreeSelectorField.js', + 'cms/javascript/ThumbnailStripField.js', + ) + ); + + Requirements::combine_files( + 'assets/cmsmain.js', + array( + 'cms/javascript/CMSMain.js', + 'cms/javascript/CMSMain_left.js', + 'cms/javascript/CMSMain_right.js', + 'cms/javascript/SideTabs.js', + 'cms/javascript/SideReports.js', + 'cms/javascript/LangSelector.js', + 'cms/javascript/TranslationTab.js', + 'jsparty/calendar/calendar.js', + 'jsparty/calendar/lang/calendar-en.js', + 'jsparty/calendar/calendar-setup.js', + ) + ); + // DEPRECATED 2.3: Use init() $dummy = null; $this->extend('augmentInit', $dummy); @@ -273,7 +332,7 @@ class LeftAndMain extends Controller { */ public function MainMenu() { // Don't accidentally return a menu if you're not logged in - it's used to determine access. - if(!Member::currentUserID()) return new DataObjectSet(); + if(!Member::currentUser()) return new DataObjectSet(); // Encode into DO set $menu = new DataObjectSet(); @@ -342,15 +401,10 @@ class LeftAndMain extends Controller { public function Left() { return $this->renderWith($this->getTemplatesWithSuffix('_left')); } + public function Right() { return $this->renderWith($this->getTemplatesWithSuffix('_right')); } - public function RightBottom() { - if(SSViewer::hasTemplate($this->getTemplatesWithSuffix('_rightbottom'))) { - return $this->renderWith($this->getTemplatesWithSuffix('_rightbottom')); - } - } - public function getRecord($id, $className = null) { if(!$className) $className = $this->stat('tree_class'); diff --git a/code/ModelAdmin.php b/code/ModelAdmin.php index 2ba3bd3f..7ed421ce 100644 --- a/code/ModelAdmin.php +++ b/code/ModelAdmin.php @@ -82,6 +82,8 @@ abstract class ModelAdmin extends LeftAndMain { * a subclass of {@link BulkLoader} (mostly CSV data). * By default {@link CsvBulkLoader} is used, assuming a standard mapping * of column names to {@link DataObject} properties/relations. + * + * e.g. "BlogEntry" => "BlogEntryCsvBulkLoader" * * @var array */ @@ -94,6 +96,19 @@ abstract class ModelAdmin extends LeftAndMain { */ protected static $page_length = 30; + /** + * Class name of the form field used for the results list. Overloading this in subclasses + * can let you customise the results table field. + */ + protected $resultsTableClassName = 'TableListField'; + + /** + * Return {@link $this->resultsTableClassName} + */ + public function resultsTableClassName() { + return $this->resultsTableClassName; + } + /** * Initialize the model admin interface. Sets up embedded jquery libraries and requisite plugins. * @@ -351,10 +366,8 @@ class ModelAdmin_CollectionController extends Controller { */ public function ImportForm() { $modelName = $this->modelClass; - $importers = $this->parentController->getModelImporters(); - - if(!$importers) return false; + if(!$importers || !isset($importers[$modelName])) return false; $fields = new FieldSet( new HiddenField('ClassName', _t('ModelAdmin.CLASSTYPE'), $modelName), @@ -374,7 +387,7 @@ class ModelAdmin_CollectionController extends Controller { $specRelations->push(new ArrayData(array('Name' => $name, 'Description' => $desc))); } $specHTML = $this->customise(array( - 'ModelName' => singleton($modelName)->i18n_singular_name(), + 'ModelName' => Convert::raw2att($modelName), 'Fields' => $specFields, 'Relations' => $specRelations, ))->renderWith('ModelAdmin_ImportSpec'); @@ -401,16 +414,24 @@ class ModelAdmin_CollectionController extends Controller { * * @todo Figure out ajax submission of files via jQuery.form plugin * - * @param unknown_type $data - * @param unknown_type $form - * @param unknown_type $request + * @param array $data + * @param Form $form + * @param HTTPRequest $request */ function import($data, $form, $request) { - $modelName = singleton($data['ClassName'])->i18n_singular_name(); + $modelName = $data['ClassName']; $importers = $this->parentController->getModelImporters(); $importerClass = $importers[$modelName]; $loader = new $importerClass($data['ClassName']); + + // File wasn't properly uploaded, show a reminder to the user + if(empty($_FILES['_CsvFile']['tmp_name'])) { + $form->sessionMessage(_t('ModelAdmin.NOCSVFILE', 'Please browse for a CSV file to import'), 'good'); + Director::redirectBack(); + return false; + } + $results = $loader->load($_FILES['_CsvFile']['tmp_name']); $message = ''; @@ -428,17 +449,21 @@ class ModelAdmin_CollectionController extends Controller { ); if(!$results->CreatedCount() && !$results->UpdatedCount()) $message .= _t('ModelAdmin.NOIMPORT', "Nothing to import"); - Session::setFormMessage('Form_ImportForm', $message, 'good'); - Director::redirect($_SERVER['HTTP_REFERER'] . '#Form_ImportForm_holder'); + $form->sessionMessage($message, 'good'); + Director::redirectBack(); } /** * Give the flexibilility to show variouse combination of columns in the search result table + * @param $columnsAvailable array The columns that should be made available for selecting. Should be a map. Keys are dot-syntax + * field names, and values are titles. By default the $summary_fields from your model will be used. */ - public function ColumnSelectionField() { + public function ColumnSelectionField($columnsAvailable = null) { $model = singleton($this->modelClass); - $source = $model->summaryFields(); + $source = $columnsAvailable ? $columnsAvailable : $model->summaryFields(); + + // select all fields by default $value = array(); if($source) foreach ($source as $fieldName => $label){ $value[] = $fieldName; @@ -535,18 +560,30 @@ class ModelAdmin_CollectionController extends Controller { return $context->getQuery($searchCriteria); } - function getResultColumns($searchCriteria) { + /** + * Returns all columns used for tabular search results display. + * Defaults to all fields specified in {@link DataObject->summaryFields()}. + * + * @param array $searchCriteria Limit fields by populating the 'ResultsAssembly' key + * @param boolean $selectedOnly Limit by 'ResultsAssempty + */ + function getResultColumns($searchCriteria, $selectedOnly = true) { $model = singleton($this->modelClass); $summaryFields = $model->summaryFields(); - $resultAssembly = $searchCriteria['ResultAssembly']; - if(!is_array($resultAssembly)) { - $explodedAssembly = split(' *, *', $resultAssembly); - $resultAssembly = array(); - foreach($explodedAssembly as $item) $resultAssembly[$item] = true; - } + $summaryFields = $this->ColumnSelectionField()->Children->dataFieldByName('ResultAssembly')->Source; - return array_intersect_key($summaryFields, $resultAssembly); + if($selectedOnly) { + $resultAssembly = $searchCriteria['ResultAssembly']; + if(!is_array($resultAssembly)) { + $explodedAssembly = split(' *, *', $resultAssembly); + $resultAssembly = array(); + foreach($explodedAssembly as $item) $resultAssembly[$item] = true; + } + return array_intersect_key($summaryFields, $resultAssembly); + } else { + return $summaryFields; + } } /** @@ -558,7 +595,8 @@ class ModelAdmin_CollectionController extends Controller { if($searchCriteria instanceof HTTPRequest) $searchCriteria = $searchCriteria->getVars(); $summaryFields = $this->getResultColumns($searchCriteria); - $tf = new TableListField( + $className = $this->parentController->resultsTableClassName(); + $tf = new $className( $this->modelClass, $this->modelClass, $summaryFields @@ -569,6 +607,10 @@ class ModelAdmin_CollectionController extends Controller { // @todo Remove records that can't be viewed by the current user $tf->setPermissions(array_merge(array('view','export'), TableListField::permissions_for_object($this->modelClass))); + // csv export settings (select all columns regardless of user checkbox settings in 'ResultsAssembly') + $exportFields = $this->getResultColumns($searchCriteria, false); + $tf->setFieldListCsv($exportFields); + $url = 'Link() . '/$ID/edit\">$value'; $tf->setFieldFormatting(array_combine(array_keys($summaryFields), array_fill(0,count($summaryFields), $url))); @@ -593,7 +635,7 @@ class ModelAdmin_CollectionController extends Controller { unset($filteredCriteria['url']); unset($filteredCriteria['action_search']); if(isset($filteredCriteria['Investors__PEFirm__IsPECMember']) && !$filteredCriteria['Investors__PEFirm__IsPECMember']) unset($filteredCriteria['Investors__PEFirm__IsPECMember']); - + $form->setFormAction($this->Link() . '/ResultsForm?' . http_build_query($filteredCriteria)); return $form; } @@ -719,9 +761,8 @@ class ModelAdmin_RecordController extends Controller { $validator = ($this->currentRecord->hasMethod('getCMSValidator')) ? $this->currentRecord->getCMSValidator() : null; - $actions = new FieldSet( - new FormAction("doSave", _t('ModelAdmin.SAVE', "Save")) - ); + $actions = $this->currentRecord->getCMSActions(); + $actions->push(new FormAction("doSave", _t('ModelAdmin.SAVE', "Save"))); if($this->currentRecord->canDelete(Member::currentUser())) { $actions->insertFirst($deleteAction = new FormAction('doDelete', _t('ModelAdmin.DELETE', 'Delete'))); diff --git a/code/SecurityAdmin.php b/code/SecurityAdmin.php index c2233261..542a33e4 100644 --- a/code/SecurityAdmin.php +++ b/code/SecurityAdmin.php @@ -20,8 +20,6 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { 'addgroup', 'addmember', 'autocomplete', - 'getmember', - 'newmember', 'removememberfromgroup', 'savemember', 'AddRecordForm', @@ -84,8 +82,11 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { $fieldName = $this->urlParams['ID']; $fieldVal = $_REQUEST[$fieldName]; $result = ''; + + // Make sure we only autocomplete on keys that actually exist, and that we don't autocomplete on password + if(!array_key_exists($fieldName, singleton($this->stat('subitem_class'))->stat('db')) || $fieldName == 'Password') return; - $matches = DataObject::get($this->stat('subitem_class'),"\"$fieldName\" LIKE '" . addslashes($fieldVal) . "%'"); + $matches = DataObject::get($this->stat('subitem_class'),"\"$fieldName\" LIKE '" . Convert::raw2sql($fieldVal) . "%'"); if($matches) { $result .= ""; @@ -101,15 +101,6 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { } } - public function getmember() { - Session::set('currentMember', $_REQUEST['ID']); - SSViewer::setOption('rewriteHashlinks', false); - $result = $this->renderWith("LeftAndMain_rightbottom"); - $parts = split(']*>', $result); - echo $parts[1]; - } - - public function MemberForm() { $id = $_REQUEST['ID'] ? $_REQUEST['ID'] : Session::get('currentMember'); if($id) @@ -235,24 +226,6 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { return $this->returnItemToUser($newGroup); } - public function newmember() { - Session::clear('currentMember'); - $newMemberForm = array( - "MemberForm" => $this->getMemberForm('new'), - ); - // This should be using FormResponse ;-) - if(Director::is_ajax()) { - SSViewer::setOption('rewriteHashlinks', false); - $customised = $this->customise($newMemberForm); - $result = $customised->renderWith($this->class . "_rightbottom"); - $parts = split(']*>', $result); - return $parts[1]; - - } else { - return $newMemberForm; - } - } - public function EditedMember() { if(Session::get('currentMember')) return DataObject::get_by_id("Member", Session::get('currentMember')); diff --git a/code/StaticExporter.php b/code/StaticExporter.php index 34c2bda5..870f555d 100755 --- a/code/StaticExporter.php +++ b/code/StaticExporter.php @@ -3,6 +3,12 @@ * This class lets you export a static copy of your site. * It creates a huge number of folders each containing an index.html file. * This preserves the URL naming format. + * + * Requirements: Unix Filesystem supporting symlinking. + * Doesn't work on Windows. + * + * @see StaticPublisher + * * @package cms * @subpackage export */ @@ -41,63 +47,60 @@ class StaticExporter extends Controller { } function export() { - - if($_REQUEST['baseurl']) { + // specify custom baseurl for publishing to other webroot + if(isset($_REQUEST['baseurl'])) { $base = $_REQUEST['baseurl']; if(substr($base,-1) != '/') $base .= '/'; Director::setBaseURL($base); } - $folder = '/tmp/static-export/' . project(); - if(!project()) $folder .= 'site'; - if(!file_exists($folder)) mkdir($folder, Filesystem::$folder_create_mask, true); + // setup temporary folders + $tmpBaseFolder = TEMP_FOLDER . '/static-export'; + $tmpFolder = (project()) ? "$tmpBaseFolder/" . project() : "$tmpBaseFolder/site"; + if(!file_exists($tmpFolder)) Filesystem::makeFolder($tmpFolder); + $baseFolderName = basename($tmpFolder); + // symlink /assets $f1 = ASSETS_PATH; $f2 = Director::baseFolder() . '/' . project(); - `cd $folder; ln -s $f1; ln -s $f2`; + `cd $tmpFolder; ln -s $f1; ln -s $f2`; - - $baseFolder = basename($folder); - - if($folder && file_exists($folder)) { - $pages = DataObject::get("SiteTree"); - foreach($pages as $page) { - $subfolder = "$folder/$page->URLSegment"; - $contentfile = "$folder/$page->URLSegment/index.html"; - - // Make the folder - if(!file_exists($subfolder)) { - mkdir($subfolder, Filesystem::$folder_create_mask); - } - - // Run the page - Requirements::clear(); - $controllerClass = "{$page->class}_Controller"; - if(class_exists($controllerClass)) { - $controller = new $controllerClass($page); - $pageContent = $controller->handleRequest(new HTTPRequest('GET',''))->getBody(); - - // Write to file - if($fh = fopen($contentfile, 'w')) { - fwrite($fh, $pageContent->getBody()); - fclose($fh); - } - } + // iterate through all instances of SiteTree + $pages = DataObject::get("SiteTree"); + foreach($pages as $page) { + $subfolder = "$tmpFolder/$page->URLSegment"; + $contentfile = "$tmpFolder/$page->URLSegment/index.html"; + + // Make the folder + if(!file_exists($subfolder)) { + Filesystem::makeFolder($subfolder); } - copy("$folder/home/index.html", "$folder/index.html"); + // Run the page + Requirements::clear(); + $link = Director::makeRelative($page->Link()); + $response = Director::test($link); - `cd /tmp/static-export; tar -czhf $baseFolder.tar.gz $baseFolder`; - - $content = file_get_contents("/tmp/static-export/$baseFolder.tar.gz"); - Filesystem::removeFolder('/tmp/static-export'); - - return HTTPRequest::send_file($content, "$baseFolder.tar.gz"); - - } else { - echo _t('StaticExporter.ONETHATEXISTS',"Please specify a folder that exists"); + // Write to file + if($fh = fopen($contentfile, 'w')) { + fwrite($fh, $response->getBody()); + fclose($fh); + } } - + + // copy homepage (URLSegment: "home") to webroot + copy("$tmpFolder/home/index.html", "$tmpFolder/index.html"); + + // archive all generated files + `cd $tmpBaseFolder; tar -czhf $baseFolderName.tar.gz $baseFolderName`; + $archiveContent = file_get_contents("$tmpBaseFolder/$baseFolderName.tar.gz"); + + // remove temporary files and folder + Filesystem::removeFolder($tmpBaseFolder); + + // return as download to the client + $response = HTTPRequest::send_file($archiveContent, "$baseFolderName.tar.gz", 'application/x-tar-gz'); + echo $response->output(); } } diff --git a/code/staticpublisher/FilesystemPublisher.php b/code/staticpublisher/FilesystemPublisher.php index a996a7cf..1a133226 100644 --- a/code/staticpublisher/FilesystemPublisher.php +++ b/code/staticpublisher/FilesystemPublisher.php @@ -114,3 +114,5 @@ class FilesystemPublisher extends StaticPublisher { } } } + +?> \ No newline at end of file diff --git a/code/staticpublisher/StaticPublisher.php b/code/staticpublisher/StaticPublisher.php index 274ef54b..ccac974a 100644 --- a/code/staticpublisher/StaticPublisher.php +++ b/code/staticpublisher/StaticPublisher.php @@ -75,3 +75,5 @@ abstract class StaticPublisher extends DataObjectDecorator { return $urls; } } + +?> \ No newline at end of file diff --git a/css/cms_right.css b/css/cms_right.css index c4b34b68..bb1645be 100644 --- a/css/cms_right.css +++ b/css/cms_right.css @@ -193,62 +193,6 @@ clear: left; } -/** - * Bottom-right - */ -#rightbottom { - border: none; - margin-top: 4px; - margin-left: 1px; - border: 1px solid #808080; -} - -#rightbottom form { - margin: 1em; -} - -#rightbottom form div { - margin-top: 3px; -} - -#rightbottom form div.field { - clear: both; - margin-left: 10em; - font-size: 12px; - border: none; -} - -#rightbottom form label.left { - float: left; - width: 10em; - margin-left: -10em; -} - -#rightbottom form input, -#rightbottom form select, -#rightbottom form textarea { - width: 90%; -} - -#rightbottom form input.checkbox, -#rightbottom form .optionset input, -#rightbottom form .htmleditor select, -#rightbottom form input.action { - width: auto; -} -#rightbottom form .optionset li { - list-style: none; -} - -#rightbottom form h2 { - clear: both; -} - -#rightbottom form .fieldgroup input, -#rightbottom form .fieldgroup select { - width: auto; -} - /** * RHS Action Parameters boxes */ diff --git a/css/layout.css b/css/layout.css index bd58c1e4..e9e7d281 100644 --- a/css/layout.css +++ b/css/layout.css @@ -119,7 +119,7 @@ body.stillLoading select { border: 1px solid #acbbcc; background: #fff; } -#right, #rightbottom { +#right { position: absolute; left: 208px; top: 45px; @@ -132,10 +132,6 @@ body.stillLoading select { margin-right: 3px; } -#rightbottom { - height: 30%; -} - #separator { position: absolute; top: 51px; @@ -161,17 +157,13 @@ body.stillLoading select { } -#left div.title, #right div.title, #rightbottom div.title { +#left div.title, #right div.title { border-top: 1px solid #77BBEE; height: 22px !important; background: #0075C9 url(../images/texture/obar.gif) repeat-x 0 0; } -#rightbottom div.light { - background-image: url(../images/textures/obar-light.png) !important; -} - -#left div.title div, #right div.title div, #rightbottom div.title div { +#left div.title div, #right div.title div { font-size: 14px; font-weight: bold; color: #fff; diff --git a/javascript/LeftAndMain.js b/javascript/LeftAndMain.js index 4f25f852..04b996d5 100644 --- a/javascript/LeftAndMain.js +++ b/javascript/LeftAndMain.js @@ -1,5 +1,15 @@ var _AJAX_LOADING = false; +// Resize the tabs once the document is properly loaded +// @todo most of this file needs to be tidied up using jQuery +if(typeof(jQuery) != 'undefined') { + (function($) { + $(document).ready(function() { + window.onresize(true); + }); + })(jQuery); +} + /** * Code for the separator bar between the two panes */ @@ -33,8 +43,7 @@ DraggableSeparator.prototype = { } function fixRightWidth() { - if( !$('right') ) - return; + if(!$('right')) return; // Absolutely position all the elements var sep = getDimension($('left'),'width') + getDimension($('left'),'left'); @@ -53,14 +62,7 @@ function fixRightWidth() { $('contentPanel').style.left = leftWidth + sepWidth + rightWidth + sepWidth + 23 + 'px'; } - if( rightWidth >= 0 ) - $('right').style.width = rightWidth + 'px'; - - var rb; - if(rb = $('rightbottom')) { - rb.style.left = $('right').style.left; - rb.style.width = $('right').style.width; - } + if(rightWidth >= 0) $('right').style.width = rightWidth + 'px'; } Behaviour.register({ @@ -140,7 +142,7 @@ window.ontabschanged = function() { fitToParent(divs[i], 3); } }*/ - + if(typeof _TAB_DIVS_ON_PAGE != 'undefined') { for(i = 0; i < _TAB_DIVS_ON_PAGE.length; i++ ) { fitToParent(_TAB_DIVS_ON_PAGE[i], 30); @@ -150,8 +152,6 @@ window.ontabschanged = function() { window.onresize = function(init) { var right = $('right'); - var rightbottom = $('rightbottom'); - if(rightbottom) rightbottom.style.display = 'none'; if(typeof fitToParent == 'function') { fitToParent('right', 12); @@ -171,14 +171,6 @@ window.onresize = function(init) { $('left').style.height = $('separator').style.height = rightH + 'px'; } - if(rightbottom) { - var newHeight = rightH / 3; - right.style.height = (newHeight*2) + 'px'; - rightbottom.style.height = newHeight + 'px'; - rightbottom.style.display = ''; - rightbottom.style.top = getDimension(right,'top') + (newHeight*2) + 'px'; - } - if(typeof fitToParent == 'function') { fitToParent('Form_EditForm'); if($('Form_EditorToolbarImageForm') && $('Form_EditorToolbarImageForm').style.display == "block") { diff --git a/javascript/LeftAndMain_right.js b/javascript/LeftAndMain_right.js index 36dd40f9..8482fd50 100755 --- a/javascript/LeftAndMain_right.js +++ b/javascript/LeftAndMain_right.js @@ -317,7 +317,7 @@ CMSRightForm.prototype = { }*/ } -CMSForm.applyTo('#Form_SubForm', 'rightbottom'); +CMSForm.applyTo('#Form_SubForm'); CMSRightForm.applyTo('#Form_EditForm', 'right'); function action_save_right() { diff --git a/javascript/ModelAdmin.js b/javascript/ModelAdmin.js index 688fd72b..7258064c 100644 --- a/javascript/ModelAdmin.js +++ b/javascript/ModelAdmin.js @@ -111,7 +111,7 @@ $(document).ready(function() { * Clear search button */ $('#SearchForm_holder button[name=action_clearsearch]').click(function(e) { - $(this.form).clearForm(); + $(this.form).resetForm(); return false; }); diff --git a/javascript/WidgetAreaEditor.js b/javascript/WidgetAreaEditor.js index d3b6b685..6a740132 100644 --- a/javascript/WidgetAreaEditor.js +++ b/javascript/WidgetAreaEditor.js @@ -103,16 +103,22 @@ WidgetAreaEditor.prototype = { // Order the sort by the order the widgets are in the list var usedWidgets = $('WidgetAreaEditor_usedWidgets'); - if (usedWidgets) { + if(usedWidgets) { widgets = usedWidgets.childNodes; - for( i = 0; div = widgets[i]; i++ ) { - var fields = div.getElementsByTagName('input'); - for( j = 0; field = fields.item(j); j++ ) { - if( field.name == div.id + '[Sort]' ) { - field.value = i; + for(i = 0; i < widgets.length; i++) { + var div = widgets[i]; + + if(div.nodeName != '#comment') { + var fields = div.getElementsByTagName('input'); + + for(j = 0; field = fields.item(j); j++) { + if(field.name == div.id + '[Sort]') { + field.value = i; + } } } + } } }, diff --git a/javascript/tinymce.template.js b/javascript/tinymce.template.js index eee141c7..be4bd5b3 100755 --- a/javascript/tinymce.template.js +++ b/javascript/tinymce.template.js @@ -26,9 +26,10 @@ if((typeof tinyMCE != 'undefined')) { theme_advanced_toolbar_location : "top", theme_advanced_toolbar_align : "left", theme_advanced_toolbar_parent : "right", - plugins : "template,contextmenu,table,emotions,paste,../../tinymce_ssbuttons,../../tinymce_advcode,spellchecker", + plugins : "blockquote,template,contextmenu,table,emotions,paste,../../tinymce_ssbuttons,../../tinymce_advcode,spellchecker", + blockquote_clear_tag : "p", table_inline_editing : true, - theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,separator,bullist,numlist,outdent,indent,hr,charmap", + theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,separator,bullist,numlist,outdent,indent,blockquote,hr,charmap", theme_advanced_buttons2 : "undo,redo,separator,cut,copy,paste,pastetext,pasteword,spellchecker,separator,ssimage,ssflash,sslink,unlink,anchor,separator,template,advcode,separator,search,replace,selectall,visualaid,separator,tablecontrols", theme_advanced_buttons3 : "", spellchecker_languages : "$SpellcheckLangs", @@ -39,9 +40,7 @@ if((typeof tinyMCE != 'undefined')) { safari_warning : false, relative_urls : true, - verify_html : true, - valid_elements : "+a[id|rel|rev|dir|tabindex|accesskey|type|name|href|target|title|class],-strong/-b[class],-em/-i[class],-strike[class],-u[class],#p[id|dir|class|align],-ol[class],-ul[class],-li[class],br,img[id|dir|longdesc|usemap|class|src|border|alt=|title|width|height|align],-sub[class],-sup[class],-blockquote[dir|class],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|dir|id|style],-tr[id|dir|class|rowspan|width|height|align|valign|bgcolor|background|bordercolor|style],tbody[id|class|style],thead[id|class|style],tfoot[id|class|style],-td[id|dir|class|colspan|rowspan|width|height|align|valign|scope|style],-th[id|dir|class|colspan|rowspan|width|height|align|valign|scope|style],caption[id|dir|class],-div[id|dir|class|align],-span[class|align],-pre[class|align],address[class|align],-h1[id|dir|class|align],-h2[id|dir|class|align],-h3[id|dir|class|align],-h4[id|dir|class|align],-h5[id|dir|class|align],-h6[id|dir|class|align],hr[class],dd[id|class|title|dir],dl[id|class|title|dir],dt[id|class|title|dir],iframe[align + <% if can(add) %> <% if Markable %> <% end_if %> $AddRecordForm.CellFields @@ -31,6 +32,7 @@ <% if Can(edit) %> <% end_if %> <% if Can(delete) %> <% end_if %> + <% end_if %> <% if Items %> diff --git a/templates/Includes/ModelAdmin_left.ss b/templates/Includes/ModelAdmin_left.ss index eb776446..a25b148f 100755 --- a/templates/Includes/ModelAdmin_left.ss +++ b/templates/Includes/ModelAdmin_left.ss @@ -31,10 +31,13 @@

    <% _t('SEARCHLISTINGS','Search') %>

    $SearchForm - -

    <% _t('IMPORT_TAB_HEADER', 'Import') %>

    - $ImportForm - + + <% if ImportForm %> +

    <% _t('IMPORT_TAB_HEADER', 'Import') %>

    + $ImportForm + <% end_if %> + + <% end_control %> \ No newline at end of file diff --git a/templates/LeftAndMain.ss b/templates/LeftAndMain.ss index efb7f022..f3b8a7f8 100644 --- a/templates/LeftAndMain.ss +++ b/templates/LeftAndMain.ss @@ -24,13 +24,6 @@ $Right - <% if RightBottom %> -
    - $RightBottom - -
    - <% end_if %> -