silverstripe-framework/Forms/Schema/FormSchema.php
Ingo Schommer 1e478a5378 Consistently set 'id' in FormSchema
The URL to request the schema representation is the unique identifier.
We can't default to $request->getURL() since that's different for form submissions.

The schema.schema_url key is redundant, since the identifier is already contained on the top level 'id' key.
Keeping schema_url in a schema itself makes it less portable, particularly once we transition into
generic schemas which are not reliant on a particular record context (that's only contained in the schema_url)

This also fixes the issue of form schemas not refreshing after submit,
e.g. when form fields are added or removed.
2016-10-20 15:33:50 +13:00

91 lines
2.1 KiB
PHP

<?php
namespace SilverStripe\Forms\Schema;
use SilverStripe\Forms\CompositeField;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormField;
/**
* Represents a {@link Form} as structured data which allows a frontend library to render it.
* Includes information about the form as well as its fields.
* Can create a "schema" (structure only) as well as "state" (data only).
*/
class FormSchema {
/**
* Gets the schema for this form as a nested array.
*
* @param Form $form
* @param string $schemaLink Link to get this schema
* @return array
*/
public function getSchema(Form $form, $schemaLink) {
$schema = [
'name' => $form->getName(),
'id' => $form->FormName(),
'action' => $form->FormAction(),
'method' => $form->FormMethod(),
'attributes' => $form->getAttributes(),
'data' => [],
'fields' => [],
'actions' => []
];
/** @var FormField $action */
foreach ($form->Actions() as $action) {
$schema['actions'][] = $action->getSchemaData();
}
/** @var FormField $field */
foreach ($form->Fields() as $field) {
$schema['fields'][] = $field->getSchemaData();
}
return $schema;
}
/**
* Gets the current state of this form as a nested array.
*
* @param Form $form
* @return array
*/
public function getState(Form $form) {
$state = [
'id' => $form->FormName(),
'fields' => [],
'messages' => []
];
// flattened nested fields are returned, rather than only top level fields.
$state['fields'] = array_merge(
$this->getFieldStates($form->Fields()),
$this->getFieldStates($form->Actions())
);
if($form->Message()) {
$state['messages'][] = [
'value' => $form->Message(),
'type' => $form->MessageType(),
];
}
return $state;
}
protected function getFieldStates($fields) {
$states = [];
/** @var FormField $field */
foreach ($fields as $field) {
$states[] = $field->getSchemaState();
if ($field instanceof CompositeField) {
$subFields = $field->FieldList();
$states = array_merge($states, $this->getFieldStates($subFields));
}
}
return $states;
}
}