diff --git a/code/controllers/AssetAdmin.php b/code/controllers/AssetAdmin.php index 7d4ef041..3a9672d4 100644 --- a/code/controllers/AssetAdmin.php +++ b/code/controllers/AssetAdmin.php @@ -31,6 +31,7 @@ class AssetAdmin extends LeftAndMain { 'savefile', 'deleteUnusedThumbnails' => 'ADMIN', 'SyncForm', + 'filter', ); /** @@ -41,8 +42,6 @@ class AssetAdmin extends LeftAndMain { return $_REQUEST['ID']; } elseif (is_numeric($this->urlParams['ID'])) { return $this->urlParams['ID']; - } elseif(is_numeric(Session::get("{$this->class}.currentPage"))) { - return Session::get("{$this->class}.currentPage"); } else { return "root"; } @@ -58,7 +57,8 @@ class AssetAdmin extends LeftAndMain { if(!file_exists(ASSETS_PATH)) Filesystem::makeFolder(ASSETS_PATH); Requirements::javascript(CMS_DIR . "/javascript/AssetAdmin.js"); - Requirements::css(CMS_DIR . "/css/AssetAdmin.css"); + Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang', false, true); + Requirements::css(CMS_DIR . "/css/screen.css"); Requirements::customScript(<<currentPage(); + $fields = $form->Fields(); + + $fields->push(new HiddenField('ID', false, $folder->ID)); + + // File listing + $gridFieldConfig = GridFieldConfig::create()->addComponents( + new GridFieldSortableHeader(), + new GridFieldFilter(), + new GridFieldDefaultColumns(), + new GridFieldPaginator(10), + new GridFieldAction_Delete(), + new GridFieldAction_Edit(), + $gridFieldForm = new GridFieldPopupForms(Controller::curr(), 'EditForm') + ); + $gridFieldForm->setTemplate('CMSGridFieldPopupForms'); + $files = DataList::create('File') + ->filter('ParentID', $folder->ID) + ->sort('(CASE WHEN "ClassName" = \'Folder\' THEN 0 ELSE 1 END)'); + $gridField = new GridField('File','Files', $files, $gridFieldConfig); + $gridField->setDisplayFields(array( + 'StripThumbnail' => '', + // 'Parent.FileName' => 'Folder', + 'Title' => _t('File.Name'), + 'Created' => _t('AssetAdmin.CREATED', 'Date'), + 'Size' => _t('AssetAdmin.SIZE', 'Size'), + )); + $gridField->setFieldCasting(array( + 'Created' => 'Date->Nice' + )); + $gridField->setAttribute( + 'data-url-folder-template', + Controller::join_links($this->Link('show'), '%s') + ); + + if($folder->canCreate()) { + $uploadBtn = new LiteralField( + 'UploadButton', + sprintf( + '%s', + Controller::join_links(singleton('CMSFileAddController')->Link(), '?ID=' . $folder->ID), + _t('Folder.UploadFilesButton', 'Upload') + ) + ); + } else { + $uploadBtn = null; + } + + if(!$folder->hasMethod('canAddChildren') || ($folder->hasMethod('canAddChildren') && $folder->canAddChildren())) { + // TODO Will most likely be replaced by GridField logic + $addFolderBtn = new LiteralField( + 'AddFolderButton', + sprintf( + '%s', + Controller::join_links($this->Link('addfolder'), '?ParentID=' . $folder->ID), + _t('Folder.AddFolderButton', 'Add folder') + ) + ); + } else { + $addFolderBtn = ''; + } + + // Move existing fields to a "details" tab, unless they've already been tabbed out through extensions. + // Required to keep Folder->getCMSFields() simple and reuseable, + // without any dependencies into AssetAdmin (e.g. useful for "add folder" views). + if(!$fields->hasTabset()) { + $tabs = new TabSet('Root', + $tabList = new Tab('ListView', _t('AssetAdmin.ListView', 'List View')), + $tabTree = new Tab('TreeView', _t('AssetAdmin.TreeView', 'Tree View')) + ); + if($fields->Count() && $folder->exists()) { + $tabs->push($tabDetails = new Tab('DetailsView', _t('AssetAdmin.DetailsView', 'Details'))); + foreach($fields as $field) { + $fields->removeByName($field->Name()); + $tabDetails->push($field); + } + } + $fields->push($tabs); + } + + // List view + $fields->addFieldsToTab('Root.ListView', array( + $actionsComposite = Object::create('CompositeField', + Object::create('CompositeField', + $uploadBtn, + $addFolderBtn + )->addExtraClass('cms-actions-row') + )->addExtraClass('cms-content-toolbar field'), + $gridField + )); + + // Tree view + $fields->addFieldsToTab('Root.TreeView', array( + clone $actionsComposite, + // TODO Replace with lazy loading on client to avoid performance hit of rendering potentially unused views + new LiteralField( + 'Tree', + FormField::createTag( + 'div', + array( + 'class' => 'cms-tree', + 'data-url-tree' => $this->Link('getsubtree'), + 'data-url-savetreenode' => $this->Link('savetreenode') + ), + $this->SiteTreeAsUL() + ) + ) + )); + + $fields->setForm($form); + $form->addExtraClass('cms-edit-form'); + $form->setTemplate($this->getTemplatesWithSuffix('_EditForm')); + // TODO Can't merge $FormAttributes in template at the moment + $form->addExtraClass('center ss-tabset ' . $this->BaseCSSClasses()); + $form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet'); + + $this->extend('updateEditForm', $form); + + return $form; + } + + public function addfolder($request) { + $obj = $this->customise(array( + 'EditForm' => $this->AddForm() + )); + + if($this->isAjax()) { + // Rendering is handled by template, which will call EditForm() eventually + $content = $obj->renderWith($this->getTemplatesWithSuffix('_Content')); + } else { + $content = $obj->renderWith($this->getViewer('show')); + } + + return $content; + } + + /** + * Returns a form for filtering of files and assets gridfield + * + * @return Form + * @see AssetAdmin.js + */ + public function FilterForm() { + $fields = new FieldList(); + // Below is the filters that this field should filter on + $fields->push(new TextField('Title')); + $fields->push(new TextField('ClassName','Type')); + + $actions = new FieldList(); + $actions->push(new FormAction('doFilter', 'Filter')); + $actions->push(new ResetFormAction('doResetFilter', 'Clear Filter')); + + $form = new Form($this, 'filter', $fields, $actions); + $form->addExtraClass('cms-filter-form'); + // This have to match data-name attribute on the gridfield so that the javascript selectors work + $form->setAttribute('data-gridfield', 'File'); + return $form; + } + + /** + * If this method get's called, it means that javascript didn't hook into to the submit on + * FilterForm and we can currently not do a Filter without javascript. + * + * @param SS_HTTPRequest $data + * @throws SS_HTTPResponse_Exception + */ + public function filter(SS_HTTPRequest $data) { + throw new SS_HTTPResponse_Exception('Filterpanel doesn\'t work without javascript enabled.'); + } public function AddForm() { $form = parent::AddForm(); - $form->Actions()->fieldByName('action_doAdd')->setTitle(_t('AssetAdmin.ActionAdd', 'Add folder')); + $folder = singleton('Folder'); + + $form->Actions()->fieldByName('action_doAdd') + ->setTitle(_t('AssetAdmin.ActionAdd', 'Add folder')) + ->setAttribute('data-icon', 'accept'); + + $fields = $folder->getCMSFields(); + $fields->replaceField('Name', new TextField("Name", _t('File.Name'))); + $fields->dataFieldByName('ParentID')->setValue($this->request->getVar('ParentID')); + $form->setFields($fields); + + $form->addExtraClass('cms-edit-form'); + $form->setTemplate($this->getTemplatesWithSuffix('_EditForm')); + $form->addExtraClass('center ' . $this->BaseCSSClasses()); return $form; } @@ -103,7 +288,7 @@ JS && !$parentRecord->canAddChildren() ) return Security::permissionFailure($this); } - + $parent = (isset($data['ParentID']) && is_numeric($data['ParentID'])) ? (int)$data['ParentID'] : 0; $name = (isset($data['Name'])) ? basename($data['Name']) : _t('AssetAdmin.NEWFOLDER',"NewFolder"); if(!isset($parentRecord) || !$parentRecord->ID) $parent = 0; @@ -119,7 +304,8 @@ JS $record = new Folder(); $record->ParentID = $parent; - + $record->Name = $record->Title = basename($filename); + // Ensure uniqueness $i = 2; $baseFilename = substr($record->Filename, 0, -1) . '-'; @@ -134,10 +320,9 @@ JS mkdir($record->FullPath); chmod($record->FullPath, Filesystem::$file_create_mask); - // Used in TinyMCE inline folder creation - if(isset($data['returnID'])) { - return $record->ID; - } else if($this->isAjax()) { + if($this->isAjax()) { + $link = Controller::join_links($this->Link('show'), $record->ID); + $this->getResponse()->addHeader('X-ControllerURL', $link); $form = $this->getEditForm($record->ID); return $form->forTemplate(); } else { @@ -151,9 +336,10 @@ JS public function currentPage() { $id = $this->currentPageID(); if($id && is_numeric($id)) { - return DataObject::get_by_id('File', $id); - } else if($id == 'root') { - return singleton('File'); + return DataObject::get_by_id('Folder', $id); + } else { + // ID is either '0' or 'root' + return singleton('Folder'); } } @@ -183,11 +369,12 @@ JS new FieldList( ), new FieldList( - $btn = new FormAction('doSync', _t('FILESYSTEMSYNC','Look for new files')) + FormAction::create('doSync', _t('FILESYSTEMSYNC','Look for new files')) + ->describe(_t('AssetAdmin_left.ss.FILESYSTEMSYNC_DESC', 'SilverStripe maintains its own database of the files & images stored in your assets/ folder. Click this button to update that database, if files are added to the assets/ folder from outside SilverStripe, for example, if you have uploaded files via FTP.')) + ->setUseButtonTag(true) ) ); $form->setFormMethod('GET'); - $btn->describe(_t('AssetAdmin_left.ss.FILESYSTEMSYNC_DESC', 'SilverStripe maintains its own database of the files & images stored in your assets/ folder. Click this button to update that database, if files are added to the assets/ folder from outside SilverStripe, for example, if you have uploaded files via FTP.')); return $form; } diff --git a/code/controllers/CMSFileAddController.php b/code/controllers/CMSFileAddController.php index e282a10c..74e7309b 100644 --- a/code/controllers/CMSFileAddController.php +++ b/code/controllers/CMSFileAddController.php @@ -24,22 +24,38 @@ class CMSFileAddController extends AssetAdmin { Requirements::javascript(SAPPHIRE_DIR . '/javascript/AssetUploadField.js'); Requirements::css(SAPPHIRE_DIR . '/css/AssetUploadField.css'); + $folder = $this->currentPage(); + $uploadField = Object::create('UploadField', 'AssetUploadField', ''); $uploadField->setConfig('previewMaxWidth', 40); $uploadField->setConfig('previewMaxHeight', 30); $uploadField->addExtraClass('ss-assetuploadfield'); $uploadField->removeExtraClass('ss-uploadfield'); $uploadField->setTemplate('AssetUploadField'); - if ($this->currentPage()->exists() && $this->currentPage()->getFilename()) { + if ($folder->exists() && $folder->getFilename()) { $uploadField->setFolderName($this->currentPage()->getFilename()); } $form = new Form($this, 'getEditForm', new FieldList($uploadField), new FieldList()); - $form->addExtraClass('cms-content center cms-edit-form ' . $this->BaseCSSClasses()); + $form->addExtraClass('center cms-edit-form ' . $this->BaseCSSClasses()); $form->setTemplate($this->getTemplatesWithSuffix('_EditForm')); + $form->Fields()->push( + new LiteralField( + 'BackLink', + sprintf( + '%s', + Controller::join_links(singleton('AssetAdmin')->Link('show'), $folder ? $folder->ID : 0), + _t('AssetAdmin.BackToFolder', 'Back to folder') + ) + ) + ); + return $form; } + function Tools() { + return false; + } } \ No newline at end of file diff --git a/code/controllers/CMSMain.php b/code/controllers/CMSMain.php index b092bf5a..1384c32c 100644 --- a/code/controllers/CMSMain.php +++ b/code/controllers/CMSMain.php @@ -58,7 +58,7 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr parent::init(); - Requirements::css(CMS_DIR . '/css/CMSMain.css'); + Requirements::css(CMS_DIR . '/css/screen.css'); Requirements::combine_files( 'cmsmain.js', @@ -205,10 +205,13 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr $dateTo->setConfig('showcalendar', true); $actions = new FieldList( - $resetAction = new ResetFormAction('clear', _t('CMSMain_left.ss.CLEAR', 'Clear')), - $searchAction = new FormAction('doSearch', _t('CMSMain_left.ss.SEARCH', 'Search')) + Object::create('ResetFormAction', 'clear', _t('CMSMain_left.ss.CLEAR', 'Clear')) + ->addExtraClass('ss-ui-action-minor'), + FormAction::create('doSearch', _t('CMSMain_left.ss.SEARCH', 'Search')) ); - $resetAction->addExtraClass('ss-ui-action-minor'); + + // Use