You are here

pdfpreview.module in PDFPreview 7

This file contains hooks for the pdfpreview module

@author Juanjo Garcia <juanjo.gcia@gmail.com> @author Florian Auer <floeschie@gmail.com>

File

pdfpreview.module
View source
<?php

/**
 * @file
 * This file contains hooks for the pdfpreview module
 *
 * @author Juanjo Garcia <juanjo.gcia@gmail.com>
 * @author Florian Auer <floeschie@gmail.com>
 *
 */

/**
 * Implements hook_field_formatter_info()
 *
 * @todo What's the imagecache thing doing?
 */
function pdfpreview_field_formatter_info() {
  $formatters = array(
    'default' => array(
      'label' => t('PDF Preview'),
      'field types' => array(
        'file',
      ),
      'description' => t('Displays an snapshot of the first page of the PDF'),
    ),
  );
  if (module_exists('imagecache')) {
    foreach (imagecache_presets() as $preset) {
      $formatters[$preset['presetname'] . '][pdfpreview'] = array(
        'label' => t('PDF Preview: @preset image', array(
          '@preset' => $preset['presetname'],
        )),
        'field types' => array(
          'filefield',
        ),
        'description' => t('Display an snapshot using imagecache preset @preset', array(
          '@preset' => $preset['presetname'],
        )),
      );
    }
  }
  return $formatters;
}

/**
 * Implements hook_field_formatter_view()
 *
 * @see _pdfpreview_create_preview()
 */
function pdfpreview_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  foreach ($items as $delta => $item) {
    $file = file_load($item['fid']);
    $element[$delta]['#file'] = $file;
    if ($item['filemime'] == 'application/pdf') {
      $item['preview'] = _pdfpreview_create_preview($file);
      $element[$delta] = array(
        '#preview' => $item['preview'],
        '#markup' => theme($display['type'], array(
          'item' => $item,
          'field' => $instance,
        )),
      );
    }
    else {
      module_load_include('inc', 'file', 'file.field');
      $display['type'] = 'file_default';
      $tmp = file_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, array(
        $item,
      ), $display);
      $element[$delta] = $tmp[0];
    }
  }
  return $element;
}

/**
 * Implements hook_menu()
 */
function pdfpreview_menu() {
  $items = array(
    'admin/config/media/pdfpreview' => array(
      'title' => 'PDF Preview',
      'description' => 'Configure PDF Preview settings',
      'access arguments' => array(
        'administer content',
      ),
      'page callback' => 'drupal_get_form',
      'page arguments' => array(
        '_pdfpreview_admin_settings',
      ),
      'type' => MENU_NORMAL_ITEM,
    ),
  );
  return $items;
}

/**
 * Implements hook_theme().
 *
 */
function pdfpreview_theme() {
  $theme = array(
    'file_default' => array(
      'function' => 'theme_pdfpreview_formatter',
      'variables' => array(
        'element' => NULL,
      ),
    ),
  );

  //  if (module_exists('imagecache')) {
  //    foreach (imagecache_presets() as $preset) {
  //      $theme['pdfpreview_formatter_'. $preset['presetname'] . '][pdfpreview'] = array(
  //        'function' => 'theme_pdfpreview_formatter',
  //        'arguments' => array('element' => NULL),
  //      );
  //    }
  //  }
  return $theme;
}

// ----- custom module functions ----- //

/**
 * Creates the module settings render array
 *
 * If you want to extend the module's settings form, append the elements you
 * need to the $form array. Don't forget to update the pdfpreview_uninstall()
 * routine in the pdfpreview.install file as well.
 *
 */
function _pdfpreview_admin_settings() {
  $form = array(
    'pdfpreview_pathtoimages' => array(
      '#type' => 'textfield',
      '#title' => t('Images folder'),
      '#description' => t('Path, inside files directory, where snapshots are stored. For example <em>pdfpreview</em>'),
      '#default_value' => variable_get('pdfpreview_pathtoimages', 'pdfpreview'),
    ),
    'pdfpreview_previewsize' => array(
      '#type' => 'textfield',
      '#title' => t('Preview size'),
      '#description' => t('Size of the preview in pixels. For example <em>100x100</em>'),
      '#default_value' => variable_get('pdfpreview_previewsize', '100x100'),
    ),
    'pdfpreview_description' => array(
      '#type' => 'checkbox',
      '#title' => t('Description'),
      '#description' => t('Show file description beside image'),
      '#options' => array(
        0 => t('No'),
        1 => t('Yes'),
      ),
      '#default_value' => variable_get('pdfpreview_description', 1),
    ),
    'pdfpreview_tag' => array(
      '#type' => 'radios',
      '#title' => t('HTML tag'),
      '#description' => t('Select which kind of HTML element will be used to theme elements'),
      '#options' => array(
        'span' => 'span',
        'div' => 'div',
      ),
      '#default_value' => variable_get('pdfpreview_tag', 1),
    ),
  );

  // Callback function which checks for existing preview directory on save
  $form['#submit'][] = '_pdfpreview_prepare_filesystem';
  return system_settings_form($form);
}

/**
 * Convert the first page of a PDF document
 *
 * This function converts the first page of a PDF document using ImageMagick's
 * convert executable and returns TRUE on success, FALSE else. You can provide
 * optional parameters for the convert executable by simply passing them with
 * in an array to the $args parameter. For details about convert arguments see
 * the <a href="http://www.imagemagick.org/Usage/basics/#cmdline">ImageMagick
 * documentation</a>.
 *
 * @param $source URI to the PDF file
 * @param $dest URI where the preview file will be saved
 * @param $args Optional arguments for the convert executable
 * @see _imagemagick_convert()
 * @see _pdfpreview_create_preview()
 */
function _pdfpreview_convert_first_page($source, $dest, $args = array()) {
  $source = drupal_realpath($source) . '[0]';
  $dest = drupal_realpath($dest);
  $args['quality'] = '-quality ' . escapeshellarg(variable_get('imagemagick_quality', 75));
  $args['previewsize'] = '-resize ' . escapeshellarg(variable_get('pdfpreview_previewsize', '100x100'));
  $context = array(
    'source' => $source,
    'destination' => $dest,
  );
  drupal_alter('imagemagick_arguments', $args, $context);

  // To make use of ImageMagick 6's parenthetical command grouping we need to make
  // the $source image the first parameter and $dest the last.
  // See http://www.imagemagick.org/Usage/basics/#cmdline
  $command = escapeshellarg($source) . ' ' . implode(' ', $args) . ' ' . escapeshellarg($dest);
  if (_imagemagick_convert_exec($command, $output, $error) !== TRUE) {
    return FALSE;
  }
  return file_exists($dest);
}

/**
 * Creates the PDF preview file and returns its URI
 *
 * @param File $file
 * @return string URI of the newly created preview image
 * @see _pdfpreview_convert_first_page()
 * @see pdfpreview_field_formatter_view()
 */
function _pdfpreview_create_preview($file) {
  $output_dir = file_default_scheme() . '://' . variable_get('pdfpreview_pathtoimages', 'pdfpreview');
  $output_filename = $output_dir . '/' . md5('pdfpreview' . $file->fid) . '.jpg';

  // Create preview image using ImageMagick
  if (!file_exists($output_filename) && function_exists('_imagemagick_convert')) {
    $pdf = drupal_realpath($file->uri);
    _pdfpreview_convert_first_page($pdf, $output_filename);
  }
  return $output_filename;
}

/**
 * Prepare the file system for PDF preview image creation
 *
 * This function is called after the module's setting form is submitted. It
 * checks whether the target directory for preview images exists. If this is not
 * the case, the directory will be created.
 *
 * @see _pdfpreview_admin_settings()
 * @see system_settings_form_submit()
 */
function _pdfpreview_prepare_filesystem($form, &$form_state) {
  $output_uri = file_default_scheme() . '://' . $form['pdfpreview_pathtoimages']['#value'];
  $output_dir = drupal_realpath($output_uri);
  if (!file_exists($output_dir)) {
    if (!mkdir($output_dir)) {
      drupal_set_message(t('Error creating directory @dir', array(
        '%dir' => $output_dir,
      )), 'error');
      watchdog('pdfpreview', 'Error creating directory @dir', array(
        '%dir' => $output_dir,
      ), WATCHDOG_ERROR);
    }
    $message = t('The directory %dir has been created', array(
      '%dir' => $output_dir,
    ));
    watchdog('pdfpreview', 'The directory %dir has been created', array(
      '%dir' => $output_dir,
    ));
    drupal_set_message($message, 'status');
  }
  elseif (!is_dir($output_dir)) {
    $message = t('The path %dir is not a directory', array(
      '%dir' => $output_dir,
    ));
    watchdog('pdfpreview', 'The path %dir is not a directory', array(
      '%dir' => $output_dir,
    ), WATCHDOG_ERROR);
    drupal_set_message($message, 'error');
  }
}

/**
 * Theming functions for our formatters
 *
 * @todo Clearify the image cache thing...
 * @todo Let user choose what preview image to show on non-PDF files
 */
function theme_pdfpreview_formatter($element) {
  $img_tag = '';
  $item = $element['item'];

  // TODO: Not sure what this part is doing...
  // if (list($namespace, $presetname) = explode('][', $element['#formatter'], 2)) {
  //   if ($preset = imagecache_preset_by_name($namespace)) {
  //     $output = theme('imagecache', $namespace, $output_filename, $item['data']['alt'], $item['data']['title']);
  //   }
  // }

  //debug($item);
  $file_url = file_create_url($item['uri']);
  $img_url = file_create_url($item['preview']);
  $title = $alt = $item['description'];
  $img_tag = sprintf('<img src="%s" title="%s" alt="%s" />', $img_url, $title, $alt);
  $wrapper_tag = variable_get('pdfpreview_tag', 'span');
  $description = variable_get("pdfpreview_description", 1) ? '<' . $wrapper_tag . ' class="pdfpreview-description">' . $title . '</' . $wrapper_tag . '>' : '';
  return sprintf('<div class="pdfpreview" id="pdfpreview-%s">' . ' <%s class="pdfpreview-image-wrapper"><a href="%s" title="%s">%s</a></%s>' . ' %s' . '</div>', $item['fid'], $wrapper_tag, $file_url, $title, $img_tag, $wrapper_tag, $description);
}

Functions

Namesort descending Description
pdfpreview_field_formatter_info Implements hook_field_formatter_info()
pdfpreview_field_formatter_view Implements hook_field_formatter_view()
pdfpreview_menu Implements hook_menu()
pdfpreview_theme Implements hook_theme().
theme_pdfpreview_formatter Theming functions for our formatters
_pdfpreview_admin_settings Creates the module settings render array
_pdfpreview_convert_first_page Convert the first page of a PDF document
_pdfpreview_create_preview Creates the PDF preview file and returns its URI
_pdfpreview_prepare_filesystem Prepare the file system for PDF preview image creation