mirror of
https://github.com/colymba/GridFieldBulkEditingTools.git
synced 2024-10-22 11:05:57 +02:00
Refactor edit forms generation process
This commit is contained in:
parent
4a17d7d74a
commit
e2b15ad30c
@ -23,10 +23,10 @@ class GridFieldBulkActionEditHandler extends GridFieldBulkActionHandler
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a form for all the selected DataObject
|
* Return a form for all the selected DataObjects
|
||||||
* with their respective editable fields.
|
* with their respective editable fields.
|
||||||
*
|
*
|
||||||
* @return form Selected DataObject editable fields
|
* @return Form Selected DataObjects editable fields
|
||||||
*/
|
*/
|
||||||
public function editForm()
|
public function editForm()
|
||||||
{
|
{
|
||||||
@ -84,25 +84,19 @@ class GridFieldBulkActionEditHandler extends GridFieldBulkActionHandler
|
|||||||
|
|
||||||
foreach ( $recordList as $id )
|
foreach ( $recordList as $id )
|
||||||
{
|
{
|
||||||
$record = DataObject::get_by_id($modelClass, $id);
|
$record = DataObject::get_by_id($modelClass, $id);
|
||||||
|
$recordEditingFields = $this->getRecordEditingFields($record);
|
||||||
|
|
||||||
$recordCMSDataFields = GridFieldBulkEditingHelper::getModelCMSDataFields( $config, $this->gridField->list->dataClass );
|
$toggleField = ToggleCompositeField::create(
|
||||||
$recordCMSDataFields = GridFieldBulkEditingHelper::getModelFilteredDataFields($config, $recordCMSDataFields);
|
'RecordFields_'.$id,
|
||||||
$recordCMSDataFields = GridFieldBulkEditingHelper::populateCMSDataFields( $recordCMSDataFields, $this->gridField->list->dataClass, $id );
|
$record->getTitle(),
|
||||||
|
$recordEditingFields
|
||||||
//$recordCMSDataFields['ID'] = new HiddenField('ID', '', $id);
|
)
|
||||||
$recordCMSDataFields = GridFieldBulkEditingHelper::escapeFormFieldsName( $recordCMSDataFields, $id );
|
->setHeadingLevel(4)
|
||||||
|
->setAttribute('data-id', $id)
|
||||||
$recordsFieldList->push(
|
->addExtraClass('bulkEditingFieldHolder');
|
||||||
ToggleCompositeField::create(
|
|
||||||
'RecordFields_'.$id,
|
$recordsFieldList->push($toggleField);
|
||||||
$record->getTitle(),
|
|
||||||
array_values($recordCMSDataFields)
|
|
||||||
)
|
|
||||||
->setHeadingLevel(4)
|
|
||||||
->setAttribute('data-id', $id)
|
|
||||||
->addExtraClass('bulkEditingFieldHolder')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$form = new Form(
|
$form = new Form(
|
||||||
@ -118,6 +112,92 @@ class GridFieldBulkActionEditHandler extends GridFieldBulkActionHandler
|
|||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a record's populated form fields
|
||||||
|
* with all filtering done ready to be included in the main form
|
||||||
|
*
|
||||||
|
* @uses DataObject::getCMSFields()
|
||||||
|
*
|
||||||
|
* @param DataObject $record The record to get the fields from
|
||||||
|
* @return array The record's editable fields
|
||||||
|
*/
|
||||||
|
private function getRecordEditingFields(DataObject $record)
|
||||||
|
{
|
||||||
|
$tempForm = Form::create(
|
||||||
|
$this, "TempEditForm",
|
||||||
|
$record->getCMSFields(),
|
||||||
|
FieldList::create()
|
||||||
|
);
|
||||||
|
|
||||||
|
$tempForm->loadDataFrom($record);
|
||||||
|
$fields = $tempForm->Fields();
|
||||||
|
|
||||||
|
$fields = $this->filterRecordEditingFields($fields, $record->ID);
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters a records editable fields
|
||||||
|
* based on component's config
|
||||||
|
* and escape each field with unique name.
|
||||||
|
*
|
||||||
|
* See {@link GridFieldBulkManager} component for filtering config.
|
||||||
|
*
|
||||||
|
* @param FieldList $fields Record's CMS Fields
|
||||||
|
* @param integer $id Record's ID, used fir unique name
|
||||||
|
* @return array Filtered record's fields
|
||||||
|
*/
|
||||||
|
private function filterRecordEditingFields(FieldList $fields, $id)
|
||||||
|
{
|
||||||
|
$config = $this->component->getConfig();
|
||||||
|
$editableFields = $config['editableFields'];
|
||||||
|
$fieldsNameBlacklist = $config['fieldsNameBlacklist'];
|
||||||
|
$readOnlyClasses = $config['readOnlyFieldClasses'];
|
||||||
|
|
||||||
|
// get all dataFields or just the ones allowed in config
|
||||||
|
if ( $editableFields )
|
||||||
|
{
|
||||||
|
$dataFields = array();
|
||||||
|
|
||||||
|
foreach ($editableFields as $fieldName)
|
||||||
|
{
|
||||||
|
array_push(
|
||||||
|
$dataFields,
|
||||||
|
$fields->dataFieldByName($fieldName)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$dataFields = $fields->dataFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove and/or set readonly fields in blacklists
|
||||||
|
foreach ($dataFields as $name => $field)
|
||||||
|
{
|
||||||
|
if ( in_array($name, $fieldsNameBlacklist) )
|
||||||
|
{
|
||||||
|
unset( $dataFields[$name] );
|
||||||
|
}
|
||||||
|
else if ( in_array(get_class($field), $readOnlyClasses) )
|
||||||
|
{
|
||||||
|
$newField = $field->performReadonlyTransformation();
|
||||||
|
$dataFields[$name] = $newField;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// escape field names with unique prefix
|
||||||
|
foreach ( $dataFields as $name => $field )
|
||||||
|
{
|
||||||
|
$field->Name = 'record_' . $id . '_' . $name;
|
||||||
|
$dataFields[$name] = $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dataFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,261 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Generic helper class for the various bulk editing component
|
|
||||||
* contains common functions
|
|
||||||
*
|
|
||||||
* @todo clean up functions names: makes them consistent and more explicit
|
|
||||||
*
|
|
||||||
* @author colymba
|
|
||||||
* @package GridFieldBulkEditingTools
|
|
||||||
*/
|
|
||||||
class GridFieldBulkEditingHelper {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all or allowed Form Fields for editing
|
|
||||||
*
|
|
||||||
* @param type $config
|
|
||||||
* @param type $modelClass
|
|
||||||
* @param type $recordID
|
|
||||||
* @return type
|
|
||||||
*/
|
|
||||||
public static function getModelCMSDataFields ( $config, $modelClass )
|
|
||||||
{
|
|
||||||
$cmsFields = singleton($modelClass)->getCMSFields();
|
|
||||||
|
|
||||||
$cmsDataFields = $cmsFields->dataFields();
|
|
||||||
$cmsDataFields = GridFieldBulkEditingHelper::filterNonEditableRecordsFields($config, $cmsDataFields);
|
|
||||||
|
|
||||||
return $cmsDataFields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Populate the FomFields with a given record's value
|
|
||||||
*
|
|
||||||
* @TODO: UploadField get populated OK, however, file recovery and controllers URL are all wrong and should be updated manually
|
|
||||||
* UploadField url should point to GridFieldBulkManager_Request appropriate method
|
|
||||||
*
|
|
||||||
* @param type $cmsDataFields
|
|
||||||
* @param type $modelClass
|
|
||||||
* @param type $recordID
|
|
||||||
* @return type
|
|
||||||
*/
|
|
||||||
public static function populateCMSDataFields ( $cmsDataFields, $modelClass, $recordID )
|
|
||||||
{
|
|
||||||
$record = DataObject::get_by_id($modelClass, $recordID);
|
|
||||||
|
|
||||||
$recordComponents = array(
|
|
||||||
'one' => $record->has_one(),
|
|
||||||
'many' => $record->has_many(),
|
|
||||||
'manymany' => $record->many_many()
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ( $cmsDataFields as $name => $f )
|
|
||||||
{
|
|
||||||
if ( array_key_exists($name, $recordComponents['one']) )
|
|
||||||
{
|
|
||||||
$obj = $record->{$name}();
|
|
||||||
switch ( get_class($f) )
|
|
||||||
{
|
|
||||||
case 'UploadField':
|
|
||||||
$cmsDataFields[$name]->setRecord($record);
|
|
||||||
$cmsDataFields[$name]->setItems( DataList::create($obj->ClassName)->byID($obj->ID) );
|
|
||||||
print_r($cmsDataFields[$name]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$cmsDataFields[$name]->setValue( $obj->ID );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if ( array_key_exists($name, $recordComponents['many']) || array_key_exists($name, $recordComponents['manymany']) )
|
|
||||||
{
|
|
||||||
$list = $record->{$name}();
|
|
||||||
switch ( get_class($f) )
|
|
||||||
{
|
|
||||||
case 'UploadField':
|
|
||||||
$cmsDataFields[$name]->setRecord($record);
|
|
||||||
$cmsDataFields[$name]->setItems($list);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'DropdownField':
|
|
||||||
case 'ListboxField':
|
|
||||||
$cmsDataFields[$name]->setValue( array_values($list->getIDList()) );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
|
||||||
$cmsDataFields[$name]->setValue( $record->getField($name) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $cmsDataFields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all the fields that were not explicitly specified as editable via the $config
|
|
||||||
*
|
|
||||||
* @param type $config
|
|
||||||
* @param type $dataFields
|
|
||||||
* @return type
|
|
||||||
*/
|
|
||||||
public static function filterNonEditableRecordsFields ( $config, $dataFields )
|
|
||||||
{
|
|
||||||
if ( isset($config['editableFields']) )
|
|
||||||
{
|
|
||||||
if ( $config['editableFields'] != null )
|
|
||||||
{
|
|
||||||
foreach ($dataFields as $name => $field)
|
|
||||||
{
|
|
||||||
if ( !in_array($name, $config['editableFields']) )
|
|
||||||
{
|
|
||||||
unset( $dataFields[$name] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $dataFields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filters out all unwanted fields from the config settings
|
|
||||||
*
|
|
||||||
* @param array $config
|
|
||||||
* @param array $dataFields
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function getModelFilteredDataFields ( $config, $dataFields )
|
|
||||||
{
|
|
||||||
//remove the image field - for bulk image upload
|
|
||||||
if ( isset($config['imageFieldName']) )
|
|
||||||
{
|
|
||||||
if ( $config['imageFieldName'] != null )
|
|
||||||
{
|
|
||||||
unset( $dataFields[ substr($config['imageFieldName'], 0, -2) ] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if class blacklist filter
|
|
||||||
if ( count($config['fieldsClassBlacklist']) > 0 )
|
|
||||||
{
|
|
||||||
foreach ($dataFields as $fieldName => $field)
|
|
||||||
{
|
|
||||||
if ( in_array(get_class($field), $config['fieldsClassBlacklist']) )
|
|
||||||
{
|
|
||||||
array_push($config['fieldsNameBlacklist'], $fieldName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if name blacklist filter
|
|
||||||
if ( count($config['fieldsNameBlacklist']) > 0 )
|
|
||||||
{
|
|
||||||
foreach ( $config['fieldsNameBlacklist'] as $badFieldName )
|
|
||||||
{
|
|
||||||
unset( $dataFields[ $badFieldName ] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $dataFields;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function filterDatafieldsByClass ( $config, $dataFields )
|
|
||||||
{
|
|
||||||
//@todo
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function filterDataFieldsByName ( $config, $dataFields )
|
|
||||||
{
|
|
||||||
//@todo
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a list of DataFields into a list of their repective HTML
|
|
||||||
*
|
|
||||||
* @param type $dataFields
|
|
||||||
* @return type
|
|
||||||
*/
|
|
||||||
public static function dataFieldsToHTML ( $dataFields )
|
|
||||||
{
|
|
||||||
$fieldsHTML = array();
|
|
||||||
|
|
||||||
foreach ( $dataFields as $key => $field )
|
|
||||||
{
|
|
||||||
//@TODO: FieldHolder() does not seem to exist on UploadField
|
|
||||||
$fieldsHTML[$key] = $field->FieldHolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $fieldsHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Escape form fields name with a $unique token
|
|
||||||
* avoid having an ID URLParams sent through and cought as a pageID
|
|
||||||
*
|
|
||||||
* @param type $formFields
|
|
||||||
* @param type $unique
|
|
||||||
* @return type
|
|
||||||
*/
|
|
||||||
public static function escapeFormFieldsName ( $formFields, $unique )
|
|
||||||
{
|
|
||||||
$prefix = 'record_'.$unique.'_';
|
|
||||||
|
|
||||||
foreach ( $formFields as $name => $f )
|
|
||||||
{
|
|
||||||
$f->Name = $prefix . $f->Name;
|
|
||||||
$formFields[$name] = $f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $formFields;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Escape HTML form node names with a $unique token
|
|
||||||
* avoid having an ID URLParams sent through and cought as a pageID
|
|
||||||
*
|
|
||||||
* @param type $formFieldsHTML
|
|
||||||
* @param type $unique
|
|
||||||
* @return type
|
|
||||||
*/
|
|
||||||
public static function escapeFormFieldsHTML ( $formFieldsHTML, $unique )
|
|
||||||
{
|
|
||||||
$prefix = 'record_'.$unique.'_';
|
|
||||||
|
|
||||||
foreach ( $formFieldsHTML as $name => $html )
|
|
||||||
{
|
|
||||||
$formFieldsHTML[$name] = str_ireplace ( array('id="', 'for="', 'name="'),
|
|
||||||
array('id="'.$prefix, 'for="'.$prefix, 'name="'.$prefix),
|
|
||||||
$html);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $formFieldsHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple function that replace the 'record_XX_' off of the ID field name
|
|
||||||
* prefix needed since it was taken for a pageID if sent as is as well as fixing other things
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function unescapeFormFieldsPOSTData ( $requestVars )
|
|
||||||
{
|
|
||||||
$return = array();
|
|
||||||
|
|
||||||
foreach( $requestVars as $key => $val)
|
|
||||||
{
|
|
||||||
$return[ preg_replace( '/record_(\d+)_(\w+)/i', '$2', $key) ] = $val;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isset($return['url']) ) unset($return['url']);
|
|
||||||
if ( isset($return['cacheBuster']) ) unset($return['cacheBuster']);
|
|
||||||
|
|
||||||
return $return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -12,17 +12,17 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
|
|||||||
*
|
*
|
||||||
* 'imageFieldName' => field name of the $has_one Model Image relation
|
* 'imageFieldName' => field name of the $has_one Model Image relation
|
||||||
* 'editableFields' => fields editable on the Model
|
* 'editableFields' => fields editable on the Model
|
||||||
* 'fieldsClassBlacklist' => field types that will be removed from the automatic form generation
|
* 'readOnlyFieldClasses' => field types that will be converted to readonly
|
||||||
* 'fieldsNameBlacklist' => fields that will be removed from the automatic form generation
|
* 'fieldsNameBlacklist' => fields that will be removed from the automatic form generation
|
||||||
* 'actions' => maps of action name and configuration
|
* 'actions' => maps of action name and configuration
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $config = array(
|
protected $config = array(
|
||||||
'editableFields' => null,
|
'editableFields' => null,
|
||||||
'fieldsClassBlacklist' => array(),
|
'fieldsNameBlacklist' => array(),
|
||||||
'fieldsNameBlacklist' => array(),
|
'readOnlyFieldClasses' => array(),
|
||||||
'actions' => array()
|
'actions' => array()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -30,13 +30,13 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
|
|||||||
* Holds any class that should not be used as they break the component
|
* Holds any class that should not be used as they break the component
|
||||||
* These cannot be removed from the blacklist
|
* These cannot be removed from the blacklist
|
||||||
*/
|
*/
|
||||||
protected $forbiddenFieldsClasses = array( 'GridField', 'UploadField' );
|
protected $readOnlyFieldClasses = array('GridField', 'UploadField');
|
||||||
|
|
||||||
|
|
||||||
public function __construct($editableFields = null, $defaultActions = true)
|
public function __construct($editableFields = null, $defaultActions = true)
|
||||||
{
|
{
|
||||||
if ( $editableFields != null ) $this->setConfig ( 'editableFields', $editableFields );
|
if ( $editableFields != null ) $this->setConfig ( 'editableFields', $editableFields );
|
||||||
$this->config['fieldsClassBlacklist'] = $this->forbiddenFieldsClasses;
|
$this->config['readOnlyFieldClasses'] = $this->readOnlyFieldClasses;
|
||||||
|
|
||||||
if ( $defaultActions )
|
if ( $defaultActions )
|
||||||
{
|
{
|
||||||
@ -73,12 +73,12 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a component configuration parameter
|
* Sets the component configuration parameter
|
||||||
*
|
*
|
||||||
* @param string $reference
|
* @param string $reference
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*/
|
*/
|
||||||
function setConfig ( $reference, $value )
|
function setConfig($reference, $value)
|
||||||
{
|
{
|
||||||
if (!key_exists($reference, $this->config) )
|
if (!key_exists($reference, $this->config) )
|
||||||
{
|
{
|
||||||
@ -90,15 +90,15 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
|
|||||||
user_error("Bulk actions must be edited via addBulkAction() and removeBulkAction()", E_USER_ERROR);
|
user_error("Bulk actions must be edited via addBulkAction() and removeBulkAction()", E_USER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ($reference == 'fieldsClassBlacklist' || $reference == 'fieldsClassBlacklist' || $reference == 'editableFields') && !is_array($value) )
|
if ( ($reference == 'readOnlyFieldClasses' || $reference == 'fieldsNameBlacklist' || $reference == 'editableFields') && !is_array($value) )
|
||||||
{
|
{
|
||||||
$value = array($value);
|
$value = array($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
//makes sure $forbiddenFieldsClasses are in no matter what
|
//makes sure $readOnlyFieldClasses are in no matter what
|
||||||
if ( $reference == 'fieldsClassBlacklist' )
|
if ( $reference == 'readOnlyFieldClasses' )
|
||||||
{
|
{
|
||||||
$value = array_unique( array_merge($value, $this->forbiddenFieldsClasses) );
|
$value = array_unique( array_merge($value, $this->readOnlyFieldClasses) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->config[$reference] = $value;
|
$this->config[$reference] = $value;
|
||||||
@ -135,9 +135,9 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
|
|||||||
* @param string $className
|
* @param string $className
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function addClassToBlacklist ( $className )
|
function addClassToReadOnlyList ( $className )
|
||||||
{
|
{
|
||||||
return array_push( $this->config['fieldsClassBlacklist'], $className);
|
return array_push( $this->config['readOnlyFieldClasses'], $className);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -161,10 +161,10 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr
|
|||||||
* @param string $className
|
* @param string $className
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function removeClassFromBlacklist ( $className )
|
function removeClassFromReadOnlyList ( $className )
|
||||||
{
|
{
|
||||||
if (key_exists($className, $this->config['fieldsNameBlacklist']) && !in_array($className, $this->forbiddenFieldsClasses)) {
|
if (key_exists($className, $this->config['readOnlyFieldClasses']) && !in_array($className, $this->forbiddenFieldsClasses)) {
|
||||||
return delete( $this->config['fieldsNameBlacklist'][$className] );
|
return delete( $this->config['readOnlyFieldClasses'][$className] );
|
||||||
}else{
|
}else{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user