You are here

linkimagefield.module in Link Image Field 5

Same filename and directory in other branches
  1. 8 linkimagefield.module
  2. 6 linkimagefield.module
  3. 7 linkimagefield.module

Defines an link image field type. linkimagefield uses content.module to store the fid, and the drupal files table to store the actual file data.

File

linkimagefield.module
View source
<?php

/**
 * @file
 * Defines an link image field type.
 * linkimagefield uses content.module to store the fid, and the drupal files 
 * table to store the actual file data.
 *
 */
function linkimagefield_default_item() {
  return array(
    'fid' => 0,
    'title' => '',
    'alt' => '',
    'url' => '',
  );
}
function linkimagefield_menu($maycache) {
  $items = array();
  if (!$maycache && $_SESSION['linkimagefield']) {

    // Add handlers for previewing new uploads.
    foreach ($_SESSION['linkimagefield'] as $fieldname => $files) {
      if (is_array($files)) {
        foreach ($files as $delta => $file) {
          if ($file['preview']) {
            $items[] = array(
              'path' => $file['preview'],
              'callback' => '_linkimagefield_preview',
              'access' => TRUE,
              'type' => MENU_CALLBACK,
            );
          }
        }
      }
    }
  }
  return $items;
}

/**
 *  transfer a file that is in a 'preview' state.
 *  @todo  multiple support
 */
function _linkimagefield_preview() {
  foreach ($_SESSION['linkimagefield'] as $fieldname => $files) {
    foreach ($files as $delta => $file) {
      if ($file['preview'] == $_GET['q']) {
        file_transfer($file['filepath'], array(
          'Content-Type: ' . mime_header_encode($file['filemime']),
          'Content-Length: ' . $file['filesize'],
        ));
        exit;
      }
    }
  }
}

/**
 * Implementation of hook_field_info().
 */
function linkimagefield_field_info() {
  return array(
    'linkimage' => array(
      'label' => 'Link Image',
    ),
  );
}

/**
 * Implementation of hook_field_settings().
 */
function linkimagefield_field_settings($op, $field) {
  switch ($op) {
    case 'form':
      $form = array();
      return $form;
    case 'validate':
      break;
    case 'save':
      return array();
    case 'database columns':
      $columns = array(
        'fid' => array(
          'type' => 'int',
          'not null' => TRUE,
          'default' => '0',
        ),
        'title' => array(
          'type' => 'varchar',
          length => 255,
          'not null' => TRUE,
          'default' => "''",
          'sortable' => TRUE,
        ),
        'alt' => array(
          'type' => 'varchar',
          length => 255,
          'not null' => TRUE,
          'default' => "''",
          'sortable' => TRUE,
        ),
        'url' => array(
          'type' => 'varchar',
          length => 255,
          'not null' => TRUE,
          'default' => "''",
          'sortable' => TRUE,
        ),
      );
      return $columns;
  }
}

/**
 * insert a file into the database.
 * @param $node
 *    node object file will be associated with.
 * @param $file
 *    file to be inserted, passed by reference since fid should be attached.
 *    
 */
function linkimagefield_file_insert($node, &$file, $field) {
  $fieldname = $field['field_name'];
  $filepath = file_create_path($field['widget']['image_path']) . '/' . $file['filename'];
  if (linkimagefield_check_directory($field['widget']['image_path']) && ($file = file_save_upload((object) $file, $filepath))) {
    $file = (array) $file;
    $file['fid'] = db_next_id('{files}_fid');
    db_query("INSERT into {files} (fid, nid, filename, filepath, filemime, filesize)\n             VALUES (%d, %d, '%s','%s','%s',%d)", $file['fid'], $node->nid, $file['filename'], $file['filepath'], $file['filemime'], $file['filesize']);
    return (array) $file;
  }
  else {

    // Include file name in upload error.
    form_set_error(NULL, t('Image upload was unsuccessful.'));
    return FALSE;
  }
}

/**
 * update the file record if necessary
 * @param $node
 * @param $file
 * @param $field
 */
function linkimagefield_file_update($node, &$file, $field) {
  $file = (array) $file;
  if ($file['flags']['delete'] == TRUE) {
    if (_linkimagefield_file_delete($file, $field['field_name'])) {
      return array();
    }
  }
  if ($file['fid'] == 'upload') {
    return linkimagefield_file_insert($node, $file, $field);
  }
  else {

    // if fid is not numeric here we should complain.
    // else we update the file table.
  }
  return $file;
}

/**
 * Implementation of hook_field().
 */
function linkimagefield_field($op, $node, $field, &$node_field, $teaser, $page) {
  $fieldname = $field['field_name'];
  switch ($op) {

    // called after content.module loads default data.
    case 'load':
      if (count($node_field)) {
        $values = array();
        foreach ($node_field as $delta => $file) {
          if (!empty($file)) {
            $file = _linkimagefield_file_load($file['fid']);

            // In certain cases, content.module calls this function with
            // $items[$delta] set, even if the field has not yet been stored at
            // all or has already been deleted. In that case, $file['fid'] == 0
            // and file_load() returns an empty array. When that happens,
            // unset() the delta so that subsequent hooks are not bothered.
            if (empty($file)) {
              unset($node_field[$delta]);
            }
            else {

              // otherwise, merge our info with CCK's, and all is fine.
              $node_field[$delta] = array_merge((array) $node_field[$delta], $file);
            }
          }
        }
        return array(
          $fieldname => $node_field,
        );
      }
      return array();

    // called before content.module defaults.
    case 'insert':
      foreach ($node_field as $delta => $item) {
        if ($item['url'] == "") {
          $item['url'] = "node/" . $node->nid;
        }
        $node_field[$delta] = linkimagefield_file_insert($node, $item, $field);

        // Remove non-existant images from items
        if (empty($node_field[$delta])) {
          unset($node_field[$delta]);
        }
      }
      linkimagefield_clear_field_session($fieldname);
      break;

    // called before content.module defaults.
    case 'update':
      foreach ($node_field as $delta => $item) {
        if ($item['url'] == "") {
          $item['url'] = "node/" . $node->nid;
        }

        // If we're dealing with a single value field, and we just received
        // a new file item, we need to mark the existing (old) one for
        // deletion.  Otherwise, it will become orphaned.
        // Update each file item.
        $node_field[$delta] = linkimagefield_file_update($node, $item, $field);

        // If the file has been deleted, unset the file entry so that it's
        // actually deleted from the database, or at least set it to a
        // default item if CCK won't delete it.
        if (empty($node_field[$delta])) {
          if ($field['multiple']) {
            unset($node_field[$delta]);
          }
          else {
            $node_field[$delta] = linkimagefield_default_item();
          }
        }
      }

      // Compact deltas.
      $node_field = array_values($node_field);
      linkimagefield_clear_field_session($fieldname);
      break;
    case 'delete':
      foreach ($node_field as $delta => $item) {
        _linkimagefield_file_delete($item, $field['field_name']);
      }
      break;
  }
}

/**
 * Implementation of hook_widget_info().
 */
function linkimagefield_widget_info() {
  return array(
    'linkimage' => array(
      'label' => 'Link Image',
      'field types' => array(
        'linkimage',
      ),
    ),
  );
}

/**
 * Implementation of hook_widget_settings().
 */
function linkimagefield_widget_settings($op, $widget) {
  switch ($op) {
    case 'callbacks':
      return array(
        'default value' => CONTENT_CALLBACK_CUSTOM,
      );
    case 'form':
      $form = array();
      $form['max_resolution'] = array(
        '#type' => 'textfield',
        '#title' => t('Maximum resolution for Images'),
        '#default_value' => $widget['max_resolution'] ? $widget['max_resolution'] : 0,
        '#size' => 15,
        '#maxlength' => 10,
        '#description' => t('The maximum allowed image size expressed as WIDTHxHEIGHT (e.g. 640x480). Set to 0 for no restriction.'),
      );
      $form['image_path'] = array(
        '#type' => 'textfield',
        '#title' => t('Image path'),
        '#default_value' => $widget['image_path'] ? $widget['image_path'] : '',
        '#description' => t('Optional subdirectory within the "%dir" directory where images will be stored. Do not include trailing slash.', array(
          '%dir' => variable_get('file_directory_path', 'files'),
        )),
        '#after_build' => array(
          'linkimagefield_form_check_directory',
        ),
      );
      $form['custom_alt'] = array(
        '#type' => 'checkbox',
        '#title' => t('Enable custom alternate text'),
        '#default_value' => $widget['custom_alt'] ? $widget['custom_alt'] : 0,
        '#description' => t('Enable custom alternate text for images. Filename will be used if not checked.'),
      );
      $form['custom_title'] = array(
        '#type' => 'checkbox',
        '#title' => t('Enable custom title text'),
        '#default_value' => $widget['custom_title'] ? $widget['custom_title'] : 0,
        '#description' => t('Enable custom title text for images. Filename will be used if not checked.'),
      );
      return $form;
    case 'validate':
      break;
    case 'save':
      return array(
        'max_resolution',
        'image_path',
        'custom_url',
        'custom_alt',
        'custom_title',
        'teaser_preset',
        'body_preset',
      );
  }
}

/**
 * Wrapper function for linkimagefield_check_directory that accepts a form element
 * to validate - if user specified one. Won't allow form submit unless the
 * directory exists & is writable
 * 
 * @param $form_element
 *   The form element containing the name of the directory to check.
 */
function linkimagefield_form_check_directory($form_element) {
  if (!empty($form_element['#value'])) {
    linkimagefield_check_directory($form_element['#value'], $form_element);
  }
  return $form_element;
}

/**
 * Create the image directory relative to the 'files' dir recursively for every
 * directory in the path.
 * 
 * @param $directory
 *   The directory path under files to check, such as 'photo/path/here'
 * @param $form_element
 *   A form element to throw an error on if the directory is not writable
 */
function linkimagefield_check_directory($directory, $form_element = array()) {
  foreach (explode('/', $directory) as $dir) {
    $dirs[] = $dir;
    $path = file_create_path(implode($dirs, '/'));
    file_check_directory($path, FILE_CREATE_DIRECTORY, $form_element['#parents'][0]);
  }
  return TRUE;
}
function _linkimagefield_scale_image($file, $resolution = 0) {
  $info = image_get_info($file['filepath']);
  if ($info) {
    list($width, $height) = explode('x', $resolution);
    if ($width && $height) {
      $result = image_scale($file['filepath'], $file['filepath'], $width, $height);
      if ($result) {
        $file['filesize'] = filesize($file['filepath']);
        drupal_set_message(t('The image was resized to fit within the maximum allowed resolution of %resolution pixels', array(
          '%resolution' => $resolution,
        )));
      }
    }
  }
  return $file;
}
function linkimagefield_clear_session() {
  if (is_array($_SESSION['linkimagefield']) && count($_SESSION['linkimagefield'])) {
    foreach (array_keys($_SESSION['linkimagefield']) as $fieldname) {
      linkimagefield_clear_field_session($fieldname);
    }
    unset($_SESSION['linkimagefield']);
  }
}
function linkimagefield_clear_field_session($fieldname) {
  if (is_array($_SESSION['linkimagefield'][$fieldname]) && count($_SESSION['linkimagefield'][$fieldname])) {
    foreach ($_SESSION['linkimagefield'][$fieldname] as $delta => $file) {
      if (is_file($file['filepath'])) {
        file_delete($file['filepath']);
      }
    }
    unset($_SESSION['linkimagefield'][$fieldname]);
  }
}
function _linkimagefield_file_delete($file, $fieldname) {
  if (is_numeric($file['fid'])) {
    db_query('DELETE FROM {files} WHERE fid = %d', $file['fid']);
  }
  else {
    unset($_SESSION['linkimagefield'][$fieldname][$file['sessionid']]);
  }
  return file_delete($file['filepath']);
}

/**
 * Implementation of hook_widget().
 */
function linkimagefield_widget($op, &$node, $field, &$node_field) {
  $fieldname = $field['field_name'];
  $content_type = $field['type_name'];
  switch ($op) {
    case 'default value':
      return array();
    case 'prepare form values':
      _linkimagefield_widget_prepare_form_values($node, $field, $node_field);
      return;
    case 'form':
      $form = _linkimagefield_widget_form($node, $field, $node_field);
      return $form;
    case 'validate':
      _linkimagefield_widget_form_validate($node, $field, $node_field);
      return;
  }
}
function _linkimagefield_widget_prepare_form_values($node, $field, &$node_field) {
  $fieldname = $field['field_name'];

  // clean up the session if we weren't posted.
  if (!count($_POST)) {
    linkimagefield_clear_session();
  }

  // Attach new files
  if ($file = file_check_upload($fieldname . '_upload')) {
    $file = (array) $file;
    if (strpos($file['filemime'], 'image') !== FALSE) {
      $file = _linkimagefield_scale_image($file, $field['widget']['max_resolution']);

      // Create the filepath for the image preview
      $filepath = file_create_filename($file['filename'], file_create_path($field['widget']['image_path']));
      if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PRIVATE) {
        if (strpos($filepath, file_directory_path()) !== FALSE) {
          $filepath = trim(substr($filepath, strlen(file_directory_path())), '\\/');
        }
        $filepath = 'system/files/' . $filepath;
      }
      $file['fid'] = 'upload';
      $file['preview'] = $filepath;

      // If a single field, mark any other images for deletion and delete files in session
      if (!$field['multiple']) {
        if (is_array($node_field)) {
          foreach ($node_field as $delta => $session_file) {
            $node_field[$delta]['flags']['delete'] = TRUE;
          }
        }
        linkimagefield_clear_field_session($fieldname);
      }

      // Add the file to the session
      $file_id = count($node_field) + count($_SESSION['linkimagefield'][$fieldname]);
      $_SESSION['linkimagefield'][$fieldname][$file_id] = $file;
    }
  }

  // Load files from preview state. before committing actions.
  if (is_array($_SESSION['linkimagefield'][$fieldname]) && count($_SESSION['linkimagefield'][$fieldname])) {
    foreach ($_SESSION['linkimagefield'][$fieldname] as $delta => $file) {
      $node_field[] = $file;
    }
  }
}
function _linkimagefield_widget_form($node, $field, &$node_field) {
  $fieldname = $field['field_name'];
  drupal_add_css(drupal_get_path('module', 'linkimagefield') . '/linkimagefield.css');
  $form = array();
  $form[$fieldname] = array(
    '#type' => 'fieldset',
    '#title' => t($field['widget']['label']),
    '#weight' => $field['widget']['weight'],
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#tree' => TRUE,
  );

  // Seperate from tree becase of that silly things won't be
  // displayed if they are a child of '#type' = form issue
  $form[$fieldname][$fieldname . '_upload'] = array(
    '#type' => 'file',
    '#title' => $delta == 0 ? t('Image') : NULL,
    '#description' => $field['widget']['description'],
    '#tree' => FALSE,
    '#weight' => 1,
  );
  $form[$fieldname]['upload'] = array(
    '#type' => 'button',
    '#value' => t('Upload'),
    '#name' => 'cck_linkimagefield_' . $fieldname . '_op',
    '#attributes' => array(
      'id' => $fieldname . '-attach-button',
    ),
    '#tree' => FALSE,
    '#weight' => 2,
  );

  // Store the file data object to be carried on.
  if (is_array($node_field) && count($node_field)) {
    foreach ($node_field as $delta => $file) {
      if ($file['filepath'] && !$file['flags']['delete']) {
        $form[$fieldname][$delta] = array(
          '#theme' => 'linkimagefield_edit_image_row',
        );
        $form[$fieldname][$delta]['flags']['delete'] = array(
          '#type' => 'checkbox',
          '#title' => t('Delete'),
          '#default_value' => 0,
        );
        $filename = $file['fid'] == 'upload' ? file_create_filename($file['filename'], file_create_path($field['widget']['image_path'])) : $file['filepath'];
        $form[$fieldname][$delta]['preview'] = array(
          '#type' => 'markup',
          '#value' => theme('linkimagefield_image', $file, $file['alt'], $file['url'], $file['title'], array(
            'width' => '150',
          ), FALSE),
        );

        //drupal_set_message('linkimagefield['. $fieldname .'] '. $op .' node field: <pre>'. print_r($node_field, true) .'</pre>');
        $form[$fieldname][$delta]['description'] = array(
          '#type' => 'markup',
          '#value' => '<strong>' . t('Filename: ') . '</strong>' . $file['filename'],
        );
        $form[$fieldname][$delta]['alt'] = array(
          '#type' => 'hidden',
          '#value' => $file['filename'],
        );

        // overwrite with an input field if custom_alt is flagged;
        if ($field['widget']['custom_alt']) {
          $form[$fieldname][$delta]['alt'] = array(
            '#type' => 'textfield',
            '#title' => t('Alternate text'),
            '#default_value' => $file['alt'],
            '#description' => t('Alternate text to be displayed if the image cannot be displayed.'),
            '#maxlength' => 255,
            '#size' => 10,
          );
        }
        $form[$fieldname][$delta]['title'] = array(
          '#type' => 'hidden',
          '#value' => $file['filename'],
        );

        // overwrite with an input field if custom_title is flagged;
        if ($field['widget']['custom_title']) {
          $form[$fieldname][$delta]['title'] = array(
            '#type' => 'textfield',
            '#title' => t('Title'),
            '#default_value' => $file['title'],
            '#description' => t('Text to be displayed on mouse overs.'),
            '#maxlength' => 255,
            '#size' => 10,
          );
        }
        $form[$fieldname][$delta]['url'] = array(
          '#type' => 'textfield',
          '#title' => t('URL'),
          '#default_value' => $file['url'],
          '#description' => t('URL. Leave blank to point to the respective node.'),
          '#maxlength' => 255,
          '#size' => 10,
        );

        // Special handling for single value fields
        if (!$field['multiple']) {
          $form[$fieldname][$delta]['replace'] = array(
            '#type' => 'markup',
            '#value' => t('If a new image is chosen, the current image will be replaced upon submitting the form.'),
          );
        }
      }
      elseif ($file['filepath'] && $file['flags']['delete']) {

        // Hide all the form values if this item is marked for deletion
        $form[$fieldname][$delta]['flags']['delete'] = array(
          '#type' => 'value',
          '#value' => $file['flags']['delete'],
        );
        $form[$fieldname][$delta]['title'] = array(
          '#type' => 'value',
          '#value' => $file['title'],
        );
        $form[$fieldname][$delta]['alt'] = array(
          '#type' => 'value',
          '#value' => $file['alt'],
        );
        $form[$fieldname][$delta]['url'] = array(
          '#type' => 'value',
          '#value' => $file['url'],
        );
      }
      $form[$fieldname][$delta]['filename'] = array(
        '#type' => 'value',
        '#value' => $file['filename'],
      );
      $form[$fieldname][$delta]['filepath'] = array(
        '#type' => 'value',
        '#value' => $file['filepath'],
      );
      $form[$fieldname][$delta]['filemime'] = array(
        '#type' => 'value',
        '#value' => $file['filemime'],
      );
      $form[$fieldname][$delta]['filesize'] = array(
        '#type' => 'value',
        '#value' => $file['filesize'],
      );
      $form[$fieldname][$delta]['fid'] = array(
        '#type' => 'value',
        '#value' => $file['fid'],
      );
    }
  }
  return $form;
}
function _linkimagefield_widget_form_validate($node, $field, $node_field) {
  $fieldname = $field['field_name'];
  if ($field['required']) {
    if (!count($node_field)) {
      form_set_error($fieldname, $field['widget']['label'] . ' is required.');
    }
  }
}

/**
 * Implementation of hook_field_formatter_info().
 */
function linkimagefield_field_formatter_info() {
  $formatters = array(
    'default' => array(
      'label' => 'Default',
      'field types' => array(
        'linkimage',
      ),
    ),
  );
  return $formatters;
}

/**
 * Implementation of hook_field_formatter().
 *
 */
function linkimagefield_field_formatter($field, $item, $formatter) {
  if (empty($item['fid'])) {
    return '';
  }
  $file = _linkimagefield_file_load($item['fid']);
  return theme('linkimagefield_image', $file, $item['alt'], $item['url'], $item['title']);
}
function _linkimagefield_file_load($fid = NULL) {

  // Don't bother if we weren't passed and fid.
  if (!empty($fid) && is_numeric($fid)) {
    $result = db_query('SELECT * FROM {files} WHERE fid = %d', $fid);
    $file = db_fetch_array($result);
    if ($file) {
      return $file;
    }
  }

  // return an empty array if nothing was found.
  return array();
}
function theme_linkimagefield_view_image($file, $alt = '', $url = '', $title = '', $attributes = NULL, $getsize = TRUE) {
  return theme('linkimagefield_image', $file, $alt, $url, $title, $attributes, $getsize);
}
function theme_linkimagefield_edit_image_row($element) {
  $output = '<div class="linkimagefield-edit-preview">' . drupal_render($element['preview']) . '</div>';
  $output .= '<div class="linkimagefield-edit-image-detail">';
  $output .= '<div class="linkimagefield-edit-image-flags">' . drupal_render($element['flags']) . '</div>';
  $output .= '<div class="linkimagefield-edit-image-description">' . drupal_render($element['description']);
  $output .= '</div>';
  $output .= drupal_render($element['alt']);
  $output .= drupal_render($element['title']);
  $output .= drupal_render($element['url']);
  $output .= '</div>';

  //$output .= '<div class="linkimagefield-edit-image-fid">'. $element['fid']['#value'] .'</div>';
  $output = '<div class="linkimagefield-edit-image-row clear-block">' . $output . '</div>';
  if (isset($element['replace'])) {
    $output .= '<div class="linkimagefield-edit-image-replace">' . drupal_render($element['replace']) . '</div>';
  }
  return $output;
}
function theme_linkimagefield_image($file, $alt = '', $url_link = '', $title = '', $attributes = NULL, $getsize = TRUE) {
  $file = (array) $file;
  if (!$getsize || is_file($file['filepath']) && (list($width, $height, $type, $image_attributes) = @getimagesize($file['filepath']))) {
    $attributes = drupal_attributes($attributes);
    $path = $file['fid'] == 'upload' ? $file['preview'] : $file['filepath'];
    $alt = empty($alt) ? $file['alt'] : $alt;

    //$url_link;
    $title = empty($title) ? $file['title'] : $title;
    $url = file_create_url($path);
    $url_link = url($url_link);
    return '<a href="' . $url_link . '"><img src="' . check_url($url) . '" alt="' . check_plain($alt) . '" title="' . check_plain($title) . '" ' . $image_attributes . $attributes . ' /></a>';
  }
}

/**
 * formats an array of images.
 * @param images
 *    array of individually themed images
 * @return 
 *    html string
 */
function theme_linkimagefield_multiple($images) {
  return implode("\n", $images);
}

/** 
 * implementation of hook_filedownload
 * replicated from upload.module.
 *
 * conditionally included since we're just replicating the 
 * work of upload.module for now.
 */
if (!function_exists('upload_file_download')) {
  function linkimagefield_file_download($file) {
    $file = file_create_path($file);
    $result = db_query("SELECT f.* FROM {files} f WHERE filepath = '%s'", $file);
    if ($file = db_fetch_object($result)) {
      if (user_access('view uploaded files')) {
        $node = node_load($file->nid);
        if (node_access('view', $node)) {
          $name = mime_header_encode($file->filename);
          $type = mime_header_encode($file->filemime);

          // Serve images and text inline for the browser to display rather than download.
          $disposition = ereg('^(text/|image/)', $file->filemime) ? 'inline' : 'attachment';
          return array(
            'Content-Type: ' . $type . '; name=' . $name,
            'Content-Length: ' . $file->filesize,
            'Content-Disposition: ' . $disposition . '; filename=' . $name,
            'Cache-Control: private',
          );
        }
        else {
          return -1;
        }
      }
      else {
        return -1;
      }
    }
  }
}

Functions

Namesort descending Description
linkimagefield_check_directory Create the image directory relative to the 'files' dir recursively for every directory in the path.
linkimagefield_clear_field_session
linkimagefield_clear_session
linkimagefield_default_item @file Defines an link image field type. linkimagefield uses content.module to store the fid, and the drupal files table to store the actual file data.
linkimagefield_field Implementation of hook_field().
linkimagefield_field_formatter Implementation of hook_field_formatter().
linkimagefield_field_formatter_info Implementation of hook_field_formatter_info().
linkimagefield_field_info Implementation of hook_field_info().
linkimagefield_field_settings Implementation of hook_field_settings().
linkimagefield_file_insert insert a file into the database.
linkimagefield_file_update update the file record if necessary
linkimagefield_form_check_directory Wrapper function for linkimagefield_check_directory that accepts a form element to validate - if user specified one. Won't allow form submit unless the directory exists & is writable
linkimagefield_menu
linkimagefield_widget Implementation of hook_widget().
linkimagefield_widget_info Implementation of hook_widget_info().
linkimagefield_widget_settings Implementation of hook_widget_settings().
theme_linkimagefield_edit_image_row
theme_linkimagefield_image
theme_linkimagefield_multiple formats an array of images.
theme_linkimagefield_view_image
_linkimagefield_file_delete
_linkimagefield_file_load
_linkimagefield_preview transfer a file that is in a 'preview' state. @todo multiple support
_linkimagefield_scale_image
_linkimagefield_widget_form
_linkimagefield_widget_form_validate
_linkimagefield_widget_prepare_form_values