NEW UploadField lists all files, shows path info

It doesn't make a lot of sense to limit the listing
to assets/Uploads/, which is the default set through FileField->folderName.
Showing all files regardless of folder makes them easier
to find, users can still opt-in to filtering by folder
through the TreeDropdownField.
This commit is contained in:
Ingo Schommer 2013-06-05 18:09:33 +02:00
parent 7591e43ab9
commit 60333f68ee
3 changed files with 64 additions and 11 deletions

View File

@ -4,6 +4,7 @@
* Minimum PHP version raised to 5.3.3 * Minimum PHP version raised to 5.3.3
* DataObject::validate() method visibility changed to public * DataObject::validate() method visibility changed to public
* UploadField "Select from files" shows files in all folders by default
## Changelog ## Changelog
@ -23,4 +24,11 @@ this example:
... ...
} }
### UploadField "Select from files" shows files in all folders by default
In order to list files in a single folder by default (previous default behaviour),
use `setDisplayFolderName()` with a folder path relative to `assets/`:
UploadField::create('MyField')->setDisplayFolderName('Uploads');
### Bugfixes ### Bugfixes

View File

@ -163,6 +163,15 @@ class UploadField extends FileField {
'overwriteWarning' => true 'overwriteWarning' => true
); );
/**
* @var String Folder to display in "Select files" list.
* Defaults to listing all files regardless of folder.
* The folder path should be relative to the webroot.
* See {@link FileField->folderName} to set the upload target instead.
* @example admin/folder/subfolder
*/
protected $displayFolderName;
/** /**
* FieldList $fields or string $name (of a method on File to provide a fields) for the EditForm * FieldList $fields or string $name (of a method on File to provide a fields) for the EditForm
* @example 'getCMSFields' * @example 'getCMSFields'
@ -301,6 +310,21 @@ class UploadField extends FileField {
return $this->setConfig('overwriteWarning', $overwriteWarning); return $this->setConfig('overwriteWarning', $overwriteWarning);
} }
/**
* @param String
*/
public function setDisplayFolderName($name) {
$this->displayFolderName = $name;
return $this;
}
/**
* @return String
*/
public function getDisplayFolderName() {
return $this->displayFolderName;
}
/** /**
* Force a record to be used as "Parent" for uploaded Files (eg a Page with a has_one to File) * Force a record to be used as "Parent" for uploaded Files (eg a Page with a has_one to File)
* @param DataObject $record * @param DataObject $record
@ -1537,8 +1561,8 @@ class UploadField_SelectHandler extends RequestHandler {
public function Form() { public function Form() {
// Find out the requested folder ID. // Find out the requested folder ID.
$folderID = $this->parent->getRequest()->requestVar('ParentID'); $folderID = $this->parent->getRequest()->requestVar('ParentID');
if (!isset($folderID)) { if ($folderID === null && $this->parent->getDisplayFolderName()) {
$folder = Folder::find_or_make($this->folderName); $folder = Folder::find_or_make($this->parent->getDisplayFolderName());
$folderID = $folder ? $folder->ID : 0; $folderID = $folder ? $folder->ID : 0;
} }
@ -1571,19 +1595,19 @@ class UploadField_SelectHandler extends RequestHandler {
$config = GridFieldConfig::create(); $config = GridFieldConfig::create();
$config->addComponent(new GridFieldSortableHeader()); $config->addComponent(new GridFieldSortableHeader());
$config->addComponent(new GridFieldFilterHeader()); $config->addComponent(new GridFieldFilterHeader());
$config->addComponent($columns = new GridFieldDataColumns()); $config->addComponent($colsComponent = new GridFieldDataColumns());
$columns->setDisplayFields(array( $colsComponent->setDisplayFields(array(
'StripThumbnail' => '', 'Title' => singleton('File')->fieldLabel('Name'),
'Name' => 'Name', 'Filename' => singleton('File')->fieldLabel('Filename'),
'Title' => 'Title' 'Size' => singleton('File')->fieldLabel('Size')
)); ));
$config->addComponent(new GridFieldPaginator(8));
// If relation is to be autoset, we need to make sure we only list compatible objects. // If relation is to be autoset, we need to make sure we only list compatible objects.
$baseClass = $this->parent->getRelationAutosetClass(); $baseClass = $this->parent->getRelationAutosetClass();
// Create the data source for the list of files within the current directory. // Create the data source for the list of files within the current directory.
$files = DataList::create($baseClass)->filter('ParentID', $folderID); $files = DataList::create($baseClass);
if($folderID) $files = $files->filter('ParentID', $folderID);
$fileField = new GridField('Files', false, $files, $config); $fileField = new GridField('Files', false, $files, $config);
$fileField->setAttribute('data-selectable', true); $fileField->setAttribute('data-selectable', true);

View File

@ -646,13 +646,29 @@ class UploadFieldTest extends FunctionalTest {
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1'); $record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file4 = $this->objFromFixture('File', 'file4'); $file4 = $this->objFromFixture('File', 'file4');
$file5 = $this->objFromFixture('File', 'file5');
$fileSubfolder = $this->objFromFixture('File', 'file-subfolder'); $fileSubfolder = $this->objFromFixture('File', 'file-subfolder');
$fileNoEdit = $this->objFromFixture('File', 'file-noedit');
$response = $this->get('UploadFieldTest_Controller/Form/field/ManyManyFiles/select/'); $response = $this->get('UploadFieldTest_Controller/Form/field/ManyManyFiles/select/');
$this->assertFalse($response->isError()); $this->assertFalse($response->isError());
// A bit too much coupling with GridField, but a full template overload would make things too complex
$parser = new CSSContentParser($response->getBody());
$items = $parser->getBySelector('.ss-gridfield-item');
$itemIDs = array_map(create_function('$el', 'return (int)$el["data-id"];'), $items);
$this->assertContains($file4->ID, $itemIDs, 'Contains file in assigned folder');
$this->assertContains($fileSubfolder->ID, $itemIDs, 'Contains file in subfolder');
}
public function testSelectWithDisplayFolderName() {
$this->loginWithPermission('ADMIN');
$record = $this->objFromFixture('UploadFieldTest_Record', 'record1');
$file4 = $this->objFromFixture('File', 'file4');
$fileSubfolder = $this->objFromFixture('File', 'file-subfolder');
$response = $this->get('UploadFieldTest_Controller/Form/field/HasManyDisplayFolder/select/');
$this->assertFalse($response->isError());
// A bit too much coupling with GridField, but a full template overload would make things too complex // A bit too much coupling with GridField, but a full template overload would make things too complex
$parser = new CSSContentParser($response->getBody()); $parser = new CSSContentParser($response->getBody());
$items = $parser->getBySelector('.ss-gridfield-item'); $items = $parser->getBySelector('.ss-gridfield-item');
@ -908,6 +924,10 @@ class UploadFieldTestForm extends Form implements TestOnly {
$fieldHasManyNoView = UploadField::create('HasManyNoViewFiles') $fieldHasManyNoView = UploadField::create('HasManyNoViewFiles')
->setFolderName('UploadFieldTest'); ->setFolderName('UploadFieldTest');
$fieldHasManyDisplayFolder = UploadField::create('HasManyDisplayFolder')
->setFolderName('UploadFieldTest')
->setDisplayFolderName('UploadFieldTest');
$fieldReadonly = UploadField::create('ReadonlyField') $fieldReadonly = UploadField::create('ReadonlyField')
->setFolderName('UploadFieldTest') ->setFolderName('UploadFieldTest')
->performReadonlyTransformation(); ->performReadonlyTransformation();
@ -938,6 +958,7 @@ class UploadFieldTestForm extends Form implements TestOnly {
$fieldHasManyMaxTwo, $fieldHasManyMaxTwo,
$fieldManyMany, $fieldManyMany,
$fieldHasManyNoView, $fieldHasManyNoView,
$fieldHasManyDisplayFolder,
$fieldReadonly, $fieldReadonly,
$fieldDisabled, $fieldDisabled,
$fieldSubfolder, $fieldSubfolder,