$schemaID]; // Default to schema if not set if ($form && ($wantSchema || empty($schemaParts))) { $return['schema'] = $this->getSchema($form); } // Return 'state' if requested, or if there are errors and 'auto' if ($form && ($wantState || ($auto && !$result))) { $return['state'] = $this->getState($form); } // Return errors if 'errors' or 'auto' if ($result && ($wantErrors || $auto)) { $return['errors'] = $this->getErrors($result); } return $return; } /** * Gets the schema for this form as a nested array. * * @param Form $form * @return array */ public function getSchema(Form $form) { $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 ($message = $form->getSchemaMessage()) { $state['messages'][] = $message; } return $state; } /** * @param ValidationResult $result * @return array List of errors */ public function getErrors(ValidationResult $result) { $messages = []; foreach ($result->getMessages() as $message) { $messages[] = $this->getSchemaForMessage($message); } return $messages; } /** * Return form schema for encoded validation message * * @param array $message Internal ValidationResult format for this message * @return array Form schema format for this message */ protected function getSchemaForMessage($message) { // Form schema messages treat simple strings as plain text, so nest for html messages $value = $message['message']; if ($message['messageCast'] === ValidationResult::CAST_HTML) { $value = ['html' => $message]; } return [ 'value' => $value, 'type' => $message['messageType'], 'field' => empty($message['fieldName']) ? null : $message['fieldName'], ]; } 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; } }