mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
ENHANCEMENT Refactored AssetAdmin to use SearchContext for filtering records, rather than relying on GridFieldFilter - less coupling to one view (we also have gallery and tree views), and more flexible filtering on columns/criteria which are not present in GridField
This commit is contained in:
parent
7125af918d
commit
d1581c2b9b
@ -76,6 +76,40 @@ JS
|
|||||||
CMSBatchActionHandler::register('delete', 'AssetAdmin_DeleteBatchAction', 'Folder');
|
CMSBatchActionHandler::register('delete', 'AssetAdmin_DeleteBatchAction', 'Folder');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the files and subfolders contained in the currently selected folder,
|
||||||
|
* defaulting to the root node. Doubles as search results, if any search parameters
|
||||||
|
* are set through {@link SearchForm()}.
|
||||||
|
*
|
||||||
|
* @return SS_List
|
||||||
|
*/
|
||||||
|
public function getList() {
|
||||||
|
$folder = $this->currentPage();
|
||||||
|
$context = $this->getSearchContext();
|
||||||
|
$params = $this->request->requestVar('q');
|
||||||
|
$list = $context->getResults($params);
|
||||||
|
|
||||||
|
// Always show folders at the top
|
||||||
|
$list->sort('(CASE WHEN "File"."ClassName" = \'Folder\' THEN 0 ELSE 1 END)');
|
||||||
|
|
||||||
|
// If a search is conducted, check for the "current folder" limitation.
|
||||||
|
// Otherwise limit by the current folder as denoted by the URL.
|
||||||
|
if(!$params || @$params['CurrentFolderOnly']) {
|
||||||
|
$list->filter('ParentID', $folder->ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Category filter
|
||||||
|
if(isset($params['AppCategory'])) {
|
||||||
|
$exts = File::$app_categories[$params['AppCategory']];
|
||||||
|
$categorySQLs = array();
|
||||||
|
foreach($exts as $ext) $categorySQLs[] = '"File"."Name" LIKE \'%.' . $ext . '\'';
|
||||||
|
// TODO Use DataList->filterAny() once OR connectives are implemented properly
|
||||||
|
$list->where('(' . implode(' OR ', $categorySQLs) . ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
public function getEditForm($id = null, $fields = null) {
|
public function getEditForm($id = null, $fields = null) {
|
||||||
$form = parent::getEditForm($id, $fields);
|
$form = parent::getEditForm($id, $fields);
|
||||||
$folder = ($id && is_numeric($id)) ? DataObject::get_by_id('Folder', $id, false) : $this->currentPage();
|
$folder = ($id && is_numeric($id)) ? DataObject::get_by_id('Folder', $id, false) : $this->currentPage();
|
||||||
@ -86,19 +120,15 @@ JS
|
|||||||
// File listing
|
// File listing
|
||||||
$gridFieldConfig = GridFieldConfig::create()->addComponents(
|
$gridFieldConfig = GridFieldConfig::create()->addComponents(
|
||||||
new GridFieldSortableHeader(),
|
new GridFieldSortableHeader(),
|
||||||
new GridFieldFilter(),
|
|
||||||
new GridFieldDefaultColumns(),
|
new GridFieldDefaultColumns(),
|
||||||
new GridFieldPaginator(15),
|
new GridFieldPaginator(15),
|
||||||
new GridFieldAction_Edit(),
|
new GridFieldAction_Edit(),
|
||||||
new GridFieldAction_Delete(),
|
new GridFieldAction_Delete(),
|
||||||
new GridFieldPopupForms()
|
new GridFieldPopupForms()
|
||||||
);
|
);
|
||||||
$files = DataList::create('File')
|
$gridField = new GridField('File','Files', $this->getList(), $gridFieldConfig);
|
||||||
->filter('ParentID', $folder->ID)
|
|
||||||
->sort('(CASE WHEN "ClassName" = \'Folder\' THEN 0 ELSE 1 END)');
|
|
||||||
$gridField = new GridField('File','Files', $files, $gridFieldConfig);
|
|
||||||
$gridField->setDisplayFields(array(
|
$gridField->setDisplayFields(array(
|
||||||
// 'StripThumbnail' => '',
|
'StripThumbnail' => '',
|
||||||
// 'Parent.FileName' => 'Folder',
|
// 'Parent.FileName' => 'Folder',
|
||||||
'Title' => _t('File.Name'),
|
'Title' => _t('File.Name'),
|
||||||
'Created' => _t('AssetAdmin.CREATED', 'Date'),
|
'Created' => _t('AssetAdmin.CREATED', 'Date'),
|
||||||
@ -213,18 +243,51 @@ JS
|
|||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getSearchContext() {
|
||||||
|
$context = singleton('File')->getDefaultSearchContext();
|
||||||
|
|
||||||
|
// Namespace fields, for easier detection if a search is present
|
||||||
|
foreach($context->getFields() as $field) $field->setName(sprintf('q[%s]', $field->getName()));
|
||||||
|
foreach($context->getFilters() as $filter) $filter->setFullName(sprintf('q[%s]', $filter->getFullName()));
|
||||||
|
|
||||||
|
// Customize fields
|
||||||
|
$appCategories = array(
|
||||||
|
'image' => _t('AssetAdmin.AppCategoryImage', 'Image'),
|
||||||
|
'audio' => _t('AssetAdmin.AppCategoryAudio', 'Audio'),
|
||||||
|
'mov' => _t('AssetAdmin.AppCategoryVideo', 'Video'),
|
||||||
|
'flash' => _t('AssetAdmin.AppCategoryFlash', 'Flash', PR_MEDIUM, 'The fileformat'),
|
||||||
|
'zip' => _t('AssetAdmin.AppCategoryArchive', 'Archive', PR_MEDIUM, 'A collection of files'),
|
||||||
|
);
|
||||||
|
$context->addField(
|
||||||
|
new DropdownField(
|
||||||
|
'q[AppCategory]',
|
||||||
|
_t('AssetAdmin.Filetype', 'File type'),
|
||||||
|
$appCategories,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
' '
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$context->addField(
|
||||||
|
new CheckboxField('q[CurrentFolderOnly]' ,_t('AssetAdmin.CurrentFolderOnly', 'Limit to current folder?'))
|
||||||
|
);
|
||||||
|
$context->getFields()->removeByName('q[Title]');
|
||||||
|
|
||||||
|
return $context;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a form for filtering of files and assets gridfield
|
* Returns a form for filtering of files and assets gridfield.
|
||||||
|
* Result filtering takes place in {@link getList()}.
|
||||||
*
|
*
|
||||||
* @return Form
|
* @return Form
|
||||||
* @see AssetAdmin.js
|
* @see AssetAdmin.js
|
||||||
*/
|
*/
|
||||||
public function FilterForm() {
|
public function SearchForm() {
|
||||||
$fields = new FieldList();
|
$folder = $this->currentPage();
|
||||||
// Below is the filters that this field should filter on
|
$context = $this->getSearchContext();
|
||||||
$fields->push(new TextField('Title'));
|
|
||||||
$fields->push(new TextField('ClassName','Type'));
|
|
||||||
|
|
||||||
|
$fields = $context->getSearchFields();
|
||||||
$actions = new FieldList(
|
$actions = new FieldList(
|
||||||
Object::create('ResetFormAction', 'clear', _t('CMSMain_left.ss.CLEAR', 'Clear'))
|
Object::create('ResetFormAction', 'clear', _t('CMSMain_left.ss.CLEAR', 'Clear'))
|
||||||
->addExtraClass('ss-ui-action-minor'),
|
->addExtraClass('ss-ui-action-minor'),
|
||||||
@ -232,23 +295,16 @@ JS
|
|||||||
);
|
);
|
||||||
|
|
||||||
$form = new Form($this, 'filter', $fields, $actions);
|
$form = new Form($this, 'filter', $fields, $actions);
|
||||||
$form->addExtraClass('cms-filter-form');
|
$form->setFormMethod('GET');
|
||||||
|
$form->setFormAction(Controller::join_links($this->Link('show'), $folder->ID ? $folder->ID : 'root'));
|
||||||
|
$form->addExtraClass('cms-search-form');
|
||||||
|
$form->loadDataFrom($this->request->getVars());
|
||||||
|
$form->disableSecurityToken();
|
||||||
// This have to match data-name attribute on the gridfield so that the javascript selectors work
|
// This have to match data-name attribute on the gridfield so that the javascript selectors work
|
||||||
$form->setAttribute('data-gridfield', 'File');
|
$form->setAttribute('data-gridfield', 'File');
|
||||||
return $form;
|
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() {
|
public function AddForm() {
|
||||||
$form = parent::AddForm();
|
$form = parent::AddForm();
|
||||||
$folder = singleton('Folder');
|
$folder = singleton('Folder');
|
||||||
@ -488,6 +544,18 @@ JS
|
|||||||
// The root element should explicitly point to the root node
|
// The root element should explicitly point to the root node
|
||||||
$items[0]->Link = Controller::join_links($this->Link('show'), 'root');
|
$items[0]->Link = Controller::join_links($this->Link('show'), 'root');
|
||||||
|
|
||||||
|
// If a search is in progress, don't show the path
|
||||||
|
if($this->request->requestVar('q')) {
|
||||||
|
$items = $items->getRange(0, 1);
|
||||||
|
$items->push(new ArrayData(array(
|
||||||
|
'Title' => _t('LeftAndMain.SearchResults', 'Search Results'),
|
||||||
|
'Link' => Controller::join_links($this->Link(), '?' . http_build_query(array('q' => $this->request->requestVar('q'))))
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Remove once ViewableData->First()/Last() is fixed
|
||||||
|
foreach($items as $i => $item) $item->iteratorProperties($i, $items->Count());
|
||||||
|
|
||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<div class="cms-content-tools west cms-panel cms-panel-layout collapsed" id="cms-content-tools" data-expandOnClick="true" data-layout-type="border">
|
<div class="cms-content-tools west cms-panel cms-panel-layout collapsed" id="cms-content-tools" data-expandOnClick="true" data-layout-type="border">
|
||||||
<div class="cms-panel-content center">
|
<div class="cms-panel-content center">
|
||||||
<h3 class="cms-panel-header"><% _t('FILTER', 'Filter') %></h3>
|
<h3 class="cms-panel-header"><% _t('FILTER', 'Filter') %></h3>
|
||||||
$FilterForm
|
$SearchForm
|
||||||
</div>
|
</div>
|
||||||
<div class="cms-panel-content-collapsed">
|
<div class="cms-panel-content-collapsed">
|
||||||
<h3 class="cms-panel-header"><% _t('FILTER', 'Filter') %></h3>
|
<h3 class="cms-panel-header"><% _t('FILTER', 'Filter') %></h3>
|
||||||
|
Loading…
Reference in New Issue
Block a user