You are here

barcode.module in Barcode 7.2

Same filename and directory in other branches
  1. 8 barcode.module
  2. 6.2 barcode.module
  3. 6 barcode.module

File

barcode.module
View source
<?php

/**
 * Implements hook_help().
 */
function barcode_help($path, $arg) {
  switch ($path) {
    case 'admin/help#barcode':
      $output = '<p>' . t('A module that provides a new FAPI element to handle barcodes.') . '</p>';
      return $output;
  }
}

/**
 * Implements hook_menu().
 */
function barcode_menu() {
  $items['admin/config/media/barcode'] = array(
    'title' => 'Barcode',
    'description' => 'Configure barcode settings.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'barcode_settings',
    ),
    'access arguments' => array(
      'administer barcodes',
    ),
    'file' => 'includes/barcode.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_permission().
 */
function barcode_permission() {
  return array(
    'administer barcodes' => array(
      'title' => t('Administer barcode module settings'),
      'description' => t('Perform administration tasks for the barcode module.'),
    ),
  );
}

/**
 * Implements hook_theme().
 */
function barcode_theme() {
  return array(
    'barcode_formatter_plain' => array(
      'variables' => array(
        'barcode_value' => NULL,
      ),
    ),
    'barcode_image' => array(
      'variables' => array(
        'barcode_value' => NULL,
        'encoding' => NULL,
        'height' => NULL,
        'scale' => NULL,
        'bgcolor' => NULL,
        'barcolor' => NULL,
        'image_format' => NULL,
      ),
    ),
  );
}

/**
 * Theme function for 'barcode_plain' barcode field formatter.
 */
function theme_barcode_formatter_plain($variables) {
  return $variables['barcode_value'];
}

/**
 * Theme function for the barcode image.
 *
 * @ingroup themeable
 */
function theme_barcode_image($variables) {
  if (empty($variables['barcode_value'])) {
    return '';
  }
  $barcode = barcode_get_settings();
  if (isset($variables['encoding'])) {
    $barcode['encoding'] = $variables['encoding'];
  }
  $variables['image_format'] = $variables['image_format'] ? $variables['image_format'] : $barcode['image_format'];
  $variables['encoding'] = $variables['encoding'] ? $variables['encoding'] : $barcode['encoding'];
  $variables['height'] = $variables['height'] ? $variables['height'] : $barcode['height'];
  $variables['barcolor'] = $variables['barcolor'] ? $variables['barcolor'] : $barcode['barcolor'];
  $variables['bgcolor'] = $variables['bgcolor'] ? $variables['bgcolor'] : $barcode['bgcolor'];
  $variables['scale'] = $variables['scale'] ? $variables['scale'] : $barcode['scale'];
  module_load_include('inc', 'barcode', 'includes/barcode.plugins');
  $filename = barcode_generate_image($barcode, $variables);
  if (!$filename) {
    drupal_set_message(t('An error occured while generating the barcode.'), 'error');
    return '';
  }
  return theme('image', array(
    'path' => $filename,
    'alt' => $variables['barcode_value'],
    'title' => $variables['barcode_value'],
    'attributes' => array(
      'class' => array(
        'barcode',
      ),
    ),
  ));
}

/**
 * Validate an individual barcode element.
 */
function barcode_element_validate($element, &$form_state) {
  $value = trim($element['#value'], " \0\t\v");
  form_set_value($element, $value, $form_state);
  $length = strlen($value);

  // Check length. @TODO we need to set up plugins in a more modular way
  // so they can handle their own validation.
  if ($value != '') {
    switch ($element['#encoding']) {
      case 'EAN-8':
        if ($length != $element['#maxlength'] || !is_numeric($value)) {
          form_error($element, t('EAN-8 barcode must have 8 digits'));
        }
      case 'EAN-13':
        if ($length != $element['#maxlength'] || !is_numeric($value)) {
          form_error($element, t('EAN-13 barcode must have 13 digits'));
        }
      case 'ISBN':
        if ($length != $element['#maxlength']) {
          form_error($element, t('The ISBN barcode must have %count digits.', array(
            '%count' => $element['#maxlength'],
          )));
        }
        break;
      case 'POSTNET':
        if ($length != 5 and $length != 9 and $length != 11) {
          form_error($element, t('Postnet number must have 5, 9 or 11 digits.'));
        }
        break;
      case 'UPC-A':
        if ($length != 12) {
          form_error($element, t('UPC-A code must have 12 digits.'));
        }
        break;
      case 'ISBN':
        if (substr($value, 0, 3) != '978') {
          form_error($element, t('ISBN barcode number must start with 978.'));
        }
        break;
    }
  }
  return $element;
}

/***************************************************************
 * Field Type API hooks
 ***************************************************************/

/**
 * Implements hook_field_info().
 */
function barcode_field_info() {
  return array(
    'barcode_field' => array(
      'label' => t('Barcode'),
      'description' => t('This field stores a barcode in the database.'),
      'default_widget' => 'barcode_textfield',
      'enable_tokens' => 1,
      'default_formatter' => 'barcode_default',
      'property_type' => 'text',
    ),
  );
}

/**
 * Implements hook_field_settings_form().
 */
function barcode_field_settings_form($field, $instance, $has_data) {
  $form = array();
  $option = array(
    'UPC-A' => t('UPC-A'),
    'EAN-13' => t('EAN-13'),
    'ISBN' => t('ISBN'),
    'UPC-E' => t('UPC-E'),
    'EAN-8' => t('EAN-8'),
    'S2O5' => t('Standard 2 of 5'),
    'I2O5' => t('Industrial 2 of 5'),
    'I25' => t('Interleaved 2 of 5'),
    'POSTNET' => t('Postnet'),
    'CODABAR' => t('Codabar'),
    'CODE128' => t('Code 128'),
    'CODE39' => t('Code 39'),
    'CODE93' => t('Code 93'),
    'QRCODE' => t('QR Code'),
  );
  $form['encoding'] = array(
    '#type' => 'select',
    '#title' => t('Code Type'),
    '#options' => $option,
    '#default_value' => isset($field['settings']['encoding']) ? $field['settings']['encoding'] : $option['EAN-13'],
    '#description' => t('choose the coding method.'),
    '#disabled' => $has_data,
  );
  $form['dbsize'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum length'),
    '#description' => t('The maximum length of the field in characters. Please change it according to the coding standard you have chosen to optimize your database space'),
    '#default_value' => isset($field['settings']['dbsize']) ? $field['settings']['dbsize'] : 255,
    '#size' => 4,
    '#required' => TRUE,
    '#disabled' => $has_data,
  );
  return $form;
}

/**
 * Implements hook_field_instance_settings_form().
 */
function barcode_field_instance_settings_form($field, $instance) {
  $barcode_default_settings = barcode_get_settings();
  if ($field['settings']['encoding'] == 'QRCODE') {
    $form['barcode_height'] = array(
      '#title' => t('Height'),
      '#description' => t('Integer! in order to scan the printed barcode, the suggested height is 200'),
      '#type' => 'textfield',
      '#default_value' => isset($instance['settings']['barcode_height']) ? $instance['settings']['barcode_height'] : 200,
      '#size' => 2,
      '#required' => TRUE,
    );
  }
  else {
    $form['barcode_height'] = array(
      '#title' => t('Height'),
      '#description' => t('Integer! in order to scan the printed barcode, the suggested height is 40'),
      '#type' => 'textfield',
      '#default_value' => isset($instance['settings']['barcode_height']) ? $instance['settings']['barcode_height'] : $barcode_default_settings['height'],
      '#size' => 2,
      '#required' => TRUE,
    );
    $form['barcode_scale'] = array(
      '#title' => t('Scale'),
      '#description' => t('Float! in order to scan the printed barcode, the suggested height is 2.0'),
      '#type' => 'textfield',
      '#default_value' => isset($instance['settings']['barcode_scale']) ? $instance['settings']['barcode_scale'] : $barcode_default_settings['scale'],
      '#size' => 2,
      '#required' => TRUE,
    );
    $form['barcode_bgcolor'] = array(
      '#title' => t('Background color'),
      '#description' => t('Hex value'),
      '#type' => 'textfield',
      '#default_value' => isset($instance['settings']['barcode_bgcolor']) ? $instance['settings']['barcode_bgcolor'] : $barcode_default_settings['bgcolor'],
      '#size' => 8,
      '#required' => TRUE,
    );
    $form['barcode_barcolor'] = array(
      '#title' => t('Bar color'),
      '#description' => t('Hex value'),
      '#type' => 'textfield',
      '#default_value' => isset($instance['settings']['barcode_barcolor']) ? $instance['settings']['barcode_barcolor'] : $barcode_default_settings['barcolor'],
      '#size' => 8,
      '#required' => TRUE,
    );
  }
  $form['barcode_image_format'] = array(
    '#title' => t('Image format'),
    '#description' => t('The image format used for generated barcodes. Supported formats: png, gif, jpg.'),
    '#type' => 'select',
    '#default_value' => isset($instance['settings']['barcode_image_format']) ? $instance['settings']['barcode_image_format'] : $barcode_default_settings['image_format'],
    '#options' => array(
      'png' => 'png',
      'jpg' => 'jpg',
      'gif' => 'gif',
    ),
    '#maxlength' => 4,
    '#required' => TRUE,
  );

  // Add token module replacements fields
  if (module_exists('token')) {
    $form['tokens'] = array(
      '#type' => 'fieldset',
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#title' => t('Placeholder tokens'),
      '#description' => t("The following placeholder tokens can be used in DEFAULT VALUE of the field. When used in DEFAULT VALUE, they will be replaced with the appropriate values."),
    );
    $token_type = array(
      'theme' => 'token_tree',
      'token_types' => array(
        $instance['entity_type'],
      ),
      'global_types' => TRUE,
      'click_insert' => TRUE,
      'recursion_limit' => 2,
    );
    $form['tokens']['help'] = array(
      '#type' => 'markup',
      '#markup' => theme('token_tree', $token_type),
    );
  }
  return $form;
}

/**
 * Implementation of hook_content_migrate_field_alter().
 */
function barcode_content_migrate_field_alter(&$field_value) {

  // When fields are migrated from D6 to D7, we leave the title column behind
  // This column is a relic from the link module, and doesn't really belong in
  // barcode
  unset($field_value['columns']['title']);
}

/**
 * Implements hook_field_is_empty().
 */
function barcode_field_is_empty($item, $field) {
  return empty($item['value']);
}

/***********************************************************************
 *  Field Type API: Formatter
 **********************************************************************/

/**
 * Implements hook_field_formatter_info().
 */
function barcode_field_formatter_info() {
  return array(
    'barcode_default' => array(
      'label' => t('Barcode Image'),
      'field types' => array(
        'barcode_field',
      ),
    ),
    'barcode_plain' => array(
      'label' => t('Text'),
      'field types' => array(
        'barcode_field',
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function barcode_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) {
  $element = array();
  if ($display['type'] == 'barcode_plain') {
    foreach ($items as $delta => $item) {
      $element[$delta] = array(
        '#markup' => theme('barcode_formatter_plain', array(
          'barcode_value' => check_plain($items[$delta]['value']),
        )),
      );
    }
  }
  else {
    foreach ($items as $delta => $item) {
      $temp = array(
        'barcode_value' => check_plain($items[$delta]['value']),
        'encoding' => $field['settings']['encoding'],
        'height' => $instance['settings']['barcode_height'],
        'image_format' => $instance['settings']['barcode_image_format'],
      );
      if ($field['settings']['encoding'] != 'QRCODE') {
        $temp += array(
          'bgcolor' => $instance['settings']['barcode_bgcolor'],
          'barcolor' => $instance['settings']['barcode_barcolor'],
          'scale' => $instance['settings']['barcode_scale'],
        );
      }
      $element[$delta] = array(
        '#markup' => theme('barcode_image', $temp),
      );
    }
  }
  return $element;
}

/**
 * Implements hook_field_prepare_view().
 */
function barcode_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
  foreach ($items as $entity_id => $entity_items) {
    foreach ($entity_items as $delta => $value) {
      _barcode_sanitize($items[$entity_id][$delta], $delta, $field, $instances[$entity_id], $entities[$entity_id], $entity_type);
    }
  }
}

/**************************************************************************
 * Field Type API: Widget
 **************************************************************************/

/**
* Implements hook_field_widget_info().
*/
function barcode_field_widget_info() {
  return array(
    'barcode_textfield' => array(
      'label' => t('Text field'),
      'field types' => array(
        'barcode_field',
      ),
      'multiple values' => FIELD_BEHAVIOR_DEFAULT,
    ),
    'barcode_textarea' => array(
      'label' => t('Text area'),
      'field types' => array(
        'barcode_field',
      ),
    ),
  );
}

/**
 * Implements hook_field_widget_form().
 */
function barcode_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $encoding = isset($field['settings']['encoding']) ? $field['settings']['encoding'] : '';
  module_load_include('inc', 'barcode', 'includes/barcode.plugins');
  $maxlength = barcode_plugin_max_length($encoding);
  $element['value'] = $element + array(
    '#encoding' => $encoding,
    '#maxlength' => $maxlength,
    '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : '',
    '#element_validate' => array(
      'barcode_element_validate',
    ),
  );
  switch ($instance['widget']['type']) {
    case 'barcode_textfield':
      $element['value'] += array(
        '#type' => 'textfield',
        '#size' => 20,
      );
      break;
    case 'barcode_textarea':
      $element['value'] += array(
        '#type' => 'textarea',
        '#rows' => 6,
      );
      break;
  }
  return $element;
}

/**
 * change token to appropriate values.
 *
 */
function _barcode_sanitize(&$item, $delta, &$field, $instance, $entity, $entity_type) {
  if (empty($item['value'])) {
    return;
  }
  if (is_numeric($entity)) {
    $entity = entity_load_single($entity_type, $entity);
  }
  $item['value'] = token_replace($item['value'], array(
    $entity_type => $entity,
  ), array(
    'clear' => 1,
  ));
}

/**************************************************************************
 * Barcode Helper Functions
 **************************************************************************/

/**
 * Returns the barcode settings.
 */
function barcode_get_settings() {
  return array(
    'default_path' => variable_get('barcode_default_path', 'public://barcodes'),
    'font' => variable_get('barcode_font', drupal_get_path('module', 'barcode') . "/fonts/DroidSans.ttf"),
    'encoding' => variable_get('barcode_encoding', 'EAN-13'),
    'height' => 40,
    'scale' => 2.0,
    'bgcolor' => '#FFFFFF',
    'barcolor' => '#000000',
    'image_format' => 'png',
  );
}