mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merged [47044]: Introduces modifications to Sapphire's form handling that allows it to ignore fields marked as Disabled when saving the contents of a form's fields to a DataObject.
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@60469 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
0bd9bc4ff8
commit
130ecfe5aa
@ -32,6 +32,12 @@ class DataObject extends ViewableData implements DataObjectInterface {
|
||||
*/
|
||||
protected $components;
|
||||
|
||||
/**
|
||||
* DEPRECATED
|
||||
*
|
||||
* @var array List of fields and their old values before the last write.
|
||||
*/
|
||||
protected $lastWriteFields;
|
||||
|
||||
/**
|
||||
* True if this DataObject has been destroyed.
|
||||
@ -58,7 +64,6 @@ class DataObject extends ViewableData implements DataObjectInterface {
|
||||
*/
|
||||
static $api_access = false;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new DataObject.
|
||||
*
|
||||
|
@ -5,6 +5,9 @@
|
||||
* @subpackage fields-basic
|
||||
*/
|
||||
class CheckboxFieldDisabled extends CheckboxField {
|
||||
|
||||
protected $disabled = true;
|
||||
|
||||
/**
|
||||
* Returns a single checkbox field - used by templates.
|
||||
*/
|
||||
|
@ -148,6 +148,11 @@ class CheckboxSetField extends OptionsetField {
|
||||
}
|
||||
}
|
||||
|
||||
function performDisabledTransformation() {
|
||||
$this->setDisabled(true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a pretty readonly field
|
||||
*/
|
||||
|
@ -148,10 +148,14 @@ JS;
|
||||
* @subpackage fields-datetime
|
||||
*/
|
||||
class CompositeDateField_Disabled extends DateField {
|
||||
|
||||
protected $disabled = true;
|
||||
|
||||
function setValue($val) {
|
||||
if($val && $val != "0000-00-00") $this->value = date('d/m/Y', strtotime($val));
|
||||
else $this->value = _t('Form.DATENOTSET', "(No date set)");
|
||||
}
|
||||
|
||||
function Field() {
|
||||
if($this->value) {
|
||||
$df = new Date($this->name);
|
||||
@ -163,6 +167,7 @@ class CompositeDateField_Disabled extends DateField {
|
||||
|
||||
return "<span class=\"readonly\" id=\"" . $this->id() . "\">$val</span>";
|
||||
}
|
||||
|
||||
function Type() {
|
||||
return "date_disabled readonly";
|
||||
}
|
||||
|
@ -100,11 +100,16 @@ class CompositeField extends FormField {
|
||||
* Add all of the non-composite fields contained within this field to the list.
|
||||
* Sequentialisation is used when connecting the form to its data source
|
||||
*/
|
||||
public function collateDataFields(&$list) {
|
||||
public function collateDataFields(&$list, $saveableOnly = false) {
|
||||
foreach($this->children as $field) {
|
||||
if(is_object($field)) {
|
||||
if($field->isComposite()) $field->collateDataFields($list);
|
||||
if($field->hasData()) {
|
||||
if($field->isComposite()) $field->collateDataFields($list, $saveableOnly);
|
||||
if($saveableOnly) {
|
||||
$isIncluded = ($field->hasData() && !$field->isReadonly() && !$field->isDisabled());
|
||||
} else {
|
||||
$isIncluded = ($field->hasData());
|
||||
}
|
||||
if($isIncluded) {
|
||||
$name = $field->Name();
|
||||
if($name) {
|
||||
$formName = (isset($this->form)) ? $this->form->FormName() : '(unknown form)';
|
||||
|
@ -30,6 +30,7 @@ class DateField extends TextField {
|
||||
function performReadonlyTransformation() {
|
||||
$field = new DateField_Disabled($this->name, $this->title, $this->value);
|
||||
$field->setForm($this->form);
|
||||
$field->readonly = true;
|
||||
return $field;
|
||||
}
|
||||
|
||||
@ -90,6 +91,8 @@ JS;
|
||||
*/
|
||||
class DateField_Disabled extends DateField {
|
||||
|
||||
protected $disabled = true;
|
||||
|
||||
function setValue($val) {
|
||||
if($val && $val != "0000-00-00") $this->value = date('d/m/Y', strtotime($val));
|
||||
else $this->value = '('._t('DateField.NODATESET', 'No date set').')';
|
||||
|
@ -68,6 +68,7 @@ class DropdownField extends FormField {
|
||||
$field = new LookupField($this->name, $this->title, $this->source);
|
||||
$field->setValue($this->value);
|
||||
$field->setForm($this->form);
|
||||
$field->setReadonly(true);
|
||||
return $field;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ class FieldSet extends DataObjectSet {
|
||||
* @var array
|
||||
*/
|
||||
protected $sequentialSet;
|
||||
protected $sequentialSaveableSet;
|
||||
|
||||
/**
|
||||
* Return a sequential set of all fields that have data. This excludes wrapper composite fields
|
||||
@ -24,12 +25,22 @@ class FieldSet extends DataObjectSet {
|
||||
if(!$this->sequentialSet) $this->collateDataFields($this->sequentialSet);
|
||||
return $this->sequentialSet;
|
||||
}
|
||||
|
||||
protected function collateDataFields(&$list) {
|
||||
|
||||
public function saveableFields() {
|
||||
if(!$this->sequentialSaveableSet) $this->collateDataFields($this->sequentialSaveableSet, true);
|
||||
return $this->sequentialSaveableSet;
|
||||
}
|
||||
|
||||
protected function collateDataFields(&$list, $saveableOnly = false) {
|
||||
foreach($this as $field) {
|
||||
if($field->isComposite()) $field->collateDataFields($list, $saveableOnly);
|
||||
|
||||
if($field->isComposite()) $field->collateDataFields($list);
|
||||
if($field->hasData()) {
|
||||
if($saveableOnly) {
|
||||
$isIncluded = ($field->hasData() && !$field->isReadonly() && !$field->isDisabled());
|
||||
} else {
|
||||
$isIncluded = ($field->hasData());
|
||||
}
|
||||
if($isIncluded) {
|
||||
$name = $field->Name();
|
||||
if(isset($list[$name])) {
|
||||
$errSuffix = "";
|
||||
|
@ -739,7 +739,7 @@ class Form extends RequestHandlingData {
|
||||
* It will make use of setCastedField() to do this.
|
||||
*/
|
||||
function saveInto(DataObjectInterface $dataObject) {
|
||||
$dataFields = $this->fields->dataFields();
|
||||
$dataFields = $this->fields->saveableFields();
|
||||
$lastField = null;
|
||||
|
||||
if($dataFields) foreach($dataFields as $field) {
|
||||
|
@ -69,6 +69,7 @@ class FormAction extends FormField {
|
||||
* Globally disabled buttons would break the CMS.
|
||||
*/
|
||||
function performReadonlyTransformation() {
|
||||
$this->setDisabled(true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,16 @@ class FormField extends RequestHandlingData {
|
||||
*/
|
||||
protected $tabIndex;
|
||||
|
||||
/**
|
||||
* @var $readonly boolean
|
||||
*/
|
||||
protected $readonly = false;
|
||||
|
||||
/**
|
||||
* @var $disabled boolean
|
||||
*/
|
||||
protected $disabled = false;
|
||||
|
||||
/**
|
||||
* Create a new field.
|
||||
* @param name The internal field name, passed to forms.
|
||||
@ -352,8 +362,36 @@ HTML;
|
||||
*/
|
||||
function hasData() { return true; }
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
function isReadonly() {
|
||||
return !in_array($this->class, array("ReadonlyField","FormField","LookupField"));
|
||||
return $this->readonly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets readonly-flag on form-field. Please use performReadonlyTransformation()
|
||||
* to actually transform this instance.
|
||||
* @param $bool boolean Setting "false" has no effect on the field-state.
|
||||
*/
|
||||
function setReadonly($bool) {
|
||||
$this->readonly = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
function isDisabled() {
|
||||
return $this->disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets disabed-flag on form-field. Please use performDisabledTransformation()
|
||||
* to actually transform this instance.
|
||||
* @param $bool boolean Setting "false" has no effect on the field-state.
|
||||
*/
|
||||
function setDisabled($bool) {
|
||||
$this->disabled = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,7 @@ class HiddenField extends FormField {
|
||||
return $this->Field();
|
||||
}
|
||||
function performReadonlyTransformation() {
|
||||
$this->setReadonly(true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,9 @@ class InlineFormAction extends FormField {
|
||||
* @subpackage actions
|
||||
*/
|
||||
class InlineFormAction_ReadOnly extends FormField {
|
||||
|
||||
protected $readonly = true;
|
||||
|
||||
function Field() {
|
||||
return "<input type=\"submit\" name=\"action_{$this->name}\" value=\"{$this->title}\" id=\"{$this->id()}\" disabled=\"disabled\" class=\"action$extraClass\" />";
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ class LiteralField extends DatalessField {
|
||||
}
|
||||
|
||||
function performReadonlyTransformation() {
|
||||
$this->setReadonly(true);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
*/
|
||||
class LookupField extends DropdownField {
|
||||
|
||||
protected $readonly = true;
|
||||
|
||||
/**
|
||||
* Returns a readonly span containing the correct value.
|
||||
*/
|
||||
@ -40,9 +42,11 @@ class LookupField extends DropdownField {
|
||||
"\">$mappedValue</span><input type=\"hidden\" name=\"" . $this->name .
|
||||
"\" value=\"" . $valforInput . "\" />";
|
||||
}
|
||||
|
||||
function performReadonlyTransformation() {
|
||||
return $this;
|
||||
}
|
||||
|
||||
function Type() {
|
||||
return "lookup readonly";
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ class OptionsetField extends DropdownField {
|
||||
$items = $this->source;
|
||||
$field = new LookupField($this->name,$this->title ? $this->title : "" ,$items,$this->value);
|
||||
$field->setForm($this->form);
|
||||
$field->setReadonly(true);
|
||||
return $field;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ class PasswordField extends FormField {
|
||||
|
||||
$field = new ReadonlyField($this->name, $this->title ? $this->title : '', $stars);
|
||||
$field->setForm($this->form);
|
||||
$field->setReadonly(true);
|
||||
return $field;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@
|
||||
*/
|
||||
class ReadonlyField extends FormField {
|
||||
|
||||
protected $readonly = true;
|
||||
|
||||
function performReadonlyTransformation() {
|
||||
return $this;
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ class SimpleImageField extends FileField {
|
||||
function performReadonlyTransformation() {
|
||||
$field = new SimpleImageField_Disabled($this->name, $this->title, $this->value);
|
||||
$field->setForm($this->form);
|
||||
$field->setReadonly(true);
|
||||
return $field;
|
||||
}
|
||||
}
|
||||
|
@ -311,11 +311,13 @@ class TableField extends TableListField {
|
||||
|
||||
function performReadonlyTransformation() {
|
||||
$this->permissions = array('show');
|
||||
$this->setReadonly(true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
function performDisabledTransformation() {
|
||||
$this->permissions = array('show');
|
||||
$this->setDisabled(true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -488,8 +488,8 @@ JS
|
||||
function performReadonlyTransformation() {
|
||||
$this->setShowPagination(false);
|
||||
$this->setPermissions(array('show'));
|
||||
$this->IsReadOnly = true;
|
||||
$this->addExtraClass( 'readonly' );
|
||||
$this->setReadonly(true);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@ -654,11 +654,11 @@ JS
|
||||
* Template accessor for Permissions
|
||||
*/
|
||||
function Can($mode) {
|
||||
if($mode == 'add' && $this->IsReadOnly) {
|
||||
if($mode == 'add' && $this->isReadonly()) {
|
||||
return false;
|
||||
} else if($mode == 'delete' && $this->IsReadOnly) {
|
||||
} else if($mode == 'delete' && $this->isReadonly()) {
|
||||
return false;
|
||||
} else if($mode == 'edit' && $this->IsReadOnly) {
|
||||
} else if($mode == 'edit' && $this->isReadonly()) {
|
||||
return false;
|
||||
} else {
|
||||
return (in_array($mode, $this->permissions));
|
||||
@ -1207,7 +1207,7 @@ class TableListField_Item extends ViewableData {
|
||||
function MarkingCheckbox() {
|
||||
$name = $this->parent->Name() . '[]';
|
||||
|
||||
if($this->parent->IsReadOnly || !$this->Can('edit'))
|
||||
if($this->parent->isReadonly())
|
||||
return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" disabled=\"disabled\" />";
|
||||
else
|
||||
return "<input class=\"checkbox\" type=\"checkbox\" name=\"$name\" value=\"{$this->item->ID}\" />";
|
||||
@ -1234,7 +1234,7 @@ class TableListField_Item extends ViewableData {
|
||||
/**
|
||||
* Legacy: Please use permissions instead
|
||||
*/
|
||||
function IsReadOnly() {
|
||||
function isReadonly() {
|
||||
return $this->parent->Can('delete');
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,8 @@ class TimeField extends TextField {
|
||||
*/
|
||||
class TimeField_Readonly extends TimeField {
|
||||
|
||||
protected $readonly = true;
|
||||
|
||||
function Field() {
|
||||
if( $this->value )
|
||||
$val = $this->attrValue();
|
||||
|
@ -132,6 +132,7 @@ HTML;
|
||||
$field = new LookupField($this->name, $this->title, $source);
|
||||
$field->setValue($this->value);
|
||||
$field->setForm($this->form);
|
||||
$field->setReadonly(true);
|
||||
return $field;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user