Skip to content

Commit 559abec

Browse files
committed
API Copying instance props on FormField readonly/disabled transformations
Introduced new FormField->castedCopy() method which tries to replicate the existing form field instance as closely as possible. Primarily, the fix was targeted at consistently passing through FormField->description to all of its variations.
1 parent 6f9d01f commit 559abec

19 files changed

+172
-69
lines changed

forms/CheckboxField.php

-6
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,6 @@ public function performReadonlyTransformation() {
4040
$field->setForm($this->form);
4141
return $field;
4242
}
43-
44-
public function performDisabledTransformation() {
45-
$clone = clone $this;
46-
$clone->setDisabled(true);
47-
return $clone;
48-
}
4943

5044
}
5145

forms/CheckboxSetField.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,8 @@ public function performReadonlyTransformation() {
276276
}
277277
}
278278

279-
$title = ($this->title) ? $this->title : '';
280-
281-
$field = new ReadonlyField($this->name, $title, $values);
282-
$field->setForm($this->form);
279+
$field = $this->castedCopy('ReadonlyField');
280+
$field->setValue($values);
283281

284282
return $field;
285283
}

forms/CompositeField.php

+7
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,8 @@ public function performReadonlyTransformation() {
265265

266266
$clone->children = $newChildren;
267267
$clone->readonly = true;
268+
$clone->addExtraClass($this->extraClass());
269+
$clone->setDescription($this->getDescription());
268270

269271
return $clone;
270272
}
@@ -285,6 +287,11 @@ public function performDisabledTransformation() {
285287

286288
$clone->children = $newChildren;
287289
$clone->readonly = true;
290+
$clone->addExtraClass($this->extraClass());
291+
$clone->setDescription($this->getDescription());
292+
foreach($this->attributes as $k => $v) {
293+
$clone->setAttribute($k, $v);
294+
}
288295

289296
return $clone;
290297
}

forms/ConfirmedPasswordField.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,10 @@ public function saveInto(DataObjectInterface $record) {
320320
* Makes a pretty readonly field with some stars in it
321321
*/
322322
public function performReadonlyTransformation() {
323-
$stars = '*****';
323+
$field = $this->castedCopy('ReadonlyField')
324+
->setTitle($this->title ? $this->title : _t('Member.PASSWORD'))
325+
->setValue('*****');
324326

325-
$field = new ReadonlyField($this->name, $this->title ? $this->title : _t('Member.PASSWORD'), $stars);
326-
$field->setForm($this->form);
327327
return $field;
328328
}
329329
}

forms/CurrencyField.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ public function Type() {
4040
* Create a new class for this field
4141
*/
4242
public function performReadonlyTransformation() {
43-
$field = new CurrencyField_Readonly($this->name, $this->title, $this->value);
44-
$field -> addExtraClass($this->extraClass());
45-
return $field;
43+
return $this->castedCopy('CurrencyField_Readonly');
4644
}
4745

4846
public function validate($validator) {

forms/DateField.php

+14-2
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,25 @@ public function dataValue() {
279279
}
280280

281281
public function performReadonlyTransformation() {
282-
$field = new DateField_Disabled($this->name, $this->title, $this->dataValue());
283-
$field->setForm($this->form);
282+
$field = $this->castedCopy('DateField_Disabled');
283+
$field->setValue($this->dataValue());
284284
$field->readonly = true;
285285

286286
return $field;
287287
}
288288

289+
public function castedCopy($class) {
290+
$copy = new $class($this->name);
291+
if($copy->hasMethod('setConfig')) {
292+
$config = $this->getConfig();
293+
foreach($config as $k => $v) {
294+
$copy->setConfig($k, $v);
295+
}
296+
}
297+
298+
return parent::castedCopy($copy);
299+
}
300+
289301
/**
290302
* Validate an array with expected keys 'day', 'month' and 'year.
291303
* Used because Zend_Date::isDate() doesn't provide this.

forms/DatetimeField.php

+16-2
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,22 @@ public function validate($validator) {
283283
}
284284

285285
public function performReadonlyTransformation() {
286-
$field = new DatetimeField_Readonly($this->name, $this->title, $this->dataValue());
287-
$field->setForm($this->form);
286+
$field = $this->castedCopy('DatetimeField_Readonly');
287+
$field->setValue($this->dataValue());
288+
289+
$dateFieldConfig = $this->getDateField()->getConfig();
290+
if($dateFieldConfig) {
291+
foreach($dateFieldConfig as $k => $v) {
292+
$field->getDateField()->setConfig($k, $v);
293+
}
294+
}
295+
296+
$timeFieldConfig = $this->getTimeField()->getConfig();
297+
if($timeFieldConfig) {
298+
foreach($timeFieldConfig as $k => $v) {
299+
$field->getTimeField()->setConfig($k, $v);
300+
}
301+
}
288302

289303
return $field;
290304
}

forms/DropdownField.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,10 @@ public function getEmptyString() {
239239
}
240240

241241
public function performReadonlyTransformation() {
242-
$field = new LookupField($this->name, $this->title, $this->getSource());
243-
$field->setValue($this->value);
244-
$field->setForm($this->form);
242+
$field = $this->castedCopy('LookupField');
243+
$field->setSource($this->getSource());
245244
$field->setReadonly(true);
245+
246246
return $field;
247247
}
248248
}

forms/FormField.php

+49-10
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ public function getAttributes() {
357357
'id' => $this->ID(),
358358
'disabled' => $this->isDisabled(),
359359
);
360-
360+
361361
return array_merge($attrs, $this->attributes);
362362
}
363363

@@ -709,10 +709,9 @@ public function setDisabled($bool) {
709709
* Returns a readonly version of this field
710710
*/
711711
public function performReadonlyTransformation() {
712-
$field = new ReadonlyField($this->name, $this->title, $this->value);
713-
$field->addExtraClass($this->extraClass());
714-
$field->setForm($this->form);
715-
return $field;
712+
$copy = $this->castedCopy('ReadonlyField');
713+
$copy->setReadonly(true);
714+
return $copy;
716715
}
717716

718717
/**
@@ -723,14 +722,15 @@ public function performReadonlyTransformation() {
723722
* @return FormField
724723
*/
725724
public function performDisabledTransformation() {
726-
$clone = clone $this;
727-
$disabledClassName = $clone->class . '_Disabled';
725+
$disabledClassName = $this->class . '_Disabled';
728726
if(ClassInfo::exists($disabledClassName)) {
729-
return new $disabledClassName($this->name, $this->title, $this->value);
727+
$clone = $this->castedCopy($disabledClassName);
730728
} else {
729+
$clone = clone $this;
731730
$clone->setDisabled(true);
732-
return $clone;
733731
}
732+
733+
return $clone;
734734
}
735735

736736
public function transform(FormTransformation $trans) {
@@ -774,7 +774,8 @@ public function validate($validator) {
774774

775775
/**
776776
* Describe this field, provide help text for it.
777-
* By default, renders as a "title" attribute on the form field.
777+
* By default, renders as a <span class="description">
778+
* underneath the form field.
778779
*
779780
* @return string Description
780781
*/
@@ -828,5 +829,43 @@ public function rootFieldList() {
828829
if(is_object($this->containerFieldList)) return $this->containerFieldList->rootFieldList();
829830
else user_error("rootFieldList() called on $this->class object without a containerFieldList", E_USER_ERROR);
830831
}
832+
833+
/**
834+
* Returns another instance of this field, but "cast" to a different class.
835+
* The logic tries to retain all of the instance properties,
836+
* and may be overloaded by subclasses to set additional ones.
837+
*
838+
* Assumes the standard FormField parameter signature with
839+
* its name as the only mandatory argument. Mainly geared towards
840+
* creating *_Readonly or *_Disabled subclasses of the same type,
841+
* or casting to a {@link ReadonlyField}.
842+
*
843+
* Does not copy custom field templates, since they probably won't apply to
844+
* the new instance.
845+
*
846+
* @param String $classOrCopy Class name for copy, or existing copy instance to update
847+
* @return FormField
848+
*/
849+
public function castedCopy($classOrCopy) {
850+
$field = (is_object($classOrCopy)) ? $classOrCopy : new $classOrCopy($this->name);
851+
$field
852+
->setValue($this->value) // get value directly from property, avoid any conversions
853+
->setForm($this->form)
854+
->setTitle($this->Title())
855+
->setLeftTitle($this->LeftTitle())
856+
->setRightTitle($this->RightTitle())
857+
->addExtraClass($this->extraClass())
858+
->setDescription($this->getDescription());
859+
860+
// Only include built-in attributes, ignore anything
861+
// set through getAttributes(), since those might change important characteristics
862+
// of the field, e.g. its "type" attribute.
863+
foreach($this->attributes as $k => $v) {
864+
$field->setAttribute($k, $v);
865+
}
866+
$field->dontEscape = $this->dontEscape;
867+
868+
return $field;
869+
}
831870

832871
}

forms/HtmlEditorField.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ public function saveInto(DataObjectInterface $record) {
204204
* @return HtmlEditorField_Readonly
205205
*/
206206
public function performReadonlyTransformation() {
207-
$field = new HtmlEditorField_Readonly($this->name, $this->title, $this->value);
208-
$field->setForm($this->form);
207+
$field = $this->castedCopy('HtmlEditorField_Readonly');
209208
$field->dontEscape = true;
209+
210210
return $field;
211211
}
212212

forms/InlineFormAction.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function __construct($action, $title = "", $extraClass = '') {
2424
}
2525

2626
public function performReadonlyTransformation() {
27-
return new InlineFormAction_ReadOnly( $this->name, $this->title );
27+
return $this->castedCopy('InlineFormAction_ReadOnly');
2828
}
2929

3030
public function Field($properties = array()) {

forms/LookupField.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function Field($properties = array()) {
3232

3333
// Don't check if string arguments are matching against the source,
3434
// as they might be generated HTML diff views instead of the actual values
35-
if($this->value && !$mapped) {
35+
if($this->value && !is_array($this->value) && !$mapped) {
3636
$mapped = array(trim($this->value));
3737
$values = array();
3838
}

forms/OptionsetField.php

+2-3
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,8 @@ public function Field($properties = array()) {
9292

9393
public function performReadonlyTransformation() {
9494
// Source and values are DataObject sets.
95-
$items = $this->getSource();
96-
$field = new LookupField($this->name, $this->title ? $this->title : '', $items, $this->value);
97-
$field->setForm($this->form);
95+
$field = $this->castedCopy('LookupField');
96+
$field->setValue($this->getSource());
9897
$field->setReadonly(true);
9998

10099
return $field;

forms/PasswordField.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,9 @@ public function getAttributes() {
3131
* Makes a pretty readonly field with some stars in it
3232
*/
3333
public function performReadonlyTransformation() {
34-
$stars = '*****';
35-
36-
$field = new ReadonlyField($this->name, $this->title ? $this->title : '', $stars);
37-
$field->setForm($this->form);
38-
$field->setReadonly(true);
34+
$field = $this->castedCopy('ReadonlyField');
35+
$field->setValue('*****');
36+
3937
return $field;
4038
}
4139

forms/TextareaField.php

-14
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,6 @@ public function getAttributes() {
4444
);
4545
}
4646

47-
/**
48-
* Performs a disabled transformation on this field. You shouldn't be able to
49-
* copy from this field, and it should not send any data when you submit the
50-
* form it's attached to.
51-
*
52-
* The element shouldn't be both disabled and readonly at the same time.
53-
*/
54-
public function performDisabledTransformation() {
55-
$clone = clone $this;
56-
$clone->setDisabled(true);
57-
$clone->setReadonly(false);
58-
return $clone;
59-
}
60-
6147
public function Type() {
6248
return parent::Type() . ($this->readonly ? ' readonly' : '');
6349
}

forms/TimeField.php

+13-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,19 @@ public function getConfig($name = null) {
191191
* Creates a new readonly field specified below
192192
*/
193193
public function performReadonlyTransformation() {
194-
return new TimeField_Readonly($this->name, $this->title, $this->dataValue(), $this->getConfig('timeformat'));
194+
return $this->castedCopy('TimeField_Readonly');
195+
}
196+
197+
public function castedCopy($class) {
198+
$copy = parent::castedCopy($class);
199+
if($copy->hasMethod('setConfig')) {
200+
$config = $this->getConfig();
201+
foreach($config as $k => $v) {
202+
$copy->setConfig($k, $v);
203+
}
204+
}
205+
206+
return $copy;
195207
}
196208

197209
}

0 commit comments

Comments
 (0)