Commit edbe2839 authored by webchick's avatar webchick

Issue #2072995 by claudiu.cristea, yched: Change notice: Move FAPI callbacks...

Issue #2072995 by claudiu.cristea, yched: Change notice: Move FAPI callbacks for file/image widgets in classes.
parent 97072d86
......@@ -1544,7 +1544,7 @@ protected function handleInputElement($form_id, &$element, &$form_state) {
// Set the element's #value property.
if (!isset($element['#value']) && !array_key_exists('#value', $element)) {
$value_callback = !empty($element['#value_callback']) ? $element['#value_callback'] : 'form_type_' . $element['#type'] . '_value';
$value_callable = !empty($element['#value_callback']) ? $element['#value_callback'] : 'form_type_' . $element['#type'] . '_value';
if ($process_input) {
// Get the input for the current element. NULL values in the input need
// to be explicitly distinguished from missing input. (see below)
......@@ -1568,8 +1568,8 @@ protected function handleInputElement($form_id, &$element, &$form_state) {
// If we have input for the current element, assign it to the #value
// property, optionally filtered through $value_callback.
if ($input_exists) {
if (function_exists($value_callback)) {
$element['#value'] = $value_callback($element, $input, $form_state);
if (is_callable($value_callable)) {
$element['#value'] = call_user_func_array($value_callable, array(&$element, $input, &$form_state));
}
if (!isset($element['#value']) && isset($input)) {
$element['#value'] = $input;
......@@ -1584,8 +1584,8 @@ protected function handleInputElement($form_id, &$element, &$form_state) {
if (!isset($element['#value'])) {
// Call #type_value without a second argument to request default_value
// handling.
if (function_exists($value_callback)) {
$element['#value'] = $value_callback($element, FALSE, $form_state);
if (is_callable($value_callable)) {
$element['#value'] = call_user_func_array($value_callable, array(&$element, FALSE, &$form_state));
}
// Final catch. If we haven't set a value yet, use the explicit default
// value. Avoid image buttons (which come with garbage value), so we
......
......@@ -525,7 +525,7 @@ public function executeHandlers($type, &$form, &$form_state);
* rendering each element). Each of these three pipelines provides ample
* opportunity for modules to customize what happens. For example, during this
* function's life cycle, the following functions get called for each element:
* - $element['#value_callback']: A function that implements how user input is
* - $element['#value_callback']: A callable that implements how user input is
* mapped to an element's #value property. This defaults to a function named
* 'form_type_TYPE_value' where TYPE is $element['#type'].
* - $element['#process']: An array of functions called after user input has
......
This diff is collapsed.
......@@ -14,115 +14,6 @@ function image_field_info_alter(&$info) {
$info['image']['settings']['uri_scheme'] = file_default_scheme();
}
/**
* An element #process callback for the image_image field type.
*
* Expands the image_image type to include the alt and title fields.
*/
function image_field_widget_process($element, &$form_state, $form) {
$item = $element['#value'];
$item['fids'] = $element['fids']['#value'];
$element['#theme'] = 'image_widget';
$element['#attached']['css'][] = drupal_get_path('module', 'image') . '/css/image.theme.css';
// Add the image preview.
if (!empty($element['#files']) && $element['#preview_image_style']) {
$file = reset($element['#files']);
$variables = array(
'style_name' => $element['#preview_image_style'],
'uri' => $file->getFileUri(),
);
// Determine image dimensions.
if (isset($element['#value']['width']) && isset($element['#value']['height'])) {
$variables['width'] = $element['#value']['width'];
$variables['height'] = $element['#value']['height'];
}
else {
$image = \Drupal::service('image.factory')->get($file->getFileUri());
if ($image->isSupported()) {
$variables['width'] = $image->getWidth();
$variables['height'] = $image->getHeight();
}
else {
$variables['width'] = $variables['height'] = NULL;
}
}
$element['preview'] = array(
'#theme' => 'image_style',
'#width' => $variables['width'],
'#height' => $variables['height'],
'#style_name' => $variables['style_name'],
'#uri' => $variables['uri'],
);
// Store the dimensions in the form so the file doesn't have to be accessed
// again. This is important for remote files.
$element['width'] = array(
'#type' => 'hidden',
'#value' => $variables['width'],
);
$element['height'] = array(
'#type' => 'hidden',
'#value' => $variables['height'],
);
}
// Add the additional alt and title fields.
$element['alt'] = array(
'#title' => t('Alternate text'),
'#type' => 'textfield',
'#default_value' => isset($item['alt']) ? $item['alt'] : '',
'#description' => t('This text will be used by screen readers, search engines, or when the image cannot be loaded.'),
// @see https://drupal.org/node/465106#alt-text
'#maxlength' => 512,
'#weight' => -2,
'#access' => (bool) $item['fids'] && $element['#alt_field'],
'#element_validate' => $element['#alt_field_required'] == 1 ? array('_image_field_required_fields_validate') : array(),
);
$element['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#default_value' => isset($item['title']) ? $item['title'] : '',
'#description' => t('The title is used as a tool tip when the user hovers the mouse over the image.'),
'#maxlength' => 1024,
'#weight' => -1,
'#access' => (bool) $item['fids'] && $element['#title_field'],
'#element_validate' => $element['#alt_field_required'] == 1 ? array('_image_field_required_fields_validate') : array(),
);
return $element;
}
/**
* Validate callback for alt and title field, if the user wants them required.
*
* This is separated in a validate function instead of a #required flag to avoid
* being validated on the process callback.
*/
function _image_field_required_fields_validate($element, &$form_state) {
// Only do validation if the function is triggered from other places than
// the image process form.
if (!in_array('file_managed_file_submit', $form_state['triggering_element']['#submit'])) {
// If the image is not there, we do not check for empty values.
$parents = $element['#parents'];
$field = array_pop($parents);
$image_field = NestedArray::getValue($form_state['input'], $parents);
// We check for the array key, so that it can be NULL (like if the user
// submits the form without using the "upload" button).
if (!array_key_exists($field, $image_field)) {
return;
}
// Check if field is left emtpy.
elseif (empty($image_field[$field])) {
form_error($element, $form_state, t('The field !title is required', array('!title' => $element['#title'])));
return;
}
}
}
/**
* Returns HTML for an image field widget.
*
......
......@@ -7,8 +7,9 @@
namespace Drupal\image\Plugin\Field\FieldWidget;
use Drupal\file\Plugin\Field\FieldWidget\FileWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Component\Utility\NestedArray;
use Drupal\file\Plugin\Field\FieldWidget\FileWidget;
/**
* Plugin implementation of the 'image_image' widget.
......@@ -119,14 +120,127 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
$element['#upload_validators']['file_validate_extensions'][0] = implode(' ', $extensions);
// Add all extra functionality provided by the image widget.
$element['#process'][] = 'image_field_widget_process';
// Add properties needed by image_field_widget_process().
$element['#process'][] = array(get_class($this), 'process');
// Add properties needed by process() method.
$element['#preview_image_style'] = $this->getSetting('preview_image_style');
$element['#title_field'] = $field_settings['title_field'];
$element['#title_field_required'] = $field_settings['title_field_required'];
$element['#alt_field'] = $field_settings['alt_field'];
$element['#alt_field_required'] = $field_settings['alt_field_required'];
return $element;
}
/**
* Form API callback: Processes a image_image field element.
*
* Expands the image_image type to include the alt and title fields.
*
* This method is assigned as a #process callback in formElement() method.
*/
public static function process($element, &$form_state, $form) {
$item = $element['#value'];
$item['fids'] = $element['fids']['#value'];
$element['#theme'] = 'image_widget';
$element['#attached']['css'][] = drupal_get_path('module', 'image') . '/css/image.theme.css';
// Add the image preview.
if (!empty($element['#files']) && $element['#preview_image_style']) {
$file = reset($element['#files']);
$variables = array(
'style_name' => $element['#preview_image_style'],
'uri' => $file->getFileUri(),
);
// Determine image dimensions.
if (isset($element['#value']['width']) && isset($element['#value']['height'])) {
$variables['width'] = $element['#value']['width'];
$variables['height'] = $element['#value']['height'];
}
else {
$image = \Drupal::service('image.factory')->get($file->getFileUri());
if ($image->getExtension()) {
$variables['width'] = $image->getWidth();
$variables['height'] = $image->getHeight();
}
else {
$variables['width'] = $variables['height'] = NULL;
}
}
$element['preview'] = array(
'#theme' => 'image_style',
'#width' => $variables['width'],
'#height' => $variables['height'],
'#style_name' => $variables['style_name'],
'#uri' => $variables['uri'],
);
// Store the dimensions in the form so the file doesn't have to be
// accessed again. This is important for remote files.
$element['width'] = array(
'#type' => 'hidden',
'#value' => $variables['width'],
);
$element['height'] = array(
'#type' => 'hidden',
'#value' => $variables['height'],
);
}
// Add the additional alt and title fields.
$element['alt'] = array(
'#title' => t('Alternate text'),
'#type' => 'textfield',
'#default_value' => isset($item['alt']) ? $item['alt'] : '',
'#description' => t('This text will be used by screen readers, search engines, or when the image cannot be loaded.'),
// @see http://www.gawds.org/show.php?contentid=28
'#maxlength' => 512,
'#weight' => -2,
'#access' => (bool) $item['fids'] && $element['#alt_field'],
'#element_validate' => $element['#alt_field_required'] == 1 ? array(array(get_called_class(), 'validateRequiredFields')) : array(),
);
$element['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#default_value' => isset($item['title']) ? $item['title'] : '',
'#description' => t('The title is used as a tool tip when the user hovers the mouse over the image.'),
'#maxlength' => 1024,
'#weight' => -1,
'#access' => (bool) $item['fids'] && $element['#title_field'],
'#element_validate' => $element['#title_field_required'] == 1 ? array(array(get_called_class(), 'validateRequiredFields')) : array(),
);
return $element;
}
/**
* Validate callback for alt and title field, if the user wants them required.
*
* This is separated in a validate function instead of a #required flag to
* avoid being validated on the process callback.
*/
public static function validateRequiredFields($element, &$form_state) {
// Only do validation if the function is triggered from other places than
// the image process form.
if (!in_array('file_managed_file_submit', $form_state['triggering_element']['#submit'])) {
// If the image is not there, we do not check for empty values.
$parents = $element['#parents'];
$field = array_pop($parents);
$image_field = NestedArray::getValue($form_state['input'], $parents);
// We check for the array key, so that it can be NULL (like if the user
// submits the form without using the "upload" button).
if (!array_key_exists($field, $image_field)) {
return;
}
// Check if field is left empty.
elseif (empty($image_field[$field])) {
\Drupal::formBuilder()->setError($element, $form_state, t('The field !title is required', array('!title' => $element['#title'])));
return;
}
}
}
}
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