From e2b15ad30cf6809673b5ab8f1de2e7d522a638cc Mon Sep 17 00:00:00 2001 From: Thierry Francois Date: Sun, 4 May 2014 16:24:30 +0300 Subject: [PATCH] Refactor edit forms generation process --- .../code/GridFieldBulkActionEditHandler.php | 120 ++++++-- .../code/GridFieldBulkEditingHelper.php | 261 ------------------ bulkManager/code/GridFieldBulkManager.php | 36 +-- 3 files changed, 118 insertions(+), 299 deletions(-) delete mode 100644 bulkManager/code/GridFieldBulkEditingHelper.php diff --git a/bulkManager/code/GridFieldBulkActionEditHandler.php b/bulkManager/code/GridFieldBulkActionEditHandler.php index 2de85da..2c5b2dc 100644 --- a/bulkManager/code/GridFieldBulkActionEditHandler.php +++ b/bulkManager/code/GridFieldBulkActionEditHandler.php @@ -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. * - * @return form Selected DataObject editable fields + * @return Form Selected DataObjects editable fields */ public function editForm() { @@ -84,25 +84,19 @@ class GridFieldBulkActionEditHandler extends GridFieldBulkActionHandler 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 ); - $recordCMSDataFields = GridFieldBulkEditingHelper::getModelFilteredDataFields($config, $recordCMSDataFields); - $recordCMSDataFields = GridFieldBulkEditingHelper::populateCMSDataFields( $recordCMSDataFields, $this->gridField->list->dataClass, $id ); - - //$recordCMSDataFields['ID'] = new HiddenField('ID', '', $id); - $recordCMSDataFields = GridFieldBulkEditingHelper::escapeFormFieldsName( $recordCMSDataFields, $id ); - - $recordsFieldList->push( - ToggleCompositeField::create( - 'RecordFields_'.$id, - $record->getTitle(), - array_values($recordCMSDataFields) - ) - ->setHeadingLevel(4) - ->setAttribute('data-id', $id) - ->addExtraClass('bulkEditingFieldHolder') - ); + $toggleField = ToggleCompositeField::create( + 'RecordFields_'.$id, + $record->getTitle(), + $recordEditingFields + ) + ->setHeadingLevel(4) + ->setAttribute('data-id', $id) + ->addExtraClass('bulkEditingFieldHolder'); + + $recordsFieldList->push($toggleField); } $form = new Form( @@ -118,6 +112,92 @@ class GridFieldBulkActionEditHandler extends GridFieldBulkActionHandler 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; + } /** diff --git a/bulkManager/code/GridFieldBulkEditingHelper.php b/bulkManager/code/GridFieldBulkEditingHelper.php deleted file mode 100644 index ed00fdb..0000000 --- a/bulkManager/code/GridFieldBulkEditingHelper.php +++ /dev/null @@ -1,261 +0,0 @@ -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; - } - - -} \ No newline at end of file diff --git a/bulkManager/code/GridFieldBulkManager.php b/bulkManager/code/GridFieldBulkManager.php index daf4775..96d1fc3 100644 --- a/bulkManager/code/GridFieldBulkManager.php +++ b/bulkManager/code/GridFieldBulkManager.php @@ -12,17 +12,17 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr * * 'imageFieldName' => field name of the $has_one Model Image relation * '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 * 'actions' => maps of action name and configuration * * @var array */ protected $config = array( - 'editableFields' => null, - 'fieldsClassBlacklist' => array(), - 'fieldsNameBlacklist' => array(), - 'actions' => array() + 'editableFields' => null, + 'fieldsNameBlacklist' => array(), + 'readOnlyFieldClasses' => 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 * These cannot be removed from the blacklist */ - protected $forbiddenFieldsClasses = array( 'GridField', 'UploadField' ); + protected $readOnlyFieldClasses = array('GridField', 'UploadField'); public function __construct($editableFields = null, $defaultActions = true) { if ( $editableFields != null ) $this->setConfig ( 'editableFields', $editableFields ); - $this->config['fieldsClassBlacklist'] = $this->forbiddenFieldsClasses; + $this->config['readOnlyFieldClasses'] = $this->readOnlyFieldClasses; 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 mixed $value */ - function setConfig ( $reference, $value ) + function setConfig($reference, $value) { 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); } - if ( ($reference == 'fieldsClassBlacklist' || $reference == 'fieldsClassBlacklist' || $reference == 'editableFields') && !is_array($value) ) + if ( ($reference == 'readOnlyFieldClasses' || $reference == 'fieldsNameBlacklist' || $reference == 'editableFields') && !is_array($value) ) { $value = array($value); } - //makes sure $forbiddenFieldsClasses are in no matter what - if ( $reference == 'fieldsClassBlacklist' ) + //makes sure $readOnlyFieldClasses are in no matter what + if ( $reference == 'readOnlyFieldClasses' ) { - $value = array_unique( array_merge($value, $this->forbiddenFieldsClasses) ); + $value = array_unique( array_merge($value, $this->readOnlyFieldClasses) ); } $this->config[$reference] = $value; @@ -135,9 +135,9 @@ class GridFieldBulkManager implements GridField_HTMLProvider, GridField_ColumnPr * @param string $className * @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 * @return boolean */ - function removeClassFromBlacklist ( $className ) + function removeClassFromReadOnlyList ( $className ) { - if (key_exists($className, $this->config['fieldsNameBlacklist']) && !in_array($className, $this->forbiddenFieldsClasses)) { - return delete( $this->config['fieldsNameBlacklist'][$className] ); + if (key_exists($className, $this->config['readOnlyFieldClasses']) && !in_array($className, $this->forbiddenFieldsClasses)) { + return delete( $this->config['readOnlyFieldClasses'][$className] ); }else{ return false; }