You are here

dragndrop_upload_file.module in Drag & Drop Upload 7

Provides an dragndrop_upload element and a widget for a File field.

File

modules/dragndrop_upload_file/dragndrop_upload_file.module
View source
<?php

/**
 * @file
 * Provides an dragndrop_upload element and a widget for a File field.
 */

/**
 * Implements hook_field_widget_info().
 */
function dragndrop_upload_file_field_widget_info() {
  return array(
    'dragndrop_upload_file' => array(
      'label' => t('Drag & Drop Upload'),
      'field types' => array(
        'file',
      ),
      'settings' => array(
        'progress_indicator' => 'throbber',
        // This setting is responsive for showing Browse button or not.
        'standard_upload' => 1,
        'allow_replace' => 0,
        'upload_event' => 'manual',
        'upload_button_text' => t('Upload'),
        'droppable_area_text' => t('Drop files here to upload'),
        // This settings allows to drop multiple files at once.
        'multiupload' => 0,
      ),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
        'default value' => FIELD_BEHAVIOR_NONE,
      ),
    ),
  );
}

/**
 * Implements hook_field_widget_settings_form().
 */
function dragndrop_upload_file_field_widget_settings_form($field, $instance) {
  $form = file_field_widget_settings_form($field, $instance);
  $widget = $instance['widget'];
  $settings = $widget['settings'];
  $_fieldset =& $form['dragndrop_fieldset'];
  $_fieldset = array(
    '#type' => 'fieldset',
    '#title' => t('Drag & Drop Upload settings'),
    '#weight' => 20,
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#parents' => array(
      'instance',
      'widget',
      'settings',
    ),
  );
  $_fieldset['upload_event'] = array(
    '#type' => 'radios',
    '#title' => t('Upload method'),
    '#description' => t('Choose a way in which a dropped image will be uploaded'),
    '#options' => array(
      'auto' => t('Automatic upload'),
      'manual' => t('User should click a button to upload an image to the server'),
    ),
    '#default_value' => $settings['upload_event'],
  );
  $_fieldset['upload_button_text'] = array(
    '#type' => 'textfield',
    '#title' => t('Upload button text'),
    '#default_value' => $settings['upload_button_text'],
    '#states' => array(
      'invisible' => array(
        'input[name="instance[widget][settings][upload_event]"]' => array(
          'value' => 'auto',
        ),
      ),
    ),
  );
  $_fieldset['droppable_area_text'] = array(
    '#type' => 'textfield',
    '#title' => t('Droppable area text'),
    '#default_value' => $settings['droppable_area_text'],
  );
  $_fieldset['standard_upload'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show Browse button'),
    '#description' => t('Show Browse button in the Drag & Drop area'),
    '#default_value' => $settings['standard_upload'],
  );
  $_fieldset['allow_replace'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow replacing of existing file'),
    '#description' => t('Allow to add new file to the droppable area even if it already contains' . ' file, so newly added file will replace the existing one.' . '<br/> This option works only when field cardinality (Number of values)' . ' is 1'),
    '#default_value' => $settings['allow_replace'],
    '#states' => array(
      'enabled' => array(
        'select[name="field[cardinality]"]' => array(
          'value' => 1,
        ),
      ),
    ),
  );

  // Tell about multiupload availability.
  $_fieldset['multiupload'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow multiupload'),
    '#default_value' => module_exists('dragndrop_upload_multi') ? $settings['multiupload'] : 0,
  );
  if (!module_exists('dragndrop_upload_multi')) {
    $_fieldset['multiupload']['#disabled'] = TRUE;
    $_fieldset['multiupload']['#description'] = t('You should enable the module "Drag & Drop Upload: Multiupload support" for this setting.');
  }

  // Tell about Media browser integration availability.
  $_fieldset['media_browser'] = array(
    '#type' => 'checkbox',
    '#title' => t('Use Media browser'),
    '#default_value' => module_exists('dragndrop_upload_media') ? $settings['media_browser'] : 0,
  );
  if (!module_exists('dragndrop_upload_media')) {
    $_fieldset['media_browser']['#disabled'] = TRUE;
    $_fieldset['media_browser']['#description'] = t('You should enable the module "Drag & Drop Upload: Media module integration"' . ' for this setting.');
  }
  drupal_alter('dnd_upload_widget_settings_form', $form, $field, $instance);
  return $form;
}

/**
 * Implements hook_field_widget_form().
 *
 * Define the actual field input element.
 * TODO: dive into this function again.
 */
function dragndrop_upload_file_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $defaults = array(
    'fid' => 0,
    'display' => !empty($field['settings']['display_default']),
    'description' => '',
  );

  // Load the items for form rebuilds from the field state as they might not be
  // in $form_state['values'] because of validation limitations. Also, they are
  // only passed in as $items when editing existing entities.
  $field_state = field_form_get_state($element['#field_parents'], $field['field_name'], $langcode, $form_state);
  if (isset($field_state['items'])) {
    $items = $field_state['items'];
  }

  // Essentially we use the `dragndrop_upload_file` type,
  // extended with some enhancements.
  $widget_settings = $instance['widget']['settings'];
  $instance_settings = $instance['settings'];
  $element_info = element_info('dragndrop_upload');
  $pre_render = array_merge($element_info['#pre_render'], array(
    'dragndrop_upload_file_pre_render',
  ));
  $element += array(
    '#type' => 'dragndrop_upload',
    '#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',
    )),
    '#pre_render' => $pre_render,
    '#progress_indicator' => $widget_settings['progress_indicator'],
    '#upload_event' => $widget_settings['upload_event'],
    '#standard_upload' => $widget_settings['standard_upload'],
    '#allow_replace' => $widget_settings['allow_replace'],
    '#upload_button_text' => t($widget_settings['upload_button_text']),
    '#droppable_area_text' => t($widget_settings['droppable_area_text']),
    '#file_upload_max_size' => $instance_settings['max_filesize'] ? $instance_settings['max_filesize'] : file_upload_max_size(),
    '#cardinality' => $field['cardinality'],
    // Do not allow for 'multiupload' setting to be enabled if the module
    // is disabled.
    '#multiupload' => module_exists('dragndrop_upload_multi') ? $widget_settings['multiupload'] : 0,
    // Allows this field to return an array instead of a single value.
    '#extended' => TRUE,
  );
  if ($field['cardinality'] != 1) {
    $element['#pre_render'] = array(
      'dragndrop_upload_element_pre_render',
    );
  }

  // If there are multiple values, add an element for each existing one.
  $_count_items = count($items);
  do {
    $item = !empty($items[$delta]) ? $items[$delta] : $defaults;
    $elements[$delta] = $element;
    $elements[$delta]['#default_value'] = $item;
    $elements[$delta]['#weight'] = $delta;
    $delta++;
  } while ($delta < $_count_items);
  $delta = $_count_items;
  if ($field['cardinality'] != 1) {

    // And then add one more empty row for new uploads except when this is a
    // programmed form as it is not necessary.
    $elements[$delta] = $element;
    $elements[$delta]['#default_value'] = $defaults;
    $elements[$delta]['#weight'] = $delta;
    $elements[$delta]['#required'] = $element['#required'] && $delta == 0;
    $elements[$delta]['#access'] = FALSE;
    $elements[$delta]['#pre_render'] = $pre_render;
    if ($field['cardinality'] != -1) {
      $elements[$delta]['#cardinality'] -= $delta;
    }

    // Enable access to next element if needed.
    if (($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $field['cardinality']) && empty($form_state['programmed'])) {
      $elements[$delta]['#access'] = TRUE;
    }

    // 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(
      'upload_validators' => $elements[0]['#upload_validators'],
    ));
  }
  else {

    // If there's only one field, return it as delta 0.
    if (empty($elements[0]['#default_value']['fid'])) {
      $elements[0]['#description'] = theme('file_upload_help', array(
        'description' => $instance['description'],
        'upload_validators' => $elements[0]['#upload_validators'],
      ));
    }
  }
  return $elements;
}

/**
 * Pre render callback for the widget.
 */
function dragndrop_upload_file_pre_render($element) {
  if (isset($element['droppable_area']['#access']) && !$element['droppable_area']['#access']) {
    return $element;
  }
  $path = drupal_get_path('module', 'dragndrop_upload_file');
  $element['#attached']['js'][] = array(
    'type' => 'file',
    'data' => $path . '/js/dragndrop-upload-file.class.js',
    'weight' => 5.31,
  );
  $element['#attached']['js'][] = array(
    'type' => 'file',
    'data' => $path . '/js/dragndrop-upload-file.js',
    'weight' => 5.32,
  );
  $element['#attached']['js'][] = array(
    'type' => 'setting',
    'data' => array(
      'dragndropUploadFile' => array(
        '#' . $element['droppable_area']['#dnd_id'],
      ),
    ),
  );
  return $element;
}

/**
 * Implementation of hook_insert_widgets()
 * - Provides integration support for the 'Insert' module
 */
function dragndrop_upload_file_insert_widgets() {
  return array(
    'dragndrop_upload_file' => array(
      'element_type' => 'dragndrop_upload',
      'wrapper' => '.file-widget',
      'fields' => array(
        'title' => 'input[name$="[title]"], textarea[name$="[title]"]',
        'description' => 'input[name$="[description]"], textarea[name$="[description]"]',
      ),
    ),
  );
}