2016-02-22 02:13:35 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace SilverStripe\Forms\Schema;
|
|
|
|
|
|
|
|
trait FormFieldSchemaTrait {
|
|
|
|
|
2016-03-01 04:15:47 +01:00
|
|
|
/**
|
|
|
|
* The type of front-end component to render the FormField as.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $schemaComponent;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Structured schema data representing the FormField.
|
|
|
|
* Used to render the FormField as a ReactJS Component on the front-end.
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $schemaData = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Structured schema state representing the FormField's current data and validation.
|
|
|
|
* Used to render the FormField as a ReactJS Component on the front-end.
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
protected $schemaState = [];
|
|
|
|
|
2016-02-22 02:13:35 +01:00
|
|
|
/**
|
|
|
|
* Sets the component type the FormField will be rendered as on the front-end.
|
|
|
|
*
|
|
|
|
* @param string $componentType
|
|
|
|
* @return FormField
|
|
|
|
*/
|
|
|
|
public function setSchemaComponent($componentType) {
|
|
|
|
$this->schemaComponent = $componentType;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the type of front-end component the FormField will be rendered as.
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getSchemaComponent() {
|
|
|
|
return $this->schemaComponent;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the schema data used for rendering the field on the front-end.
|
|
|
|
* Merges the passed array with the current `$schemaData` or {@link getSchemaDataDefaults()}.
|
|
|
|
* Any passed keys that are not defined in {@link getSchemaDataDefaults()} are ignored.
|
|
|
|
* If you want to pass around ad hoc data use the `data` array e.g. pass `['data' => ['myCustomKey' => 'yolo']]`.
|
|
|
|
*
|
|
|
|
* @param array $schemaData - The data to be merged with $this->schemaData.
|
|
|
|
* @return FormField
|
|
|
|
*
|
|
|
|
* @todo Add deep merging of arrays like `data` and `attributes`.
|
|
|
|
*/
|
|
|
|
public function setSchemaData($schemaData = []) {
|
|
|
|
$current = $this->getSchemaData();
|
|
|
|
|
|
|
|
$this->schemaData = array_merge($current, array_intersect_key($schemaData, $current));
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the schema data used to render the FormField on the front-end.
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function getSchemaData() {
|
|
|
|
return array_merge($this->getSchemaDataDefaults(), $this->schemaData);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the defaults for $schemaData.
|
|
|
|
* The keys defined here are immutable, meaning undefined keys passed to {@link setSchemaData()} are ignored.
|
|
|
|
* Instead the `data` array should be used to pass around ad hoc data.
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
2016-03-01 04:15:47 +01:00
|
|
|
public function getSchemaDataDefaults() {
|
2016-02-22 02:13:35 +01:00
|
|
|
return [
|
|
|
|
'type' => $this->class,
|
|
|
|
'component' => $this->getSchemaComponent(),
|
|
|
|
'id' => $this->ID,
|
|
|
|
'holder_id' => null,
|
|
|
|
'name' => $this->getName(),
|
|
|
|
'title' => $this->Title(),
|
|
|
|
'source' => null,
|
|
|
|
'extraClass' => $this->ExtraClass(),
|
|
|
|
'description' => $this->getDescription(),
|
|
|
|
'rightTitle' => $this->RightTitle(),
|
|
|
|
'leftTitle' => $this->LeftTitle(),
|
|
|
|
'readOnly' => $this->isReadOnly(),
|
|
|
|
'disabled' => $this->isDisabled(),
|
|
|
|
'customValidationMessage' => $this->getCustomValidationMessage(),
|
|
|
|
'attributes' => [],
|
|
|
|
'data' => [],
|
|
|
|
];
|
|
|
|
}
|
2016-03-01 04:15:47 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the schema data used for rendering the field on the front-end.
|
|
|
|
* Merges the passed array with the current `$schemaData` or {@link getSchemaDataDefaults()}.
|
|
|
|
* Any passed keys that are not defined in {@link getSchemaDataDefaults()} are ignored.
|
|
|
|
* If you want to pass around ad hoc data use the `data` array e.g. pass `['data' => ['myCustomKey' => 'yolo']]`.
|
|
|
|
*
|
|
|
|
* @param array $schemaData - The data to be merged with $this->schemaData.
|
|
|
|
* @return FormField
|
|
|
|
*
|
|
|
|
* @todo Add deep merging of arrays like `data` and `attributes`.
|
|
|
|
*/
|
|
|
|
public function setSchemaState($schemaState = []) {
|
|
|
|
$current = $this->getSchemaState();
|
|
|
|
|
|
|
|
$this->schemaState = array_merge($current, array_intersect_key($schemaState, $current));
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the schema state used to render the FormField on the front-end.
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function getSchemaState() {
|
|
|
|
return array_merge($this->getSchemaStateDefaults(), $this->schemaState);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the defaults for $schemaState.
|
|
|
|
* The keys defined here are immutable, meaning undefined keys passed to {@link setSchemaState()} are ignored.
|
|
|
|
* Instead the `data` array should be used to pass around ad hoc data.
|
|
|
|
* Includes validation data if the field is associated to a {@link Form},
|
|
|
|
* and {@link Form->validate()} has been called.
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function getSchemaStateDefaults() {
|
|
|
|
$field = $this;
|
|
|
|
$form = $this->getForm();
|
|
|
|
$validator = $form ? $form->getValidator() : null;
|
|
|
|
$errors = $validator ? (array)$validator->getErrors() : [];
|
|
|
|
$messages = array_filter(array_map(function($error) use ($field) {
|
|
|
|
if($error['fieldName'] === $field->getName()) {
|
|
|
|
return [
|
|
|
|
'value' => $error['message'],
|
|
|
|
'type' => $error['messageType']
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}, $errors));
|
|
|
|
|
|
|
|
return [
|
|
|
|
'id' => $this->ID(),
|
|
|
|
'value' => $this->Value(),
|
|
|
|
'valid' => (count($messages) === 0),
|
|
|
|
'messages' => (array)$messages,
|
|
|
|
'data' => [],
|
|
|
|
];
|
|
|
|
}
|
2016-02-22 02:13:35 +01:00
|
|
|
}
|