Reorganise + bulkupload start
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
//define global path to Components' root folder
|
||||
if(!defined('BULK_EDIT_TOOLS_PATH'))
|
||||
if(!defined('BULKEDITTOOLS_UPLOAD_PATH'))
|
||||
{
|
||||
define('BULK_EDIT_TOOLS_PATH', rtrim(basename(dirname(__FILE__))));
|
||||
$folder = rtrim(basename(dirname(__FILE__)));
|
||||
define('BULKEDITTOOLS_UPLOAD_PATH', $folder . '/bulkupload');
|
||||
define('BULKEDITTOOLS_MANAGER_PATH', $folder . '/bulkManager');
|
||||
}
|
@ -108,9 +108,9 @@ class GridFieldBulkActionEditHandler extends GridFieldBulkActionHandler
|
||||
$form->addExtraClass('center cms-content');
|
||||
$form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
|
||||
|
||||
Requirements::javascript(BULK_EDIT_TOOLS_PATH . '/javascript/GridFieldBulkEditingForm.js');
|
||||
Requirements::css(BULK_EDIT_TOOLS_PATH . '/css/GridFieldBulkEditingForm.css');
|
||||
Requirements::add_i18n_javascript(BULK_EDIT_TOOLS_PATH . '/javascript/lang');
|
||||
Requirements::javascript(BULKEDITTOOLS_MANAGER_PATH . '/javascript/GridFieldBulkEditingForm.js');
|
||||
Requirements::css(BULKEDITTOOLS_MANAGER_PATH . '/css/GridFieldBulkEditingForm.css');
|
||||
Requirements::add_i18n_javascript(BULKEDITTOOLS_MANAGER_PATH . '/javascript/lang');
|
||||
|
||||
if($this->request->isAjax())
|
||||
{
|
@ -287,9 +287,9 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
|
||||
*/
|
||||
public function getHTMLFragments($gridField)
|
||||
{
|
||||
Requirements::css(BULK_EDIT_TOOLS_PATH . '/css/GridFieldBulkManager.css');
|
||||
Requirements::javascript(BULK_EDIT_TOOLS_PATH . '/javascript/GridFieldBulkManager.js');
|
||||
Requirements::add_i18n_javascript(BULK_EDIT_TOOLS_PATH . '/javascript/lang');
|
||||
Requirements::css(BULKEDITTOOLS_MANAGER_PATH . '/css/GridFieldBulkManager.css');
|
||||
Requirements::javascript(BULKEDITTOOLS_MANAGER_PATH . '/javascript/GridFieldBulkManager.js');
|
||||
Requirements::add_i18n_javascript(BULKEDITTOOLS_MANAGER_PATH . '/javascript/lang');
|
||||
|
||||
if ( !count($this->config['actions']) )
|
||||
{
|
15
bulkManager/lang/cs.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
cs:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Hromadně nahrát
|
||||
FINISH_BTN_LABEL: Dokončit
|
||||
SAVE_BTN_LABEL: Uložit vše
|
||||
CANCEL_BTN_LABEL: Storno & Smazat vše
|
||||
EDIT_SELECT_LABEL: Upravit
|
||||
UNLINK_SELECT_LABEL: Odstranit vazbu
|
||||
DELETE_SELECT_LABEL: Smazat
|
||||
ACTION_BTN_LABEL: Provést
|
||||
SELECT_ALL_LABEL: Vybrat vše
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Storno
|
15
bulkManager/lang/de.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
de:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Bulk Upload
|
||||
FINISH_BTN_LABEL: Fertigstellen
|
||||
SAVE_BTN_LABEL: Alle speichern
|
||||
CANCEL_BTN_LABEL: Abbrechen & alle löschen
|
||||
EDIT_SELECT_LABEL: Bearbeiten
|
||||
UNLINK_SELECT_LABEL: Verbindung entfernen
|
||||
DELETE_SELECT_LABEL: Löschen
|
||||
ACTION_BTN_LABEL: Los
|
||||
SELECT_ALL_LABEL: Alle auswählen
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Abbrechen
|
15
bulkManager/lang/en.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
en:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Bulk Upload
|
||||
FINISH_BTN_LABEL: Finish
|
||||
SAVE_BTN_LABEL: Save All
|
||||
CANCEL_BTN_LABEL: Cancel & Delete All
|
||||
EDIT_SELECT_LABEL: Edit
|
||||
UNLINK_SELECT_LABEL: Unlink
|
||||
DELETE_SELECT_LABEL: Delete
|
||||
ACTION_BTN_LABEL: Go
|
||||
SELECT_ALL_LABEL: Select all
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Cancel
|
15
bulkManager/lang/fr.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
fr:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Upload groupé
|
||||
FINISH_BTN_LABEL: Terminer
|
||||
SAVE_BTN_LABEL: Enregistrer tout
|
||||
CANCEL_BTN_LABEL: Annuler & supprimer tout
|
||||
EDIT_SELECT_LABEL: Editer
|
||||
UNLINK_SELECT_LABEL: Retirer
|
||||
DELETE_SELECT_LABEL: Supprimer
|
||||
ACTION_BTN_LABEL: Go
|
||||
SELECT_ALL_LABEL: Sélectionner tout
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Annuler
|
15
bulkManager/lang/nl.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
nl:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Bulk Upload
|
||||
FINISH_BTN_LABEL: Afronden
|
||||
SAVE_BTN_LABEL: Alles opslaan
|
||||
CANCEL_BTN_LABEL: Annuleren & alles verwijderen
|
||||
EDIT_SELECT_LABEL: Bewerken
|
||||
UNLINK_SELECT_LABEL: Loskoppelen
|
||||
DELETE_SELECT_LABEL: Verwijderen
|
||||
ACTION_BTN_LABEL: Gaan
|
||||
SELECT_ALL_LABEL: Selecteer alles
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Annuleren
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
@ -5,7 +5,7 @@
|
||||
* @author colymba
|
||||
* @package GridFieldBulkEditingTools
|
||||
*/
|
||||
class GridFieldBulkImageUpload implements GridField_HTMLProvider, GridField_URLHandler {
|
||||
class GridFieldBulkUpload implements GridField_HTMLProvider, GridField_URLHandler {
|
||||
|
||||
/**
|
||||
* component configuration
|
||||
@ -150,27 +150,132 @@ class GridFieldBulkImageUpload implements GridField_HTMLProvider, GridField_URLH
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************************************************************************** */
|
||||
|
||||
/**
|
||||
* Get the first has_one Image/File relation from the GridField managed DataObject
|
||||
* i.e. 'MyImage' => 'Image' will return 'MyImage'
|
||||
*
|
||||
* @return string Name of the $has_one relation
|
||||
*/
|
||||
public function getDefaultFileRelationName($gridField)
|
||||
{
|
||||
$recordClass = $gridField->list->dataClass;
|
||||
$hasOneFields = Config::inst()->get($recordClass, 'has_one', Config::INHERITED);
|
||||
|
||||
$imageField = null;
|
||||
foreach( $hasOneFields as $field => $type )
|
||||
{
|
||||
if( $type === 'Image' || $type === 'File' || is_subclass_of($type, 'File') )
|
||||
{
|
||||
$imageField = $field;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $imageField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the Image/File field name from the managed record
|
||||
* Either as set in the component config or the default one
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFileRelationName($gridField)
|
||||
{
|
||||
$configFileRelationName = $this->getConfig('fileRelationName');
|
||||
return $configFileRelationName ? $configFileRelationName : $this->getDefaultFileRelationName($gridField);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ClassName of the fileRelation
|
||||
* i.e. 'MyImage' => 'Image' will return 'Image'
|
||||
* i.e. 'MyImage' => 'File' will return 'File'
|
||||
*
|
||||
* @return string file relation className
|
||||
*/
|
||||
public function getFileRelationClassName($gridField)
|
||||
{
|
||||
$recordClass = $gridField->list->dataClass;
|
||||
$hasOneFields = Config::inst()->get($recordClass, 'has_one', Config::INHERITED);
|
||||
|
||||
$fieldName = $this->getFileRelationName($gridField);
|
||||
if($fieldName)
|
||||
{
|
||||
return $hasOneFields[$fieldName];
|
||||
}
|
||||
else{
|
||||
return 'File';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ******************************************************************************** */
|
||||
|
||||
public function bulkUploadField($gridField)
|
||||
{
|
||||
$fileRelationName = $this->getFileRelationName($gridField);
|
||||
$uploadField = UploadField::create($fileRelationName, '')
|
||||
->setForm($gridField->getForm())
|
||||
|
||||
->setConfig('previewMaxWidth', 20)
|
||||
->setConfig('previewMaxHeight', 20)
|
||||
->setConfig('changeDetection', false)
|
||||
|
||||
->setDownloadTemplateName('colymba-bulkuploaddownloadtemplate')
|
||||
|
||||
->setConfig('url', $gridField->Link('bulkupload/upload'))
|
||||
->setConfig('urlSelectDialog', $gridField->Link('bulkupload/select'))
|
||||
->setConfig('urlAttach', $gridField->Link('bulkupload/attach'))
|
||||
->setConfig('urlFileExists', $gridField->Link('bulkupload/fileexists'))
|
||||
;
|
||||
|
||||
//max file size
|
||||
$maxFileSize = $this->getConfig('maxFileSize');
|
||||
if ( $maxFileSize !== null )
|
||||
{
|
||||
$uploadField->getValidator()->setAllowedMaxFileSize( $maxFileSize );
|
||||
}
|
||||
|
||||
//upload dir
|
||||
$uploadDir = $this->getConfig('folderName');
|
||||
if ( $uploadDir !== null )
|
||||
{
|
||||
$uploadField->setFolderName($uploadDir);
|
||||
}
|
||||
|
||||
//sequential upload
|
||||
$uploadField->setConfig('sequentialUploads', $this->getConfig('sequentialUploads'));
|
||||
|
||||
return $uploadField;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param GridField $gridField
|
||||
* @return array
|
||||
*/
|
||||
public function getHTMLFragments($gridField) {
|
||||
|
||||
Requirements::css(BULK_EDIT_TOOLS_PATH . '/css/GridFieldBulkImageUpload.css');
|
||||
|
||||
$targetFragment = 'before';
|
||||
if ( $gridField->getConfig()->getComponentByType('GridFieldButtonRow') )
|
||||
public function getHTMLFragments($gridField)
|
||||
{
|
||||
// permission check
|
||||
if( !singleton($gridField->getModelClass())->canEdit() )
|
||||
{
|
||||
$targetFragment = 'buttons-before-right';
|
||||
return array();
|
||||
}
|
||||
|
||||
$bulkUploadBtn = new ArrayData(array(
|
||||
'Link' => $gridField->Link('bulkimageupload')
|
||||
$data = ArrayData::create(array(
|
||||
'Colspan' => count($gridField->getColumns()),
|
||||
'UploadField' => $this->bulkUploadField($gridField)->Field() // call ->Field() to get requirements in right order
|
||||
));
|
||||
|
||||
Requirements::css(BULKEDITTOOLS_UPLOAD_PATH . '/css/GridFieldBulkUpload.css');
|
||||
Requirements::javascript(BULKEDITTOOLS_UPLOAD_PATH . '/javascript/GridFieldBulkUpload.js');
|
||||
Requirements::javascript(BULKEDITTOOLS_UPLOAD_PATH . '/javascript/GridFieldBulkUpload_downloadtemplate.js');
|
||||
Requirements::add_i18n_javascript(BULKEDITTOOLS_UPLOAD_PATH . '/javascript/lang');
|
||||
|
||||
return array(
|
||||
$targetFragment => $bulkUploadBtn->renderWith('BulkUploadButton')
|
||||
'header' => $data->renderWith('GridFieldBulkUpload')
|
||||
);
|
||||
}
|
||||
|
||||
@ -181,7 +286,7 @@ class GridFieldBulkImageUpload implements GridField_HTMLProvider, GridField_URLH
|
||||
*/
|
||||
public function getURLHandlers($gridField) {
|
||||
return array(
|
||||
'bulkimageupload' => 'handleBulkUpload'
|
||||
'bulkupload' => 'handleBulkUpload'
|
||||
);
|
||||
}
|
||||
|
||||
@ -195,8 +300,9 @@ class GridFieldBulkImageUpload implements GridField_HTMLProvider, GridField_URLH
|
||||
public function handleBulkUpload($gridField, $request)
|
||||
{
|
||||
$controller = $gridField->getForm()->Controller();
|
||||
$handler = new GridFieldBulkImageUpload_Request($gridField, $this, $controller);
|
||||
$handler = new GridFieldBulkUpload_Request($gridField, $this, $controller);
|
||||
|
||||
return $handler->handleRequest($request, DataModel::inst());
|
||||
}
|
||||
}
|
||||
|
288
bulkUpload/code/GridFieldBulkUpload_Request.php
Normal file
@ -0,0 +1,288 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles request from the GridFieldBulkImageUpload component
|
||||
*
|
||||
* Handles:
|
||||
* * Form creation
|
||||
* * file upload
|
||||
* * editing and cancelling records
|
||||
*
|
||||
* @author colymba
|
||||
* @package GridFieldBulkEditingTools
|
||||
*/
|
||||
class GridFieldBulkUpload_Request extends RequestHandler {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var GridField
|
||||
*/
|
||||
protected $gridField;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var GridField_URLHandler
|
||||
*/
|
||||
protected $component;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Controller
|
||||
*/
|
||||
protected $controller;
|
||||
|
||||
/**
|
||||
* Cache the records FieldList from getCMSfields()
|
||||
*
|
||||
* @var FieldList
|
||||
*/
|
||||
protected $recordCMSFieldList;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static $allowed_actions = array(
|
||||
'upload', 'select', 'attach', 'fileexists', 'update', 'cancel'
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static $url_handlers = array(
|
||||
'$Action!' => '$Action'
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param GridFIeld $gridField
|
||||
* @param GridField_URLHandler $component
|
||||
* @param Controller $controller
|
||||
*/
|
||||
public function __construct($gridField, $component, $controller) {
|
||||
$this->gridField = $gridField;
|
||||
$this->component = $component;
|
||||
$this->controller = $controller;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL for this RequestHandler
|
||||
*
|
||||
* @author SilverStripe
|
||||
* @see GridFieldDetailForm_ItemRequest
|
||||
* @param string $action
|
||||
* @return string
|
||||
*//*
|
||||
public function Link($action = null) {
|
||||
return Controller::join_links($this->gridField->Link(), 'bulkimageupload', $action);
|
||||
}*/
|
||||
|
||||
|
||||
/**
|
||||
* Returns the list of editable fields from the managed record
|
||||
* Either as set in the component config or the default ones
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getRecordEditableFields()
|
||||
{
|
||||
$fields = $this->component->getConfig('editableFields');
|
||||
if ( $fields == null ) $fields = $this->getDefaultRecordEditableFields();
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $recordID
|
||||
* @return type
|
||||
*/
|
||||
function getRecordHTMLFormFields( $recordID = 0 )
|
||||
{
|
||||
$config = $this->component->getConfig();
|
||||
$recordCMSDataFields = GridFieldBulkEditingHelper::getModelCMSDataFields( $config, $this->gridField->list->dataClass );
|
||||
|
||||
//@TODO: if editableFields given use them with filterNonEditableRecordsFields()
|
||||
// otherwise go through getModelFilteredDataFields
|
||||
|
||||
|
||||
$recordCMSDataFields = GridFieldBulkEditingHelper::filterNonEditableRecordsFields($config, $recordCMSDataFields);
|
||||
|
||||
$config['fileRelationName'] = $config['fileRelationName'] ? $config['fileRelationName'] : $this->component->getDefaultFileRelationName($this->gridField);
|
||||
|
||||
$recordCMSDataFields = GridFieldBulkEditingHelper::getModelFilteredDataFields($config, $recordCMSDataFields);
|
||||
$recordCMSDataFields = GridFieldBulkEditingHelper::populateCMSDataFields($recordCMSDataFields, $this->gridField->list->dataClass, $recordID);
|
||||
$formFieldsHTML = GridFieldBulkEditingHelper::dataFieldsToHTML($recordCMSDataFields);
|
||||
$formFieldsHTML = GridFieldBulkEditingHelper::escapeFormFieldsHTML($formFieldsHTML, $recordID);
|
||||
|
||||
return $formFieldsHTML;
|
||||
}
|
||||
|
||||
|
||||
public function getUploadField()
|
||||
{
|
||||
return $this->component->bulkUploadField($this->gridField);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Noop.
|
||||
*/
|
||||
public function index($request)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process upload through UploadField,
|
||||
* creates new record and link newly uploaded file
|
||||
* adds record to GrifField relation list
|
||||
* and return image/file data and record edit form
|
||||
*
|
||||
* @param SS_HTTPRequest $request
|
||||
* @return string json
|
||||
*/
|
||||
public function upload(SS_HTTPRequest $request)
|
||||
{
|
||||
//create record
|
||||
$recordClass = $this->gridField->list->dataClass;
|
||||
$record = Object::create($recordClass);
|
||||
$record->write();
|
||||
|
||||
// passes the current gridfield-instance to a call-back method on the new object
|
||||
//$record->extend("onBulkImageUpload", $this->gridField);
|
||||
$record->extend("onBulkFileUpload", $this->gridField);
|
||||
|
||||
//get uploadField and process upload
|
||||
//$fileRelationName = $this->getFileRelationName();
|
||||
//$uploadField = $this->uploadForm()->Fields()->fieldByName($fileRelationName);
|
||||
$uploadField = $this->getUploadField();
|
||||
$uploadField->setRecord($record);
|
||||
|
||||
$fileRelationName = $uploadField->getName();
|
||||
$uploadResponse = $uploadField->upload($request);
|
||||
|
||||
//get uploaded File response datas
|
||||
$uploadResponse = Convert::json2array( $uploadResponse->getBody() );
|
||||
$uploadResponse = array_shift( $uploadResponse );
|
||||
|
||||
// Attach the file to record.
|
||||
$record->{"{$fileRelationName}ID"} = $uploadResponse['id'];
|
||||
$record->write();
|
||||
|
||||
// attached record to gridField relation
|
||||
$this->gridField->list->add($record->ID);
|
||||
|
||||
//get record's CMS Fields
|
||||
//$recordEditableFormFields = $this->getRecordHTMLFormFields( $record->ID );
|
||||
|
||||
//fetch uploadedFile record and sort out previewURL
|
||||
//update $uploadResponse datas in case changes happened onAfterWrite()
|
||||
$uploadedFile = DataObject::get_by_id( $this->component->getFileRelationClassName($this->gridField), $uploadResponse['id'] );
|
||||
if ( $uploadedFile )
|
||||
{
|
||||
$uploadResponse['name'] = $uploadedFile->Name;
|
||||
$uploadResponse['url'] = $uploadedFile->getURL();
|
||||
|
||||
if ( $uploadedFile instanceof Image )
|
||||
{
|
||||
$uploadResponse['preview_url'] = $uploadedFile->setHeight(50)->Link();
|
||||
$uploadResponse['thumbnail_url'] = $uploadedFile->CroppedImage(30,30)->getURL();
|
||||
}
|
||||
else{
|
||||
$uploadResponse['preview_url'] = $uploadedFile->Icon();
|
||||
$uploadResponse['thumbnail_url'] = $uploadedFile->Icon();
|
||||
}
|
||||
}
|
||||
|
||||
// Collect all data for JS template
|
||||
$return = array_merge($uploadResponse, array(
|
||||
'record' => array(
|
||||
'id' => $record->ID
|
||||
)
|
||||
));
|
||||
|
||||
$response = new SS_HTTPResponse(Convert::raw2json(array($return)));
|
||||
$response->addHeader('Content-Type', 'text/json');
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
public function select(SS_HTTPRequest $request)
|
||||
{
|
||||
$uploadField = $this->getUploadField();
|
||||
return $uploadField->handleSelect($request);
|
||||
}
|
||||
|
||||
|
||||
public function attach(SS_HTTPRequest $request)
|
||||
{
|
||||
$uploadField = $this->getUploadField();
|
||||
return $uploadField->attach($request);
|
||||
}
|
||||
|
||||
|
||||
public function fileexists(SS_HTTPRequest $request)
|
||||
{
|
||||
$uploadField = $this->getUploadField();
|
||||
return $uploadField->fileexists($request);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update a record with the newly edited fields
|
||||
*
|
||||
* @param SS_HTTPRequest $request
|
||||
* @return string
|
||||
*/
|
||||
public function update(SS_HTTPRequest $request)
|
||||
{
|
||||
$data = GridFieldBulkEditingHelper::unescapeFormFieldsPOSTData($request->requestVars());
|
||||
$record = DataObject::get_by_id($this->gridField->list->dataClass, $data['ID']);
|
||||
|
||||
foreach($data as $field => $value)
|
||||
{
|
||||
if ( $record->hasMethod($field) ) {
|
||||
$list = $record->$field();
|
||||
$list->setByIDList( $value );
|
||||
}else{
|
||||
$record->setCastedField($field, $value);
|
||||
}
|
||||
}
|
||||
$record->write();
|
||||
|
||||
return '{done:1,recordID:'.$data['ID'].'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the Image Object and File as well as the DataObject
|
||||
* according to the ID sent from the form
|
||||
*
|
||||
* @param SS_HTTPRequest $request
|
||||
* @return string json
|
||||
*/
|
||||
public function cancel(SS_HTTPRequest $request)
|
||||
{
|
||||
$data = GridFieldBulkEditingHelper::unescapeFormFieldsPOSTData($request->requestVars());
|
||||
$return = array();
|
||||
|
||||
$recordClass = $this->gridField->list->dataClass;
|
||||
$record = DataObject::get_by_id($recordClass, $data['ID']);
|
||||
|
||||
$imageField = $this->getFileRelationName();
|
||||
$imageID = $record->$imageField.'ID';
|
||||
$image = DataObject::get_by_id('Image', $imageID);
|
||||
|
||||
$return[$data['ID']]['imageID'] = $imageID;
|
||||
$return[$data['ID']]['deletedDataObject'] = DataObject::delete_by_id($recordClass, $data['ID']);
|
||||
|
||||
$return[$data['ID']]['deletedFormattedImages'] = $image->deleteFormattedImages();
|
||||
$return[$data['ID']]['deletedImageFile'] = unlink( Director::getAbsFile($image->getRelativePath()) );
|
||||
|
||||
|
||||
$response = new SS_HTTPResponse(Convert::raw2json($return));
|
||||
$response->addHeader('Content-Type', 'text/plain');
|
||||
return $response;
|
||||
}
|
||||
}
|
124
bulkUpload/css/GridFieldBulkUpload.css
Normal file
@ -0,0 +1,124 @@
|
||||
.bulkUpload {
|
||||
padding: 0 !important;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); }
|
||||
.bulkUpload:hover {
|
||||
background-color: #444546; }
|
||||
.bulkUpload .component {
|
||||
padding: 0 !important;
|
||||
color: #fff;
|
||||
background: #98aab6;
|
||||
border-top: 1px solid #a4b4bf;
|
||||
border-left: 1px solid #a4b4bf;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); }
|
||||
.bulkUpload .component div.ss-uploadfield {
|
||||
position: relative;
|
||||
float: left;
|
||||
clear: both;
|
||||
width: 100%;
|
||||
padding-top: 70px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files {
|
||||
float: left;
|
||||
clear: both;
|
||||
width: 100%; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item {
|
||||
position: relative;
|
||||
float: left;
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
width: 98%;
|
||||
padding: 5px 1% 5px 1%;
|
||||
border: none; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item:nth-child(2n-1) {
|
||||
background-color: rgba(0, 0, 0, 0.1); }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-preview {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 38px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info {
|
||||
height: 30px;
|
||||
margin-left: 40px;
|
||||
line-height: 30px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 40px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .name {
|
||||
color: #eee; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .ss-uploadfield-item-status {
|
||||
float: left;
|
||||
width: auto;
|
||||
padding: 0 0 0 5px;
|
||||
text-align: left;
|
||||
max-width: none; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .ss-uploadfield-item-status.ui-state-warning-text {
|
||||
color: #f2be08; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .ss-uploadfield-item-status.ui-state-success-text {
|
||||
color: #298530; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
margin: 0;
|
||||
padding: 5px 0 5px 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-progress {
|
||||
left: 50px;
|
||||
right: 35px;
|
||||
margin-top: 8px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions button {
|
||||
margin: 0 10px 0 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions button .ui-button-text {
|
||||
padding-top: 4px;
|
||||
padding-bottom: 3px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-cancel {
|
||||
position: relative;
|
||||
top: 7px;
|
||||
right: auto;
|
||||
float: right; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-cancel button {
|
||||
background: none; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-overwrite {
|
||||
position: relative;
|
||||
float: right;
|
||||
margin-top: 2px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
float: left;
|
||||
clear: both;
|
||||
width: 98%;
|
||||
height: 50px;
|
||||
padding: 1%; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile.borderTop {
|
||||
border: none; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-preview.ss-uploadfield-dropzone {
|
||||
float: right;
|
||||
width: 35%;
|
||||
height: 43px;
|
||||
margin: 0;
|
||||
line-height: 43px;
|
||||
color: #eee;
|
||||
background-color: #8898a3;
|
||||
border: 2px dashed #73818a;
|
||||
box-shadow: #73818a 0 0 10px 0 inset; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-preview.ss-uploadfield-dropzone.hover {
|
||||
color: #444546;
|
||||
background-color: #eee; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info {
|
||||
float: left;
|
||||
width: 60%;
|
||||
margin: 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-item-name {
|
||||
height: 20px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-ui-button .ui-button-text .ui-button-text {
|
||||
padding: 0px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-fromcomputer {
|
||||
margin-bottom: 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-fromfiles {
|
||||
margin-bottom: 0;
|
||||
padding: .5px; }
|
248
bulkUpload/css/GridFieldBulkUpload.scss
Normal file
@ -0,0 +1,248 @@
|
||||
@import 'bourbon/bourbon';
|
||||
|
||||
.bulkUpload
|
||||
{
|
||||
padding: 0 !important;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
|
||||
&:hover
|
||||
{
|
||||
background-color: #444546;
|
||||
}
|
||||
|
||||
.component
|
||||
{
|
||||
padding: 0 !important;
|
||||
|
||||
color: #fff;
|
||||
background: #98aab6;
|
||||
|
||||
border-top: 1px solid #a4b4bf;
|
||||
border-left: 1px solid #a4b4bf;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
|
||||
div.ss-uploadfield
|
||||
{
|
||||
position: relative;
|
||||
|
||||
float: left;
|
||||
clear: both;
|
||||
width: 100%;
|
||||
|
||||
padding-top: 70px;
|
||||
|
||||
// uploading file progress
|
||||
.ss-uploadfield-files
|
||||
{
|
||||
float: left;
|
||||
clear: both;
|
||||
width: 100%;
|
||||
|
||||
$itemHeight: 30px;
|
||||
|
||||
// each individual upload
|
||||
.ss-uploadfield-item
|
||||
{
|
||||
position: relative;
|
||||
float: left;
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
|
||||
width: 98%;
|
||||
padding: 5px 1% 5px 1%;
|
||||
|
||||
border: none;
|
||||
//border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
|
||||
&:nth-child(2n-1)
|
||||
{
|
||||
background-color: rgba(0,0,0,.1); // #4a4b4d;
|
||||
}
|
||||
|
||||
.ss-uploadfield-item-preview
|
||||
{
|
||||
width: $itemHeight;
|
||||
height: $itemHeight;
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
.ss-uploadfield-item-info
|
||||
{
|
||||
height: $itemHeight;
|
||||
margin-left: 40px;
|
||||
line-height: $itemHeight;
|
||||
|
||||
.ss-uploadfield-item-name
|
||||
{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50px;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 40px;
|
||||
|
||||
.name
|
||||
{
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
.ss-uploadfield-item-status
|
||||
{
|
||||
float: left;
|
||||
width: auto;
|
||||
padding: 0 0 0 5px;
|
||||
text-align: left;
|
||||
max-width: none;
|
||||
|
||||
&.ui-state-warning-text
|
||||
{
|
||||
color: #f2be08;
|
||||
}
|
||||
&.ui-state-success-text
|
||||
{
|
||||
color: #298530;
|
||||
}
|
||||
}// .ss-uploadfield-item-status
|
||||
}// .ss-uploadfield-item-name
|
||||
|
||||
.ss-uploadfield-item-actions
|
||||
{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
width: 100%;
|
||||
height: $itemHeight;
|
||||
|
||||
margin: 0;
|
||||
padding: 5px 0 5px 0;
|
||||
|
||||
.ss-uploadfield-item-progress
|
||||
{
|
||||
left: 50px;
|
||||
right: 35px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
button
|
||||
{
|
||||
margin: 0 10px 0 0;
|
||||
|
||||
.ui-button-text
|
||||
{
|
||||
padding-top: 4px;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.ss-uploadfield-item-cancel
|
||||
{
|
||||
position: relative;
|
||||
top: 7px;
|
||||
right: auto;
|
||||
float: right;
|
||||
|
||||
button
|
||||
{
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ss-uploadfield-item-overwrite
|
||||
{
|
||||
position: relative;
|
||||
float: right;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}// .ss-uploadfield-item-actions
|
||||
}// .ss-uploadfield-item-info
|
||||
|
||||
.ss-uploadfield-item-editform
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}// .ss-uploadfield-files
|
||||
|
||||
// upload tools
|
||||
.ss-uploadfield-addfile
|
||||
{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
float: left;
|
||||
clear: both;
|
||||
|
||||
width: 98%;
|
||||
height: 50px;
|
||||
|
||||
padding: 1%;
|
||||
|
||||
&.borderTop
|
||||
{
|
||||
border: none;
|
||||
}
|
||||
|
||||
.ss-uploadfield-item-preview.ss-uploadfield-dropzone
|
||||
{
|
||||
float: right;
|
||||
width: 35%;
|
||||
height: 43px;
|
||||
margin: 0;
|
||||
|
||||
line-height: 43px;
|
||||
|
||||
color: #eee;
|
||||
background-color: #8898a3;
|
||||
border: 2px dashed #73818a;
|
||||
box-shadow: #73818a 0 0 10px 0 inset;
|
||||
|
||||
&.hover
|
||||
{
|
||||
color: #444546;
|
||||
background-color: #eee;
|
||||
}
|
||||
}
|
||||
|
||||
.ss-uploadfield-item-info
|
||||
{
|
||||
float: left;
|
||||
width: 60%;
|
||||
margin: 0;
|
||||
|
||||
.ss-uploadfield-item-name
|
||||
{
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.ss-ui-button
|
||||
{
|
||||
.ui-button-text
|
||||
{
|
||||
.ui-button-text
|
||||
{
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ss-uploadfield-fromcomputer
|
||||
{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.ss-uploadfield-fromfiles
|
||||
{
|
||||
margin-bottom: 0;
|
||||
padding: .5px;
|
||||
}
|
||||
}
|
||||
}// .ss-uploadfield-item
|
||||
|
||||
}// .ss-uploadfield
|
||||
|
||||
}// .component
|
||||
|
||||
}// .bulkUpload
|
@ -115,6 +115,25 @@
|
||||
|
||||
$.entwine('colymba', function($) {
|
||||
|
||||
/**
|
||||
* Makes sure the component is at the top :)
|
||||
*/
|
||||
$('.bulkUpload').entwine({
|
||||
onmatch: function(){
|
||||
var $tr = this.parents('thead').find('tr'),
|
||||
$component = this.clone(),
|
||||
index = $tr.index(this)
|
||||
;
|
||||
if ( index > 1 )
|
||||
{
|
||||
$component.insertAfter($tr.eq(0));
|
||||
this.remove();
|
||||
}
|
||||
},
|
||||
onunmatch: function(){}
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
* handles individual edit forms changes
|
||||
* updates buttons and visual styles
|
@ -1,6 +1,6 @@
|
||||
window.tmpl.cache['colymba-gfbiu-uploadfield-downloadtemplate'] = tmpl(
|
||||
window.tmpl.cache['colymba-bulkuploaddownloadtemplate'] = tmpl(
|
||||
'{% for (var i=0, files=o.files, l=files.length, file=files[0]; i<l; file=files[++i]) { %}' +
|
||||
'<li class="ss-uploadfield-item template-download{% if (file.error) { %} ui-state-error{% } %}" data-fileid="{%=file.id%}">' +
|
||||
'<li class="ss-uploadfield-item template-download{% if (file.error) { %} ui-state-error{% }else{ %} done{% } %}" data-fileid="{%=file.id%} data-recordid="{%=file.record.id%}">' +
|
||||
'<div class="ss-uploadfield-item-preview preview"><span>' +
|
||||
'<img src="{%=file.thumbnail_url%}" alt="" />' +
|
||||
'</span></div>' +
|
||||
@ -26,21 +26,6 @@ window.tmpl.cache['colymba-gfbiu-uploadfield-downloadtemplate'] = tmpl(
|
||||
//'<div class="ss-uploadfield-item-actions">{% print(file.buttons, true); %}</div>' +
|
||||
'{% } %}' +
|
||||
'</div>' +
|
||||
'{% if (!file.error) { %}' +
|
||||
|
||||
'<div class="ss-uploadfield-item-editform">'+
|
||||
'<form action="" method="post" class="bulkImageUploadUpdateForm" name="BIUUF_{%=file.record.ID%}">'+
|
||||
'<input type="hidden" name="record_{%=file.record.ID%}_ID" value="{%=file.record.ID%}"/>'+
|
||||
'<img class="imgPreview" src="{%=file.preview_url%}" />'+
|
||||
|
||||
'{% for (var key in file.record.fields) { %}' +
|
||||
'{%#file.record.fields[key]%}' +
|
||||
'{% } %}' +
|
||||
|
||||
'</form>'+
|
||||
'</div>' +
|
||||
|
||||
'{% } %}' +
|
||||
'</li>' +
|
||||
'{% } %}'
|
||||
);
|
15
bulkUpload/lang/cs.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
cs:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Hromadně nahrát
|
||||
FINISH_BTN_LABEL: Dokončit
|
||||
SAVE_BTN_LABEL: Uložit vše
|
||||
CANCEL_BTN_LABEL: Storno & Smazat vše
|
||||
EDIT_SELECT_LABEL: Upravit
|
||||
UNLINK_SELECT_LABEL: Odstranit vazbu
|
||||
DELETE_SELECT_LABEL: Smazat
|
||||
ACTION_BTN_LABEL: Provést
|
||||
SELECT_ALL_LABEL: Vybrat vše
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Storno
|
15
bulkUpload/lang/de.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
de:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Bulk Upload
|
||||
FINISH_BTN_LABEL: Fertigstellen
|
||||
SAVE_BTN_LABEL: Alle speichern
|
||||
CANCEL_BTN_LABEL: Abbrechen & alle löschen
|
||||
EDIT_SELECT_LABEL: Bearbeiten
|
||||
UNLINK_SELECT_LABEL: Verbindung entfernen
|
||||
DELETE_SELECT_LABEL: Löschen
|
||||
ACTION_BTN_LABEL: Los
|
||||
SELECT_ALL_LABEL: Alle auswählen
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Abbrechen
|
15
bulkUpload/lang/en.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
en:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Bulk Upload
|
||||
FINISH_BTN_LABEL: Finish
|
||||
SAVE_BTN_LABEL: Save All
|
||||
CANCEL_BTN_LABEL: Cancel & Delete All
|
||||
EDIT_SELECT_LABEL: Edit
|
||||
UNLINK_SELECT_LABEL: Unlink
|
||||
DELETE_SELECT_LABEL: Delete
|
||||
ACTION_BTN_LABEL: Go
|
||||
SELECT_ALL_LABEL: Select all
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Cancel
|
15
bulkUpload/lang/fr.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
fr:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Upload groupé
|
||||
FINISH_BTN_LABEL: Terminer
|
||||
SAVE_BTN_LABEL: Enregistrer tout
|
||||
CANCEL_BTN_LABEL: Annuler & supprimer tout
|
||||
EDIT_SELECT_LABEL: Editer
|
||||
UNLINK_SELECT_LABEL: Retirer
|
||||
DELETE_SELECT_LABEL: Supprimer
|
||||
ACTION_BTN_LABEL: Go
|
||||
SELECT_ALL_LABEL: Sélectionner tout
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Annuler
|
15
bulkUpload/lang/nl.yml
Normal file
@ -0,0 +1,15 @@
|
||||
# DO NOT MODIFY. Generated by build task.
|
||||
# Contribute here: https://www.transifex.com/projects/p/gridfieldbulkeditingtools/
|
||||
nl:
|
||||
GridFieldBulkTools:
|
||||
BULK_UPLOAD_BTN_LABEL: Bulk Upload
|
||||
FINISH_BTN_LABEL: Afronden
|
||||
SAVE_BTN_LABEL: Alles opslaan
|
||||
CANCEL_BTN_LABEL: Annuleren & alles verwijderen
|
||||
EDIT_SELECT_LABEL: Bewerken
|
||||
UNLINK_SELECT_LABEL: Loskoppelen
|
||||
DELETE_SELECT_LABEL: Verwijderen
|
||||
ACTION_BTN_LABEL: Gaan
|
||||
SELECT_ALL_LABEL: Selecteer alles
|
||||
GridFieldBulkManager:
|
||||
CANCEL_BTN_LABEL: Annuleren
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
9
bulkUpload/templates/GridFieldBulkUpload.ss
Normal file
@ -0,0 +1,9 @@
|
||||
<tr class="bulkUpload">
|
||||
<th class="component" colspan="$Colspan">
|
||||
|
||||
<div class="upload ss-upload ss-uploadfield">
|
||||
$UploadField
|
||||
</div>
|
||||
|
||||
</th>
|
||||
</tr>
|
@ -1,485 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Handles request from the GridFieldBulkImageUpload component
|
||||
*
|
||||
* Handles:
|
||||
* * Form creation
|
||||
* * file upload
|
||||
* * editing and cancelling records
|
||||
*
|
||||
* @author colymba
|
||||
* @package GridFieldBulkEditingTools
|
||||
*/
|
||||
class GridFieldBulkImageUpload_Request extends RequestHandler {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var GridField
|
||||
*/
|
||||
protected $gridField;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var GridField_URLHandler
|
||||
*/
|
||||
protected $component;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Controller
|
||||
*/
|
||||
protected $controller;
|
||||
|
||||
/**
|
||||
* Cache the records FieldList from getCMSfields()
|
||||
*
|
||||
* @var FieldList
|
||||
*/
|
||||
protected $recordCMSFieldList;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static $allowed_actions = array(
|
||||
'index', 'upload', 'update', 'cancel'
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static $url_handlers = array(
|
||||
'$Action!' => '$Action'
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param GridFIeld $gridField
|
||||
* @param GridField_URLHandler $component
|
||||
* @param Controller $controller
|
||||
*/
|
||||
public function __construct($gridField, $component, $controller) {
|
||||
$this->gridField = $gridField;
|
||||
$this->component = $component;
|
||||
$this->controller = $controller;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL for this RequestHandler
|
||||
*
|
||||
* @author SilverStripe
|
||||
* @see GridFieldDetailForm_ItemRequest
|
||||
* @param string $action
|
||||
* @return string
|
||||
*/
|
||||
public function Link($action = null) {
|
||||
return Controller::join_links($this->gridField->Link(), 'bulkimageupload', $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first has_one Image relation from the GridField managed DataObject
|
||||
* i.e. 'MyImage' => 'Image' will return 'MyImage'
|
||||
*
|
||||
* @return string Name of the $has_one relation
|
||||
*/
|
||||
function getDefaultFileRelationName()
|
||||
{
|
||||
$recordClass = $this->gridField->list->dataClass;
|
||||
$recordHasOneFields = Config::inst()->get($recordClass, 'has_one', Config::INHERITED);
|
||||
|
||||
$imageField = null;
|
||||
foreach( $recordHasOneFields as $field => $type )
|
||||
{
|
||||
if($type == 'Image' || is_subclass_of($type, 'Image')) {
|
||||
$imageField = $field;// . 'ID';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $imageField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the Image field name from the managed record
|
||||
* Either as set in the component config or the default one
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getFileRelationName()
|
||||
{
|
||||
$fieldName = $this->component->getConfig('fileRelationName');
|
||||
if ( $fieldName == null ) $fieldName = $this->getDefaultFileRelationName();
|
||||
|
||||
return $fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ClassName of the fileRelation
|
||||
* i.e. 'MyImage' => 'Image' will return 'Image'
|
||||
* i.e. 'MyImage' => 'File' will return 'File'
|
||||
*
|
||||
* @return string file relation className
|
||||
*/
|
||||
private function getFileRelationClassName()
|
||||
{
|
||||
$recordClass = $this->gridField->list->dataClass;
|
||||
$recordHasOneFields = Config::inst()->get($recordClass, 'has_one', Config::INHERITED);
|
||||
|
||||
$fieldName = $this->getFileRelationName();
|
||||
if($fieldName != null)
|
||||
{
|
||||
return $recordHasOneFields[$fieldName];
|
||||
}
|
||||
else{
|
||||
return 'File';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of editable fields from the managed record
|
||||
* Either as set in the component config or the default ones
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getRecordEditableFields()
|
||||
{
|
||||
$fields = $this->component->getConfig('editableFields');
|
||||
if ( $fields == null ) $fields = $this->getDefaultRecordEditableFields();
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $recordID
|
||||
* @return type
|
||||
*/
|
||||
function getRecordHTMLFormFields( $recordID = 0 )
|
||||
{
|
||||
$config = $this->component->getConfig();
|
||||
$recordCMSDataFields = GridFieldBulkEditingHelper::getModelCMSDataFields( $config, $this->gridField->list->dataClass );
|
||||
|
||||
//@TODO: if editableFields given use them with filterNonEditableRecordsFields()
|
||||
// otherwise go through getModelFilteredDataFields
|
||||
|
||||
|
||||
$recordCMSDataFields = GridFieldBulkEditingHelper::filterNonEditableRecordsFields($config, $recordCMSDataFields);
|
||||
|
||||
if ( $config['fileRelationName'] == null ) $config['fileRelationName'] = $this->getDefaultFileRelationName();
|
||||
|
||||
$recordCMSDataFields = GridFieldBulkEditingHelper::getModelFilteredDataFields($config, $recordCMSDataFields);
|
||||
$recordCMSDataFields = GridFieldBulkEditingHelper::populateCMSDataFields($recordCMSDataFields, $this->gridField->list->dataClass, $recordID);
|
||||
$formFieldsHTML = GridFieldBulkEditingHelper::dataFieldsToHTML($recordCMSDataFields);
|
||||
$formFieldsHTML = GridFieldBulkEditingHelper::escapeFormFieldsHTML($formFieldsHTML, $recordID);
|
||||
|
||||
return $formFieldsHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and return the bulk upload form
|
||||
*
|
||||
* @return Form
|
||||
*/
|
||||
public function uploadForm($id = null, $fields = null)
|
||||
{
|
||||
$crumbs = $this->Breadcrumbs();
|
||||
if($crumbs && $crumbs->count()>=2)
|
||||
{
|
||||
$one_level_up = $crumbs->offsetGet($crumbs->count()-2);
|
||||
$one_level_up = $one_level_up->Link;
|
||||
}
|
||||
|
||||
$actions = new FieldList();
|
||||
|
||||
$actions->push(
|
||||
FormAction::create('Finish', _t('GridFieldBulkTools.FINISH_BTN_LABEL', 'Finish'))
|
||||
->setAttribute('id', 'bulkImageUploadFinishBtn')
|
||||
->addExtraClass('cms-panel-link')
|
||||
->setAttribute('data-icon', 'accept')
|
||||
->setAttribute('href', $one_level_up)
|
||||
->setUseButtonTag(true)
|
||||
->setAttribute('src', '')//changes type to image so isn't hooked by default actions handlers
|
||||
);
|
||||
|
||||
$actions->push(
|
||||
FormAction::create('SaveAll', _t('GridFieldBulkTools.SAVE_BTN_LABEL', 'Save All'))
|
||||
->setAttribute('id', 'bulkImageUploadUpdateBtn')
|
||||
->addExtraClass('ss-ui-action-constructive')
|
||||
->setAttribute('data-icon', 'accept')
|
||||
->setAttribute('data-url', $this->Link('update'))
|
||||
->setUseButtonTag(true)
|
||||
->setAttribute('src', '')//changes type to image so isn't hooked by default actions handlers
|
||||
);
|
||||
|
||||
$actions->push(
|
||||
FormAction::create('Cancel', _t('GridFieldBulkTools.CANCEL_BTN_LABEL', 'Cancel & Delete All'))
|
||||
->setAttribute('id', 'bulkImageUploadUpdateCancelBtn')
|
||||
->addExtraClass('ss-ui-action-destructive')
|
||||
->setAttribute('data-icon', 'decline')
|
||||
->setAttribute('data-url', $this->Link('cancel'))
|
||||
->setUseButtonTag(true)
|
||||
->setAttribute('src', '')//changes type to image so isn't hooked by default actions handlers
|
||||
);
|
||||
|
||||
|
||||
/* *
|
||||
* UploadField
|
||||
*/
|
||||
$fileRelationName = $this->getFileRelationName();
|
||||
$uploadField = UploadField::create($fileRelationName, '');
|
||||
$uploadField->setConfig('previewMaxWidth', 40);
|
||||
$uploadField->setConfig('previewMaxHeight', 30);
|
||||
$uploadField->addExtraClass('ss-assetuploadfield');
|
||||
$uploadField->removeExtraClass('ss-uploadfield');
|
||||
$uploadField->setTemplate('AssetUploadField');
|
||||
|
||||
$uploadField->setDownloadTemplateName('colymba-gfbiu-uploadfield-downloadtemplate');
|
||||
|
||||
//always overwrite
|
||||
$uploadField->setOverwriteWarning(false);
|
||||
|
||||
/* *
|
||||
* UploadField configs
|
||||
*/
|
||||
//custom upload url
|
||||
$uploadField->setConfig('url', $this->Link('upload'));
|
||||
|
||||
//max file size
|
||||
$maxFileSize = $this->component->getConfig('maxFileSize');
|
||||
if ( $maxFileSize !== null )
|
||||
{
|
||||
$uploadField->getValidator()->setAllowedMaxFileSize( $maxFileSize );
|
||||
}
|
||||
|
||||
//upload dir
|
||||
$uploadDir = $this->component->getConfig('folderName');
|
||||
if ( $uploadDir !== null )
|
||||
{
|
||||
$uploadField->setFolderName($uploadDir);
|
||||
}
|
||||
|
||||
//sequential upload
|
||||
$uploadField->setConfig('sequentialUploads', $this->component->getConfig('sequentialUploads'));
|
||||
|
||||
//Create form
|
||||
$form = new Form(
|
||||
$this,
|
||||
'uploadForm',
|
||||
new FieldList(
|
||||
$uploadField
|
||||
),
|
||||
$actions
|
||||
);
|
||||
|
||||
if($one_level_up)
|
||||
{
|
||||
$form->Backlink = $one_level_up;
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default and main action that returns the upload form etc...
|
||||
*
|
||||
* @return string Form's HTML
|
||||
*/
|
||||
public function index($request)
|
||||
{
|
||||
Requirements::javascript(FRAMEWORK_DIR . '/javascript/AssetUploadField.js');
|
||||
Requirements::css(FRAMEWORK_DIR . '/css/AssetUploadField.css');
|
||||
|
||||
$form = $this->uploadForm();
|
||||
$form->setTemplate('LeftAndMain_EditForm');
|
||||
$form->addExtraClass('cms-content center LeftAndMain'); //not using cms-edit-form to avoid btn being hooked with default handlers
|
||||
$form->setAttribute('data-pjax-fragment', 'Content');
|
||||
|
||||
Requirements::javascript(THIRDPARTY_DIR . '/javascript-templates/tmpl.js');
|
||||
|
||||
Requirements::javascript(BULK_EDIT_TOOLS_PATH . '/javascript/GridFieldBulkImageUpload.js');
|
||||
Requirements::css(BULK_EDIT_TOOLS_PATH . '/css/GridFieldBulkImageUpload.css');
|
||||
Requirements::javascript(BULK_EDIT_TOOLS_PATH . '/javascript/GridFieldBulkImageUpload_downloadtemplate.js');
|
||||
Requirements::add_i18n_javascript(BULK_EDIT_TOOLS_PATH . '/javascript/lang');
|
||||
|
||||
if($request->isAjax())
|
||||
{
|
||||
$response = new SS_HTTPResponse(
|
||||
Convert::raw2json(array( 'Content' => $form->forAjaxTemplate()->getValue() ))
|
||||
);
|
||||
$response->addHeader('X-Pjax', 'Content');
|
||||
$response->addHeader('Content-Type', 'text/json');
|
||||
$response->addHeader('X-Title', 'SilverStripe - Bulk '.$this->gridField->list->dataClass.' Image Upload');
|
||||
return $response;
|
||||
}
|
||||
else {
|
||||
$controller = $this->getToplevelController();
|
||||
return $controller->customise(array( 'Content' => $form ));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse up nested requests until we reach the first that's not a GridFieldDetailForm or GridFieldDetailForm_ItemRequest.
|
||||
* The opposite of {@link Controller::curr()}, required because
|
||||
* Controller::$controller_stack is not directly accessible.
|
||||
*
|
||||
* @return Controller
|
||||
*/
|
||||
protected function getToplevelController() {
|
||||
$c = $this->controller;
|
||||
while($c && ($c instanceof GridFieldDetailForm_ItemRequest || $c instanceof GridFieldDetailForm)) {
|
||||
$c = $c->getController();
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process upload through UploadField,
|
||||
* creates new record and link newly uploaded file
|
||||
* adds record to GrifField relation list
|
||||
* and return image/file data and record edit form
|
||||
*
|
||||
* @param SS_HTTPRequest $request
|
||||
* @return string json
|
||||
*/
|
||||
public function upload(SS_HTTPRequest $request)
|
||||
{
|
||||
//create record
|
||||
$recordClass = $this->gridField->list->dataClass;
|
||||
$record = Object::create($recordClass);
|
||||
$record->write();
|
||||
|
||||
// passes the current gridfield-instance to a call-back method on the new object
|
||||
$record->extend("onBulkImageUpload", $this->gridField);
|
||||
|
||||
//get uploadField and process upload
|
||||
$fileRelationName = $this->getFileRelationName();
|
||||
$uploadField = $this->uploadForm()->Fields()->fieldByName($fileRelationName);
|
||||
$uploadField->setRecord($record);
|
||||
$uploadResponse = $uploadField->upload( $request );
|
||||
|
||||
//get uploaded File response datas
|
||||
$uploadResponse = Convert::json2array( $uploadResponse->getBody() );
|
||||
$uploadResponse = array_shift( $uploadResponse );
|
||||
|
||||
// Attach the file to record.
|
||||
$record->{"{$fileRelationName}ID"} = $uploadResponse['id'];
|
||||
$record->write();
|
||||
|
||||
// attached record to gridField relation
|
||||
$this->gridField->list->add($record->ID);
|
||||
|
||||
//get record's CMS Fields
|
||||
$recordEditableFormFields = $this->getRecordHTMLFormFields( $record->ID );
|
||||
|
||||
//fetch uploadedFile record and sort out previewURL
|
||||
//update $uploadResponse datas in case changes happened onAfterWrite()
|
||||
$uploadedFile = DataObject::get_by_id( $this->getFileRelationClassName(), $uploadResponse['id'] );
|
||||
if ( $uploadedFile )
|
||||
{
|
||||
$uploadResponse['name'] = $uploadedFile->Name;
|
||||
$uploadResponse['url'] = $uploadedFile->getURL();
|
||||
|
||||
if ( $uploadedFile instanceof Image )
|
||||
{
|
||||
$uploadResponse['preview_url'] = $uploadedFile->setHeight(55)->Link();
|
||||
$uploadResponse['thumbnail_url'] = $uploadedFile->StripThumbnail()->getURL();
|
||||
}
|
||||
else{
|
||||
$uploadResponse['preview_url'] = $uploadedFile->Icon();
|
||||
$uploadResponse['thumbnail_url'] = $uploadedFile->Icon();
|
||||
}
|
||||
}
|
||||
|
||||
// Collect all output data.
|
||||
$return = array_merge($uploadResponse, array(
|
||||
'record' => array(
|
||||
'ID' => $record->ID,
|
||||
'fields' => $recordEditableFormFields
|
||||
)
|
||||
));
|
||||
|
||||
$response = new SS_HTTPResponse(Convert::raw2json(array($return)));
|
||||
$response->addHeader('Content-Type', 'text/plain');
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a record with the newly edited fields
|
||||
*
|
||||
* @param SS_HTTPRequest $request
|
||||
* @return string
|
||||
*/
|
||||
public function update(SS_HTTPRequest $request)
|
||||
{
|
||||
$data = GridFieldBulkEditingHelper::unescapeFormFieldsPOSTData($request->requestVars());
|
||||
$record = DataObject::get_by_id($this->gridField->list->dataClass, $data['ID']);
|
||||
|
||||
foreach($data as $field => $value)
|
||||
{
|
||||
if ( $record->hasMethod($field) ) {
|
||||
$list = $record->$field();
|
||||
$list->setByIDList( $value );
|
||||
}else{
|
||||
$record->setCastedField($field, $value);
|
||||
}
|
||||
}
|
||||
$record->write();
|
||||
|
||||
return '{done:1,recordID:'.$data['ID'].'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the Image Object and File as well as the DataObject
|
||||
* according to the ID sent from the form
|
||||
*
|
||||
* @param SS_HTTPRequest $request
|
||||
* @return string json
|
||||
*/
|
||||
public function cancel(SS_HTTPRequest $request)
|
||||
{
|
||||
$data = GridFieldBulkEditingHelper::unescapeFormFieldsPOSTData($request->requestVars());
|
||||
$return = array();
|
||||
|
||||
$recordClass = $this->gridField->list->dataClass;
|
||||
$record = DataObject::get_by_id($recordClass, $data['ID']);
|
||||
|
||||
$imageField = $this->getFileRelationName();
|
||||
$imageID = $record->$imageField.'ID';
|
||||
$image = DataObject::get_by_id('Image', $imageID);
|
||||
|
||||
$return[$data['ID']]['imageID'] = $imageID;
|
||||
$return[$data['ID']]['deletedDataObject'] = DataObject::delete_by_id($recordClass, $data['ID']);
|
||||
|
||||
$return[$data['ID']]['deletedFormattedImages'] = $image->deleteFormattedImages();
|
||||
$return[$data['ID']]['deletedImageFile'] = unlink( Director::getAbsFile($image->getRelativePath()) );
|
||||
|
||||
|
||||
$response = new SS_HTTPResponse(Convert::raw2json($return));
|
||||
$response->addHeader('Content-Type', 'text/plain');
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edited version of the GridFieldEditForm function
|
||||
* adds the 'Bulk Upload' at the end of the crums
|
||||
*
|
||||
* CMS-specific functionality: Passes through navigation breadcrumbs
|
||||
* to the template, and includes the currently edited record (if any).
|
||||
* see {@link LeftAndMain->Breadcrumbs()} for details.
|
||||
*
|
||||
* @author SilverStripe original Breadcrumbs() method
|
||||
* @see GridFieldDetailForm_ItemRequest
|
||||
* @param boolean $unlinked
|
||||
* @return ArrayData
|
||||
*/
|
||||
function Breadcrumbs($unlinked = false) {
|
||||
if(!$this->controller->hasMethod('Breadcrumbs')) return;
|
||||
|
||||
$items = $this->controller->Breadcrumbs($unlinked);
|
||||
$items->push(new ArrayData(array(
|
||||
'Title' => 'Bulk Upload',
|
||||
'Link' => false
|
||||
)));
|
||||
return $items;
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/* ************************************************************************
|
||||
* GRIDFIELD
|
||||
*/
|
||||
|
||||
#bulkImageUploadGFButton
|
||||
{
|
||||
float: right;
|
||||
margin: 0 0 0 20px;
|
||||
}
|
||||
|
||||
/* ************************************************************************
|
||||
* UPLOAD
|
||||
*/
|
||||
|
||||
.ss-assetuploadfield .ss-uploadfield-files .ss-uploadfield-item-editform
|
||||
{
|
||||
position: relative;
|
||||
height: auto!important;
|
||||
display: block;
|
||||
}
|
||||
|
||||
li.ss-uploadfield-item .ss-uploadfield-item-editform
|
||||
{
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
li.ss-uploadfield-item.template-download .imgPreview
|
||||
{
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
#Form_uploadForm .ss-uploadfield-item-info.updated
|
||||
{
|
||||
background-color: #a4ca3a;
|
||||
|
||||
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #a4ca3a), color-stop(100%, #59781D));
|
||||
background-image: -webkit-linear-gradient(top, #a4ca3a 0%, #59781D 100%);
|
||||
background-image: -moz-linear-gradient(top, #a4ca3a 0%, #59781D 100%);
|
||||
background-image: -o-linear-gradient(top, #a4ca3a 0%, #59781D 100%);
|
||||
background-image: -ms-linear-gradient(top, #a4ca3a 0%, #59781D 100%);
|
||||
background-image: linear-gradient(top, #a4ca3a 0%, #59781D 100%);
|
||||
}
|
||||
|
||||
#Form_uploadForm .ss-uploadfield-item-info.dirty
|
||||
{
|
||||
background-color: #f2ba11;
|
||||
|
||||
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f2ba11), color-stop(100%, #df6e00));
|
||||
background-image: -webkit-linear-gradient(top, #f2ba11 0%, #df6e00 100%);
|
||||
background-image: -moz-linear-gradient(top, #f2ba11 0%, #df6e00 100%);
|
||||
background-image: -o-linear-gradient(top, #f2ba11 0%, #df6e00 100%);
|
||||
background-image: -ms-linear-gradient(top, #f2ba11 0%, #df6e00 100%);
|
||||
background-image: linear-gradient(top, #f2ba11 0%, #df6e00 100%);
|
||||
}
|
||||
|
||||
#Form_uploadForm .ss-uploadfield-item-status.updated
|
||||
{
|
||||
color: #3b8716;
|
||||
}
|
||||
#Form_uploadForm .ss-uploadfield-item-status.dirty
|
||||
{
|
||||
color: #f25000;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
<a id="bulkImageUploadGFButton" href="$Link" class="cms-panel-link ss-ui-action-constructive ss-ui-button" data-icon="drive-upload">
|
||||
<%t GridFieldBulkTools.BULK_UPLOAD_BTN_LABEL "Bulk Upload" %>
|
||||
</a>
|