Commit 4c5bed3f authored by catch's avatar catch

Issue #1751174 by zuuperman, yched: Convert file and image module widgets /...

Issue #1751174 by zuuperman, yched: Convert file and image module widgets / formatters to Plugin system.
parent 2825cc0c
......@@ -310,151 +310,6 @@ function file_field_displayed($item, $field) {
return TRUE;
}
/**
* Implements hook_field_formatter_info().
*/
function file_field_formatter_info() {
return array(
'file_default' => array(
'label' => t('Generic file'),
'field types' => array('file'),
),
'file_table' => array(
'label' => t('Table of files'),
'field types' => array('file'),
),
'file_url_plain' => array(
'label' => t('URL to file'),
'field types' => array('file'),
),
'file_rss_enclosure' => array(
'label' => t('RSS enclosure'),
'field types' => array('file'),
),
);
}
/**
* Implements hook_field_widget_info().
*/
function file_field_widget_info() {
return array(
'file_generic' => array(
'label' => t('File'),
'field types' => array('file'),
'settings' => array(
'progress_indicator' => 'throbber',
),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_CUSTOM,
'default value' => FIELD_BEHAVIOR_NONE,
),
),
);
}
/**
* Implements hook_field_widget_settings_form().
*/
function file_field_widget_settings_form($field, $instance) {
$widget = $instance['widget'];
$settings = $widget['settings'];
$form['progress_indicator'] = array(
'#type' => 'radios',
'#title' => t('Progress indicator'),
'#options' => array(
'throbber' => t('Throbber'),
'bar' => t('Bar with progress meter'),
),
'#default_value' => $settings['progress_indicator'],
'#description' => t('The throbber display does not show the status of uploads but takes up less space. The progress bar is helpful for monitoring progress on large uploads.'),
'#weight' => 16,
'#access' => file_progress_implementation(),
);
return $form;
}
/**
* Implements hook_field_widget_form().
*/
function file_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$defaults = array(
'fid' => 0,
'display' => !empty($field['settings']['display_default']),
'description' => '',
);
// 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($element['#field_parents'], $field['field_name'], $langcode, $form_state);
if (isset($field_state['items'])) {
$items = $field_state['items'];
}
// Essentially we use the managed_file type, extended with some enhancements.
$element_info = element_info('managed_file');
$element += array(
'#type' => 'managed_file',
'#upload_location' => file_field_widget_uri($field, $instance),
'#upload_validators' => file_field_widget_upload_validators($field, $instance),
'#value_callback' => 'file_field_widget_value',
'#process' => array_merge($element_info['#process'], array('file_field_widget_process')),
'#progress_indicator' => $instance['widget']['settings']['progress_indicator'],
// Allows this field to return an array instead of a single value.
'#extended' => TRUE,
);
if ($field['cardinality'] == 1) {
// Set the default value.
$element['#default_value'] = !empty($items) ? $items[0] : $defaults;
// If there's only one field, return it as delta 0.
if (empty($element['#default_value']['fid'])) {
$element['#description'] = theme('file_upload_help', array('description' => $element['#description'], 'upload_validators' => $element['#upload_validators']));
}
$elements = array($element);
}
else {
// If there are multiple values, add an element for each existing one.
foreach ($items as $item) {
$elements[$delta] = $element;
$elements[$delta]['#default_value'] = $item;
$elements[$delta]['#weight'] = $delta;
$delta++;
}
// And then add one more empty row for new uploads except when this is a
// programmed form as it is not necessary.
if (($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $field['cardinality']) && empty($form_state['programmed'])) {
$elements[$delta] = $element;
$elements[$delta]['#default_value'] = $defaults;
$elements[$delta]['#weight'] = $delta;
$elements[$delta]['#required'] = ($element['#required'] && $delta == 0);
}
// The group of elements all-together need some extra functionality
// after building up the full list (like draggable table rows).
$elements['#file_upload_delta'] = $delta;
$elements['#theme'] = 'file_widget_multiple';
$elements['#theme_wrappers'] = array('fieldset');
$elements['#process'] = array('file_field_widget_process_multiple');
$elements['#title'] = $element['#title'];
$elements['#description'] = $element['#description'];
$elements['#field_name'] = $element['#field_name'];
$elements['#language'] = $element['#language'];
$elements['#display_field'] = $field['settings']['display_field'];
// Add some properties that will eventually be added to the file upload
// field. These are added here so that they may be referenced easily through
// a hook_form_alter().
$elements['#file_upload_title'] = t('Add a new file');
$elements['#file_upload_description'] = theme('file_upload_help', array('description' => '', 'upload_validators' => $elements[0]['#upload_validators']));
}
return $elements;
}
/**
* Retrieves the upload validators for a file field.
*
......@@ -897,60 +752,6 @@ function theme_file_upload_help($variables) {
return implode('<br />', $descriptions);
}
/**
* Implements hook_field_formatter_view().
*/
function file_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'file_default':
foreach ($items as $delta => $item) {
$element[$delta] = array(
'#theme' => 'file_link',
'#file' => (object) $item,
);
}
break;
case 'file_url_plain':
foreach ($items as $delta => $item) {
$element[$delta] = array('#markup' => empty($item['uri']) ? '' : file_create_url($item['uri']));
}
break;
case 'file_table':
if (!empty($items)) {
// Display all values in a single element..
$element[0] = array(
'#theme' => 'file_formatter_table',
'#items' => $items,
);
}
break;
case 'file_rss_enclosure':
// Add the first file as an enclosure to the RSS item. RSS allows only one
// enclosure per item. See: http://en.wikipedia.org/wiki/RSS_enclosure
foreach ($items as $item) {
if ($item['display']) {
$entity->rss_elements[] = array(
'key' => 'enclosure',
'attributes' => array(
'url' => file_create_url($item['uri']),
'length' => $item['filesize'],
'type' => $item['filemime'],
),
);
break;
}
}
break;
}
return $element;
}
/**
* Determine whether a field references files stored in {file_managed}.
*
......
<?php
/**
* @file
* Contains \Drupal\file\Plugin\field\formatter\GenericFileFormatter.
*/
namespace Drupal\file\Plugin\field\formatter;
use Drupal\Core\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\field\Plugin\Type\Formatter\FormatterBase;
use Drupal\Core\Entity\EntityInterface;
/**
* Plugin implementation of the 'file_default' formatter.
*
* @Plugin(
* id = "file_default",
* module = "file",
* label = @Translation("Generic file"),
* field_types = {
* "file"
* }
* )
*/
class GenericFileFormatter extends FormatterBase {
/**
* Implements \Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
*/
public function viewElements(EntityInterface $entity, $langcode, array $items) {
$elements = array();
foreach ($items as $delta => $item) {
$elements[$delta] = array(
'#theme' => 'file_link',
'#file' => (object) $item,
);
}
return $elements;
}
}
<?php
/**
* @file
* Contains \Drupal\file\Plugin\field\formatter\RSSEnclosureFormatter.
*/
namespace Drupal\file\Plugin\field\formatter;
use Drupal\Core\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\field\Plugin\Type\Formatter\FormatterBase;
use Drupal\Core\Entity\EntityInterface;
/**
* Plugin implementation of the 'file_rss_enclosure' formatter.
*
* @Plugin(
* id = "file_rss_enclosure",
* module = "file",
* label = @Translation("RSS enclosure"),
* field_types = {
* "file"
* }
* )
*/
class RSSEnclosureFormatter extends FormatterBase {
/**
* Implements \Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
*/
public function viewElements(EntityInterface $entity, $langcode, array $items) {
// Add the first file as an enclosure to the RSS item. RSS allows only one
// enclosure per item. See: http://en.wikipedia.org/wiki/RSS_enclosure
foreach ($items as $item) {
if ($item['display']) {
$entity->rss_elements[] = array(
'key' => 'enclosure',
'attributes' => array(
'url' => file_create_url($item['uri']),
'length' => $item['filesize'],
'type' => $item['filemime'],
),
);
break;
}
}
}
}
<?php
/**
* @file
* Contains \Drupal\file\Plugin\field\formatter\TableFormatter.
*/
namespace Drupal\file\Plugin\field\formatter;
use Drupal\Core\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\field\Plugin\Type\Formatter\FormatterBase;
use Drupal\Core\Entity\EntityInterface;
/**
* Plugin implementation of the 'file_table' formatter.
*
* @Plugin(
* id = "file_table",
* module = "file",
* label = @Translation("Table of files"),
* field_types = {
* "file"
* }
* )
*/
class TableFormatter extends FormatterBase {
/**
* Implements \Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
*/
public function viewElements(EntityInterface $entity, $langcode, array $items) {
$elements = array();
if (!empty($items)) {
// Display all values in a single element.
$elements[0] = array(
'#theme' => 'file_formatter_table',
'#items' => $items,
);
}
return $elements;
}
}
<?php
/**
* @file
* Contains \Drupal\file\Plugin\field\formatter\UrlPlainFormatter.
*/
namespace Drupal\file\Plugin\field\formatter;
use Drupal\Core\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\field\Plugin\Type\Formatter\FormatterBase;
use Drupal\Core\Entity\EntityInterface;
/**
* Plugin implementation of the 'file_url_plain' formatter.
*
* @Plugin(
* id = "file_url_plain",
* module = "file",
* label = @Translation("URL to file"),
* field_types = {
* "file"
* }
* )
*/
class UrlPlainFormatter extends FormatterBase {
/**
* Implements \Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements().
*/
public function viewElements(EntityInterface $entity, $langcode, array $items) {
$elements = array();
foreach ($items as $delta => $item) {
$elements[$delta] = array('#markup' => empty($item['uri']) ? '' : file_create_url($item['uri']));
}
return $elements;
}
}
<?php
/**
* @file
* Contains \Drupal\file\Plugin\field\widget\FileWidget.
*/
namespace Drupal\file\Plugin\field\widget;
use Drupal\Core\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\field\Plugin\Type\Widget\WidgetBase;
use Drupal\Core\Entity\EntityInterface;
/**
* Plugin implementation of the 'file_generic' widget.
*
* @Plugin(
* id = "file_generic",
* module = "file",
* label = @Translation("File"),
* field_types = {
* "file"
* },
* settings = {
* "progress_indicator" = "throbber"
* },
* default_value = FALSE
* )
*/
class FileWidget extends WidgetBase {
/**
* Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm().
*/
public function settingsForm(array $form, array &$form_state) {
$element['progress_indicator'] = array(
'#type' => 'radios',
'#title' => t('Progress indicator'),
'#options' => array(
'throbber' => t('Throbber'),
'bar' => t('Bar with progress meter'),
),
'#default_value' => $this->getSetting('progress_indicator'),
'#description' => t('The throbber display does not show the status of uploads but takes up less space. The progress bar is helpful for monitoring progress on large uploads.'),
'#weight' => 16,
'#access' => file_progress_implementation(),
);
return $element;
}
/**
* Overrides \Drupal\field\Plugin\Type\Widget\WidgetBase::formMultipleElements().
*
* Special handling for draggable multiple widgets and 'add more' button.
*/
protected function formMultipleElements(EntityInterface $entity, array $items, $langcode, array &$form, array &$form_state) {
$field = $this->field;
$instance = $this->instance;
$field_name = $field['field_name'];
$parents = $form['#parents'];
// 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, $langcode, $form_state);
if (isset($field_state['items'])) {
$items = $field_state['items'];
}
// Determine the number of widgets to display.
switch ($field['cardinality']) {
case FIELD_CARDINALITY_UNLIMITED:
$max = count($items);
$is_multiple = TRUE;
break;
default:
$max = $field['cardinality'] - 1;
$is_multiple = ($field['cardinality'] > 1);
break;
}
$id_prefix = implode('-', array_merge($parents, array($field_name)));
$wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper');
$title = check_plain($instance['label']);
$description = field_filter_xss($instance['description']);
$elements = array();
$delta = 0;
// Add an element for every existing item.
foreach ($items as $item) {
$element = array(
'#title' => $title,
'#description' => $description,
);
$element = $this->formSingleElement($entity, $items, $delta, $langcode, $element, $form, $form_state);
if ($element) {
// Input field for the delta (drag-n-drop reordering).
if ($is_multiple) {
// We name the element '_weight' to avoid clashing with elements
// defined by widget.
$element['_weight'] = array(
'#type' => 'weight',
'#title' => t('Weight for row @number', array('@number' => $delta + 1)),
'#title_display' => 'invisible',
// Note: this 'delta' is the FAPI #type 'weight' element's property.
'#delta' => $max,
'#default_value' => isset($item['_weight']) ? $item['_weight'] : $delta,
'#weight' => 100,
);
}
$elements[$delta] = $element;
$delta++;
}
}
$empty_single_allowed = ($this->field['cardinality'] == 1 && $delta == 0);
$empty_multiple_allowed = ($this->field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $this->field['cardinality']) && empty($form_state['programmed']);
// Add one more empty row for new uploads except when this is a programmed
// multiple form as it is not necessary.
if ($empty_single_allowed || $empty_multiple_allowed) {
$element = array(
'#title' => $title,
'#description' => $description,
);
$element = $this->formSingleElement($entity, $items, $delta, $langcode, $element, $form, $form_state);
if ($element) {
$element['#required'] = ($element['#required'] && $delta == 0);
$elements[$delta] = $element;
}
}
if ($is_multiple) {
// The group of elements all-together need some extra functionality after
// building up the full list (like draggable table rows).
$elements['#file_upload_delta'] = $delta;
$elements['#theme'] = 'file_widget_multiple';
$elements['#theme_wrappers'] = array('fieldset');
$elements['#process'] = array('file_field_widget_process_multiple');
$elements['#title'] = $title;
$elements['#description'] = $description;
$elements['#field_name'] = $element['#field_name'];
$elements['#language'] = $element['#language'];
$elements['#display_field'] = !empty($this->field['settings']['display_field']);
// Add some properties that will eventually be added to the file upload
// field. These are added here so that they may be referenced easily
// through a hook_form_alter().
$elements['#file_upload_title'] = t('Add a new file');
$elements['#file_upload_description'] = theme('file_upload_help', array('description' => '', 'upload_validators' => $elements[0]['#upload_validators']));
}
return $elements;
}
/**
* Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
*/
public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
$defaults = array(
'fid' => 0,
'display' => !empty($this->field['settings']['display_default']),
'description' => '',
);
// Essentially we use the managed_file type, extended with some
// enhancements.
$element_info = element_info('managed_file');
$element += array(
'#type' => 'managed_file',
'#upload_location' => file_field_widget_uri($this->field, $this->instance),
'#upload_validators' => file_field_widget_upload_validators($this->field, $this->instance),
'#value_callback' => 'file_field_widget_value',
'#process' => array_merge($element_info['#process'], array('file_field_widget_process')),
'#progress_indicator' => $this->getSetting('progress_indicator'),
// Allows this field to return an array instead of a single value.
'#extended' => TRUE,
);
$element['#weight'] = $delta;
$element['#default_value'] = !empty($items[$delta]) ? $items[$delta] : $defaults;
if (empty($element['#default_value']['fid'])) {
$element['#description'] = theme('file_upload_help', array('description' => $element['#description'], 'upload_validators' => $element['#upload_validators']));
}