You are here

function filefield_widget_process in FileField 6.3

An element #process callback for the filefield_widget field type.

Expands the filefield_widget type to include the upload field, upload and remove buttons, and the description field.

1 string reference to 'filefield_widget_process'
filefield_elements in ./filefield.module
Implementation of hook_elements().

File

./filefield_widget.inc, line 266
This file contains CCK widget related functionality.

Code

function filefield_widget_process($element, $edit, &$form_state, $form) {
  static $settings_added;
  $item = $element['#value'];
  $field_name = $element['#field_name'];
  $delta = $element['#delta'];
  $element['#theme'] = 'filefield_widget_item';
  $field = $form['#field_info'][$field_name];

  // The widget is being presented, so apply the JavaScript.
  drupal_add_js(drupal_get_path('module', 'filefield') . '/filefield.js');
  if (!isset($settings_added[$field_name]) && isset($element['#upload_validators']['filefield_validate_extensions'])) {
    $settings_added[$field_name] = TRUE;
    $settings = array(
      'filefield' => array(
        $field_name => $element['#upload_validators']['filefield_validate_extensions'][0],
      ),
    );
    drupal_add_js($settings, 'setting');
  }

  // Title is not necessary for each individual field.
  if ($field['multiple'] > 0) {
    unset($element['#title']);
  }

  // Set up the buttons first since we need to check if they were clicked.
  $element['filefield_upload'] = array(
    '#type' => 'submit',
    '#value' => t('Upload'),
    '#submit' => array(
      'node_form_submit_build_node',
    ),
    '#ahah' => array(
      // with JavaScript
      'path' => 'filefield/ahah/' . $element['#type_name'] . '/' . $element['#field_name'] . '/' . $element['#delta'],
      'wrapper' => $element['#id'] . '-ahah-wrapper',
      'method' => 'replace',
      'effect' => 'fade',
    ),
    '#field_name' => $element['#field_name'],
    '#delta' => $element['#delta'],
    '#type_name' => $element['#type_name'],
    '#upload_validators' => $element['#upload_validators'],
    '#weight' => 100,
    '#post' => $element['#post'],
  );
  $element['filefield_remove'] = array(
    // With default CCK edit forms, $element['#parents'] is array($element['#field_name'], $element['#delta']).
    // However, if some module (for example, flexifield) places our widget deeper in the tree, we want to
    // use that information in constructing the button name.
    '#name' => implode('_', $element['#parents']) . '_filefield_remove',
    '#type' => 'submit',
    '#value' => t('Remove'),
    '#submit' => array(
      'node_form_submit_build_node',
    ),
    '#ahah' => array(
      // with JavaScript
      'path' => 'filefield/ahah/' . $element['#type_name'] . '/' . $element['#field_name'] . '/' . $element['#delta'],
      'wrapper' => $element['#id'] . '-ahah-wrapper',
      'method' => 'replace',
      'effect' => 'fade',
    ),
    '#field_name' => $element['#field_name'],
    '#delta' => $element['#delta'],
    '#weight' => 101,
    '#post' => $element['#post'],
  );

  // Because the output of this field changes depending on the button clicked,
  // we need to ask FAPI immediately if the remove button was clicked.
  // It's not good that we call this private function, but
  // $form_state['clicked_button'] is only available after this #process
  // callback is finished.
  if (_form_button_was_clicked($element['filefield_remove'])) {

    // Delete the file if it is currently unused. Note that field_file_delete()
    // does a reference check in addition to our basic status check.
    if (isset($edit['fid'])) {
      $removed_file = field_file_load($edit['fid']);

      // Users are only allowed to remove their own files.
      if ($removed_file['status'] == 0 && $GLOBALS['user']->uid == $removed_file['uid']) {
        field_file_delete($removed_file);
      }
    }
    $item = array(
      'fid' => 0,
      'list' => $field['list_default'],
      'data' => array(
        'description' => '',
      ),
    );
  }

  // Add progress bar support to the upload if possible.
  $progress_indicator = isset($field['widget']['progress_indicator']) ? $field['widget']['progress_indicator'] : 'bar';
  if ($progress_indicator != 'throbber' && ($implementation = filefield_progress_implementation())) {
    $upload_progress_key = md5(mt_rand());
    if ($implementation == 'uploadprogress') {
      $element['UPLOAD_IDENTIFIER'] = array(
        '#type' => 'hidden',
        '#value' => $upload_progress_key,
        '#attributes' => array(
          'class' => 'filefield-progress',
        ),
      );
    }
    elseif ($implementation == 'apc') {
      $element['APC_UPLOAD_PROGRESS'] = array(
        '#type' => 'hidden',
        '#value' => $upload_progress_key,
        '#attributes' => array(
          'class' => 'filefield-progress',
        ),
      );
    }

    // Add the upload progress callback.
    $element['filefield_upload']['#ahah']['progress']['type'] = 'bar';
    $element['filefield_upload']['#ahah']['progress']['path'] = 'filefield/progress/' . $upload_progress_key;
  }

  // Set the FID.
  $element['fid'] = array(
    '#type' => 'hidden',
    '#value' => isset($item['fid']) ? $item['fid'] : 0,
  );
  if (!empty($item['fid'])) {
    if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE && function_exists('file_download_access') && !empty($item['status']) && !file_download_access($item['filepath'])) {
      $element['preview'] = array(
        '#type' => 'markup',
        '#value' => t('Access denied'),
      );
    }
    else {
      $element['preview'] = array(
        '#type' => 'markup',
        '#value' => theme('filefield_widget_preview', $item),
      );
    }
  }

  // Grant access to temporary files.
  if (!empty($item['fid']) && isset($item['status']) && $item['status'] == 0 && variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE) {
    $_SESSION['filefield_access'][] = $item['fid'];
  }

  // placeholder.. will be serialized into the data column. this is a place for widgets
  // to put additional data.
  $element['data'] = array(
    '#tree' => 'true',
    '#access' => !empty($item['fid']),
  );
  if (!empty($field['description_field'])) {
    $element['data']['description'] = array(
      '#title' => t('Description'),
      '#value' => isset($item['data']['description']) ? $item['data']['description'] : '',
      '#type' => variable_get('filefield_description_type', 'textfield'),
      '#maxlength' => variable_get('filefield_description_length', 128),
    );
  }
  if (!empty($field['list_field'])) {
    $element['list'] = array(
      '#type' => empty($item['fid']) ? 'hidden' : 'checkbox',
      '#title' => t('List'),
      '#value' => isset($item['list']) && !empty($item['fid']) ? $item['list'] : $field['list_default'],
      '#attributes' => array(
        'class' => 'filefield-list',
      ),
    );
  }
  else {
    $element['list'] = array(
      '#type' => 'hidden',
      '#value' => '1',
    );
  }
  foreach ($element['#upload_validators'] as $callback => $arguments) {
    $help_func = $callback . '_help';
    if (function_exists($help_func)) {
      $desc[] = call_user_func_array($help_func, $arguments);
    }
  }
  $element['upload'] = array(
    '#name' => 'files[' . implode('_', $element['#array_parents']) . ']',
    '#type' => 'file',
    '#description' => implode('<br />', $desc),
    '#size' => 22,
    '#access' => empty($item['fid']),
  );
  $element['#attributes']['id'] = $element['#id'] . '-ahah-wrapper';
  $element['#prefix'] = '<div ' . drupal_attributes($element['#attributes']) . '>';
  $element['#suffix'] = '</div>';
  return $element;
}