You are here

image_fupload.module in Image FUpload 6.3

Same filename and directory in other branches
  1. 6 image_fupload.module
  2. 6.2 image_fupload.module

File

image_fupload.module
View source
<?php

define('IMAGE_UNMACHINED', 'image_raw');
define('IMAGE_HALFPROCESSED', 'image_halfwork');
define('IMAGE_PROCESSED', 'image_processed');

// mark images (using body field) whose captions aren't edited yet
define('IMAGE_NOT_COMPLETED', 'image_not_completed');

/**
 * Implementation of hook_menu().
 */
function image_fupload_menu() {
  $items['fupload/flash'] = array(
    'title' => 'Image FUpload',
    'page callback' => 'fupload_filetransfer',
    'access callback' => TRUE,
    // must be examined later
    'type' => MENU_CALLBACK,
  );
  $items['fupload/js/deletequeue/%'] = array(
    'title' => 'Image FUpload',
    'page callback' => 'fupload_empty_queue',
    'page arguments' => array(
      3,
    ),
    'access arguments' => array(
      'mass upload images',
    ),
    'type' => MENU_CALLBACK,
  );
  $items['node/add/%image_node_type/list_images'] = array(
    'title' => 'Edit Captions',
    'access arguments' => array(
      'edit captions',
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'fupload_list_images_image',
      2,
    ),
    'type' => MENU_CALLBACK,
    'file' => 'includes/images.previewlist.image.inc',
  );
  $items['node/add/%image_node_type/list_imagefields'] = array(
    'title' => 'Edit Captions',
    'access arguments' => array(
      'edit captions',
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'fupload_list_images_imagefield',
      2,
    ),
    'type' => MENU_CALLBACK,
    'file' => 'includes/images.previewlist.imagefield.inc',
  );
  return $items;
}

/**
 * Menu callback; loads a image node type object
 */
function image_node_type_load($node_type, $simple_check = FALSE) {
  $image_node_types = variable_get('image_node_types', array());

  // test if given node type is image (field) node type
  $node_type = str_replace("-", "_", $node_type);

  // simple check without checking url arguments
  if ($simple_check && isset($image_node_types[$node_type])) {
    return $node_type;
  }
  if (isset($image_node_types[$node_type])) {
    if (arg(3) == "list_imagefields" && $image_node_types[$node_type]['type'] == "cck") {
      return $node_type;
    }
    elseif (arg(3) == "list_images" && $image_node_types[$node_type]['type'] == "image") {
      return $node_type;
    }
    else {
      return FALSE;
    }
  }
  else {
    return FALSE;
  }
}

/**
 * returns a identifier for images so that their status (current step) can easily be set
 */
function image_fupload_image_status($field_name, $status = IMAGE_UNMACHINED) {
  switch ($status) {
    case IMAGE_NOT_COMPLETED:
      return "<!--" . $field_name . "/" . IMAGE_NOT_COMPLETED . "-->";
      break;
    default:
      return $field_name . "/" . $status;
      break;
  }
}

/**
 * Implementation of hook_perm().
 */
function image_fupload_perm() {
  return array(
    'mass upload images',
    'edit captions',
  );
}

/**
 * Implementation of hook_help().
 */
function image_fupload_help($path, $arg) {
  switch ($path) {
    case 'admin/help#image_fupload':
      $output = '<p>' . t("The Image FUpload module is used to provide an alternate upload form to image module itself.") . '</p>';
      $output .= '<p>' . t("This is a great advantage because multiple images can be selected with one click which are automatically uploaded and processed without any further user interaction. Additionally, this module fully integrates in image module. Consequently, all settings made by image module are observed (thumb creation, file size limit etc.).") . '</p>';
      $output .= '<p>' . t("Image FUpload administration allows to define some characters which are replaced in the node title by a whitespace. In addition to that, the option can be selected to show a link to the original upload form to those users whose browser doesn't support this Flash / JS solution.") . '</p>';
      $output .= t('<p>You can</p>
<ul>
<li>create images using F(lash)Upload at <a href="!node-create-image">node &gt;&gt; create &gt;&gt; image</a>.</li>
<li>configure Image FUpload settings at <a href="!admin-settings-image-fupload">administer &gt;&gt; settings &gt;&gt; image &gt;&gt; image_fupload</a>.</li>
', array(
        '!node-create-image' => url('node/add/image'),
        '!admin-image-galleries' => url('admin/image/galleries'),
        '!admin-settings-image-fupload' => url('admin/settings/image/image_fupload'),
      )) . '</ul>';
      $output .= '<p>' . t('For more information please read the configuration and customization handbook <a href="!image">Image FUpload page</a>.', array(
        '!image' => 'http://www.drupal.org/handbook/modules/image/',
      )) . '</p>';
      return $output;
  }
}

/**
 * Implementation of hook_theme() registry.
 */
function image_fupload_theme() {
  return array(
    'swfupload_settings' => array(
      'template' => 'swfupload-settings',
      'arguments' => array(
        'modulepath' => NULL,
        'uploadpath' => NULL,
        'maxfilesize' => NULL,
        'fileextensions' => NULL,
        'sessionid' => NULL,
        'uploadlimit' => NULL,
        'nodetype' => NULL,
        'fieldname' => NULL,
        'field_required' => NULL,
        'storage_mode' => NULL,
        'redirect_url' => NULL,
      ),
    ),
    'fupload_create_filename' => array(
      'arguments' => array(
        'image' => NULL,
        'replacements' => NULL,
      ),
    ),
    'fupload_imagepreview_image' => array(
      'arguments' => array(
        'image' => NULL,
        'image_info' => NULL,
        'node_image' => NULL,
        'attributes' => NULL,
      ),
      'file' => 'includes/images.previewlist.image.inc',
    ),
  );
}
function fupload_filetransfer() {

  // huh.. swfUpload sends some data...let's see
  global $user;
  $sid = $_POST['PHPSESSID'];
  $node_type = check_plain($_POST['nodetype']);
  $field_name = check_plain($_POST['fieldname']);

  // validate given session id
  $result = db_query("SELECT * FROM {sessions} WHERE sid = '%s' AND hostname = '%s' LIMIT 1", $sid, ip_address());
  $upload_user = db_fetch_object($result);

  // Get users profile
  $user = user_load(array(
    'uid' => $upload_user->uid,
  ));

  // Do some checks before upload
  $field_access = FALSE;
  if (!empty($upload_user) && !empty($node_type) && !empty($field_name)) {

    // user valid? node_type & field_name received?
    // Check if given node_type & field_name combination is possible for user
    switch ($node_type) {
      case "image":

        // image node type
        if ($field_name == "images") {
          $field_access = node_access('create', $node_type, $user);

          // get suitable validators for our upload: image module
          $validators = array(
            'file_validate_is_image' => array(),
            'file_validate_size' => array(
              variable_get('image_max_upload_size', 800) * 1024,
            ),
          );
        }
        break;
      default:

        // probably cck image node type
        if (module_exists('content')) {
          if (image_node_type_load($node_type, TRUE) && ($field = content_fields($field_name, $node_type))) {
            $field_access = node_access('create', $node_type, $user);

            // also get suitable validators for our upload: cck imagefield module
            $validators = array_merge(filefield_widget_upload_validators($field), imagefield_widget_upload_validators($field));
          }
        }
        break;
    }
  }
  if (user_access('mass upload images', $user) && $field_access) {

    // Adapt to drupal files structure
    $_FILES['files']['name']['image'] = $_FILES['Filedata']['name'];
    $_FILES['files']['type']['image'] = $_FILES['Filedata']['type'];
    $_FILES['files']['tmp_name']['image'] = $_FILES['Filedata']['tmp_name'];
    $_FILES['files']['error']['image'] = $_FILES['Filedata']['error'];
    $_FILES['files']['size']['image'] = $_FILES['Filedata']['size'];

    // do some checks via transliteration module if available
    if (module_exists('transliteration')) {
      require_once drupal_get_path('module', 'transliteration') . '/transliteration.inc';
      $_FILES['files']['name']['image'] = transliteration_clean_filename($_FILES['Filedata']['name']);
    }
    if ($file = file_save_upload('image', $validators)) {
      $image = image_get_info($file->filepath);

      // Get real mime-type
      if (!db_query("UPDATE {files} SET filename = '%s', filemime = '%s' WHERE fid = %d", image_fupload_image_status($field_name, IMAGE_UNMACHINED), $image['mime_type'], $file->fid)) {
        drupal_json(array(
          'status' => FALSE,
          'data' => t('A database related problem appeared during upload. Please inform the site administrator if this is a permanent problem.'),
        ));
        exit;
      }

      // Get all status messages and add them to server message for swfUpload --> inform client
      $messages = drupal_get_messages('status');
      drupal_json(array(
        'status' => TRUE,
        'data' => t('Complete. !messages', array(
          '!messages' => !empty($messages['status']) ? implode(' ', $messages['status']) : '',
        )),
      ));

      // Reply a status message to satisfy swfUpload
    }
    else {

      // Get responsible error messages and send it to swfUpload
      $messages = form_get_errors();
      drupal_json(array(
        'status' => FALSE,
        'data' => t('Upload failed: !errors', array(
          '!errors' => implode(' ', $messages),
        )),
      ));
    }
  }
  else {
    drupal_access_denied();
  }
}
function fupload_empty_queue($field_name) {
  global $user;

  // Set "processed" flag so that these images aren't processed again; images are deleted later by cron (--> temporary files)
  db_query("UPDATE {files} SET filename = '%s' WHERE uid = %d AND status = %d AND filename = '%s'", image_fupload_image_status(check_plain($field_name), IMAGE_PROCESSED), $user->uid, FILE_STATUS_TEMPORARY, image_fupload_image_status(check_plain($field_name), IMAGE_UNMACHINED));

  // Output message to user via AJAX
  drupal_set_message();
  drupal_set_message(t('All queued images were deleted.'), 'warning');
  drupal_json(array(
    'status' => TRUE,
    'data' => theme('status_messages'),
  ));
}
function theme_fupload_create_filename($image, $replacements = NULL) {

  // Get filename out of filepath
  $filename = trim(basename($image->filepath), ' ');
  $length1 = drupal_strlen(strrchr($filename, '.'));
  $length2 = drupal_strlen($filename);
  $image_name = drupal_ucfirst(drupal_substr($filename, 0, $length2 - $length1));

  // Remove some given (userdefined) elements
  if (is_null($replacements)) {
    $replacements = variable_get('fupload_title_replacements', '_;{;}');
  }
  $image_name = str_replace(explode(';', $replacements), ' ', $image_name);
  return $image_name;
}

/**
 * Helper function which emulates "node_form_validate" of node.pages.inc
 * Need this because body causes validation error with some settings, but I don't need a body field, later yes =)
 */
function fupload_node_form_validate($form, &$form_state) {
  $node = (object) $form_state['values'];
  $node->body = NULL;

  // Little Hack to disable body validation
  node_validate($node, $form);
}

/**
 * This function allows to validate a file on given $validator functions.
 * This code is taken from file_save_upload (D 6.4) (22.09.2008)
 *
 * @param object $file
 * @param array $validators
 * @return Boolean
 *   returns TRUE, if validation was successful, otherwise FALSE
 */
function file_validate($file, $validators = array()) {

  // Call the validation functions.
  $errors = array();
  foreach ($validators as $function => $args) {
    array_unshift($args, $file);
    $errors = array_merge($errors, call_user_func_array($function, $args));
  }

  // Check for validation errors.
  if (!empty($errors)) {
    $message = t('The selected file %name could not be uploaded.', array(
      '%name' => $file->filename,
    ));
    if (count($errors) > 1) {
      $message .= '<ul><li>' . implode('</li><li>', $errors) . '</li></ul>';
    }
    else {
      $message .= ' ' . array_pop($errors);
    }
    form_set_error($source, $message);
    return FALSE;
  }
  else {

    // Validation successful =)
    return TRUE;
  }
}

/**
 * This helper function lists/read/write/delete special settings for the image previewlist
 * depending on the node type
 *
 * @param string $op
 * @param string $node_type
 * @param array $data_write
 * @return array or NULL
 */
function _fupload_imagepreview_settings($op, $node_type, $data_write = NULL) {

  // switch to the right operation: what's up?
  switch ($op) {
    case 'list':

      // generate a list of available presets for image_preview: image module or/and imagecache
      $preview_presets_list = array();

      // image module presets
      if (module_exists('image') && $node_type == "image") {
        $image_sizes = image_get_sizes();
        foreach ($image_sizes as $key => $size) {
          $preview_presets_list['image']['0_' . $key] = t('Image size') . ': ' . $size['label'];
        }
      }

      // imagecache module presets
      if (module_exists('imagecache')) {
        $image_sizes = imagecache_presets();
        foreach ($image_sizes as $key => $size) {
          $preview_presets_list['imagecache']['1_' . $size['presetname']] = t('Image size') . ': ' . $size['presetname'];
        }
      }

      //output list
      return $preview_presets_list;
      break;
    case 'read':

      // read actual setting for this node type
      $image_node_types = variable_get('image_node_types', array());
      switch ($node_type) {
        case 'image':

          // image node type
          if (!empty($image_node_types['image']['image_selection'])) {

            // image module preset
            return '0_' . $image_node_types['image']['image_selection'];
          }
          elseif (!empty($image_node_types['image']['imagecache_preset'])) {

            // imagecache module preset
            return '1_' . $image_node_types['image']['imagecache_preset'];
          }
          else {

            // no setting saved yet?
            return '';
          }
          break;
        default:

          // node type with CCK ImageField
          // return imagecache preset
          return '1_' . $image_node_types[$node_type]['imagecache_preset'];
          break;
      }
      break;
    case 'write':
      if (isset($data_write)) {

        // is some data available?
        // write input data to database
        $image_node_types = variable_get('image_node_types', array());

        // prepare type of image preview before writing into db
        $preview_preset = explode('_', $data_write['preview_preset'], 2);
        switch ($preview_preset[0]) {
          case '0':

            // image module preset
            $preview_preset_image = $preview_preset[1];
            break;
          case '1':

            // imagecache module preset
            $preview_preset_imagecache = $preview_preset[1];
            break;
        }
        switch ($node_type) {
          case 'image':

            // image node type
            $image_node_types['image'] = array(
              'type' => 'image',
              'fieldname' => 'images',
              'image_selection' => $preview_preset_image,
              'imagecache_preset' => $preview_preset_imagecache,
            );
            break;
          default:

            // node type with CCK ImageField
            $image_node_types[$node_type] = array(
              'type' => 'cck',
              'fieldname' => $data_write['fieldname'],
              'image_selection' => $preview_preset_image,
              'imagecache_preset' => $preview_preset_imagecache,
            );
            break;
        }

        // write data to database
        variable_set('image_node_types', $image_node_types);
      }
      break;
    case 'delete':

      // delete an entry from settings variable
      $image_node_types = variable_get('image_node_types', array());
      unset($image_node_types[$node_type]);

      // write data to database
      variable_set('image_node_types', $image_node_types);
      break;
  }
}

Functions

Namesort descending Description
file_validate This function allows to validate a file on given $validator functions. This code is taken from file_save_upload (D 6.4) (22.09.2008)
fupload_empty_queue
fupload_filetransfer
fupload_node_form_validate Helper function which emulates "node_form_validate" of node.pages.inc Need this because body causes validation error with some settings, but I don't need a body field, later yes =)
image_fupload_help Implementation of hook_help().
image_fupload_image_status returns a identifier for images so that their status (current step) can easily be set
image_fupload_menu Implementation of hook_menu().
image_fupload_perm Implementation of hook_perm().
image_fupload_theme Implementation of hook_theme() registry.
image_node_type_load Menu callback; loads a image node type object
theme_fupload_create_filename
_fupload_imagepreview_settings This helper function lists/read/write/delete special settings for the image previewlist depending on the node type

Constants