Commit 5f9c6c3c authored by alexpott's avatar alexpott
Browse files

Issue #2200355 by yched, andypost: Move functions in field.form.inc into Core/Field.

parent 943df0d6
......@@ -2430,7 +2430,7 @@ function template_preprocess_field_multiple_value_form(&$variables) {
$items[] = &$element[$key];
}
}
usort($items, '_field_sort_items_value_helper');
usort($items, '_field_multiple_value_form_sort_helper');
// Add the items as table rows.
foreach ($items as $item) {
......@@ -2479,6 +2479,17 @@ function template_preprocess_field_multiple_value_form(&$variables) {
}
}
/**
* Callback for usort() within template_preprocess_field_multiple_value_form().
*
* Sorts using ['_weight']['#value']
*/
function _field_multiple_value_form_sort_helper($a, $b) {
$a_weight = (is_array($a) && isset($a['_weight']['#value']) ? $a['_weight']['#value'] : 0);
$b_weight = (is_array($b) && isset($b['_weight']['#value']) ? $b['_weight']['#value'] : 0);
return $a_weight - $b_weight;
}
/**
* Provides theme registration for themes across .inc files.
*/
......
......@@ -81,7 +81,8 @@ interface EntityFormDisplayInterface extends EntityDisplayInterface {
* @endcode
*
* Additionally, some processing data is placed in $form_state, and can be
* accessed by field_form_get_state() and field_form_set_state().
* accessed by \Drupal\Core\Field\WidgetBaseInterface::getWidgetState() and
* \Drupal\Core\Field\WidgetBaseInterface::setWidgetState().
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity.
......
......@@ -63,12 +63,12 @@ public function form(FieldItemListInterface $items, array &$form, array &$form_s
$parents = $form['#parents'];
// Store field information in $form_state.
if (!field_form_get_state($parents, $field_name, $form_state)) {
if (!static::getWidgetState($parents, $field_name, $form_state)) {
$field_state = array(
'items_count' => count($items),
'array_parents' => array(),
);
field_form_set_state($parents, $field_name, $form_state, $field_state);
static::setWidgetState($parents, $field_name, $form_state, $field_state);
}
// Collect widget elements.
......@@ -106,9 +106,9 @@ public function form(FieldItemListInterface $items, array &$form, array &$form_s
}
// Populate the 'array_parents' information in $form_state['field'] after
// the form is built, so that we catch changes in the form structure performed
// in alter() hooks.
$elements['#after_build'][] = 'field_form_element_after_build';
// the form is built, so that we catch changes in the form structure
// performed in alter() hooks.
$elements['#after_build'][] = array(get_class($this), 'afterBuild');
$elements['#field_name'] = $field_name;
$elements['#field_parents'] = $parents;
// Enforce the structure of submitted values.
......@@ -148,7 +148,7 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
// Determine the number of widgets to display.
switch ($cardinality) {
case FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED:
$field_state = field_form_get_state($parents, $field_name, $form_state);
$field_state = static::getWidgetState($parents, $field_name, $form_state);
$max = $field_state['items_count'];
$is_multiple = TRUE;
break;
......@@ -232,6 +232,23 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
return $elements;
}
/**
* After-build handler for field elements in a form.
*
* This stores the final location of the field within the form structure so
* that flagErrors() can assign validation errors to the right form element.
*/
public static function afterBuild(array $element, array &$form_state) {
$parents = $element['#field_parents'];
$field_name = $element['#field_name'];
$field_state = static::getWidgetState($parents, $field_name, $form_state);
$field_state['array_parents'] = $element['#array_parents'];
static::setWidgetState($parents, $field_name, $form_state, $field_state);
return $element;
}
/**
* Submission handler for the "Add another item" button.
*/
......@@ -244,9 +261,9 @@ public static function addMoreSubmit(array $form, array &$form_state) {
$parents = $element['#field_parents'];
// Increment the items count.
$field_state = field_form_get_state($parents, $field_name, $form_state);
$field_state = static::getWidgetState($parents, $field_name, $form_state);
$field_state['items_count']++;
field_form_set_state($parents, $field_name, $form_state, $field_state);
static::setWidgetState($parents, $field_name, $form_state, $field_state);
$form_state['rebuild'] = TRUE;
}
......@@ -343,12 +360,12 @@ public function extractFormValues(FieldItemListInterface $items, array $form, ar
$items->filterEmptyItems();
// Put delta mapping in $form_state, so that flagErrors() can use it.
$field_state = field_form_get_state($form['#parents'], $field_name, $form_state);
$field_state = static::getWidgetState($form['#parents'], $field_name, $form_state);
foreach ($items as $delta => $item) {
$field_state['original_deltas'][$delta] = isset($item->_original_delta) ? $item->_original_delta : $delta;
unset($item->_original_delta, $item->_weight);
}
field_form_set_state($form['#parents'], $field_name, $form_state, $field_state);
static::setWidgetState($form['#parents'], $field_name, $form_state, $field_state);
}
}
......@@ -358,7 +375,7 @@ public function extractFormValues(FieldItemListInterface $items, array $form, ar
public function flagErrors(FieldItemListInterface $items, ConstraintViolationListInterface $violations, array $form, array &$form_state) {
$field_name = $this->fieldDefinition->getName();
$field_state = field_form_get_state($form['#parents'], $field_name, $form_state);
$field_state = static::getWidgetState($form['#parents'], $field_name, $form_state);
if ($violations->count()) {
$form_builder = \Drupal::formBuilder();
......@@ -421,6 +438,38 @@ public function flagErrors(FieldItemListInterface $items, ConstraintViolationLis
}
}
/**
* {@inheritdoc}
*/
public static function getWidgetState(array $parents, $field_name, array &$form_state) {
return NestedArray::getValue($form_state, static::getWidgetStateParents($parents, $field_name));
}
/**
* {@inheritdoc}
*/
public static function setWidgetState(array $parents, $field_name, array &$form_state, array $field_state) {
NestedArray::setValue($form_state, static::getWidgetStateParents($parents, $field_name), $field_state);
}
/**
* Returns the location of processing information within $form_state.
*
* @param array $parents
* The array of #parents where the widget lives in the form.
* @param string $field_name
* The field name.
*
* @return array
* The location of processing information within $form_state.
*/
protected static function getWidgetStateParents(array $parents, $field_name) {
// Field processing data is placed at
// $form_state['field']['#parents'][...$parents...]['#fields'][$field_name],
// to avoid clashes between field names and $parents parts.
return array_merge(array('field', '#parents'), $parents, array('#fields', $field_name));
}
/**
* {@inheritdoc}
*/
......
......@@ -13,9 +13,9 @@
* Base interface definition for "Field widget" plugins.
*
* This interface details base wrapping methods that most widget implementations
* will want to directly inherit from Drupal\Core\Field\WidgetBase.
* See Drupal\Core\Field\WidgetInterface for methods that will more
* likely be overriden.
* will want to directly inherit from Drupal\Core\Field\WidgetBase. See
* Drupal\Core\Field\WidgetInterface for methods that will more likely be
* overriden in actual widget implementations.
*/
interface WidgetBaseInterface extends PluginSettingsInterface {
......@@ -71,4 +71,41 @@ public function extractFormValues(FieldItemListInterface $items, array $form, ar
*/
public function flagErrors(FieldItemListInterface $items, ConstraintViolationListInterface $violations, array $form, array &$form_state);
/**
* Retrieves processing information about the widget from $form_state.
*
* This method is static so that is can be used in static Form API callbacks.
*
* @param array $parents
* The array of #parents where the field lives in the form.
* @param string $field_name
* The field name.
* @param array $form_state
* The form state.
*
* @return array
* An array with the following key/value pairs:
* - items_count: The number of widgets to display for the field.
* - array_parents: The location of the field's widgets within the $form
* structure. This entry is populated at '#after_build' time.
*/
public static function getWidgetState(array $parents, $field_name, array &$form_state);
/**
* Stores processing information about the widget in $form_state.
*
* This method is static so that is can be used in static Form API #callbacks.
*
* @param array $parents
* The array of #parents where the widget lives in the form.
* @param string $field_name
* The field name.
* @param array $form_state
* The form state.
* @param array $field_state
* The array of data to store. See getWidgetState() for the structure and
* content of the array.
*/
public static function setWidgetState(array $parents, $field_name, array &$form_state, array $field_state);
}
......@@ -83,8 +83,8 @@ public function settingsSummary();
* widgets can simply overlook this property. This identifies the
* location where the field values are placed within
* $form_state['values'], and is used to access processing information
* for the field through the field_form_get_state() and
* field_form_set_state() functions.
* for the field through the getWidgetState() and setWidgetState()
* methods.
* - #title: The sanitized element label for the field instance, ready for
* output.
* - #description: The sanitized element description for the field instance,
......
<?php
/**
* @file
* Field forms management.
*/
use Drupal\Component\Utility\NestedArray;
/**
* Callback for usort() within field-multiple-value-form.html.twig.
*
* Sorts using ['_weight']['#value']
*/
function _field_sort_items_value_helper($a, $b) {
$a_weight = (is_array($a) && isset($a['_weight']['#value']) ? $a['_weight']['#value'] : 0);
$b_weight = (is_array($b) && isset($b['_weight']['#value']) ? $b['_weight']['#value'] : 0);
return $a_weight - $b_weight;
}
/**
* After-build callback for field elements in a form.
*
* This stores the final location of the field within the form structure so that
* field_default_form_errors() can assign validation errors to the right form
* element.
*
* @param $element
* The form element.
* @param $form_state
* An associative array containing the current state of the form.
*
* @return
* The $element array that was passed in as a parameter.
*
* @see field_default_form_errors()
*/
function field_form_element_after_build($element, &$form_state) {
$parents = $element['#field_parents'];
$field_name = $element['#field_name'];
$field_state = field_form_get_state($parents, $field_name, $form_state);
$field_state['array_parents'] = $element['#array_parents'];
field_form_set_state($parents, $field_name, $form_state, $field_state);
return $element;
}
/**
* Retrieves processing information about a field from $form_state.
*
* @param array $parents
* The array of #parents where the field lives in the form.
* @param $field_name
* The field name.
* @param array $form_state
* The form state.
*
* @return
* An array with the following key/data pairs:
* - items_count: The number of widgets to display for the field.
* - array_parents: The location of the field's widgets within the $form
* structure. This entry is populated at '#after_build' time.
* - constraint_violations: The array of validation errors reported on the
* field. This entry is populated at form validate time.
*
* @see field_form_set_state()
*/
function field_form_get_state(array $parents, $field_name, array &$form_state) {
$form_state_parents = _field_form_state_parents($parents, $field_name);
return NestedArray::getValue($form_state, $form_state_parents);
}
/**
* Stores processing information about a field in $form_state.
*
* @param array $parents
* The array of #parents where the field lives in the form.
* @param $field_name
* The field name.
* @param array $form_state
* The form state.
* @param array $field_state
* The array of data to store. See field_form_get_state() for the structure
* and content of the array.
*
* @see field_form_get_state()
*/
function field_form_set_state(array $parents, $field_name, array &$form_state, array $field_state) {
$form_state_parents = _field_form_state_parents($parents, $field_name);
NestedArray::setValue($form_state, $form_state_parents, $field_state);
}
/**
* Returns the location of processing information within $form_state.
*
* @param array $parents
* The array of #parents where the field lives in the form.
* @param $field_name
* The field name.
*
* @return
* The location of processing information within $form_state.
*/
function _field_form_state_parents(array $parents, $field_name) {
// Field processing data is placed at
// $form_state['field']['#parents'][...$parents...]['#fields'][$field_name],
// to avoid clashes between field names and $parents parts.
return array_merge(array('field', '#parents'), $parents, array('#fields', $field_name));
}
......@@ -16,7 +16,6 @@
* mechanism for auto-loading core APIs, so we have to load them on
* every page request.
*/
require_once __DIR__ . '/field.form.inc';
require_once __DIR__ . '/field.purge.inc';
/**
......
......@@ -65,7 +65,7 @@ function template_preprocess_file_widget_multiple(&$variables) {
foreach (Element::children($element) as $key) {
$widgets[] = &$element[$key];
}
usort($widgets, '_field_sort_items_value_helper');
usort($widgets, '_field_multiple_value_form_sort_helper');
$rows = array();
foreach ($widgets as $key => &$widget) {
......
......@@ -76,7 +76,7 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f
// Load the items for form rebuilds from the field state as they might not be
// in $form_state['values'] because of validation limitations. Also, they are
// only passed in as $items when editing existing entities.
$field_state = field_form_get_state($parents, $field_name, $form_state);
$field_state = static::getWidgetState($parents, $field_name, $form_state);
if (isset($field_state['items'])) {
$items->setValue($field_state['items']);
}
......@@ -530,9 +530,9 @@ public static function submit($form, &$form_state) {
NestedArray::setValue($form_state['values'], array_slice($button['#parents'], 0, -2), $submitted_values);
// Update items.
$field_state = field_form_get_state($parents, $field_name, $form_state);
$field_state = static::getWidgetState($parents, $field_name, $form_state);
$field_state['items'] = $submitted_values;
field_form_set_state($parents, $field_name, $form_state, $field_state);
static::setWidgetState($parents, $field_name, $form_state, $field_state);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment