');
- $table[$name]['type'] = array(
- '#type' => 'select',
- '#options' => $formatter_options,
- '#default_value' => $display['type'],
- '#ajax' => array(
- 'callback' => 'field_ui_formatter_settings_js',
- 'wrapper' => 'field-display-overview-wrapper',
- 'effect' => 'fade',
- ),
- '#field_name' => $name,
- '#op' => 'change_type',
- );
- // Formatter settings.
-
- // Check the currently selected formatter, and merge persisted values for
- // formatter settings.
- if (isset($form_state['values']['settings'][$name]['type'])) {
- $formatter_type = $form_state['values']['settings'][$name]['type'];
- }
- else {
- $formatter_type = $display['type'];
- }
- if (isset($form_state['formatter_settings'][$name])) {
- $settings = $form_state['formatter_settings'][$name];
- }
- else {
- $settings = $display['settings'];
- }
- $settings += field_info_formatter_settings($formatter_type);
-
- $instance['display'][$view_mode]['type'] = $formatter_type;
- $formatter = field_info_formatter_types($formatter_type);
- $instance['display'][$view_mode]['module'] = $formatter['module'];
- $instance['display'][$view_mode]['settings'] = $settings;
-
- // Base button element for the various formatter settings actions.
- $base_button = array(
- '#submit' => array('field_ui_formatter_settings_submit'),
- '#ajax' => array(
- 'callback' => 'field_ui_formatter_settings_js',
- 'wrapper' => 'field-display-overview-wrapper',
- 'effect' => 'fade',
- ),
- '#field_name' => $name,
- );
-
- if ($form_state['formatter_settings_edit'] == $name) {
- // We are currently editing this field's formatter settings. Display the
- // settings form and submit buttons.
- $table[$name]['settings_edit_form'] = array();
- $function = $formatter['module'] . '_field_formatter_settings_form';
- $additions = $function($field, $instance, $view_mode, $form, $form_state);
- if (is_array($additions)) {
- $table[$name]['settings_edit_form'] = array(
- '#type' => 'container',
- '#attributes' => array('class' => array('field-formatter-settings-edit-form')),
- );
- $table[$name]['settings_edit_form']['label'] = array(
- '#markup' => t('Format settings:') . ' ' . $formatter['label'] . ' ',
- );
- $table[$name]['settings_edit_form']['settings'] = $additions;
- $table[$name]['settings_edit_form']['actions'] = array('#type' => 'actions');
- $table[$name]['settings_edit_form']['actions']['save_settings'] = $base_button + array(
- '#type' => 'submit',
- '#name' => $name . '_formatter_settings_update',
- '#value' => t('Update'),
- '#op' => 'update',
- );
- $table[$name]['settings_edit_form']['actions']['cancel_settings'] = $base_button + array(
- '#type' => 'submit',
- '#name' => $name . '_formatter_settings_cancel',
- '#value' => t('Cancel'),
- '#op' => 'cancel',
- // Do not check errors for the 'Cancel' button.
- '#limit_validation_errors' => array(),
- );
- $table[$name]['#settings_editing'] = TRUE;
- // When formatter is changed, cancel the currently edited settings. The
- // select 'formatter type' input is hidden in editing mode, so this only
- // happens is the row is dragged into the 'hidden' section.
- $table[$name]['type']['#ajax']['trigger_as'] = array('name' => $name . '_formatter_settings_cancel');
- }
- }
- else {
- // Display a summary of the current formatter settings.
- $summary = module_invoke($formatter['module'], 'field_formatter_settings_summary', $field, $instance, $view_mode);
- $table[$name]['settings_summary'] = array();
- $table[$name]['settings_edit'] = array();
- if ($summary) {
- $table[$name]['settings_summary'] = array(
- '#markup' => '' . $summary . '
',
- );
- $table[$name]['settings_edit'] = $base_button + array(
- '#type' => 'image_button',
- '#name' => $name . '_formatter_settings_edit',
- '#src' => 'misc/configure.png',
- '#attributes' => array('class' => array('field-formatter-settings-edit'), 'alt' => t('Edit')),
- '#op' => 'edit',
- // Do not check errors for the 'Edit' button.
- '#limit_validation_errors' => array(),
- '#prefix' => '',
- '#suffix' => '
',
- );
- }
- }
- $table['#field_rows'][] = $name;
-
- // Collect default formatters for the JS script.
- $field_type_info = field_info_field_types($field['type']);
- $default_formatters[$name] = $field_type_info['default_formatter'];
- }
-
- // Non-field elements.
- foreach ($extra_fields as $name => $extra_field) {
- $display = $extra_field['display'][$view_mode];
- $table[$name]['human_name'] = array(
- '#markup' => check_plain($extra_field['label']),
- );
- $table[$name]['weight'] = array(
- '#type' => 'textfield',
- '#default_value' => $display['weight'],
- '#size' => 3,
- );
- $table[$name]['hidden_name'] = array(
- '#type' => 'hidden',
- '#default_value' => $name,
- );
- $table[$name]['type'] = array(
- '#type' => 'select',
- '#options' => $extra_visibility_options,
- '#default_value' => $display['visible'] ? 'visible' : 'hidden',
- );
- $table[$name]['settings_summary'] = array();
- $table[$name]['settings_edit'] = array();
- $table['#field_rows'][] = $name;
- }
-
- $form['settings'] = $table;
-
- // Custom display settings.
- if ($view_mode == 'default') {
- $form['modes'] = array(
- '#type' => 'fieldset',
- '#title' => t('Custom display settings'),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- );
- // Collect options and default values for the 'Custom display settings'
- // checkboxes.
- $options = array();
- $default = array();
- $entity_info = entity_get_info($entity_type);
- $view_modes = $entity_info['view modes'];
- $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
- foreach ($view_modes as $view_mode_name => $view_mode_info) {
- $options[$view_mode_name] = $view_mode_info['label'];
- if (!empty($view_mode_settings[$view_mode_name]['custom_settings'])) {
- $default[] = $view_mode_name;
- }
- }
- $form['modes']['view_modes_custom'] = array(
- '#type' => 'checkboxes',
- '#title' => t('Use custom display settings for the following view modes'),
- '#options' => $options,
- '#default_value' => $default,
- );
- }
-
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save'));
-
- $form['#attached']['js'][] = drupal_get_path('module', 'field_ui') . '/field_ui.js';
- $form['#attached']['css'][] = drupal_get_path('module', 'field_ui') . '/field_ui.css';
-
- drupal_add_js(array('fieldDefaultFormatters' => $default_formatters), 'setting');
-
- return $form;
-}
-
-
-/**
- * Form submit handler for the formatter settings buttons.
- */
-function field_ui_formatter_settings_submit($form, &$form_state) {
- $trigger = $form_state['triggering_element'];
- $field_name = $trigger['#field_name'];
- $op = $trigger['#op'];
-
- switch ($op) {
- case 'edit':
- // Store the field whose settings are currently being edited.
- $form_state['formatter_settings_edit'] = $field_name;
- break;
-
- case 'update':
- // Store the saved settings.
- $values = $form_state['values']['settings'][$field_name]['settings_edit_form']['settings'];
- $form_state['formatter_settings'][$field_name] = $values;
- // Fall-through to the 'cancel' case.
- case 'cancel':
- // Unset the field as being currently edited.
- $form_state['formatter_settings_edit'] = NULL;
- break;
- }
-
- $form_state['rebuild'] = TRUE;
-}
-
-/**
- * AJAX handler for the formatter settings buttons.
- */
-function field_ui_formatter_settings_js($form, &$form_state) {
- $trigger = $form_state['triggering_element'];
- $field_name = $trigger['#field_name'];
- $op = $trigger['#op'];
-
- // Apply the AJAX effect to updated elements.
- switch ($op) {
- case 'change_type':
- $updated = array('settings_summary');
- break;
-
- case 'edit':
- $updated = array('settings_edit_form');
- break;
-
- case 'update':
- case 'cancel':
- $updated = array('type', 'settings_summary', 'settings_edit');
- break;
- }
- foreach ($updated as $key) {
- $element = &$form['settings'][$field_name][$key];
- $element['#prefix'] = '' . (isset($element['#prefix']) ? $element['#prefix'] : '');
- $element['#suffix'] = (isset($element['#suffix']) ? $element['#suffix'] : '') . '
';
- }
-
- return $form['settings'];
-}
-
-/**
- * Theme preprocess function for field_ui-display-overview-table.tpl.php.
- */
-function template_preprocess_field_ui_display_overview_table(&$vars) {
- $elements = &$vars['elements'];
-
- $rows = array(
- 'visible' => array(),
- 'hidden' => array(),
- );
-
- if (!empty($elements['#field_rows'])) {
- drupal_add_tabledrag('field-display-overview', 'order', 'sibling', 'field-weight');
-
- $order = _field_ui_overview_order($elements, $elements['#field_rows']);
- foreach ($order as $key) {
- $element = &$elements[$key];
- $visibility = $element['type']['#value'] == 'hidden' ? 'hidden' : 'visible';
-
- // Add target classes for the tabledrag behavior.
- $element['weight']['#attributes']['class'][] = 'field-weight';
- $element['hidden_name']['#attributes']['class'][] = 'field-name';
- $element['type']['#attributes']['class'][] = 'field-formatter-type';
- $element['type']['#attributes']['class'][] = "field-display-$visibility";
- $element['type']['#attributes']['class'][] = "field-name-$key";
-
- $row = new stdClass();
- foreach (element_children($element) as $child) {
- $row->{$child} = drupal_render($element[$child]);
- }
- $row->settings_class = (!empty($element['#settings_class']) ? $element['#settings_class'] : '');
- $row->class = 'draggable';
- if (isset($element['#settings_editing'])) {
- $row->class .= ' field-formatter-settings-editing';
- }
- $row->label_class = 'label-field';
- $row->id = 'row-' . strtr($key, '_', '-');
- $rows[$visibility][] = $row;
- }
- }
-
- $vars['rows'] = $rows;
-}
-
-/**
- * Submit handler for the display overview form.
- */
-function field_ui_display_overview_form_submit($form, &$form_state) {
- $form_values = $form_state['values'];
- $entity_type = $form['#entity_type'];
- $bundle = $form['#bundle'];
- $view_mode = $form['#view_mode'];
-
- // Save data for 'regular' fields.
- foreach ($form['#fields'] as $field_name) {
- $instance = field_info_instance($entity_type, $field_name, $bundle);
- $values = $form_values['settings'][$field_name];
- // Get formatter settings. They lie either directly in submitted form
- // values (if the whole form was submitted while some formatter
- // settings were being edited), or have been persisted in
- // $form_state.
- $settings = $instance['display'][$view_mode]['settings'];
- if (isset($values['settings_edit_form']['settings'])) {
- $settings = $values['settings_edit_form']['settings'];
- }
- elseif (isset($form_state['formatter_settings'][$field_name])) {
- $settings = $form_state['formatter_settings'][$field_name];
- }
-
- // Only save settings actually used by the selected formatter.
- $default_settings = field_info_formatter_settings($values['type']);
- $settings = array_intersect_key($settings, $default_settings);
-
- $instance['display'][$view_mode] = array(
- 'label' => $values['label'],
- 'type' => $values['type'],
- 'weight' => $values['weight'],
- 'settings' => $settings,
- );
- field_update_instance($instance);
- }
-
- // Get current bundle settings.
- $bundle_settings = field_bundle_settings($entity_type, $bundle);
-
- // Save data for 'extra' fields.
- foreach ($form['#extra'] as $name) {
- $bundle_settings['extra_fields']['display'][$name][$view_mode] = array(
- 'weight' => $form_values['settings'][$name]['weight'],
- 'visible' => $form_values['settings'][$name]['type'] == 'visible',
- );
- }
-
- // Save view modes data.
- if ($view_mode == 'default') {
- $entity_info = entity_get_info($entity_type);
- foreach ($form_values['view_modes_custom'] as $view_mode_name => $value) {
- // Display a message for each view mode newly configured to use custom
- // settings.
- if (!empty($value) && empty($bundle_settings['view_modes'][$view_mode_name]['custom_settings'])) {
- $view_mode_label = $entity_info['view modes'][$view_mode_name]['label'];
- $path = _field_ui_bundle_admin_path($entity_type, $bundle) . "/display/$view_mode_name";
- drupal_set_message(t('The %view_mode mode now uses custom display settings. You might want to configure them .', array('%view_mode' => $view_mode_label, '@url' => url($path))));
- }
- $bundle_settings['view_modes'][$view_mode_name]['custom_settings'] = !empty($value);
- }
- }
-
- // Save updated bundle settings.
- field_bundle_settings($entity_type, $bundle, $bundle_settings);
-
- drupal_set_message(t('Your settings have been saved.'));
-}
-
-/**
- * Return an array of field_type options.
- */
-function field_ui_field_type_options() {
- $options = &drupal_static(__FUNCTION__);
-
- if (!isset($options)) {
- $options = array();
- $field_types = field_info_field_types();
- $field_type_options = array();
- foreach ($field_types as $name => $field_type) {
- // Skip field types which have no widget types, or should not be add via
- // uesr interface.
- if (field_ui_widget_type_options($name) && empty($field_type['no_ui'])) {
- $options[$name] = $field_type['label'];
- }
- }
- asort($options);
- }
- return $options;
-}
-
-/**
- * Return an array of widget type options for a field type.
- *
- * If no field type is provided, returns a nested array of all widget types,
- * keyed by field type human name.
- */
-function field_ui_widget_type_options($field_type = NULL, $by_label = FALSE) {
- $options = &drupal_static(__FUNCTION__);
-
- if (!isset($options)) {
- $options = array();
- $field_types = field_info_field_types();
- foreach (field_info_widget_types() as $name => $widget_type) {
- foreach ($widget_type['field types'] as $widget_field_type) {
- // Check that the field type exists.
- if (isset($field_types[$widget_field_type])) {
- $options[$widget_field_type][$name] = $widget_type['label'];
- }
- }
- }
- }
-
- if (isset($field_type)) {
- return !empty($options[$field_type]) ? $options[$field_type] : array();
- }
- if ($by_label) {
- $field_types = field_info_field_types();
- $options_by_label = array();
- foreach ($options as $field_type => $widgets) {
- $options_by_label[$field_types[$field_type]['label']] = $widgets;
- }
- return $options_by_label;
- }
- return $options;
-}
-
-/**
- * Return an array of formatter options for a field type.
- *
- * If no field type is provided, returns a nested array of all formatters, keyed
- * by field type.
- */
-function field_ui_formatter_options($field_type = NULL) {
- $options = &drupal_static(__FUNCTION__);
-
- if (!isset($options)) {
- $field_types = field_info_field_types();
- $options = array();
- foreach (field_info_formatter_types() as $name => $formatter) {
- foreach ($formatter['field types'] as $formatter_field_type) {
- // Check that the field type exists.
- if (isset($field_types[$formatter_field_type])) {
- $options[$formatter_field_type][$name] = $formatter['label'];
- }
- }
- }
- }
-
- if ($field_type) {
- return !empty($options[$field_type]) ? $options[$field_type] : array();
- }
- return $options;
-}
-
-/**
- * Return an array of existing field to be added to a bundle.
- */
-function field_ui_existing_field_options($entity_type, $bundle) {
- $options = array();
- $field_types = field_info_field_types();
-
- foreach (field_info_instances() as $existing_entity_type => $bundles) {
- foreach ($bundles as $existing_bundle => $instances) {
- // No need to look in the current bundle.
- if (!($existing_bundle == $bundle && $existing_entity_type == $entity_type)) {
- foreach ($instances as $instance) {
- $field = field_info_field($instance['field_name']);
- // Don't show
- // - locked fields,
- // - fields already in the current bundle,
- // - fields that cannot be added to the entity type,
- // - fields that that shoud not be added via user interface.
-
- if (empty($field['locked'])
- && !field_info_instance($entity_type, $field['field_name'], $bundle)
- && (empty($field['entity_types']) || in_array($entity_type, $field['entity_types']))
- && empty($field_types[$field['type']]['no_ui'])) {
- $text = t('@type: @field (@label)', array(
- '@type' => $field_types[$field['type']]['label'],
- '@label' => t($instance['label']), '@field' => $instance['field_name'],
- ));
- $options[$instance['field_name']] = (drupal_strlen($text) > 80 ? truncate_utf8($text, 77) . '...' : $text);
- }
- }
- }
- }
- }
- // Sort the list by field name.
- asort($options);
- return $options;
-}
-
-/**
- * Menu callback; presents the field settings edit page.
- */
-function field_ui_field_settings_form($form, &$form_state, $instance) {
- $bundle = $instance['bundle'];
- $entity_type = $instance['entity_type'];
- $field = field_info_field($instance['field_name']);
-
- drupal_set_title($instance['label']);
-
- $description = '' . t('These settings apply to the %field field everywhere it is used. These settings impact the way that data is stored in the database and cannot be changed once data has been created.', array('%field' => $instance['label'])) . '
';
-
- // Create a form structure for the field values.
- $form['field'] = array(
- '#type' => 'fieldset',
- '#title' => t('Field settings'),
- '#description' => $description,
- '#tree' => TRUE,
- );
-
- // See if data already exists for this field.
- // If so, prevent changes to the field settings.
- $has_data = field_has_data($field);
- if ($has_data) {
- $form['field']['#description'] = '' . t('There is data for this field in the database. The field settings can no longer be changed.' . '
') . $form['field']['#description'];
- }
-
- // Build the non-configurable field values.
- $form['field']['field_name'] = array('#type' => 'value', '#value' => $field['field_name']);
- $form['field']['type'] = array('#type' => 'value', '#value' => $field['type']);
- $form['field']['module'] = array('#type' => 'value', '#value' => $field['module']);
- $form['field']['active'] = array('#type' => 'value', '#value' => $field['active']);
-
- // Add settings provided by the field module. The field module is
- // responsible for not returning settings that cannot be changed if
- // the field already has data.
- $form['field']['settings'] = array();
- $additions = module_invoke($field['module'], 'field_settings_form', $field, $instance, $has_data);
- if (is_array($additions)) {
- $form['field']['settings'] = $additions;
- }
- if (empty($form['field']['settings'])) {
- $form['field']['settings'] = array(
- '#markup' => t('%field has no field settings.', array('%field' => $instance['label'])),
- );
- }
- $form['#entity_type'] = $entity_type;
- $form['#bundle'] = $bundle;
-
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save field settings'));
- return $form;
-}
-
-/**
- * Save a field's settings after editing.
- */
-function field_ui_field_settings_form_submit($form, &$form_state) {
- $form_values = $form_state['values'];
- $field_values = $form_values['field'];
-
- // Merge incoming form values into the existing field.
- $field = field_info_field($field_values['field_name']);
-
- $entity_type = $form['#entity_type'];
- $bundle = $form['#bundle'];
- $instance = field_info_instance($entity_type, $field['field_name'], $bundle);
-
- // Update the field.
- $field = array_merge($field, $field_values);
-
- try {
- field_update_field($field);
- drupal_set_message(t('Updated field %label field settings.', array('%label' => $instance['label'])));
- $form_state['redirect'] = field_ui_next_destination($entity_type, $bundle);
- }
- catch (FieldException $e) {
- drupal_set_message(t('Attempt to update field %label failed: %message.', array('%label' => $instance['label'], '%message' => $e->getMessage())), 'error');
- // TODO: Where do we go from here?
- $form_state['redirect'] = field_ui_next_destination($entity_type, $bundle);
- }
-}
-
-/**
- * Menu callback; select a widget for the field.
- */
-function field_ui_widget_type_form($form, &$form_state, $instance) {
- $bundle = $instance['bundle'];
- $entity_type = $instance['entity_type'];
- $field = field_info_field($instance['field_name']);
-
- drupal_set_title($instance['label']);
-
- $field_type = field_info_field_types($field['type']);
- $widget_type = field_info_widget_types($instance['widget']['type']);
- $bundles = field_info_bundles();
- $bundle_label = $bundles[$entity_type][$bundle]['label'];
-
- $form['basic'] = array(
- '#type' => 'fieldset',
- '#title' => t('Change widget'),
- );
- $form['basic']['widget_type'] = array(
- '#type' => 'select',
- '#title' => t('Widget type'),
- '#required' => TRUE,
- '#options' => field_ui_widget_type_options($field['type']),
- '#default_value' => $instance['widget']['type'],
- '#description' => t('The type of form element you would like to present to the user when creating this field in the %type type.', array('%type' => $bundle_label)),
- );
-
- $form['#instance'] = $instance;
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Continue'));
-
- $form['#validate'] = array();
- $form['#submit'] = array('field_ui_widget_type_form_submit');
-
- return $form;
-}
-
-/**
- * Submit the change in widget type.
- */
-function field_ui_widget_type_form_submit($form, &$form_state) {
- $form_values = $form_state['values'];
- $instance = $form['#instance'];
- $bundle = $instance['bundle'];
- $entity_type = $instance['entity_type'];
-
- // Set the right module information.
- $widget_type = field_info_widget_types($form_values['widget_type']);
- $widget_module = $widget_type['module'];
-
- $instance['widget']['type'] = $form_values['widget_type'];
- $instance['widget']['module'] = $widget_module;
- try {
- field_update_instance($instance);
- drupal_set_message(t('Changed the widget for field %label.', array('%label' => $instance['label'])));
- }
- catch (FieldException $e) {
- drupal_set_message(t('There was a problem changing the widget for field %label.', array('%label' => $instance['label'])));
- }
-
- $form_state['redirect'] = field_ui_next_destination($entity_type, $bundle);
-}
-
-/**
- * Menu callback; present a form for removing a field instance from a bundle.
- */
-function field_ui_field_delete_form($form, &$form_state, $instance) {
- $bundle = $instance['bundle'];
- $entity_type = $instance['entity_type'];
- $field = field_info_field($instance['field_name']);
-
- $admin_path = _field_ui_bundle_admin_path($entity_type, $bundle);
-
- $form['entity_type'] = array('#type' => 'value', '#value' => $entity_type);
- $form['bundle'] = array('#type' => 'value', '#value' => $bundle);
- $form['field_name'] = array('#type' => 'value', '#value' => $field['field_name']);
-
- $output = confirm_form($form,
- t('Are you sure you want to delete the field %field?', array('%field' => $instance['label'])),
- $admin_path . '/fields',
- t('If you have any content left in this field, it will be lost. This action cannot be undone.'),
- t('Delete'), t('Cancel'),
- 'confirm'
- );
-
- if ($field['locked']) {
- unset($output['actions']['submit']);
- $output['description']['#markup'] = t('This field is locked and cannot be deleted.');
- }
-
- return $output;
-}
-
-/**
- * Removes a field instance from a bundle.
- *
- * If the field has no more instances, it will be marked as deleted too.
- */
-function field_ui_field_delete_form_submit($form, &$form_state) {
- $form_values = $form_state['values'];
- $field_name = $form_values['field_name'];
- $bundle = $form_values['bundle'];
- $entity_type = $form_values['entity_type'];
-
- $field = field_info_field($field_name);
- $instance = field_info_instance($entity_type, $field_name, $bundle);
- $bundles = field_info_bundles();
- $bundle_label = $bundles[$entity_type][$bundle]['label'];
-
- if (!empty($bundle) && $field && !$field['locked'] && $form_values['confirm']) {
- field_delete_instance($instance);
- // Delete the field if that was the last instance.
- if (count($field['bundles']) == 1 && count(current($field['bundles'])) == 1) {
- field_delete_field($field['field_name']);
- }
- drupal_set_message(t('The field %field has been deleted from the %type content type.', array('%field' => $instance['label'], '%type' => $bundle_label)));
- }
- else {
- drupal_set_message(t('There was a problem removing the %field from the %type content type.', array('%field' => $instance['label'], '%type' => $bundle_label)));
- }
-
- $admin_path = _field_ui_bundle_admin_path($entity_type, $bundle);
- $form_state['redirect'] = field_ui_get_destinations(array($admin_path . '/fields'));
-}
-
-/**
- * Menu callback; presents the field instance edit page.
- */
-function field_ui_field_edit_form($form, &$form_state, $instance) {
- $bundle = $instance['bundle'];
- $entity_type = $instance['entity_type'];
- $field = field_info_field($instance['field_name']);
-
- drupal_set_title($instance['label']);
-
- $form['#field'] = $field;
-
- if (!empty($field['locked'])) {
- $form['locked'] = array(
- '#markup' => t('The field %field is locked and cannot be edited.', array('%field' => $instance['label'])),
- );
- return $form;
- }
-
- $field_type = field_info_field_types($field['type']);
- $widget_type = field_info_widget_types($instance['widget']['type']);
- $bundles = field_info_bundles();
-
- // Create a form structure for the instance values.
- $form['instance'] = array(
- '#tree' => TRUE,
- '#type' => 'fieldset',
- '#title' => t('%type settings', array('%type' => $bundles[$entity_type][$bundle]['label'])),
- '#description' => t('These settings apply only to the %field field when used in the %type type.', array('%field' => $instance['label'], '%type' => $bundles[$entity_type][$bundle]['label'])),
- '#pre_render' => array('field_ui_field_edit_instance_pre_render'),
- );
-
- // Build the non-configurable instance values.
- $form['instance']['field_name'] = array(
- '#type' => 'value',
- '#value' => $instance['field_name'],
- );
- $form['instance']['entity_type'] = array(
- '#type' => 'value',
- '#value' => $entity_type,
- );
- $form['instance']['bundle'] = array(
- '#type' => 'value',
- '#value' => $bundle,
- );
- $form['instance']['widget']['weight'] = array(
- '#type' => 'value',
- '#value' => !empty($instance['widget']['weight']) ? $instance['widget']['weight'] : 0,
- );
-
- // Build the configurable instance values.
- $form['instance']['label'] = array(
- '#type' => 'textfield',
- '#title' => t('Label'),
- '#default_value' => !empty($instance['label']) ? $instance['label'] : $field['field_name'],
- '#required' => TRUE,
- '#weight' => -20,
- );
- $form['instance']['required'] = array(
- '#type' => 'checkbox',
- '#title' => t('Required field'),
- '#default_value' => !empty($instance['required']),
- '#weight' => -10,
- );
-
- $form['instance']['description'] = array(
- '#type' => 'textarea',
- '#title' => t('Help text'),
- '#default_value' => !empty($instance['description']) ? $instance['description'] : '',
- '#rows' => 5,
- '#description' => t('Instructions to present to the user below this field on the editing form. Allowed HTML tags: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())),
- '#required' => FALSE,
- '#weight' => 0,
- );
-
- // Build the widget component of the instance.
- $form['instance']['widget']['type'] = array(
- '#type' => 'value',
- '#value' => $instance['widget']['type'],
- );
- $form['instance']['widget']['module'] = array(
- '#type' => 'value',
- '#value' => $widget_type['module'],
- );
- $form['instance']['widget']['active'] = array(
- '#type' => 'value',
- '#value' => !empty($field['instance']['widget']['active']) ? 1 : 0,
- );
-
- // Add additional field instance settings from the field module.
- $additions = module_invoke($field['module'], 'field_instance_settings_form', $field, $instance);
- if (is_array($additions)) {
- $form['instance']['settings'] = $additions;
- }
-
- // Add additional widget settings from the widget module.
- $additions = module_invoke($widget_type['module'], 'field_widget_settings_form', $field, $instance);
- if (is_array($additions)) {
- $form['instance']['widget']['settings'] = $additions;
- $form['instance']['widget']['active']['#value'] = 1;
- }
-
- // Add handling for default value if not provided by any other module.
- if (field_behaviors_widget('default value', $instance) == FIELD_BEHAVIOR_DEFAULT && empty($instance['default_value_function'])) {
- $form['instance']['default_value_widget'] = field_ui_default_value_widget($field, $instance, $form, $form_state);
- }
-
- $has_data = field_has_data($field);
- if ($has_data) {
- $description = '' . t('These settings apply to the %field field everywhere it is used. Because the field already has data, some settings can no longer be changed.', array('%field' => $instance['label'])) . '
';
- }
- else {
- $description = '' . t('These settings apply to the %field field everywhere it is used.', array('%field' => $instance['label'])) . '
';
- }
-
- // Create a form structure for the field values.
- $form['field'] = array(
- '#type' => 'fieldset',
- '#title' => t('%field field settings', array('%field' => $instance['label'])),
- '#description' => $description,
- '#tree' => TRUE,
- );
-
- // Build the configurable field values.
- $description = t('Maximum number of values users can enter for this field.');
- if (field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_DEFAULT) {
- $description .= ' ' . t("'Unlimited' will provide an 'Add more' button so the users can add as many values as they like.");
- }
- $form['field']['cardinality'] = array(
- '#type' => 'select',
- '#title' => t('Number of values'),
- '#options' => array(FIELD_CARDINALITY_UNLIMITED => t('Unlimited')) + drupal_map_assoc(range(1, 10)),
- '#default_value' => $field['cardinality'],
- '#description' => $description,
- );
-
- // Add additional field type settings. The field type module is
- // responsible for not returning settings that cannot be changed if
- // the field already has data.
- $additions = module_invoke($field['module'], 'field_settings_form', $field, $instance, $has_data);
- if (is_array($additions)) {
- $form['field']['settings'] = $additions;
- }
-
- $form['actions'] = array('#type' => 'actions');
- $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save settings'));
- return $form;
-}
-
-/**
- * Pre-render function for field instance settings.
- *
- * Combines the instance, widget, and other settings into a single fieldset so
- * that elements within each group can be shown at different weights as if they
- * all had the same parent.
- */
-function field_ui_field_edit_instance_pre_render($element) {
- // Merge the widget settings into the main form.
- if (isset($element['widget']['settings'])) {
- foreach (element_children($element['widget']['settings']) as $key) {
- $element['widget_' . $key] = $element['widget']['settings'][$key];
- }
- unset($element['widget']['settings']);
- }
-
- // Merge the instance settings into the main form.
- if (isset($element['settings'])) {
- foreach (element_children($element['settings']) as $key) {
- $element['instance_' . $key] = $element['settings'][$key];
- }
- unset($element['settings']);
- }
-
- return $element;
-}
-
-/**
- * Build default value fieldset.
- */
-function field_ui_default_value_widget($field, $instance, &$form, &$form_state) {
- $field_name = $field['field_name'];
-
- $element = array(
- '#type' => 'fieldset',
- '#title' => t('Default value'),
- '#collapsible' => FALSE,
- '#tree' => TRUE,
- '#description' => t('The default value for this field, used when creating new content.'),
- // Make sure the values appear at the top-level of $form_state['values'].
- '#parents' => array(),
- );
-
- // Insert the widget.
- $items = $instance['default_value'];
- $instance['required'] = FALSE;
- $instance['description'] = '';
- // @todo Allow multiple values (requires more work on 'add more' JS handler).
- $element += field_default_form(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state, 0);
-
- return $element;
-}
-
-/**
- * Form validation handler for field instance settings form.
- */
-function field_ui_field_edit_form_validate($form, &$form_state) {
- $instance = $form_state['values']['instance'];
- $field_name = $instance['field_name'];
- $field = field_info_field($field_name);
-
- // Extract the 'default value'.
- $items = array();
- field_default_extract_form_values(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state);
- // Validate the value and report errors.
- $errors = array();
- $function = $field['module'] . '_field_validate';
- if (function_exists($function)) {
- $function(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $errors);
- }
- if (isset($errors[$field_name][LANGUAGE_NONE])) {
- $form_state['field'][$field_name][LANGUAGE_NONE]['errors'] = $errors[$field_name][LANGUAGE_NONE];
- field_default_form_errors(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state);
- }
-}
-
-/**
- * Form submit handler for field instance settings form.
- */
-function field_ui_field_edit_form_submit($form, &$form_state) {
- $instance = $form_state['values']['instance'];
- $field = $form_state['values']['field'];
-
- // Update any field settings that have changed.
- $field_source = field_info_field($instance['field_name']);
- $field = array_merge($field_source, $field);
- field_update_field($field);
-
- // Handle the default value.
- // Extract field values.
- $items = array();
- field_default_extract_form_values(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state);
- // Prepare field values.
- field_default_submit(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state);
- $instance['default_value'] = $items ? $items : NULL;
-
- // Update the instance settings.
- $instance_source = field_info_instance($instance['entity_type'], $instance['field_name'], $instance['bundle']);
- $instance = array_merge($instance_source, $instance);
- field_update_instance($instance);
-
- drupal_set_message(t('Saved %label configuration.', array('%label' => $instance['label'])));
-
- $form_state['redirect'] = field_ui_next_destination($instance['entity_type'], $instance['bundle']);
-}
-
-/**
- * Helper functions to handle multipage redirects.
- */
-function field_ui_get_destinations($destinations) {
- $path = array_shift($destinations);
- $options = drupal_parse_url($path);
- if ($destinations) {
- $options['query']['destinations'] = $destinations;
- }
- return array($options['path'], $options);
-}
-
-/**
- * Return the next redirect path in a multipage sequence.
- */
-function field_ui_next_destination($entity_type, $bundle) {
- $destinations = !empty($_REQUEST['destinations']) ? $_REQUEST['destinations'] : array();
- if (!empty($destinations)) {
- unset($_REQUEST['destinations']);
- return field_ui_get_destinations($destinations);
- }
- $admin_path = _field_ui_bundle_admin_path($entity_type, $bundle);
- return $admin_path . '/fields';
-}
-
-/**
- * Helper function to order fields when theming overview forms.
- * @todo Remove when 'Manage display' screen is done.
- */
-function _field_ui_overview_order(&$form, $field_rows) {
- // Put weight and parenting values into a $dummy render structure and let
- // drupal_render() figure out the corresponding row order.
- $dummy = array();
- // Field rows: account for weight.
- foreach ($field_rows as $name) {
- $dummy[$name] = array(
- '#markup' => $name . ' ',
- '#type' => 'markup',
- '#weight' => $form[$name]['weight']['#value'],
- );
- }
- return $dummy ? explode(' ', trim(drupal_render($dummy))) : array();
-}
-
-/**
- * Helper form element validator: integer.
- */
-function _element_validate_integer($element, &$form_state) {
- $value = $element['#value'];
- if ($value !== '' && (!is_numeric($value) || intval($value) != $value)) {
- form_error($element, t('%name must be an integer.', array('%name' => $element['#title'])));
- }
-}
-
-/**
- * Helper form element validator: integer > 0.
- */
-function _element_validate_integer_positive($element, &$form_state) {
- $value = $element['#value'];
- if ($value !== '' && (!is_numeric($value) || intval($value) != $value || $value <= 0)) {
- form_error($element, t('%name must be a positive integer.', array('%name' => $element['#title'])));
- }
-}
-
-/**
- * Helper form element validator: number.
- */
-function _element_validate_number($element, &$form_state) {
- $value = $element['#value'];
- if ($value != '' && !is_numeric($value)) {
- form_error($element, t('%name must be a number.', array('%name' => $element['#title'])));
- }
-}
diff --git a/modules/field_ui/field_ui.api.php b/modules/field_ui/field_ui.api.php
deleted file mode 100644
index 0db4c01d3a97c8fdff83eaea82ad669554104c36..0000000000000000000000000000000000000000
--- a/modules/field_ui/field_ui.api.php
+++ /dev/null
@@ -1,201 +0,0 @@
- 'textfield',
- '#title' => t('Maximum length'),
- '#default_value' => $settings['max_length'],
- '#required' => FALSE,
- '#element_validate' => array('_element_validate_integer_positive'),
- '#description' => t('The maximum length of the field in characters. Leave blank for an unlimited size.'),
- );
- return $form;
-}
-
-/**
- * Add settings to an instance field settings form.
- *
- * Invoked from field_ui_field_edit_form() to allow the module defining the
- * field to add settings for a field instance.
- *
- * @param $field
- * The field structure being configured.
- * @param $instance
- * The instance structure being configured.
- *
- * @return
- * The form definition for the field instance settings.
- */
-function hook_field_instance_settings_form($field, $instance) {
- $settings = $instance['settings'];
-
- $form['text_processing'] = array(
- '#type' => 'radios',
- '#title' => t('Text processing'),
- '#default_value' => $settings['text_processing'],
- '#options' => array(
- t('Plain text'),
- t('Filtered text (user selects text format)'),
- ),
- );
- if ($field['type'] == 'text_with_summary') {
- $form['display_summary'] = array(
- '#type' => 'select',
- '#title' => t('Display summary'),
- '#options' => array(
- t('No'),
- t('Yes'),
- ),
- '#description' => t('Display the summary to allow the user to input a summary value. Hide the summary to automatically fill it with a trimmed portion from the main post. '),
- '#default_value' => !empty($settings['display_summary']) ? $settings['display_summary'] : 0,
- );
- }
-
- return $form;
-}
-
-/**
- * Add settings to a widget settings form.
- *
- * Invoked from field_ui_field_edit_form() to allow the module defining the
- * widget to add settings for a widget instance.
- *
- * @param $field
- * The field structure being configured.
- * @param $instance
- * The instance structure being configured.
- *
- * @return
- * The form definition for the widget settings.
- */
-function hook_field_widget_settings_form($field, $instance) {
- $widget = $instance['widget'];
- $settings = $widget['settings'];
-
- if ($widget['type'] == 'text_textfield') {
- $form['size'] = array(
- '#type' => 'textfield',
- '#title' => t('Size of textfield'),
- '#default_value' => $settings['size'],
- '#element_validate' => array('_element_validate_integer_positive'),
- '#required' => TRUE,
- );
- }
- else {
- $form['rows'] = array(
- '#type' => 'textfield',
- '#title' => t('Rows'),
- '#default_value' => $settings['rows'],
- '#element_validate' => array('_element_validate_integer_positive'),
- '#required' => TRUE,
- );
- }
-
- return $form;
-}
-
-
-/**
- * Returns form elements for a formatter's settings.
- *
- * @param $field
- * The field structure being configured.
- * @param $instance
- * The instance structure being configured.
- * @param $view_mode
- * The view mode being configured.
- * @param $form
- * The (entire) configuration form array, which will usually have no use here.
- * @param $form_state
- * The form state of the (entire) configuration form.
- *
- * @return
- * The form elements for the formatter settings.
- */
-function hook_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
- $display = $instance['display'][$view_mode];
- $settings = $display['settings'];
-
- $element = array();
-
- if ($display['type'] == 'text_trimmed' || $display['type'] == 'text_summary_or_trimmed') {
- $element['trim_length'] = array(
- '#title' => t('Length'),
- '#type' => 'textfield',
- '#size' => 20,
- '#default_value' => $settings['trim_length'],
- '#element_validate' => array('_element_validate_integer_positive'),
- '#required' => TRUE,
- );
- }
-
- return $element;
-
-}
-
-/**
- * Returns a short summary for the current formatter settings of an instance.
- *
- * @param $field
- * The field structure.
- * @param $instance
- * The instance structure.
- * @param $view_mode
- * The view mode for which a settings summary is requested.
- *
- * @return
- * A string containing a short summary of the formatter settings.
- */
-function hook_field_formatter_settings_summary($field, $instance, $view_mode) {
- $display = $instance['display'][$view_mode];
- $settings = $display['settings'];
-
- $summary = '';
-
- if ($display['type'] == 'text_trimmed' || $display['type'] == 'text_summary_or_trimmed') {
- $summary = t('Length: @chars chars', array('@chars' => $settings['trim_length']));
- }
-
- return $summary;
-}
-
-/**
- * @} End of "ingroup field_ui_field_type"
- */
diff --git a/modules/field_ui/field_ui.css b/modules/field_ui/field_ui.css
deleted file mode 100644
index 9f53967cbb0d12c945f10bc1add80b0d99ca63b4..0000000000000000000000000000000000000000
--- a/modules/field_ui/field_ui.css
+++ /dev/null
@@ -1,51 +0,0 @@
-/* $Id$ */
-
-/* 'Manage fields' overview */
-#field-overview tr.add-new .label-input {
- float: left; /* LTR */
-}
-#field-overview tr.add-new .tabledrag-changed {
- display: none;
-}
-#field-overview tr.add-new .description {
- margin-bottom: 0;
-}
-#field-overview tr.add-new .add-new-placeholder {
- font-weight: bold;
- padding-bottom: .5em;
-}
-
-/* 'Manage display' overview */
-.field-display-overview tr.region-title td {
- font-weight: bold;
-}
-.field-display-overview tr.region-populated {
- display: none;
-}
-.field-display-overview .field-formatter-summary-cell {
- line-height: 1em;
-}
-.field-display-overview .field-formatter-summary {
- float: left;
- font-size: 0.9em;
-}
-.field-display-overview td.field-formatter-summary-cell span.warning {
- display: block;
- float: left;
- margin-right: .5em;
-}
-.field-display-overview .field-formatter-settings-edit-wrapper {
- float: right;
-}
-.field-display-overview .field-formatter-settings-edit {
- float: right;
-}
-.field-display-overview tr.field-formatter-settings-editing td {
- vertical-align: top;
-}
-.field-display-overview tr.field-formatter-settings-editing .field-formatter-type {
- display: none;
-}
-.field-display-overview .field-formatter-settings-edit-form .formatter-name{
- font-weight: bold;
-}
\ No newline at end of file
diff --git a/modules/field_ui/field_ui.info b/modules/field_ui/field_ui.info
deleted file mode 100644
index 46e3eb7a104b17355850009b1a9f5af5fcd8dc10..0000000000000000000000000000000000000000
--- a/modules/field_ui/field_ui.info
+++ /dev/null
@@ -1,10 +0,0 @@
-; $Id$
-name = Field UI
-description = User interface for the Field API.
-package = Core
-version = VERSION
-core = 7.x
-dependencies[] = field
-files[] = field_ui.module
-files[] = field_ui.admin.inc
-files[] = field_ui.test
diff --git a/modules/field_ui/field_ui.js b/modules/field_ui/field_ui.js
deleted file mode 100644
index 86a8515fb9834d117a79d3b666a1505fca4e8d6c..0000000000000000000000000000000000000000
--- a/modules/field_ui/field_ui.js
+++ /dev/null
@@ -1,225 +0,0 @@
-// $Id$
-
-(function($) {
-
-Drupal.behaviors.fieldManageFields = {
- attach: function (context) {
- attachUpdateSelects(context);
- }
-};
-
-function attachUpdateSelects(context) {
- var widgetTypes = Drupal.settings.fieldWidgetTypes;
- var fields = Drupal.settings.fields;
-
- // Store the default text of widget selects.
- $('#field-overview .widget-type-select', context).each(function () {
- this.initialValue = this.options[0].text;
- });
-
- // 'Field type' select updates its 'Widget' select.
- $('#field-overview .field-type-select', context).each(function () {
- this.targetSelect = $('.widget-type-select', $(this).parents('tr').eq(0));
-
- $(this).bind('change keyup', function () {
- var selectedFieldType = this.options[this.selectedIndex].value;
- var options = (selectedFieldType in widgetTypes ? widgetTypes[selectedFieldType] : []);
- this.targetSelect.fieldPopulateOptions(options);
- });
-
- // Trigger change on initial pageload to get the right widget options
- // when field type comes pre-selected (on failed validation).
- $(this).trigger('change', false);
- });
-
- // 'Existing field' select updates its 'Widget' select and 'Label' textfield.
- $('#field-overview .field-select', context).each(function () {
- this.targetSelect = $('.widget-type-select', $(this).parents('tr').eq(0));
- this.targetTextfield = $('.label-textfield', $(this).parents('tr').eq(0));
-
- $(this).bind('change keyup', function (e, updateText) {
- var updateText = (typeof updateText == 'undefined' ? true : updateText);
- var selectedField = this.options[this.selectedIndex].value;
- var selectedFieldType = (selectedField in fields ? fields[selectedField].type : null);
- var selectedFieldWidget = (selectedField in fields ? fields[selectedField].widget : null);
- var options = (selectedFieldType && (selectedFieldType in widgetTypes) ? widgetTypes[selectedFieldType] : []);
- this.targetSelect.fieldPopulateOptions(options, selectedFieldWidget);
-
- if (updateText) {
- $(this.targetTextfield).attr('value', (selectedField in fields ? fields[selectedField].label : ''));
- }
- });
-
- // Trigger change on initial pageload to get the right widget options
- // and label when field type comes pre-selected (on failed validation).
- $(this).trigger('change', false);
- });
-}
-
-jQuery.fn.fieldPopulateOptions = function (options, selected) {
- return this.each(function () {
- var disabled = false;
- if (options.length == 0) {
- options = [this.initialValue];
- disabled = true;
- }
-
- // If possible, keep the same widget selected when changing field type.
- // This is based on textual value, since the internal value might be
- // different (options_buttons vs. node_reference_buttons).
- var previousSelectedText = this.options[this.selectedIndex].text;
-
- var html = '';
- jQuery.each(options, function (value, text) {
- // Figure out which value should be selected. The 'selected' param
- // takes precedence.
- var is_selected = ((typeof selected != 'undefined' && value == selected) || (typeof selected == 'undefined' && text == previousSelectedText));
- html += '' + text + ' ';
- });
-
- $(this).html(html).attr('disabled', disabled ? 'disabled' : '');
- });
-};
-
-/**
- * Moves a field in the display settings table from visible to hidden.
- *
- * This behavior is dependent on the tableDrag behavior, since it uses the
- * objects initialized in that behavior to update the row.
- */
-Drupal.behaviors.fieldManageDisplayDrag = {
- attach: function (context, settings) {
- // tableDrag is required for this behavior.
- if (!$('table.field-display-overview', context).length || typeof Drupal.tableDrag == 'undefined') {
- return;
- }
-
- var defaultFormatters = Drupal.settings.fieldDefaultFormatters;
- var tableDrag = Drupal.tableDrag['field-display-overview'];
-
- // Add a handler for when a row is swapped, update empty regions.
- tableDrag.row.prototype.onSwap = function (swappedRow) {
- checkEmptyRegions(this.table, this);
- };
-
- // Add a handler to update the formatter selector when a row is dropped in
- // or out of the 'Hidden' section.
- tableDrag.onDrop = function () {
- var dragObject = this;
- var regionRow = $(dragObject.rowObject.element).prevAll('tr.region-message').get(0);
- var visibility = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
-
- // Update the 'format' selector if the visibility changed.
- var $select = $('select.field-formatter-type', dragObject.rowObject.element);
- var oldVisibility = $select[0].className.replace(/([^ ]+[ ]+)*field-display-([^ ]+)([ ]+[^ ]+)*/, '$2');
- if (visibility != oldVisibility) {
- $select.removeClass('field-display-' + oldVisibility).addClass('field-display-' + visibility);
-
- // Update the selected formatter if coming from an actual drag.
- if (!$select.data('noUpdate')) {
- if (visibility == 'visible') {
- // Restore the formatter back to the previously selected one if
- // available, or to the default formatter.
- var value = $select.data('oldFormatter');
- if (typeof value == 'undefined') {
- // Extract field name from the name of the select.
- var fieldName = $select[0].className.match(/\bfield-name-(\S+)\b/)[1].replace('-', '_');
- // Pseudo-fields do not have an entry in the defaultFormatters
- // array, we just return to 'visible' for those.
- value = (fieldName in defaultFormatters) ? defaultFormatters[fieldName] : 'visible';
- }
- $select.data('oldFormatter', value);
- }
- else {
- var value = 'hidden';
- }
- $select.val(value);
- // Fire AJAX update of formatter settings.
- $select.change();
- }
- $select.removeData('noUpdate');
- }
- };
-
- // Add the behavior to each formatter select list.
- $('select.field-formatter-type', context).once('field-formatter-type', function () {
- // Initialize 'previously selected formatter' as the incoming value.
- if ($(this).val() != 'hidden') {
- $(this).data('oldFormatter', $(this).val());
- }
-
- // Add change listener.
- $(this).change(function (event) {
- var $select = $(this);
- var value = $select.val();
-
- // Keep track of the last selected formatter.
- if (value != 'hidden') {
- $select.data('oldFormatter', value);
- }
-
- var visibility = (value == 'hidden') ? 'hidden' : 'visible';
- var oldVisibility = $select[0].className.replace(/([^ ]+[ ]+)*field-display-([^ ]+)([ ]+[^ ]+)*/, '$2');
- if (visibility != oldVisibility) {
- // Prevent the onDrop handler from overriding the selected option.
- $select.data('noUpdate', true);
-
- // Make our new row and select field.
- var $row = $(this).parents('tr:first');
- var $table = $(this).parents('table');
- var tableDrag = Drupal.tableDrag[$table.attr('id')];
- tableDrag.rowObject = new tableDrag.row($row);
-
- // Move the row at the bottom of the new section.
- if (visibility == 'hidden') {
- $('tr:last', tableDrag.table).after($row);
- }
- else {
- $('tr.region-title-hidden', tableDrag.table).before($row);
- }
-
- // Manually update weights and restripe.
- tableDrag.updateFields($row.get(0));
- tableDrag.rowObject.changed = true;
- if (tableDrag.oldRowElement) {
- $(tableDrag.oldRowElement).removeClass('drag-previous');
- }
- tableDrag.oldRowElement = $row.get(0);
- tableDrag.restripeTable();
- tableDrag.rowObject.markChanged();
- tableDrag.oldRowElement = $row;
- $row.addClass('drag-previous');
-
- // Modify empty regions with added or removed fields.
- checkEmptyRegions($table, tableDrag.rowObject);
- }
-
- // Remove focus from selectbox.
- $select.get(0).blur();
- });
- });
-
- var checkEmptyRegions = function ($table, rowObject) {
- $('tr.region-message', $table).each(function () {
- // If the dragged row is in this region, but above the message row, swap
- // it down one space.
- if ($(this).prev('tr').get(0) == rowObject.element) {
- // Prevent a recursion problem when using the keyboard to move rows up.
- if ((rowObject.method != 'keyboard' || rowObject.direction == 'down')) {
- rowObject.swap('after', this);
- }
- }
- // This region has become empty.
- if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').length == 0) {
- $(this).removeClass('region-populated').addClass('region-empty');
- }
- // This region has become populated.
- else if ($(this).is('.region-empty')) {
- $(this).removeClass('region-empty').addClass('region-populated');
- }
- });
- };
- }
-};
-
-})(jQuery);
diff --git a/modules/field_ui/field_ui.module b/modules/field_ui/field_ui.module
deleted file mode 100644
index 59aabb46cd7add2db251e29cfa25f3139a5660be..0000000000000000000000000000000000000000
--- a/modules/field_ui/field_ui.module
+++ /dev/null
@@ -1,368 +0,0 @@
-' . t('About') . '';
- $output .= '' . t('The Field UI module provides an administrative user interface (UI) for attaching and managing fields. Fields can be defined at the content-type level for content items and comments, at the vocabulary level for taxonomy terms, and at the site level for user accounts. Other modules may also enable fields to be defined for their data. Field types (text, image, number, etc.) are defined by modules, and collected and managed by the Field module . For more information, see the online handbook entry for Field UI module .', array('@field' => url('admin/help/field'), '@field_ui' => 'http://drupal.org/handbook/modules/field-ui')) . '
';
- $output .= '' . t('Uses') . ' ';
- $output .= '';
- $output .= '' . t('Planning fields') . ' ';
- $output .= '' . t('There are several decisions you will need to make before definining a field for content, comments, etc.:') . '';
- $output .= '' . t('What the field will be called') . ' ';
- $output .= '' . t('A field has a label (the name displayed in the user interface) and a machine name (the name used internally). The label can be changed after you create the field, if needed, but the machine name cannot be changed after you have created the field.') . '';
- $output .= ' ' . t('What type of data the field will store') . ' ';
- $output .= '' . t('Each field can store one type of data (text, number, file, etc.). When you define a field, you choose a particular field type , which corresponds to the type of data you want to store. The field type cannot be changed after you have created the field.') . ' ';
- $output .= '' . t('How the data will be input and displayed') . ' ';
- $output .= '' . t('Each field type has one or more available widgets associated with it; each widget provides a mechanism for data input when you are editing (text box, select list, file upload, etc.). Each field type also has one or more display options, which determine how the field is displayed to site visitors. The widget and display display options can be changed after you have created the field.') . ' ';
- $output .= '' . t('How many values the field will store') . ' ';
- $output .= '' . t('You can store one value, a specific maximum number of values, or an unlimited number of values in each field. For example, an employee identification number field might store a single number, whereas a phone number field might store multiple phone numbers. This setting can be changed after you have created the field, but if you reduce the maximum number of values, you may lose information.') . ' ';
- $output .= ' ';
- $output .= ' ' . t('Reusing fields') . ' ';
- $output .= '' . t('Once you have defined a field, you can reuse it. For example, if you define a custom image field for one content type, and you need to have an image field with the same parameters on another content type, you can add the same field to the second content type, in the Add existing field area of the user interface. You could also add this field to a taxonomy vocabulary, comments, user accounts, etc.') . ' ';
- $output .= '' . t('Some settings of a reused field are unique to each use of the field; others are shared across all places you use the field. For example, the label of a text field is unique to each use, while the setting for the number of values is shared.') . ' ';
- $output .= '' . t('There are two main reasons for reusing fields. First, reusing fields can save you time over defining new fields. Second, reusing fields also allows you to display, filter, group, and sort content together by field across content types. For example, the contributed Views module allows you to create lists and tables of content. So if you use the same field on multiple content types, you can create a View containing all of those content types together displaying that field, sorted by that field, and/or filtered by that field.') . ' ';
- $output .= '' . t('Fields on content items') . ' ';
- $output .= '' . t('Fields on content items are defined at the content-type level, on the Manage fields tab of the content type edit page (which you can reach from the Content types page ). When you define a field for a content type, each content item of that type will have that field added to it. Some fields, such as the Title and Body, are provided for you when you create a content type, or are provided on content types created by your installation profile.', array('@types' => url('admin/structure/types'))) . ' ';
- $output .= '' . t('Fields on taxonomy terms') . ' ';
- $output .= '' . t('Fields on taxonomy terms are defined at the taxonomy vocabulary level, on the Manage fields tab of the vocabulary edit page (which you can reach from the Taxonomy page ). When you define a field for a vocabulary, each term in that vocabulary will have that field added to it. For example, you could define an image field for a vocabulary to store an icon with each term.', array('@taxonomy' => url('admin/structure/taxonomy'))) . ' ';
- $output .= '' . t('Fields on user accounts') . ' ';
- $output .= '' . t('Fields on user accounts are defined on a site-wide basis on the Manage fields tab of the Account settings page. When you define a field for user accounts, each user account will have that field added to it. For example, you could add a long text field to allow users to include a biography.', array('@fields' => url('admin/config/people/accounts/fields'), '@accounts' => url('admin/config/people/accounts'))) . ' ';
- $output .= '' . t('Fields on comments') . ' ';
- $output .= '' . t('Fields on comments are defined at the content-type level, on the Comment fields tab of the content type edit page (which you can reach from the Content types page ). When you add a field for comments, each comment on a content item of that type will have that field added to it. For example, you could add a website field to the comments on forum posts, to allow forum commenters to add a link to their website.', array('@types' => url('admin/structure/types'))) . ' ';
- $output .= ' ';
- return $output;
-
- case 'admin/reports/fields':
- return '' . t('This list shows all fields currently in use for easy reference.') . '
';
- }
-}
-
-/**
- * Implements hook_menu().
- */
-function field_ui_menu() {
- $items['admin/reports/fields'] = array(
- 'title' => 'Field list',
- 'description' => 'Overview of fields on all entity types.',
- 'page callback' => 'field_ui_fields_list',
- 'access arguments' => array('administer content types'),
- 'type' => MENU_NORMAL_ITEM,
- 'file' => 'field_ui.admin.inc',
- );
-
- // Ensure the following is not executed until field_bundles is working and
- // tables are updated. Needed to avoid errors on initial installation.
- if (defined('MAINTENANCE_MODE')) {
- return $items;
- }
-
- // Create tabs for all possible bundles.
- foreach (entity_get_info() as $entity_type => $entity_info) {
- if ($entity_info['fieldable']) {
- foreach ($entity_info['bundles'] as $bundle_name => $bundle_info) {
- if (isset($bundle_info['admin'])) {
- // Extract path information from the bundle.
- $path = $bundle_info['admin']['path'];
- // Different bundles can appear on the same path (e.g. %node_type and
- // %comment_node_type). To allow field_ui_menu_load() to extract the
- // actual bundle object from the translated menu router path
- // arguments, we need to identify the argument position of the bundle
- // name string ('bundle argument') and pass that position to the menu
- // loader. The position needs to be casted into a string; otherwise it
- // would be replaced with the bundle name string.
- if (isset($bundle_info['admin']['bundle argument'])) {
- $bundle_arg = $bundle_info['admin']['bundle argument'];
- $bundle_pos = (string) $bundle_arg;
- }
- else {
- $bundle_arg = $bundle_name;
- $bundle_pos = '0';
- }
- // This is the position of the %field_ui_menu placeholder in the
- // items below.
- $field_position = count(explode('/', $path)) + 1;
-
- // Extract access information, providing defaults.
- $access = array_intersect_key($bundle_info['admin'], drupal_map_assoc(array('access callback', 'access arguments')));
- $access += array(
- 'access callback' => 'user_access',
- 'access arguments' => array('administer site configuration'),
- );
-
- $items["$path/fields"] = array(
- 'title' => 'Manage fields',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_field_overview_form', $entity_type, $bundle_arg),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 1,
- 'file' => 'field_ui.admin.inc',
- ) + $access;
- $items["$path/fields/%field_ui_menu"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title callback' => 'field_ui_menu_title',
- 'title arguments' => array($field_position),
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_field_edit_form', $field_position),
- 'type' => MENU_LOCAL_TASK,
- 'file' => 'field_ui.admin.inc',
- ) + $access;
- $items["$path/fields/%field_ui_menu/edit"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title' => 'Edit',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_field_edit_form', $field_position),
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- 'file' => 'field_ui.admin.inc',
- ) + $access;
- $items["$path/fields/%field_ui_menu/field-settings"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title' => 'Field settings',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_field_settings_form', $field_position),
- 'type' => MENU_LOCAL_TASK,
- 'file' => 'field_ui.admin.inc',
- ) + $access;
- $items["$path/fields/%field_ui_menu/widget-type"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title' => 'Widget type',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_widget_type_form', $field_position),
- 'type' => MENU_LOCAL_TASK,
- 'file' => 'field_ui.admin.inc',
- ) + $access;
- $items["$path/fields/%field_ui_menu/delete"] = array(
- 'load arguments' => array($entity_type, $bundle_arg, $bundle_pos, '%map'),
- 'title' => 'Delete',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_field_delete_form', $field_position),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 10,
- 'file' => 'field_ui.admin.inc',
- ) + $access;
-
- // 'Manage display' tab.
- $items["$path/display"] = array(
- 'title' => 'Manage display',
- 'page callback' => 'drupal_get_form',
- 'page arguments' => array('field_ui_display_overview_form', $entity_type, $bundle_arg, 'default'),
- 'type' => MENU_LOCAL_TASK,
- 'weight' => 2,
- 'file' => 'field_ui.admin.inc',
- ) + $access;
-
- // View modes secondary tabs.
- // The same base $path for the menu item (with a placeholder) can be
- // used for all bundles of a given entity type; but depending on
- // administrator settings, each bundle has a different set of view
- // modes available for customisation. So we define menu items for all
- // view modes, and use an access callback to determine which ones are
- // actually visible for a given bundle.
- $weight = 0;
- $view_modes = array('default' => array('label' => t('Default'))) + $entity_info['view modes'];
- foreach ($view_modes as $view_mode => $view_mode_info) {
- $items["$path/display/$view_mode"] = array(
- 'title' => $view_mode_info['label'],
- 'page arguments' => array('field_ui_display_overview_form', $entity_type, $bundle_arg, $view_mode),
- // The access callback needs to check both the current 'custom
- // display' setting for the view mode, and the overall access
- // rules for the bundle admin pages.
- 'access callback' => '_field_ui_view_mode_menu_access',
- 'access arguments' => array_merge(array($entity_type, $bundle_arg, $view_mode, $access['access callback']), $access['access arguments']),
- 'type' => ($view_mode == 'default' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK),
- 'weight' => ($view_mode == 'default' ? -10 : $weight++),
- 'file' => 'field_ui.admin.inc',
- );
- }
- }
- }
- }
- }
- return $items;
-}
-
-/**
- * Menu loader; Load a field instance based on field and bundle name.
- *
- * @param $field_name
- * The name of the field, as contained in the path.
- * @param $entity_type
- * The name of the entity.
- * @param $bundle_name
- * The name of the bundle, as contained in the path.
- * @param $bundle_pos
- * The position of $bundle_name in $map.
- * @param $map
- * The translated menu router path argument map.
- */
-function field_ui_menu_load($field_name, $entity_type, $bundle_name, $bundle_pos, $map) {
- // Extract the actual bundle name from the translated argument map.
- // The menu router path to manage fields of an entity can be shared among
- // multiple bundles. For example:
- // - admin/structure/types/manage/%node_type/fields/%field_ui_menu
- // - admin/structure/types/manage/%comment_node_type/fields/%field_ui_menu
- // The menu system will automatically load the correct bundle depending on the
- // actual path arguments, but this menu loader function only receives the node
- // type string as $bundle_name, which is not the bundle name for comments.
- // We therefore leverage the dynamically translated $map provided by the menu
- // system to retrieve the actual bundle and bundle name for the current path.
- if ($bundle_pos > 0) {
- $bundle = $map[$bundle_pos];
- $bundle_name = field_extract_bundle($entity_type, $bundle);
- }
- // Check whether the field exists at all.
- if ($field = field_info_field($field_name)) {
- // Only return the field if a field instance exists for the given entity
- // type and bundle.
- if ($instance = field_info_instance($entity_type, $field_name, $bundle_name)) {
- return $instance;
- }
- }
- return FALSE;
-}
-
-/**
- * Menu title callback.
- */
-function field_ui_menu_title($instance) {
- return t($instance['label']);
-}
-
-/**
- * Menu access callback for the 'view mode display settings' pages.
- */
-function _field_ui_view_mode_menu_access($entity_type, $bundle, $view_mode, $access_callback) {
- // First, determine visibility according to the 'use custom display'
- // setting for the view mode.
- $bundle = field_extract_bundle($entity_type, $bundle);
- $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
- $visibility = ($view_mode == 'default') || !empty($view_mode_settings[$view_mode]['custom_settings']);
-
- // Then, determine access according to the $access parameter. This duplicates
- // part of _menu_check_access().
- if ($visibility) {
- // Grab the variable 'access arguments' part.
- $args = array_slice(func_get_args(), 4);
- $callback = empty($access_callback) ? 0 : trim($access_callback);
- if (is_numeric($callback)) {
- return (bool) $callback;
- }
- else {
- // As call_user_func_array() is quite slow and user_access is a very
- // common callback, it is worth making a special case for it.
- if ($access_callback == 'user_access') {
- return (count($args) == 1) ? user_access($args[0]) : user_access($args[0], $args[1]);
- }
- elseif (function_exists($access_callback)) {
- return call_user_func_array($access_callback, $args);
- }
- }
- }
-}
-
-/**
- * Implements hook_theme().
- */
-function field_ui_theme() {
- return array(
- 'field_ui_display_overview_table' => array(
- 'render element' => 'elements',
- 'file' => 'field_ui.admin.inc',
- 'template' => 'field_ui-display-overview-table',
- ),
- 'field_ui_table' => array(
- 'render element' => 'elements',
- ),
- );
-}
-
-/**
- * Implements hook_element_info().
- */
-function field_ui_element_info() {
- return array(
- 'table' => array(
- '#theme' => 'field_ui_table',
- ),
- );
-}
-
-/**
- * Implements hook_field_attach_create_bundle().
- */
-function field_ui_field_attach_create_bundle($entity_type, $bundle) {
- // When a new bundle is created, the menu needs to be rebuilt to add our
- // menu item tabs.
- variable_set('menu_rebuild_needed', TRUE);
-}
-
-/**
- * Helper function to create the right administration path for a bundle.
- */
-function _field_ui_bundle_admin_path($entity_type, $bundle_name) {
- $bundles = field_info_bundles($entity_type);
- $bundle_info = $bundles[$bundle_name];
- return isset($bundle_info['admin']['real path']) ? $bundle_info['admin']['real path'] : $bundle_info['admin']['path'];
-}
-
-/**
- * Helper function to identify inactive fields within a bundle.
- */
-function field_ui_inactive_instances($entity_type, $bundle_name = NULL) {
- if (!empty($bundle_name)) {
- $inactive = array($bundle_name => array());
- $params = array('bundle' => $bundle_name);
- }
- else {
- $inactive = array();
- $params = array();
- }
- $params['entity_type'] = $entity_type;
-
- $active_instances = field_info_instances($entity_type);
- $all_instances = field_read_instances($params, array('include_inactive' => TRUE));
- foreach ($all_instances as $instance) {
- if (!isset($active_instances[$instance['bundle']][$instance['field_name']])) {
- $inactive[$instance['bundle']][$instance['field_name']] = $instance;
- }
- }
- if (!empty($bundle_name)) {
- return $inactive[$bundle_name];
- }
- return $inactive;
-}
-
-/**
- * Add a button Save and add fields to Create content type form.
- */
-function field_ui_form_node_type_form_alter(&$form, $form_state) {
- // We want to display the button only on add page.
- if (empty($form['#node_type']->type)) {
- $form['actions']['save_continue'] = array(
- '#type' => 'submit',
- '#value' => t('Save and add fields'),
- '#weight' => 45,
- );
- $form['#submit'][] = 'field_ui_form_node_type_form_submit';
- }
-}
-
-/**
- * Redirect to manage fields form.
- */
-function field_ui_form_node_type_form_submit($form, &$form_state) {
- if ($form_state['clicked_button']['#parents'][0] === 'save_continue') {
- $form_state['redirect'] = _field_ui_bundle_admin_path('node', $form_state['values']['type']) .'/fields';
- }
-}
-
diff --git a/modules/field_ui/field_ui.test b/modules/field_ui/field_ui.test
deleted file mode 100644
index 5baaa341af44a77452884ab9508da25b3c0547e5..0000000000000000000000000000000000000000
--- a/modules/field_ui/field_ui.test
+++ /dev/null
@@ -1,400 +0,0 @@
- 'Field UI tests',
- 'description' => 'Test the field UI functionality.',
- 'group' => 'Field UI',
- );
- }
-
- function setUp() {
- parent::setUp('field_test');
-
- // Create test user.
- $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer taxonomy'));
- $this->drupalLogin($admin_user);
-
- // Create content type, with underscores.
- $type_name = strtolower($this->randomName(8)) . '_' .'test';
- $type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name));
- $this->type = $type->type;
- // Store a valid URL name, with hyphens instead of underscores.
- $this->hyphen_type = str_replace('_', '-', $this->type);
-
- // Create random field name.
- $this->field_label = $this->randomName(8);
- $this->field_name_input = strtolower($this->randomName(8));
- $this->field_name = 'field_'. $this->field_name_input;
- }
-
- /**
- * Main entry point for the field CRUD tests.
- *
- * In order to act on the same fields, and not create the fields over and over
- * again the following tests create, update and delete the same fields.
- */
- function testCRUDFields() {
- $this->manageFieldsPage();
- $this->createField();
- $this->updateField();
- $this->addExistingField();
- }
-
- /**
- * Test the manage fields page.
- */
- function manageFieldsPage() {
- $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields');
- // Check all table columns.
- $table_headers = array(
- t('Label'),
- t('Name'),
- t('Field'),
- t('Widget'),
- t('Operations'),
- );
- foreach ($table_headers as $table_header) {
- // We check that the label appear in the table headings.
- $this->assertRaw($table_header . '', t('%table_header table header was found.', array('%table_header' => $table_header)));
- }
-
- // "Add new field" and "Add existing field" aren't a table heading so just
- // test the text.
- foreach (array('Add new field', 'Add existing field') as $element) {
- $this->assertText($element, t('"@element" was found.', array('@element' => $element)));
- }
- }
-
- /**
- * Test adding a new field.
- *
- * @todo Assert properties can bet set in the form and read back in $field and
- * $instances.
- */
- function createField() {
- // Create a test field.
- $edit = array(
- '_add_new_field[label]' => $this->field_label,
- '_add_new_field[field_name]' => $this->field_name_input,
- );
- $this->fieldUIAddNewField('admin/structure/types/manage/' . $this->hyphen_type, $edit);
-
- // Assert the field appears in the "add existing field" section for
- // different entity types; e.g. if a field was added in a node entity, it
- // should also appear in the 'taxonomy term' entity.
- $vocabulary = taxonomy_vocabulary_load(1);
- $this->drupalGet('admin/structure/taxonomy/' . $vocabulary->machine_name . '/fields');
- $this->assertTrue($this->xpath('//select[@name="_add_existing_field[field_name]"]//option[@value="' . $this->field_name . '"]'), t('Existing field was found in account settings.'));
- }
-
- /**
- * Test editing an existing field.
- */
- function updateField() {
- // Go to the field edit page.
- $this->drupalGet('admin/structure/types/manage/' . $this->hyphen_type . '/fields/' . $this->field_name);
-
- // Populate the field settings with new settings.
- $string = 'updated dummy test string';
- $edit = array(
- 'field[settings][test_field_setting]' => $string,
- 'instance[settings][test_instance_setting]' => $string,
- 'instance[widget][settings][test_widget_setting]' => $string,
- );
- $this->drupalPost(NULL, $edit, t('Save settings'));
-
- // Assert the field settings are correct.
- $this->assertFieldSettings($this->type, $this->field_name, $string);
-
- // Assert redirection back to the "manage fields" page.
- $this->assertText(t('Saved @label configuration.', array('@label' => $this->field_label)), t('Redirected to "Manage fields" page.'));
- }
-
- /**
- * Test adding an existing field in another content type.
- */
- function addExistingField() {
- // Check "Add existing field" appears.
- $this->drupalGet('admin/structure/types/manage/page/fields');
- $this->assertRaw(t('Add existing field'), t('"Add existing field" was found.'));
-
- // Check that the list of options respects entity type restrictions on
- // fields. The 'comment' field is restricted to the 'comment' entity type
- // and should not appear in the list.
- $this->assertFalse($this->xpath('//select[@id="edit--add-existing-field-field-name"]//option[@value="comment"]'), t('The list of options respects entity type restrictions.'));
-
- // Add a new field based on an existing field.
- $edit = array(
- '_add_existing_field[label]' => $this->field_label . '_2',
- '_add_existing_field[field_name]' => $this->field_name,
- );
- $this->fieldUIAddExistingField("admin/structure/types/manage/page", $edit);
- }
-
- /**
- * Assert the field settings.
- *
- * @param $bundle
- * The bundle name for the instance.
- * @param $field_name
- * The field name for the instance.
- * @param $string
- * The settings text.
- * @param $entity_type
- * The entity type for the instance.
- */
- function assertFieldSettings($bundle, $field_name, $string = 'dummy test string', $entity_type = 'node') {
- // Reset the fields info.
- _field_info_collate_fields(TRUE);
- // Assert field settings.
- $field = field_info_field($field_name);
- $this->assertTrue($field['settings']['test_field_setting'] == $string, t('Field settings were found.'));
-
- // Assert instance and widget settings.
- $instance = field_info_instance($entity_type, $field_name, $bundle);
- $this->assertTrue($instance['settings']['test_instance_setting'] == $string, t('Field instance settings were found.'));
- $this->assertTrue($instance['widget']['settings']['test_widget_setting'] == $string, t('Field widget settings were found.'));
- }
-
- /**
- * Tests that default value is correctly validated and saved.
- */
- function testDefaultValue() {
- // Create a test field and instance.
- $field_name = 'test';
- $field = array(
- 'field_name' => $field_name,
- 'type' => 'test_field'
- );
- field_create_field($field);
- $instance = array(
- 'field_name' => $field_name,
- 'entity_type' => 'node',
- 'bundle' => $this->type,
- );
- field_create_instance($instance);
-
- $langcode = LANGUAGE_NONE;
- $admin_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/' . $field_name;
- $element_id = "edit-$field_name-$langcode-0-value";
- $element_name = "{$field_name}[$langcode][0][value]";
- $this->drupalGet($admin_path);
- $this->assertFieldById($element_id, '', t('The default value widget was empty.'));
-
- // Check that invalid default values are rejected.
- $edit = array($element_name => '-1');
- $this->drupalPost($admin_path, $edit, t('Save settings'));
- $this->assertText("$field_name does not accept the value -1", t('Form vaildation failed.'));
-
- // Check that the default value is saved.
- $edit = array($element_name => '1');
- $this->drupalPost($admin_path, $edit, t('Save settings'));
- $this->assertText("Saved $field_name configuration", t('The form was successfully submitted.'));
- $instance = field_info_instance('node', $field_name, $this->type);
- $this->assertEqual($instance['default_value'], array(array('value' => 1)), t('The default value was correctly saved.'));
-
- // Check that the default value shows up in the form
- $this->drupalGet($admin_path);
- $this->assertFieldById($element_id, '1', t('The default value widget was displayed with the correct value.'));
-
- // Check that the default value can be emptied.
- $edit = array($element_name => '');
- $this->drupalPost(NULL, $edit, t('Save settings'));
- $this->assertText("Saved $field_name configuration", t('The form was successfully submitted.'));
- field_info_cache_clear();
- $instance = field_info_instance('node', $field_name, $this->type);
- $this->assertEqual($instance['default_value'], NULL, t('The default value was correctly saved.'));
- }
-
- /**
- * Tests that deletion removes fields and instances as expected.
- */
- function testDeleteField() {
- // Create a new field.
- $bundle_path1 = 'admin/structure/types/manage/' . $this->hyphen_type;
- $edit1 = array(
- '_add_new_field[label]' => $this->field_label,
- '_add_new_field[field_name]' => $this->field_name,
- );
- $this->fieldUIAddNewField($bundle_path1, $edit1);
-
- // Create an additional node type.
- $type_name2 = strtolower($this->randomName(8)) . '_' .'test';
- $type2 = $this->drupalCreateContentType(array('name' => $type_name2, 'type' => $type_name2));
- $type_name2 = $type2->type;
- $hyphen_type2 = str_replace('_', '-', $type_name2);
-
- // Add an instance to the second node type.
- $bundle_path2 = 'admin/structure/types/manage/' . $hyphen_type2;
- $edit2 = array(
- '_add_existing_field[label]' => $this->field_label,
- '_add_existing_field[field_name]' => $this->field_name,
- );
- $this->fieldUIAddExistingField($bundle_path2, $edit2);
-
- // Delete the first instance.
- $this->fieldUIDeleteField($bundle_path1, $this->field_name, $this->field_label, $this->type);
-
- // Reset the fields info.
- _field_info_collate_fields(TRUE);
- // Check that the field instance was deleted.
- $this->assertNull(field_info_instance('node', $this->field_name, $this->type), t('Field instance was deleted.'));
- // Check that the field was not deleted
- $this->assertNotNull(field_info_field($this->field_name), t('Field was not deleted.'));
-
- // Delete the second instance.
- $this->fieldUIDeleteField($bundle_path2, $this->field_name, $this->field_label, $type_name2);
-
- // Reset the fields info.
- _field_info_collate_fields(TRUE);
- // Check that the field instance was deleted.
- $this->assertNull(field_info_instance('node', $this->field_name, $type_name2), t('Field instance was deleted.'));
- // Check that the field was deleted too.
- $this->assertNull(field_info_field($this->field_name), t('Field was deleted.'));
- }
-
- /**
- * Test that Field UI respects the 'no_ui' option in hook_field_info().
- */
- function testHiddenFields() {
- $bundle_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/';
-
- // Check that the field type is not available in the 'add new field' row.
- $this->drupalGet($bundle_path);
- $this->assertFalse($this->xpath('//select[@id="edit--add-new-field-type"]//option[@value="hidden_test_field"]'), t("The 'add new field' select respects field types 'no_ui' property."));
-
- // Create a field and an instance programmatically.
- $field_name = 'hidden_test_field';
- field_create_field(array('field_name' => $field_name, 'type' => $field_name));
- $instance = array(
- 'field_name' => $field_name,
- 'bundle' => $this->type,
- 'entity_type' => 'node',
- 'label' => t('Hidden field'),
- 'widget_type' => 'test_field_widget',
- );
- field_create_instance($instance);
- $this->assertTrue(field_read_instance('node', $field_name, $this->type), t('An instance of the field %field was created programmatically.', array('%field' => $field_name)));
-
- // Check that the newly added instance appears on the 'Manage Fields'
- // screen.
- $this->drupalGet($bundle_path);
- $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $instance['label'], t('Field was created and appears in the overview page.'));
-
- // Check that the instance does not appear in the 'add existing field' row
- // on other bundles.
- $bundle_path = 'admin/structure/types/manage/article/fields/';
- $this->drupalGet($bundle_path);
- $this->assertFalse($this->xpath('//select[@id="edit--add-existing-field-field-name"]//option[@value=:field_name]', array(':field_name' => $field_name)), t("The 'add existing field' select respects field types 'no_ui' property."));
- }
-
- /**
- * Create a new field through the Field UI.
- *
- * @param $bundle_path
- * Path of the 'Manage fields' page for the bundle.
- * @param $initial_edit
- * $edit parameter for drupalPost() on the first step ('Manage fields'
- * screen).
- * @param $field_edit
- * $edit parameter for drupalPost() on the first step ('Field settings'
- * form).
- * @param $instance_edit
- * $edit parameter for drupalPost() on the second step ('Instance settings'
- * form).
- */
- function fieldUIAddNewField($bundle_path, $initial_edit, $field_edit = array(), $instance_edit = array()) {
- // Use 'test_field' field type by default.
- $initial_edit += array(
- '_add_new_field[type]' => 'test_field',
- '_add_new_field[widget_type]' => 'test_field_widget',
- );
- $label = $initial_edit['_add_new_field[label]'];
- $field_name = $initial_edit['_add_new_field[field_name]'];
-
- // First step : 'Add new field' on the 'Manage fields' page.
- $this->drupalPost("$bundle_path/fields", $initial_edit, t('Save'));
- $this->assertRaw(t('These settings apply to the %label field everywhere it is used.', array('%label' => $label)), t('Field settings page was displayed.'));
-
- // Second step : 'Field settings' form.
- $this->drupalPost(NULL, $field_edit, t('Save field settings'));
- $this->assertRaw(t('Updated field %label field settings.', array('%label' => $label)), t('Redirected to instance and widget settings page.'));
-
- // Assert the field settings are correct.
- $this->assertFieldSettings($this->type, $this->field_name);
-
- // Third step : 'Instance settings' form.
- $this->drupalPost(NULL, $instance_edit, t('Save settings'));
- $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), t('Redirected to "Manage fields" page.'));
-
- // Check that the field appears in the overview form.
- $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, t('Field was created and appears in the overview page.'));
- }
-
- /**
- * Add an existing field through the Field UI.
- *
- * @param $bundle_path
- * Path of the 'Manage fields' page for the bundle.
- * @param $initial_edit
- * $edit parameter for drupalPost() on the first step ('Manage fields'
- * screen).
- * @param $instance_edit
- * $edit parameter for drupalPost() on the second step ('Instance settings'
- * form).
- */
- function fieldUIAddExistingField($bundle_path, $initial_edit, $instance_edit = array()) {
- // Use 'test_field_widget' by default.
- $initial_edit += array(
- '_add_existing_field[widget_type]' => 'test_field_widget',
- );
- $label = $initial_edit['_add_existing_field[label]'];
- $field_name = $initial_edit['_add_existing_field[field_name]'];
-
- // First step : 'Add existing field' on the 'Manage fields' page.
- $this->drupalPost("$bundle_path/fields", $initial_edit, t('Save'));
-
- // Second step : 'Instance settings' form.
- $this->drupalPost(NULL, $instance_edit, t('Save settings'));
- $this->assertRaw(t('Saved %label configuration.', array('%label' => $label)), t('Redirected to "Manage fields" page.'));
-
- // Check that the field appears in the overview form.
- $this->assertFieldByXPath('//table[@id="field-overview"]//td[1]', $label, t('Field was created and appears in the overview page.'));
- }
-
- /**
- * Delete a field instance through the Field UI.
- *
- * @param $bundle_path
- * Path of the 'Manage fields' page for the bundle.
- * @param $field_name
- * The name of the field.
- * @param $label
- * The label of the field.
- * @param $bundle_label
- * The label of the bundle.
- */
- function fieldUIDeleteField($bundle_path, $field_name, $label, $bundle_label) {
- // Display confirmation form.
- $this->drupalGet("$bundle_path/fields/$field_name/delete");
- $this->assertRaw(t('Are you sure you want to delete the field %label', array('%label' => $label)), t('Delete confirmation was found.'));
-
- // Submit confirmation form.
- $this->drupalPost(NULL, array(), t('Delete'));
- $this->assertRaw(t('The field %label has been deleted from the %type content type.', array('%label' => $label, '%type' => $bundle_label)), t('Delete message was found.'));
-
- // Check that the field doesn not appear in the overview form
- $this->assertNoFieldByXPath('//table[@id="field-overview"]//span[@class="label-field"]', $label, t('Field does not appear in the overview page.'));
- }
-}
diff --git a/modules/file/file.css b/modules/file/file.css
deleted file mode 100644
index 10d9a899d9e6772cb614df0b36cabe54f3113cd4..0000000000000000000000000000000000000000
--- a/modules/file/file.css
+++ /dev/null
@@ -1,36 +0,0 @@
-/* $Id$ */
-
-/**
- * Managed file element styles.
- */
-.form-managed-file .form-file,
-.form-managed-file .form-submit {
- margin: 0;
-}
-
-.form-managed-file input.progress-disabled {
- float: none;
- display: inline;
-}
-
-.form-managed-file div.ajax-progress,
-.form-managed-file div.throbber {
- display: inline;
- float: none;
- padding: 1px 5px 2px 5px;
-}
-
-.form-managed-file div.ajax-progress div {
- display: inline;
-}
-
-.form-managed-file div.ajax-progress-bar {
- display: none;
- margin-top: 4px;
- width: 28em;
- padding: 0;
-}
-
-.form-managed-file div.ajax-progress-bar div.bar {
- margin: 0;
-}
diff --git a/modules/file/file.field.inc b/modules/file/file.field.inc
deleted file mode 100644
index 403f94f6678c9ada9bdb60438023145e35aff653..0000000000000000000000000000000000000000
--- a/modules/file/file.field.inc
+++ /dev/null
@@ -1,972 +0,0 @@
- array(
- 'label' => t('File'),
- 'description' => t('This field stores the ID of a file as an integer value.'),
- 'settings' => array(
- 'display_field' => 0,
- 'display_default' => 0,
- 'uri_scheme' => 'public',
- ),
- 'instance_settings' => array(
- 'file_extensions' => 'txt',
- 'file_directory' => '',
- 'max_filesize' => '',
- 'description_field' => 0,
- ),
- 'default_widget' => 'file_generic',
- 'default_formatter' => 'file_default',
- ),
- );
-}
-
-/**
- * Implements hook_field_schema().
- */
-function file_field_schema($field) {
- return array(
- 'columns' => array(
- 'fid' => array(
- 'description' => 'The {files}.fid being referenced in this field.',
- 'type' => 'int',
- 'not null' => FALSE,
- 'unsigned' => TRUE,
- ),
- 'display' => array(
- 'description' => 'Flag to control whether this file should be displayed when viewing content.',
- 'type' => 'int',
- 'size' => 'tiny',
- 'unsigned' => TRUE,
- 'not null' => TRUE,
- 'default' => 1,
- ),
- 'description' => array(
- 'description' => 'A description of the file.',
- 'type' => 'text',
- 'not null' => FALSE,
- ),
- ),
- 'indexes' => array(
- 'fid' => array('fid'),
- ),
- );
-}
-
-/**
- * Implements hook_field_settings_form().
- */
-function file_field_settings_form($field, $instance, $has_data) {
- $defaults = field_info_field_settings($field['type']);
- $settings = array_merge($defaults, $field['settings']);
-
- $form['#attached']['js'][] = drupal_get_path('module', 'file') . '/file.js';
-
- $form['display_field'] = array(
- '#type' => 'checkbox',
- '#title' => t('Enable Display field'),
- '#default_value' => $settings['display_field'],
- '#description' => t('The display option allows users to choose if a file should be shown when viewing the content.'),
- );
- $form['display_default'] = array(
- '#type' => 'checkbox',
- '#title' => t('Files displayed by default'),
- '#default_value' => $settings['display_default'],
- '#description' => t('This setting only has an effect if the display option is enabled.'),
- );
-
- $scheme_options = array();
- foreach (file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $stream_wrapper) {
- $scheme_options[$scheme] = $stream_wrapper['name'];
- }
- $form['uri_scheme'] = array(
- '#type' => 'radios',
- '#title' => t('Upload destination'),
- '#options' => $scheme_options,
- '#default_value' => $settings['uri_scheme'],
- '#description' => t('Select where the final files should be stored. Private file storage has significantly more overhead than public files, but allows restricted access to files within this field.'),
- '#disabled' => $has_data,
- );
-
- return $form;
-}
-
-/**
- * Implements hook_field_instance_settings_form().
- */
-function file_field_instance_settings_form($field, $instance) {
- $settings = $instance['settings'];
-
- $form['file_directory'] = array(
- '#type' => 'textfield',
- '#title' => t('File directory'),
- '#default_value' => $settings['file_directory'],
- '#description' => t('Optional subdirectory within the upload destination where files will be stored. Do not include preceding or trailing slashes.', array('%directory' => variable_get('file_directory_path', 'files') . '/')),
- '#element_validate' => array('_file_generic_settings_file_directory_validate'),
- '#weight' => 3,
- );
-
- // Make the extension list a little more human-friendly by comma-separation.
- $extensions = str_replace(' ', ', ', $settings['file_extensions']);
- $form['file_extensions'] = array(
- '#type' => 'textfield',
- '#title' => t('Allowed file extensions'),
- '#default_value' => $extensions,
- '#description' => t('Separate extensions with a space or comma and do not include the leading dot.'),
- '#element_validate' => array('_file_generic_settings_extensions'),
- '#weight' => 1,
- // By making this field required, we prevent a potential security issue
- // that would allow files of any type to be uploaded.
- '#required' => TRUE,
- );
-
- $form['max_filesize'] = array(
- '#type' => 'textfield',
- '#title' => t('Maximum upload size'),
- '#default_value' => $settings['max_filesize'],
- '#description' => t('Enter a value like "512" (bytes), "80 KB" (kilobytes) or "50 MB" (megabytes) in order to restrict the allowed file size. If left empty the file sizes will be limited only by PHP\'s maximum post and file upload sizes (current limit %limit ).', array('%limit' => format_size(file_upload_max_size()))),
- '#size' => 10,
- '#element_validate' => array('_file_generic_settings_max_filesize'),
- '#weight' => 5,
- );
-
- $form['description_field'] = array(
- '#type' => 'checkbox',
- '#title' => t('Enable Description field'),
- '#default_value' => isset($settings['description_field']) ? $settings['description_field'] : '',
- '#description' => t('The description field allows users to enter a description about the uploaded file.'),
- '#parents' => array('instance', 'settings', 'description_field'),
- '#weight' => 11,
- );
-
- return $form;
-}
-
-/**
- * Element validate callback for the maximum upload size field.
- *
- * Ensure a size that can be parsed by parse_size() has been entered.
- */
-function _file_generic_settings_max_filesize($element, &$form_state) {
- if (!empty($element['#value']) && !is_numeric(parse_size($element['#value']))) {
- form_error($element, t('The "!name" option must contain a valid value. You may either leave the text field empty or enter a string like "512" (bytes), "80 KB" (kilobytes) or "50 MB" (megabytes).', array('!name' => t($element['title']))));
- }
-}
-
-/**
- * Element validate callback for the allowed file extensions field.
- *
- * This doubles as a convenience clean-up function and a validation routine.
- * Commas are allowed by the end-user, but ultimately the value will be stored
- * as a space-separated list for compatibility with file_validate_extensions().
- */
-function _file_generic_settings_extensions($element, &$form_state) {
- if (!empty($element['#value'])) {
- $extensions = preg_replace('/([, ]+\.?)/', ' ', trim(strtolower($element['#value'])));
- $extensions = array_filter(explode(' ', $extensions));
- $extensions = implode(' ', array_unique($extensions));
- if (!preg_match('/^([a-z0-9]+([.][a-z0-9])* ?)+$/', $extensions)) {
- form_error($element, t('The list of allowed extensions is not valid, be sure to exclude leading dots and to separate extensions with a comma or space.'));
- }
- else {
- form_set_value($element, $extensions, $form_state);
- }
- }
-}
-
-/**
- * Element validate callback for the file destination field.
- *
- * Remove slashes from the beginning and end of the destination value and ensure
- * that the file directory path is not included at the beginning of the value.
- */
-function _file_generic_settings_file_directory_validate($element, &$form_state) {
- // Strip slashes from the beginning and end of $widget['file_directory'].
- $value = trim($element['#value'], '\\/');
-
- // Do not allow the file path to be the same as the file_directory_path().
- // This causes all sorts of problems with things like file_create_url().
- if (strpos($value, file_directory_path()) === 0) {
- form_error($element, t('The file directory (@file_directory) cannot start with the system files directory (@files_directory), as this may cause conflicts when building file URLs.', array('@file_directory' => $form_state['values']['file_directory'], '@files_directory' => file_directory_path())));
- }
- else {
- form_set_value($element, $value, $form_state);
- }
-}
-
-/**
- * Implements hook_field_load().
- */
-function file_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
-
- $fids = array();
- foreach ($entities as $id => $entity) {
- // Load the files from the files table.
- foreach ($items[$id] as $delta => $item) {
- if (!empty($item['fid'])) {
- $fids[] = $item['fid'];
- }
- }
- }
- $files = file_load_multiple($fids);
-
- foreach ($entities as $id => $entity) {
- foreach ($items[$id] as $delta => $item) {
- // If the file does not exist, mark the entire item as empty.
- if (empty($item['fid']) || !isset($files[$item['fid']])) {
- $items[$id][$delta] = NULL;
- }
- else {
- $items[$id][$delta] = array_merge($item, (array) $files[$item['fid']]);
- }
- }
- }
-}
-
-/**
- * Implements hook_field_prepare_view().
- */
-function file_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
- // Remove files specified to not be displayed.
- foreach ($entities as $id => $entity) {
- foreach ($items[$id] as $delta => $item) {
- if (!file_field_displayed($item, $field)) {
- unset($items[$id][$delta]);
- }
- // Ensure consecutive deltas.
- $items[$id] = array_values($items[$id]);
- }
- }
-}
-
-/**
- * Implements hook_field_presave().
- */
-function file_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
- // Make sure that each file which will be saved with this object has a
- // permanent status, so that it will not be removed when temporary files are
- // cleaned up.
- foreach ($items as $item) {
- $file = file_load($item['fid']);
- if (!$file->status) {
- $file->status = FILE_STATUS_PERMANENT;
- file_save($file);
- }
- }
-}
-
-/**
- * Implements hook_field_insert().
- */
-function file_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
- list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
-
- // Add a new usage of each uploaded file.
- foreach ($items as $item) {
- $file = (object) $item;
- file_usage_add($file, 'file', $entity_type, $id);
- }
-}
-
-/**
- * Implements hook_field_update().
- *
- * Checks for files that have been removed from the object.
- */
-function file_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
- list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
-
- // On new revisions, all files are considered to be a new usage and no
- // deletion of previous file usages are necessary.
- if (!empty($entity->revision)) {
- foreach ($items as $item) {
- $file = (object) $item;
- file_usage_add($file, 'file', $entity_type, $id);
- }
- return;
- }
-
- // Build a display of the current FIDs.
- $current_fids = array();
- foreach ($items as $item) {
- $current_fids[] = $item['fid'];
- }
-
- // Create a bare-bones entity so that we can load its previous values.
- $original = entity_create_stub_entity($entity_type, array($id, $vid, $bundle));
- field_attach_load($entity_type, array($id => $original), FIELD_LOAD_CURRENT, array('field_id' => $field['id']));
-
- // Compare the original field values with the ones that are being saved.
- $original_fids = array();
- if (!empty($original->{$field['field_name']}[$langcode])) {
- foreach ($original->{$field['field_name']}[$langcode] as $original_item) {
- $original_fids[] = $original_item['fid'];
- if (isset($original_item['fid']) && !in_array($original_item['fid'], $current_fids)) {
- // Decrement the file usage count by 1 and delete the file if possible.
- file_field_delete_file($original_item, $field, $entity_type, $id);
- }
- }
- }
-
- // Add new usage entries for newly added files.
- foreach ($items as $item) {
- if (!in_array($item['fid'], $original_fids)) {
- $file = (object) $item;
- file_usage_add($file, 'file', $entity_type, $id);
- }
- }
-}
-
-/**
- * Implements hook_field_delete().
- */
-function file_field_delete($entity_type, $entity, $field, $instance, $langcode, &$items) {
- list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
-
- // Delete all file usages within this entity.
- foreach ($items as $delta => $item) {
- file_field_delete_file($item, $field, $entity_type, $id, 0);
- }
-}
-
-/**
- * Implements hook_field_delete_revision().
- */
-function file_field_delete_revision($entity_type, $entity, $field, $instance, $langcode, &$items) {
- list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
- foreach ($items as $delta => $item) {
- // Decrement the file usage count by 1 and delete the file if possible.
- if (file_field_delete_file($item, $field, $entity_type, $id)) {
- $items[$delta] = NULL;
- }
- }
-}
-
-/**
- * Decrements a file usage count and attempts to delete it.
- *
- * This function only has an effect if the file being deleted is used only by
- * File module.
- *
- * @param $item
- * The field item that contains a file array.
- * @param $field
- * The field structure for the operation.
- * @param $entity_type
- * The type of $entity.
- * @param $id
- * The entity ID which contains the file being deleted.
- * @param $count
- * (optional) The number of references to decrement from the object
- * containing the file. Defaults to 1.
- *
- * @return
- * Boolean TRUE if the file was deleted, or an array of remaining references
- * if the file is still in use by other modules. Boolean FALSE if an error
- * was encountered.
- */
-function file_field_delete_file($item, $field, $entity_type, $id, $count = 1) {
- // To prevent the file field from deleting files it doesn't know about, check
- // the file reference count. Temporary files can be deleted because they
- // are not yet associated with any content at all.
- $file = (object) $item;
- $file_usage = file_usage_list($file);
- if ($file->status == 0 || !empty($file_usage['file'])) {
- file_usage_delete($file, 'file', $entity_type, $id, $count);
- return file_delete($file);
- }
-
- // Even if the file is not deleted, return TRUE to indicate the file field
- // record can be removed from the field database tables.
- return TRUE;
-}
-
-/**
- * Implements hook_field_is_empty().
- */
-function file_field_is_empty($item, $field) {
- return empty($item['fid']);
-}
-
-/**
- * Determine whether a file should be displayed when outputting field content.
- *
- * @param $item
- * A field item array.
- * @param $field
- * A field array.
- * @return
- * Boolean TRUE if the file will be displayed, FALSE if the file is hidden.
- */
-function file_field_displayed($item, $field) {
- if (!empty($field['settings']['display_field'])) {
- return (bool) $item['display'];
- }
- 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'),
- ),
- );
-}
-
-/**
- * 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 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) {
- $form['#attributes'] = array('enctype' => 'multipart/form-data');
-
- $defaults = array(
- 'fid' => 0,
- 'display' => !empty($field['settings']['display_default']),
- 'description' => '',
- );
-
- // Retrieve any values set in $form_state, as will be the case during AJAX
- // rebuilds of this form.
- if (isset($form_state['values'][$field['field_name']][$langcode])) {
- $items = $form_state['values'][$field['field_name']][$langcode];
- unset($form_state['values'][$field['field_name']][$langcode]);
- }
-
- foreach ($items as $delta => $item) {
- $items[$delta] = array_merge($defaults, $items[$delta]);
- // Remove any items from being displayed that are not needed.
- if ($items[$delta]['fid'] == 0) {
- unset($items[$delta]);
- }
- }
-
- // Re-index deltas after removing empty items.
- $items = array_values($items);
-
- // Update order according to weight.
- $items = _field_sort_items($field, $items);
-
- // Essentially we use the managed_file type, extended with some enhancements.
- $element_info = element_info('managed_file');
- $element += array(
- '#type' => 'managed_file',
- '#default_value' => isset($items[$delta]) ? $items[$delta] : $defaults,
- '#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')),
- // Allows this field to return an array instead of a single value.
- '#extended' => TRUE,
- );
-
- if ($field['cardinality'] == 1) {
- // 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.
- $delta = -1;
- foreach ($items as $delta => $item) {
- $elements[$delta] = $element;
- $elements[$delta]['#default_value'] = $item;
- $elements[$delta]['#weight'] = $delta;
- }
- // And then add one more empty row for new uploads.
- $delta++;
- if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $field['cardinality']) {
- $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;
-}
-
-/**
- * Get the upload validators for a file field.
- *
- * @param $field
- * A field array.
- * @return
- * An array suitable for passing to file_save_upload() or the file field
- * element's '#upload_validators' property.
- */
-function file_field_widget_upload_validators($field, $instance) {
- // Cap the upload size according to the PHP limit.
- $max_filesize = parse_size(file_upload_max_size());
- if (!empty($instance['settings']['max_filesize']) && parse_size($instance['settings']['max_filesize']) < $max_filesize) {
- $max_filesize = parse_size($instance['settings']['max_filesize']);
- }
-
- $validators = array();
-
- // There is always a file size limit due to the PHP server limit.
- $validators['file_validate_size'] = array($max_filesize);
-
- // Add the extension check if necessary.
- if (!empty($instance['settings']['file_extensions'])) {
- $validators['file_validate_extensions'] = array($instance['settings']['file_extensions']);
- }
-
- return $validators;
-}
-
-/**
- * Determine the URI for a file field instance.
- *
- * @param $field
- * A field array.
- * @param $instance
- * A field instance array.
- * @return
- * A file directory URI with tokens replaced.
- */
-function file_field_widget_uri($field, $instance, $account = NULL) {
- $destination = trim($instance['settings']['file_directory'], '/');
-
- // Replace tokens.
- $data = array('user' => isset($account) ? $account : $GLOBALS['user']);
- $destination = token_replace($destination, $data);
-
- return $field['settings']['uri_scheme'] . '://' . $destination;
-}
-
-/**
- * The #value_callback for the file_generic field element.
- */
-function file_field_widget_value($element, $input = FALSE, $form_state) {
- if ($input) {
- // Checkboxes lose their value when empty.
- // If the display field is present make sure its unchecked value is saved.
- $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
- if (empty($input['display'])) {
- $input['display'] = $field['settings']['display_field'] ? 0 : 1;
- }
- }
-
- // We depend on the managed file element to handle uploads.
- $return = file_managed_file_value($element, $input, $form_state);
-
- // Ensure that all the required properties are returned even if empty.
- $return += array(
- 'fid' => 0,
- 'display' => 1,
- 'description' => '',
- );
-
- return $return;
-}
-
-/**
- * An element #process callback for the file_generic field type.
- *
- * Expands the file_generic type to include the description and display fields.
- */
-function file_field_widget_process($element, &$form_state, $form) {
- $item = $element['#value'];
- $item['fid'] = $element['fid']['#value'];
-
- $field = $form_state['field'][$element['#field_name']][$element['#language']]['field'];
- $instance = $form_state['field'][$element['#field_name']][$element['#language']]['instance'];
- $settings = $instance['widget']['settings'];
-
- $element['#theme'] = 'file_widget';
-
- // Add the display field if enabled.
- if (!empty($field['settings']['display_field']) && $item['fid']) {
- $element['display'] = array(
- '#type' => empty($item['fid']) ? 'hidden' : 'checkbox',
- '#title' => t('Include file in display'),
- '#value' => isset($item['display']) ? $item['display'] : $field['settings']['display_default'],
- '#attributes' => array('class' => array('file-display')),
- );
- }
- else {
- $element['display'] = array(
- '#type' => 'hidden',
- '#value' => '1',
- );
- }
-
- // Add the description field if enabled.
- if (!empty($instance['settings']['description_field']) && $item['fid']) {
- $element['description'] = array(
- '#type' => 'textfield',
- '#title' => t('Description'),
- '#value' => isset($item['description']) ? $item['description'] : '',
- '#type' => variable_get('file_description_type', 'textfield'),
- '#maxlength' => variable_get('file_description_length', 128),
- '#description' => t('The description may be used as the label of the link to the file.'),
- );
- }
-
- // Adjust the AJAX settings so that on upload and remove of any individual
- // file, the entire group of file fields is updated together.
- if ($field['cardinality'] != 1) {
- $new_path = preg_replace('/\/\d+\//', '/', $element['remove_button']['#ajax']['path'], 1);
- $new_wrapper = preg_replace('/-\d+-/', '-', $element['remove_button']['#ajax']['wrapper'], 1);
- foreach (element_children($element) as $key) {
- if (isset($element[$key]['#ajax'])) {
- $element[$key]['#ajax']['path'] = $new_path;
- $element[$key]['#ajax']['wrapper'] = $new_wrapper;
- }
- }
- unset($element['#prefix'], $element['#suffix']);
- }
-
- return $element;
-}
-
-/**
- * An element #process callback for a group of file_generic fields.
- *
- * Adds the weight field to each row so it can be ordered and adds a new AJAX
- * wrapper around the entire group so it can be replaced all at once.
- */
-function file_field_widget_process_multiple($element, &$form_state, $form) {
- $element_children = element_children($element, TRUE);
- $count = count($element_children);
-
- foreach ($element_children as $delta => $key) {
- if ($key != $element['#file_upload_delta']) {
- $element[$key]['_weight'] = array(
- '#type' => 'weight',
- '#delta' => $count,
- '#default_value' => $delta,
- );
- }
- else {
- // The title needs to be assigned to the upload field so that validation
- // errors include the correct widget label.
- $element[$key]['#title'] = $element['#title'];
- $element[$key]['_weight'] = array(
- '#type' => 'hidden',
- '#default_value' => $delta,
- );
- }
- }
-
- // Add a new wrapper around all the elements for AJAX replacement.
- $element['#prefix'] = '';
- $element['#suffix'] = '
';
-
- return $element;
-}
-
-/**
- * Returns HTML for an individual file upload widget.
- *
- * @param $variables
- * An associative array containing:
- * - element: A render element representing the widget.
- *
- * @ingroup themeable
- */
-function theme_file_widget($variables) {
- $element = $variables['element'];
- $output = '';
-
- // The "form-managed-file" class is required for proper AJAX functionality.
- $output .= '';
- if ($element['fid']['#value'] != 0) {
- // Add the file size after the file name.
- $element['filename']['#markup'] .= ' (' . format_size($element['#file']->filesize) . ') ';
- }
- $output .= drupal_render_children($element);
- $output .= '
';
-
- return $output;
-}
-
-/**
- * Returns HTML for a group of file upload widgets.
- *
- * @param $variables
- * An associative array containing:
- * - element: A render element representing the widgets.
- *
- * @ingroup themeable
- */
-function theme_file_widget_multiple($variables) {
- $element = $variables['element'];
-
- // Get our list of widgets in order.
- $widgets = array();
- foreach (element_children($element) as $key) {
- $widgets[$key] = $element[$key];
- }
- usort($widgets, '_field_sort_items_value_helper');
-
- // Special ID and classes for draggable tables.
- $weight_class = $element['#id'] . '-weight';
- $table_id = $element['#id'] . '-table';
-
- // Build up a table of applicable fields.
- $headers = array();
- $headers[] = t('File information');
- if ($element['#display_field']) {
- $headers[] = array(
- 'data' => t('Display'),
- 'class' => array('checkbox'),
- );
- }
- $headers[] = t('Weight');
- $headers[] = t('Operations');
-
- $rows = array();
- foreach ($widgets as $key => $widget) {
- // Save the uploading row for last.
- if ($element[$key]['#file'] == FALSE) {
- $element[$key]['#title'] = $element['#file_upload_title'];
- $element[$key]['#description'] = $element['#file_upload_description'];
- continue;
- }
-
- // Delay rendering of the buttons, so that they can be rendered later in the
- // "operations" column.
- $operations_elements = array();
- foreach (element_children($element[$key]) as $sub_key) {
- if (isset($element[$key][$sub_key]['#type']) && $element[$key][$sub_key]['#type'] == 'submit') {
- hide($element[$key][$sub_key]);
- $operations_elements[] = &$element[$key][$sub_key];
- }
- }
-
- // Delay rendering of the "Display" option and the weight selector, so that
- // each can be rendered later in its own column.
- if ($element['#display_field']) {
- hide($element[$key]['display']);
- }
- hide($element[$key]['_weight']);
-
- // Render everything else together in a column, without the normal wrappers.
- $element[$key]['#theme_wrappers'] = array();
- $information = drupal_render($element[$key]);
-
- // Render the previously hidden elements, using render() instead of
- // drupal_render(), to undo the earlier hide().
- $operations = '';
- foreach ($operations_elements as $operation_element) {
- $operations .= render($operation_element);
- }
- $display = '';
- if ($element['#display_field']) {
- unset($element[$key]['display']['#title']);
- $display = array(
- 'data' => render($element[$key]['display']),
- 'class' => array('checkbox'),
- );
- }
- $element[$key]['_weight']['#attributes']['class'] = array($weight_class);
- $weight = render($element[$key]['_weight']);
-
- // Arrange the row with all of the rendered columns.
- $row = array();
- $row[] = $information;
- if ($element['#display_field']) {
- $row[] = $display;
- }
- $row[] = $weight;
- $row[] = $operations;
- $rows[] = array(
- 'data' => $row,
- 'class' => isset($element[$key]['#attributes']['class']) ? array_merge($element[$key]['#attributes']['class'], array('draggable')) : array('draggable'),
- );
- }
-
- drupal_add_tabledrag($table_id, 'order', 'sibling', $weight_class);
-
- $output = '';
- $output = empty($rows) ? '' : theme('table', array('header' => $headers, 'rows' => $rows, 'attributes' => array('id' => $table_id)));
- $output .= drupal_render_children($element);
- return $output;
-}
-
-/**
- * Returns HTML for help text based on file upload validators.
- *
- * @param $variables
- * An associative array containing:
- * - description: The normal description for this field, specified by the
- * user.
- * - upload_validators: An array of upload validators as used in
- * $element['#upload_validators'].
- *
- * @ingroup themeable
- */
-function theme_file_upload_help($variables) {
- $description = $variables['description'];
- $upload_validators = $variables['upload_validators'];
-
- $descriptions = array();
-
- if (strlen($description)) {
- $descriptions[] = $description;
- }
- if (isset($upload_validators['file_validate_size'])) {
- $descriptions[] = t('Files must be less than !size.', array('!size' => '' . format_size($upload_validators['file_validate_size'][0]) . ' '));
- }
- if (isset($upload_validators['file_validate_extensions'])) {
- $descriptions[] = t('Allowed file types: !extensions.', array('!extensions' => '' . check_plain($upload_validators['file_validate_extensions'][0]) . ' '));
- }
- if (isset($upload_validators['file_validate_image_resolution'])) {
- $max = $upload_validators['file_validate_image_resolution'][0];
- $min = $upload_validators['file_validate_image_resolution'][1];
- if ($min && $max && $min == $max) {
- $descriptions[] = t('Images must be exactly !size pixels.', array('!size' => '' . $max . ' '));
- }
- elseif ($min && $max) {
- $descriptions[] = t('Images must be between !min and !max pixels.', array('!min' => '' . $min . ' ', '!max' => '' . $max . ' '));
- }
- elseif ($min) {
- $descriptions[] = t('Images must be larger than !min pixels.', array('!min' => '' . $min . ' '));
- }
- elseif ($max) {
- $descriptions[] = t('Images must be smaller than !max pixels.', array('!max' => '' . $max . ' '));
- }
- }
-
- return implode(' ', $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':
- // Display all values in a single element..
- $element[0] = array(
- '#theme' => 'file_formatter_table',
- '#items' => $items,
- );
- break;
- }
-
- return $element;
-}
-
-/**
- * Returns HTML for a file attachments table.
- *
- * @param $variables
- * An associative array containing:
- * - items: An array of file attachments.
- *
- * @ingroup themeable
- */
-function theme_file_formatter_table($variables) {
- $header = array(t('Attachment'), t('Size'));
- $rows = array();
- foreach ($variables['items'] as $delta => $item) {
- $rows[] = array(
- theme('file_link', array('file' => (object) $item)),
- format_size($item['filesize']),
- );
- }
-
- return empty($rows) ? '' : theme('table', array('header' => $header, 'rows' => $rows));
-}
diff --git a/modules/file/file.info b/modules/file/file.info
deleted file mode 100644
index 5c36ac92db9c80ac36478600df337df5ec361acd..0000000000000000000000000000000000000000
--- a/modules/file/file.info
+++ /dev/null
@@ -1,11 +0,0 @@
-; $Id$
-name = File
-description = Defines a file field type.
-package = Core
-version = VERSION
-core = 7.x
-dependencies[] = field
-files[] = file.module
-files[] = file.field.inc
-files[] = file.install
-files[] = tests/file.test
diff --git a/modules/file/file.install b/modules/file/file.install
deleted file mode 100644
index c92068e98e0eeda52be0cf7c39f63df8ced69fed..0000000000000000000000000000000000000000
--- a/modules/file/file.install
+++ /dev/null
@@ -1,61 +0,0 @@
-apc.rfc1867 = 1 to your php.ini configuration. Alternatively, it is recommended to use PECL uploadprogress , which supports more than one simultaneous upload.');
- $severity = REQUIREMENT_INFO;
- }
- elseif (!$implementation) {
- $value = t('Not enabled');
- $description = t('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the PECL uploadprogress library (preferred) or to install APC .');
- $severity = REQUIREMENT_INFO;
- }
- elseif ($implementation == 'apc') {
- $value = t('Enabled (APC RFC1867 )');
- $description = t('Your server is capable of displaying file upload progress using APC RFC1867. Note that only one upload at a time is supported. It is recommended to use the PECL uploadprogress library if possible.');
- $severity = REQUIREMENT_OK;
- }
- elseif ($implementation == 'uploadprogress') {
- $value = t('Enabled (PECL uploadprogress )');
- $severity = REQUIREMENT_OK;
- }
- $requirements['file_progress'] = array(
- 'title' => t('Upload progress'),
- 'value' => $value,
- 'severity' => $severity,
- 'description' => $description,
- );
- }
-
- return $requirements;
-}
diff --git a/modules/file/file.js b/modules/file/file.js
deleted file mode 100644
index 7325229b3dd9ca867eb9c2d9354f6ce40d9b3241..0000000000000000000000000000000000000000
--- a/modules/file/file.js
+++ /dev/null
@@ -1,141 +0,0 @@
-// $Id$
-
-/**
- * @file
- * Provides JavaScript additions to the managed file field type.
- *
- * This file provides progress bar support (if available), popup windows for
- * file previews, and disabling of other file fields during AJAX uploads (which
- * prevents separate file fields from accidentally uploading files).
- */
-
-(function ($) {
-
-/**
- * Attach behaviors to managed file element upload fields.
- */
-Drupal.behaviors.fileValidateAutoAttach = {
- attach: function (context) {
- $('div.form-managed-file input.form-file[accept]', context).bind('change', Drupal.file.validateExtension);
- },
- detach: function (context) {
- $('div.form-managed-file input.form-file[accept]', context).unbind('change', Drupal.file.validateExtension);
- }
-};
-
-/**
- * Attach behaviors to the file upload and remove buttons.
- */
-Drupal.behaviors.fileButtons = {
- attach: function (context) {
- $('input.form-submit', context).bind('mousedown', Drupal.file.disableFields);
- $('div.form-managed-file input.form-submit', context).bind('mousedown', Drupal.file.progressBar);
- },
- detach: function (context) {
- $('input.form-submit', context).unbind('mousedown', Drupal.file.disableFields);
- $('div.form-managed-file input.form-submit', context).unbind('mousedown', Drupal.file.progressBar);
- }
-};
-
-/**
- * Attach behaviors to links within managed file elements.
- */
-Drupal.behaviors.filePreviewLinks = {
- attach: function (context) {
- $('div.form-managed-file .file a, .file-widget .file a', context).bind('click',Drupal.file.openInNewWindow);
- },
- detach: function (context){
- $('div.form-managed-file .file a, .file-widget .file a', context).unbind('click', Drupal.file.openInNewWindow);
- }
-};
-
-/**
- * File upload utility functions.
- */
-Drupal.file = Drupal.file || {
- /**
- * Client-side file input validation based on the HTML "accept" attribute.
- */
- validateExtension: function (event) {
- // Remove any previous errors.
- $('.file-upload-js-error').remove();
-
- // Add client side validation for the input[type=file] accept attribute.
- var accept = this.accept.replace(/,\s*/g, '|');
- if (accept.length > 1 && this.value.length > 0) {
- var acceptableMatch = new RegExp('\\.(' + accept + ')$', 'gi');
- if (!acceptableMatch.test(this.value)) {
- var error = Drupal.t("The selected file %filename cannot not be uploaded. Only files with the following extensions are allowed: %extensions.", {
- '%filename': this.value,
- '%extensions': accept.replace(/\|/g, ', ')
- });
- $(this).parents('div.form-managed-file').prepend('' + error + '
');
- this.value = '';
- return false;
- }
- }
- },
- /**
- * Prevent file uploads when using buttons not intended to upload.
- */
- disableFields: function (event){
- var clickedButton = this;
-
- // Only disable upload fields for AJAX buttons.
- if (!$(clickedButton).hasClass('ajax-processed')) {
- return;
- }
-
- // Check if we're working with an "Upload" button.
- var $enabledFields = [];
- if ($(this).parents('div.form-managed-file').size() > 0) {
- $enabledFields = $(this).parents('div.form-managed-file').find('input.form-file');
- }
-
- // Temporarily disable upload fields other than the one we're currently
- // working with. Filter out fields that are already disabled so that they
- // do not get enabled when we re-enable these fields at the end of behavior
- // processing. Re-enable in a setTimeout set to a relatively short amount
- // of time (1 second). All the other mousedown handlers (like Drupal's AJAX
- // behaviors) are excuted before any timeout functions are called, so we
- // don't have to worry about the fields being re-enabled too soon.
- // @todo If the previous sentence is true, why not set the timeout to 0?
- var $fieldsToTemporarilyDisable = $('div.form-managed-file input.form-file').not($enabledFields).not(':disabled');
- $fieldsToTemporarilyDisable.attr('disabled', 'disabled');
- setTimeout(function (){
- $fieldsToTemporarilyDisable.attr('disabled', '');
- }, 1000);
- },
- /**
- * Add progress bar support if possible.
- */
- progressBar: function (event) {
- var clickedButton = this;
- var $progressId = $(clickedButton).parents('div.form-managed-file').find('input.file-progress');
- if ($progressId.size()) {
- var originalName = $progressId.attr('name');
-
- // Replace the name with the required identifier.
- $progressId.attr('name', originalName.match(/APC_UPLOAD_PROGRESS|UPLOAD_IDENTIFIER/)[0]);
-
- // Restore the original name after the upload begins.
- setTimeout(function () {
- $progressId.attr('name', originalName);
- }, 1000);
- }
- // Show the progress bar if the upload takes longer than half a second.
- setTimeout(function () {
- $(clickedButton).parents('div.form-managed-file').find('div.ajax-progress-bar').slideDown();
- }, 500);
- },
- /**
- * Open links to files within forms in a new window.
- */
- openInNewWindow: function (event) {
- $(this).attr('target', '_blank');
- window.open(this.href, 'filePreview', 'toolbar=0,scrollbars=1,location=1,statusbar=1,menubar=0,resizable=1,width=500,height=550');
- return false;
- }
-};
-
-})(jQuery);
diff --git a/modules/file/file.module b/modules/file/file.module
deleted file mode 100644
index a69a21dcabca010008dde46f8ae3cda17d10cdd5..0000000000000000000000000000000000000000
--- a/modules/file/file.module
+++ /dev/null
@@ -1,972 +0,0 @@
-' . t('About') . '';
- $output .= '' . t('The File module defines a File field type for the Field module, which lets you manage and validate uploaded files attached to content on your site (see the Field module help page for more information about fields). For more information, see the online handbook entry for File module .', array('@field-help' => url('admin/help/field'), '@file' => 'http://drupal.org/handbook/modules/file')) . '
';
- $output .= '' . t('Uses') . ' ';
- $output .= '';
- $output .= '' . t('Attaching files to content') . ' ';
- $output .= '' . t('The File module allows users to attach files to content (e.g., PDF files, spreadsheets, etc.), when a File field is added to a given content type using the Field UI module . You can add validation options to your File field, such as specifying a maximum file size and allowed file extensions.', array('@fieldui-help' => url('admin/help/field_ui'))) . ' ';
- $output .= '' . t('Managing attachment display') . ' ';
- $output .= '' . t('When you attach a file to content, you can specify whether it is listed or not. Listed files are displayed automatically in a section at the bottom of your content; non-listed files are available for embedding in your content, but are not included in the list at the bottom.') . ' ';
- $output .= '' . t('Managing file locations') . ' ';
- $output .= '' . t("When you create a File field, you can specify a directory where the files will be stored, which can be within either the public or private files directory. Files in the public directory can be accessed directly through the web server; when public files are listed, direct links to the files are used, and anyone who knows a file's URL can download the file. Files in the private directory are not accessible directly through the web server; when private files are listed, the links are Drupal path requests. This adds to server load and download time, since Drupal must start up and resolve the path for each file download request, but allows for access restrictions.") . ' ';
- $output .= ' ';
- return $output;
- }
-}
-
-/**
- * Implements hook_menu().
- */
-function file_menu() {
- $items = array();
-
- $items['file/ajax'] = array(
- 'page callback' => 'file_ajax_upload',
- 'delivery callback' => 'ajax_deliver',
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- );
- $items['file/progress'] = array(
- 'page callback' => 'file_ajax_progress',
- 'delivery callback' => 'ajax_deliver',
- 'access arguments' => array('access content'),
- 'type' => MENU_CALLBACK,
- );
-
- return $items;
-}
-
-/**
- * Implements hook_element_info().
- *
- * The managed file element may be used independently anywhere in Drupal.
- */
-function file_element_info() {
- $file_path = drupal_get_path('module', 'file');
- $types['managed_file'] = array(
- '#input' => TRUE,
- '#process' => array('file_managed_file_process'),
- '#value_callback' => 'file_managed_file_value',
- '#element_validate' => array('file_managed_file_validate'),
- '#pre_render' => array('file_managed_file_pre_render'),
- '#theme' => 'file_managed_file',
- '#theme_wrappers' => array('form_element'),
- '#progress_indicator' => 'throbber',
- '#progress_message' => NULL,
- '#upload_validators' => array(),
- '#upload_location' => NULL,
- '#extended' => FALSE,
- '#attached' => array(
- 'css' => array($file_path . '/file.css'),
- 'js' => array($file_path . '/file.js'),
- ),
- );
- return $types;
-}
-
-/**
- * Implements hook_theme().
- */
-function file_theme() {
- return array(
- // file.module.
- 'file_link' => array(
- 'variables' => array('file' => NULL, 'icon_directory' => NULL),
- ),
- 'file_icon' => array(
- 'variables' => array('file' => NULL, 'icon_directory' => NULL),
- ),
- 'file_managed_file' => array(
- 'render element' => 'element',
- ),
-
- // file.field.inc.
- 'file_widget' => array(
- 'render element' => 'element',
- ),
- 'file_widget_multiple' => array(
- 'render element' => 'element',
- ),
- 'file_formatter_table' => array(
- 'variables' => array('items' => NULL),
- ),
- 'file_upload_help' => array(
- 'variables' => array('description' => NULL, 'upload_validators' => NULL),
- ),
- );
-}
-
-/**
- * Implements hook_file_download().
- *
- * This function takes an extra parameter $field_type so that it may
- * be re-used by other File-like modules, such as Image.
- */
-function file_file_download($uri, $field_type = 'file') {
- global $user;
-
- // Get the file record based on the URI. If not in the database just return.
- $files = file_load_multiple(array(), array('uri' => $uri));
- if (count($files)) {
- foreach ($files as $item) {
- // Since some database servers sometimes use a case-insensitive comparison
- // by default, double check that the filename is an exact match.
- if ($item->uri === $uri) {
- $file = $item;
- break;
- }
- }
- }
- if (!isset($file)) {
- return;
- }
-
- // Find out which (if any) file fields contain this file.
- $references = file_get_file_references($file, NULL, FIELD_LOAD_REVISION, $field_type);
-
- // TODO: Check field-level access if available here.
-
- $denied = $file->status ? NULL : FALSE;
- // Check access to content containing the file fields. If access is allowed
- // to any of this content, allow the download.
- foreach ($references as $field_name => $field_references) {
- foreach ($field_references as $entity_type => $type_references) {
- foreach ($type_references as $reference) {
- // If access is allowed to any object, immediately stop and grant
- // access. If access is denied, continue through in case another object
- // grants access.
- // TODO: Switch this to a universal access check mechanism if available.
- if ($entity_type == 'node' && ($node = node_load($reference->nid))) {
- if (node_access('view', $node)) {
- $denied = FALSE;
- break 3;
- }
- else {
- $denied = TRUE;
- }
- }
- if ($entity_type == 'user') {
- if (user_access('access user profiles') || $user->uid == $reference->uid) {
- $denied = FALSE;
- break 3;
- }
- else {
- $denied = TRUE;
- }
- }
- }
- }
- }
-
- // No access was denied or granted.
- if (!isset($denied)) {
- return;
- }
- // Access specifically denied and not granted elsewhere.
- elseif ($denied == TRUE) {
- return -1;
- }
-
- // Access is granted.
- $name = mime_header_encode($file->filename);
- $type = mime_header_encode($file->filemime);
- // Serve images, text, and flash content for display rather than download.
- $inline_types = variable_get('file_inline_types', array('^text/', '^image/', 'flash$'));
- $disposition = 'attachment';
- foreach ($inline_types as $inline_type) {
- // Exclamation marks are used as delimiters to avoid escaping slashes.
- if (preg_match('!' . $inline_type . '!', $file->filemime)) {
- $disposition = 'inline';
- }
- }
-
- return array(
- 'Content-Type' => $type . '; name="' . $name . '"',
- 'Content-Length' => $file->filesize,
- 'Content-Disposition' => $disposition . '; filename="' . $name . '"',
- 'Cache-Control' => 'private',
- );
-}
-
-/**
- * Menu callback; Shared AJAX callback for file uploads and deletions.
- *
- * This rebuilds the form element for a particular field item. As long as the
- * form processing is properly encapsulated in the widget element the form
- * should rebuild correctly using FAPI without the need for additional callbacks
- * or processing.
- */
-function file_ajax_upload() {
- $form_parents = func_get_args();
- $form_build_id = (string) array_pop($form_parents);
-
- if (empty($_POST['form_build_id']) || $form_build_id != $_POST['form_build_id']) {
- // Invalid request.
- drupal_set_message(t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', array('@size' => format_size(file_upload_max_size()))), 'error');
- $commands = array();
- $commands[] = ajax_command_replace(NULL, theme('status_messages'));
- return array('#type' => 'ajax', '#commands' => $commands, '#header' => FALSE);
- }
-
- list($form, $form_state, $form_id, $form_build_id) = ajax_get_form();
-
- if (!$form) {
- // Invalid form_build_id.
- drupal_set_message(t('An unrecoverable error occurred. Use of this form has expired. Try reloading the page and submitting again.'), 'error');
- $commands = array();
- $commands[] = ajax_command_replace(NULL, theme('status_messages'));
- return array('#type' => 'ajax', '#commands' => $commands, '#header' => FALSE);
- }
-
- // Get the current element and count the number of files.
- $current_element = $form;
- foreach ($form_parents as $parent) {
- $current_element = $current_element[$parent];
- }
- $current_file_count = isset($current_element['#file_upload_delta']) ? $current_element['#file_upload_delta'] : 0;
-
- // Build, validate and if possible, submit the form.
- drupal_process_form($form_id, $form, $form_state);
-
- // This call recreates the form relying solely on the form_state that the
- // drupal_process_form() set up.
- $form = drupal_rebuild_form($form_id, $form_state, $form);
-
- // Retrieve the element to be rendered.
- foreach ($form_parents as $parent) {
- $form = $form[$parent];
- }
-
- // Add the special AJAX class if a new file was added.
- if (isset($form['#file_upload_delta']) && $current_file_count < $form['#file_upload_delta']) {
- $form[$current_file_count]['#attributes']['class'][] = 'ajax-new-content';
- }
- // Otherwise just add the new content class on a placeholder.
- else {
- $form['#suffix'] .= ' ';
- }
-
- $output = theme('status_messages') . drupal_render($form);
- $js = drupal_add_js();
- $settings = call_user_func_array('array_merge_recursive', $js['settings']['data']);
-
- $commands = array();
- $commands[] = ajax_command_replace(NULL, $output, $settings);
- return array('#type' => 'ajax', '#commands' => $commands, '#header' => FALSE);
-}
-
-/**
- * Menu callback for upload progress.
- *
- * @param $key
- * The unique key for this upload process.
- */
-function file_ajax_progress($key) {
- $progress = array(
- 'message' => t('Starting upload...'),
- 'percentage' => -1,
- );
-
- $implementation = file_progress_implementation();
- if ($implementation == 'uploadprogress') {
- $status = uploadprogress_get_info($key);
- if (isset($status['bytes_uploaded']) && !empty($status['bytes_total'])) {
- $progress['message'] = t('Uploading... (@current of @total)', array('@current' => format_size($status['bytes_uploaded']), '@total' => format_size($status['bytes_total'])));
- $progress['percentage'] = round(100 * $status['bytes_uploaded'] / $status['bytes_total']);
- }
- }
- elseif ($implementation == 'apc') {
- $status = apc_fetch('upload_' . $key);
- if (isset($status['current']) && !empty($status['total'])) {
- $progress['message'] = t('Uploading... (@current of @total)', array('@current' => format_size($status['current']), '@total' => format_size($status['total'])));
- $progress['percentage'] = round(100 * $status['current'] / $status['total']);
- }
- }
-
- drupal_json_output($progress);
-}
-
-/**
- * Determine the preferred upload progress implementation.
- *
- * @return
- * A string indicating which upload progress system is available. Either "apc"
- * or "uploadprogress". If neither are available, returns FALSE.
- */
-function file_progress_implementation() {
- static $implementation;
- if (!isset($implementation)) {
- $implementation = FALSE;
-
- // We prefer the PECL extension uploadprogress because it supports multiple
- // simultaneous uploads. APC only supports one at a time.
- if (extension_loaded('uploadprogress')) {
- $implementation = 'uploadprogress';
- }
- elseif (extension_loaded('apc') && ini_get('apc.rfc1867')) {
- $implementation = 'apc';
- }
- }
- return $implementation;
-}
-
-/**
- * Implements hook_file_delete().
- */
-function file_file_delete($file) {
- // TODO: Remove references to a file that is in-use.
-}
-
-/**
- * Process function to expand the managed_file element type.
- *
- * Expands the file type to include Upload and Remove buttons, as well as
- * support for a default value.
- */
-function file_managed_file_process($element, &$form_state, $form) {
- $fid = isset($element['#value']['fid']) ? $element['#value']['fid'] : 0;
-
- // Set some default element properties.
- $element['#progress_indicator'] = empty($element['#progress_indicator']) ? 'none' : $element['#progress_indicator'];
- $element['#file'] = $fid ? file_load($fid) : FALSE;
- $element['#tree'] = TRUE;
-
- $ajax_settings = array(
- 'path' => 'file/ajax/' . implode('/', $element['#parents']) . '/' . $form['form_build_id']['#value'],
- 'wrapper' => $element['#id'] . '-ajax-wrapper',
- 'effect' => 'fade',
- 'progress' => array(
- 'type' => $element['#progress_indicator'],
- 'message' => $element['#progress_message'],
- ),
- );
-
- // Set up the buttons first since we need to check if they were clicked.
- $element['upload_button'] = array(
- '#name' => implode('_', $element['#parents']) . '_upload_button',
- '#type' => 'submit',
- '#value' => t('Upload'),
- '#validate' => array(),
- '#submit' => array('file_managed_file_submit'),
- '#limit_validation_errors' => array($element['#parents']),
- '#ajax' => $ajax_settings,
- '#weight' => -5,
- );
-
- $ajax_settings['progress']['type'] ? $ajax_settings['progress']['type'] == 'bar' : 'throbber';
- $ajax_settings['progress']['message'] = NULL;
- $ajax_settings['effect'] = 'none';
- $element['remove_button'] = array(
- '#name' => implode('_', $element['#parents']) . '_remove_button',
- '#type' => 'submit',
- '#value' => t('Remove'),
- '#validate' => array(),
- '#submit' => array('file_managed_file_submit'),
- '#limit_validation_errors' => array($element['#parents']),
- '#ajax' => $ajax_settings,
- '#weight' => -5,
- );
-
- $element['fid'] = array(
- '#type' => 'hidden',
- '#value' => $fid,
- );
-
- // Add progress bar support to the upload if possible.
- if ($element['#progress_indicator'] == 'bar' && $implementation = file_progress_implementation()) {
- $upload_progress_key = mt_rand();
-
- if ($implementation == 'uploadprogress') {
- $element['UPLOAD_IDENTIFIER'] = array(
- '#type' => 'hidden',
- '#value' => $upload_progress_key,
- '#attributes' => array('class' => array('file-progress')),
- );
- }
- elseif ($implementation == 'apc') {
- $element['APC_UPLOAD_PROGRESS'] = array(
- '#type' => 'hidden',
- '#value' => $upload_progress_key,
- '#attributes' => array('class' => array('file-progress')),
- );
- }
-
- // Add the upload progress callback.
- $element['upload_button']['#ajax']['progress']['path'] = 'file/progress/' . $upload_progress_key;
- }
-
- // The file upload field itself.
- $element['upload'] = array(
- '#name' => 'files[' . implode('_', $element['#parents']) . ']',
- '#type' => 'file',
- '#size' => 22,
- '#theme_wrappers' => array(),
- '#weight' => -10,
- );
-
- if ($fid && $element['#file']) {
- $element['filename'] = array(
- '#type' => 'markup',
- '#markup' => theme('file_link', array('file' => $element['#file'])) . ' ',
- '#weight' => -10,
- );
- }
-
- // The "accept" attribute is valid XHTML, but not enforced in browsers.
- // We use it for our own purposes in our JavaScript validation.
- if (isset($element['#upload_validators']['file_validate_extensions'][0])) {
- $element['upload']['#attributes']['accept'] = implode(',', array_filter(explode(' ', $element['#upload_validators']['file_validate_extensions'][0])));
- }
-
- // Prefix and suffix used for AJAX replacement.
- $element['#prefix'] = '';
- $element['#suffix'] = '
';
-
- return $element;
-}
-
-/**
- * The #value_callback for a managed_file type element.
- */
-function file_managed_file_value(&$element, $input = FALSE, $form_state = NULL) {
- $fid = 0;
-
- // Find the current value of this field from the form state.
- $form_state_fid = $form_state['values'];
- foreach ($element['#parents'] as $parent) {
- $form_state_fid = isset($form_state_fid[$parent]) ? $form_state_fid[$parent] : 0;
- }
-
- if ($element['#extended'] && isset($form_state_fid['fid'])) {
- $fid = $form_state_fid['fid'];
- }
- elseif (is_numeric($form_state_fid)) {
- $fid = $form_state_fid;
- }
-
- // Process any input and save new uploads.
- if ($input !== FALSE) {
- $return = $input;
-
- // Uploads take priority over all other values.
- if ($file = file_managed_file_save_upload($element)) {
- $fid = $file->fid;
- }
- else {
- // Check for #filefield_value_callback values.
- // Because FAPI does not allow multiple #value_callback values like it
- // does for #element_validate and #process, this fills the missing
- // functionality to allow File fields to be extended through FAPI.
- if (isset($element['#file_value_callbacks'])) {
- foreach ($element['#file_value_callbacks'] as $callback) {
- $callback($element, $input);
- }
- }
- // Load file if the FID has changed to confirm it exists.
- if (isset($input['fid']) && $file = file_load($input['fid'])) {
- $fid = $file->fid;
- }
- }
- }
-
- // If there is no input, set the default value.
- else {
- if ($element['#extended']) {
- $default_fid = isset($element['#default_value']['fid']) ? $element['#default_value']['fid'] : 0;
- $return = isset($element['#default_value']) ? $element['#default_value'] : array('fid' => 0);
- }
- else {
- $default_fid = isset($element['#default_value']) ? $element['#default_value'] : 0;
- $return = array('fid' => 0);
- }
-
- // Confirm that the file exists when used as a default value.
- if ($default_fid && $file = file_load($default_fid)) {
- $fid = $file->fid;
- }
- }
-
- $return['fid'] = $fid;
-
- return $return;
-}
-
-/**
- * An #element_validate callback for the managed_file element.
- */
-function file_managed_file_validate(&$element, &$form_state) {
- // If referencing an existing file, only allow if there are existing
- // references. This prevents unmanaged files from being deleted if this
- // item were to be deleted.
- $clicked_button = end($form_state['clicked_button']['#parents']);
- if ($clicked_button != 'remove_button' && !empty($element['fid']['#value'])) {
- if ($file = file_load($element['fid']['#value'])) {
- if ($file->status == FILE_STATUS_PERMANENT) {
- $references = file_usage_list($file);
- if (empty($references)) {
- form_error($element, t('The file used in the !name field may not be referenced.', array('!name' => $element['#title'])));
- }
- }
- }
- else {
- form_error($element, t('The file referenced by the !name field does not exist.', array('!name' => $element['#title'])));
- }
- }
-
- // Check required property based on the FID.
- if ($element['#required'] && empty($element['fid']['#value']) && !in_array($clicked_button, array('upload_button', 'remove_button'))) {
- form_error($element['upload'], t('!name field is required.', array('!name' => $element['#title'])));
- }
-
- // Consolidate the array value of this field to a single FID.
- if (!$element['#extended']) {
- form_set_value($element, $element['fid']['#value'], $form_state);
- }
-}
-
-/**
- * Submit handler for upload and remove buttons of managed_file elements.
- */
-function file_managed_file_submit($form, &$form_state) {
- // Determine whether it was the upload or the remove button that was clicked,
- // and set $element to the managed_file element that contains that button.
- $parents = $form_state['triggering_element']['#array_parents'];
- $button_key = array_pop($parents);
- $element = $form;
- foreach ($parents as $parent) {
- $element = $element[$parent];
- }
-
- // No action is needed here for the upload button, because all file uploads on
- // the form are processed by file_managed_file_value() regardless of which
- // button was clicked. Action is needed here for the remove button, because we
- // only remove a file in response to its remove button being clicked.
- if ($button_key == 'remove_button') {
- // If it's a temporary file we can safely remove it immediately, otherwise
- // it's up to the implementing module to clean up files that are in use.
- if ($element['#file'] && $element['#file']->status == 0) {
- file_delete($element['#file']);
- }
- // Update both $form_state['values'] and $form_state['input'] to reflect
- // that the file has been removed, so that the form is rebuilt correctly.
- // $form_state['values'] must be updated in case additional submit handlers
- // run, and for form building functions that run during the rebuild, such as
- // when the managed_file element is part of a field widget.
- // $form_state['input'] must be updated so that file_managed_file_value()
- // has correct information during the rebuild. The Form API provides no
- // equivalent of form_set_value() for updating $form_state['input'], so
- // inline that implementation with the same logic that form_set_value()
- // uses.
- $values_element = $element['#extended'] ? $element['fid'] : $element;
- form_set_value($values_element, NULL, $form_state);
- _form_set_value($form_state['input'], $values_element, $values_element['#parents'], NULL);
- }
-
- // Set the form to rebuild so that $form is correctly updated in response to
- // processing the file removal. Since this function did not change $form_state
- // if the upload button was clicked, a rebuild isn't necessary in that
- // situation and setting $form_state['redirect'] to FALSE would suffice.
- // However, we choose to always rebuild, to keep the form processing workflow
- // consistent between the two buttons.
- $form_state['rebuild'] = TRUE;
-}
-
-/**
- * Given a managed_file element, save any files that have been uploaded into it.
- *
- * @param $element
- * The FAPI element whose values are being saved.
- * @return
- * The file object representing the file that was saved, or FALSE if no file
- * was saved.
- */
-function file_managed_file_save_upload($element) {
- $upload_name = implode('_', $element['#parents']);
- if (empty($_FILES['files']['name'][$upload_name])) {
- return FALSE;
- }
-
- $destination = isset($element['#upload_location']) ? $element['#upload_location'] : NULL;
- if (isset($destination) && !file_prepare_directory($destination, FILE_CREATE_DIRECTORY)) {
- watchdog('file', 'The upload directory %directory for the file field !name could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled.', array('%directory' => $destination, '!name' => $element['#field_name']));
- form_set_error($upload_name, t('The file could not be uploaded.'));
- return FALSE;
- }
-
- if (!$file = file_save_upload($upload_name, $element['#upload_validators'], $destination)) {
- watchdog('file', 'The file upload failed. %upload', array('%upload' => $upload_name));
- form_set_error($upload_name, t('The file in the !name field was unable to be uploaded.', array('!name' => $element['#title'])));
- return FALSE;
- }
-
- return $file;
-}
-
-/**
- * Returns HTML for a managed file element.
- *
- * @param $variables
- * An associative array containing:
- * - element: A render element representing the file.
- *
- * @ingroup themeable
- */
-function theme_file_managed_file($variables) {
- $element = $variables['element'];
-
- // This wrapper is required to apply JS behaviors and CSS styling.
- $output = '';
- $output .= '';
- $output .= drupal_render_children($element);
- $output .= '
';
- return $output;
-}
-
-/**
- * #pre_render callback to hide display of the upload or remove controls.
- *
- * Upload controls are hidden when a file is already uploaded. Remove controls
- * are hidden when there is no file attached. Controls are hidden here instead
- * of in file_managed_file_process(), because #access for these buttons depends
- * on the managed_file element's #value. See the documentation of form_builder()
- * for more detailed information about the relationship between #process,
- * #value, and #access.
- *
- * Because #access is set here, it affects display only and does not prevent
- * JavaScript or other untrusted code from submitting the form as though access
- * were enabled. The form processing functions for these elements should not
- * assume that the buttons can't be "clicked" just because they are not
- * displayed.
- *
- * @see file_managed_file_process()
- * @see form_builder()
- */
-function file_managed_file_pre_render($element) {
- // If we already have a file, we don't want to show the upload controls.
- if (!empty($element['#value']['fid'])) {
- $element['upload']['#access'] = FALSE;
- $element['upload_button']['#access'] = FALSE;
- }
- // If we don't already have a file, there is nothing to remove.
- else {
- $element['remove_button']['#access'] = FALSE;
- }
- return $element;
-}
-
-/**
- * Returns HTML for a link to a file.
- *
- * @param $variables
- * An associative array containing:
- * - file: A file object to which the link will be created.
- * - icon_directory: (optional) A path to a directory of icons to be used for
- * files. Defaults to the value of the "file_icon_directory" variable.
- *
- * @ingroup themeable
- */
-function theme_file_link($variables) {
- $file = $variables['file'];
- $icon_directory = $variables['icon_directory'];
-
- $url = file_create_url($file->uri);
- $icon = theme('file_icon', array('file' => $file, 'icon_directory' => $icon_directory));
-
- // Set options as per anchor format described at
- // http://microformats.org/wiki/file-format-examples
- $options = array(
- 'attributes' => array(
- 'type' => $file->filemime . '; length=' . $file->filesize,
- ),
- );
-
- // Use the description as the link text if available.
- if (empty($file->description)) {
- $link_text = $file->filename;
- }
- else {
- $link_text = $file->description;
- $options['attributes']['title'] = check_plain($file->filename);
- }
-
- return '' . $icon . ' ' . l($link_text, $url, $options) . ' ';
-}
-
-/**
- * Returns HTML for an image with an appropriate icon for the given file.
- *
- * @param $variables
- * An associative array containing:
- * - file: A file object for which to make an icon.
- * - icon_directory: (optional) A path to a directory of icons to be used for
- * files. Defaults to the value of the "file_icon_directory" variable.
- *
- * @ingroup themeable
- */
-function theme_file_icon($variables) {
- $file = $variables['file'];
- $icon_directory = $variables['icon_directory'];
-
- $mime = check_plain($file->filemime);
- $icon_url = file_icon_url($file, $icon_directory);
- return ' ';
-}
-
-/**
- * Given a file object, create a URL to a matching icon.
- *
- * @param $file
- * A file object.
- * @param $icon_directory
- * (optional) A path to a directory of icons to be used for files. Defaults to
- * the value of the "file_icon_directory" variable.
- * @return
- * A URL string to the icon, or FALSE if an appropriate icon cannot be found.
- */
-function file_icon_url($file, $icon_directory = NULL) {
- if ($icon_path = file_icon_path($file, $icon_directory)) {
- return base_path() . $icon_path;
- }
- return FALSE;
-}
-
-/**
- * Given a file object, create a path to a matching icon.
- *
- * @param $file
- * A file object.
- * @param $icon_directory
- * (optional) A path to a directory of icons to be used for files. Defaults to
- * the value of the "file_icon_directory" variable.
- * @return
- * A string to the icon as a local path, or FALSE if an appropriate icon could
- * not be found.
- */
-function file_icon_path($file, $icon_directory = NULL) {
- // Use the default set of icons if none specified.
- if (!isset($icon_directory)) {
- $icon_directory = variable_get('file_icon_directory', drupal_get_path('module', 'file') . '/icons');
- }
-
- // If there's an icon matching the exact mimetype, go for it.
- $dashed_mime = strtr($file->filemime, array('/' => '-'));
- $icon_path = $icon_directory . '/' . $dashed_mime . '.png';
- if (file_exists($icon_path)) {
- return $icon_path;
- }
-
- // For a few mimetypes, we can "manually" map to a generic icon.
- $generic_mime = (string) file_icon_map($file);
- $icon_path = $icon_directory . '/' . $generic_mime . '.png';
- if ($generic_mime && file_exists($icon_path)) {
- return $icon_path;
- }
-
- // Use generic icons for each category that provides such icons.
- foreach (array('audio', 'image', 'text', 'video') as $category) {
- if (strpos($file->filemime, $category . '/') === 0) {
- $icon_path = $icon_directory . '/' . $category . '-x-generic.png';
- if (file_exists($icon_path)) {
- return $icon_path;
- }
- }
- }
-
- // Try application-octet-stream as last fallback.
- $icon_path = $icon_directory . '/application-octet-stream.png';
- if (file_exists($icon_path)) {
- return $icon_path;
- }
-
- // No icon can be found.
- return FALSE;
-}
-
-/**
- * Determine the generic icon MIME package based on a file's MIME type.
- *
- * @param $file
- * A file object.
- * @return
- * The generic icon MIME package expected for this file.
- */
-function file_icon_map($file) {
- switch ($file->filemime) {
- // Word document types.
- case 'application/msword':
- case 'application/vnd.ms-word.document.macroEnabled.12':
- case 'application/vnd.oasis.opendocument.text':
- case 'application/vnd.oasis.opendocument.text-template':
- case 'application/vnd.oasis.opendocument.text-master':
- case 'application/vnd.oasis.opendocument.text-web':
- case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
- case 'application/vnd.stardivision.writer':
- case 'application/vnd.sun.xml.writer':
- case 'application/vnd.sun.xml.writer.template':
- case 'application/vnd.sun.xml.writer.global':
- case 'application/vnd.wordperfect':
- case 'application/x-abiword':
- case 'application/x-applix-word':
- case 'application/x-kword':
- case 'application/x-kword-crypt':
- return 'x-office-document';
-
- // Spreadsheet document types.
- case 'application/vnd.ms-excel':
- case 'application/vnd.ms-excel.sheet.macroEnabled.12':
- case 'application/vnd.oasis.opendocument.spreadsheet':
- case 'application/vnd.oasis.opendocument.spreadsheet-template':
- case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
- case 'application/vnd.stardivision.calc':
- case 'application/vnd.sun.xml.calc':
- case 'application/vnd.sun.xml.calc.template':
- case 'application/vnd.lotus-1-2-3':
- case 'application/x-applix-spreadsheet':
- case 'application/x-gnumeric':
- case 'application/x-kspread':
- case 'application/x-kspread-crypt':
- return 'x-office-spreadsheet';
-
- // Presentation document types.
- case 'application/vnd.ms-powerpoint':
- case 'application/vnd.ms-powerpoint.presentation.macroEnabled.12':
- case 'application/vnd.oasis.opendocument.presentation':
- case 'application/vnd.oasis.opendocument.presentation-template':
- case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
- case 'application/vnd.stardivision.impress':
- case 'application/vnd.sun.xml.impress':
- case 'application/vnd.sun.xml.impress.template':
- case 'application/x-kpresenter':
- return 'x-office-presentation';
-
- // Compressed archive types.
- case 'application/zip':
- case 'application/x-zip':
- case 'application/stuffit':
- case 'application/x-stuffit':
- case 'application/x-7z-compressed':
- case 'application/x-ace':
- case 'application/x-arj':
- case 'application/x-bzip':
- case 'application/x-bzip-compressed-tar':
- case 'application/x-compress':
- case 'application/x-compressed-tar':
- case 'application/x-cpio-compressed':
- case 'application/x-deb':
- case 'application/x-gzip':
- case 'application/x-java-archive':
- case 'application/x-lha':
- case 'application/x-lhz':
- case 'application/x-lzop':
- case 'application/x-rar':
- case 'application/x-rpm':
- case 'application/x-tzo':
- case 'application/x-tar':
- case 'application/x-tarz':
- case 'application/x-tgz':
- return 'package-x-generic';
-
- // Script file types.
- case 'application/ecmascript':
- case 'application/javascript':
- case 'application/mathematica':
- case 'application/vnd.mozilla.xul+xml':
- case 'application/x-asp':
- case 'application/x-awk':
- case 'application/x-cgi':
- case 'application/x-csh':
- case 'application/x-m4':
- case 'application/x-perl':
- case 'application/x-php':
- case 'application/x-ruby':
- case 'application/x-shellscript':
- case 'text/vnd.wap.wmlscript':
- case 'text/x-emacs-lisp':
- case 'text/x-haskell':
- case 'text/x-literate-haskell':
- case 'text/x-lua':
- case 'text/x-makefile':
- case 'text/x-matlab':
- case 'text/x-python':
- case 'text/x-sql':
- case 'text/x-tcl':
- return 'text-x-script';
-
- // HTML aliases.
- case 'application/xhtml+xml':
- return 'text-html';
-
- // Executable types.
- case 'application/x-macbinary':
- case 'application/x-ms-dos-executable':
- case 'application/x-pef-executable':
- return 'application-x-executable';
-
- default:
- return FALSE;
- }
-}
-
-/**
- * @defgroup file-module-api File module public API functions
- * @{
- * These functions may be used to determine if and where a file is in use.
- */
-
-/**
- * Gets a list of references to a file.
- *
- * @param $file
- * A file object.
- * @param $field
- * (optional) A field array to be used for this check. If given, limits the
- * reference check to the given field.
- * @param $age
- * (optional) A constant that specifies which references to count. Use
- * FIELD_LOAD_REVISION to retrieve all references within all revisions or
- * FIELD_LOAD_CURRENT to retrieve references only in the current revisions.
- * @param $field_type
- * (optional) The name of a field type. If given, limits the reference check
- * to fields of the given type.
- *
- * @return
- * An integer value.
- */
-function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISION, $field_type = 'file') {
- $references = drupal_static(__FUNCTION__, array());
- $fields = isset($field) ? array($field['field_name'] => $field) : field_info_fields();
-
- foreach ($fields as $field_name => $file_field) {
- if ((empty($field_type) || $file_field['type'] == $field_type) && !isset($references[$field_name])) {
- // Get each time this file is used within a field.
- $query = new EntityFieldQuery();
- $query
- ->fieldCondition($file_field, 'fid', $file->fid)
- ->age($age);
- $references[$field_name] = $query->execute();
- }
- }
-
- return isset($field) ? $references[$field['field_name']] : $references;
-}
-
-/**
- * @} End of "defgroup file-module-api".
- */
diff --git a/modules/file/icons/application-octet-stream.png b/modules/file/icons/application-octet-stream.png
deleted file mode 100644
index d5453217dc5cc30e805d3d0da8fa91e5a0684b86..0000000000000000000000000000000000000000
--- a/modules/file/icons/application-octet-stream.png
+++ /dev/null
@@ -1,3 +0,0 @@
-PNG
-
-
IHDR 7 tEXtSoftware Adobe ImageReadyqe<