You are here

focal_point.module in Focal Point 7

Same filename and directory in other branches
  1. 8 focal_point.module

File

focal_point.module
View source
<?php

/**
 * @file
 * Allow users to specify a focal point on content images.
 */
require_once dirname(__FILE__) . '/focal_point.effects.inc';
define('FOCAL_POINT_DEFAULT', '50,50');

/**
 * Implements hook_menu().
 */
function focal_point_menu() {
  $items = array();
  $items['admin/config/media/focal_point'] = array(
    'type' => MENU_NORMAL_ITEM,
    'title' => 'Focal Point',
    'description' => 'Configure how the Focal Point module behaves and take a test drive.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'focal_point_configuration_form',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'focal_point.admin.inc',
  );
  $items['focal_point/test-drive'] = array(
    'type' => MENU_CALLBACK,
    'title' => 'Focal Point Test Drive',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'focal_point_test_drive_form',
    ),
    'access arguments' => array(
      'preview focal point',
    ),
    'file' => 'focal_point.admin.inc',
  );
  $items['focal_point/preview/%/%'] = array(
    'type' => MENU_CALLBACK,
    'title' => 'Image Preview',
    'page callback' => 'focal_point_preview_page',
    'page arguments' => array(
      2,
      3,
    ),
    'access arguments' => array(
      'preview focal point',
    ),
    'file' => 'focal_point.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_permission().
 */
function focal_point_permission() {
  return array(
    'preview focal point' => array(
      'title' => t('Preview focal point results'),
    ),
  );
}

/**
 * Implements hook_theme().
 */
function focal_point_theme($existing, $type, $theme, $path) {
  return array(
    // @see image_theme()
    'focal_point_image_style' => array(
      'variables' => array(
        'focal_point' => NULL,
        'style_name' => NULL,
        'path' => NULL,
        'width' => NULL,
        'height' => NULL,
        'alt' => '',
        'title' => NULL,
        'attributes' => array(),
      ),
      'file' => 'focal_point.theme.inc',
    ),
    'focal_point_image_resize_summary' => array(
      'variables' => array(
        'data' => NULL,
      ),
      'file' => 'focal_point.theme.inc',
    ),
    'focal_point_image_crop_summary' => array(
      'variables' => array(
        'data' => NULL,
      ),
      'file' => 'focal_point.theme.inc',
    ),
  );
}

/**
 * Implements hook_admin_paths().
 */
function focal_point_admin_paths() {
  $paths = array(
    'focal_point/test-drive' => TRUE,
    'focal_point/preview/*/*' => TRUE,
  );
  return $paths;
}

/**
 * Implements hook_image_default_styles().
 */
function focal_point_image_default_styles() {
  $styles = array();
  $styles['focal_point_preview'] = array(
    'label' => 'Focal Point Preview',
    'effects' => array(
      array(
        'name' => 'image_scale',
        'data' => array(
          'width' => 250,
          'height' => NULL,
          'upscale' => 1,
        ),
        'weight' => 0,
      ),
    ),
  );
  return $styles;
}

/**
 * Implements hook_file_load().
 */
function focal_point_file_load($files) {
  $focal_points = focal_point_get_multiple(array_keys($files));
  foreach ($files as &$file) {
    $file->focal_point = isset($focal_points[$file->fid]) ? $focal_points[$file->fid] : '';

    // Special handling for the "test drive file".
    if ($file->fid == variable_get('focal_point_test_drive_image', NULL)) {
      $file->focal_point = variable_get('focal_point_test_drive_focal_point', FOCAL_POINT_DEFAULT);
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function focal_point_form_file_entity_add_upload_alter(&$form, &$form_state) {

  // Add focal point to the file entity edit form used by the media browser.
  if (isset($form_state['step']) && $form_state['step'] == 4) {
    $fid = isset($form_state['values']['upload']) ? $form_state['values']['upload'] : $form_state['storage']['upload'];
    $file = file_load($fid);
    _focal_point_form_append_focal_point_preview($form, $file);
  }
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function focal_point_form_file_entity_edit_alter(&$form, &$form_state) {

  // Make sure we have an entity to work with.
  if (!isset($form_state['file'])) {
    return;
  }
  _focal_point_form_append_focal_point_preview($form, $form_state['file']);
}

/**
 * Append the focal point preview field to file edit forms.
 *
 * @param array $form
 *   The form array provided by hook_form_alter() to attach the focal point
 *   preview to.
 * @param object $file
 *   The file object we should be adding the preview for.
 */
function _focal_point_form_append_focal_point_preview(&$form, $file) {
  if (_focal_point_supported_field_type('media') && is_object($file) && _focal_point_supported_file($file)) {
    $default_value = !empty($file->focal_point) ? $file->focal_point : _focal_point_guess_default($file->fid);
    $focal_point_id = drupal_html_id('focal-point-media');
    $form['focal_point'] = array(
      '#type' => 'container',
      '#prefix' => '<label>' . t('Focal Point') . '</label>',
      'indicator' => _focal_point_indicator($focal_point_id),
      'thumbnail' => array(
        '#type' => 'markup',
        '#theme' => 'image_style',
        '#style_name' => 'focal_point_preview',
        '#path' => $file->uri,
        '#alt' => isset($file->alt) ? $file->alt : '',
        '#title' => isset($file->title) ? $file->title : '',
      ),
      'preview_link' => _focal_point_preview_link($file->fid, $focal_point_id, $file->focal_point),
      'focal_point' => _focal_point_field($focal_point_id, $default_value),
      'focal_point_help' => _focal_point_help(),
    );

    // To prevent duplicate image previews from displaying we should go ahead
    // and limit access to the preview element. Media does this already in some
    // instances, but not all.
    $form['preview']['#access'] = FALSE;
    $form['#validate'][] = 'focal_point_form_validate';
  }
}

/**
 * Implements hook_field_widget_form_alter().
 */
function focal_point_field_widget_form_alter(&$element, &$form_state, $context) {
  $widget_type = $context['instance']['widget']['type'];
  if (_focal_point_supported_widget_type($widget_type)) {
    foreach (element_children($element) as $delta) {
      $element[$delta]['#attributes']['class'][] = 'focal_point';
      $element[$delta]['#process'][] = 'focal_point_widget_process';
      $element[$delta]['#focal_point_id'] = drupal_html_id('focal-point-' . $context['instance']['field_name'] . '-' . $delta);
    }
  }
}

/**
 * Field widget process function.
 */
function focal_point_widget_process($element, &$form_state, $form) {

  // If a file has already been uploaded, include the necessary components of
  // for the focal point widget.
  $access = (bool) (!empty($element['#file']));
  if ($access) {
    $default_value = !empty($element['#default_value']['focal_point']) ? $element['#default_value']['focal_point'] : _focal_point_guess_default($element['#file']->fid);
  }
  else {
    $default_value = !empty($element['#default_value']['focal_point']) ? $element['#default_value']['focal_point'] : '';
  }
  $element['focal_point'] = _focal_point_field($element['#focal_point_id'], $default_value, $access);
  return $element;
}

/**
 * Implements template_preprocess_image_widget().
 */
function focal_point_preprocess_image_widget(&$variables) {
  $element =& $variables['element'];

  // Add the "indicator" to the default image widget.
  if (isset($element['preview']) && isset($element['#focal_point_id'])) {
    unset($element['preview']['#weight']);
    $preview = array(
      'indicator' => _focal_point_indicator($element['#focal_point_id']),
      'thumbnail' => $element['preview'],
      'preview_link' => _focal_point_preview_link($element['#file']->fid, $element['#focal_point_id'], isset($element['focal_point']['#default_value']) ? $element['focal_point']['#default_value'] : FOCAL_POINT_DEFAULT),
    );
    $element['preview'] = $preview;
    $element['focal_point_help'] = _focal_point_help();
  }
}

/**
 * Form validation function for the focal point form item.
 */
function focal_point_form_validate($form, &$form_state) {
  $focal_point = isset($form_state['values']['focal_point']) ? $form_state['values']['focal_point'] : '';
  if (!focal_point_validate($focal_point)) {
    form_set_error('focal_point', t('Focal points should be in the format ##,## without spaces where the numbers are between 1 and 100.'));
  }
}

/**
 * Validation function for the focal point widget.
 */
function focal_point_element_form_validate($element, &$form_state, $form) {
  $focal_point = isset($element['#value']) ? $element['#value'] : '';
  if (!focal_point_validate($focal_point)) {
    form_error($element, t('Focal points should be in the format ##,## without spaces where the numbers are between 1 and 100.'));
  }
}

/**
 * Implements hook_field_attach_presave().
 */
function focal_point_field_attach_presave($entity_type, $entity) {
  list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);

  // Check every field as its data is being inserted and if it has focal point
  // support, save the focal point data.
  foreach (field_info_instances($entity_type, $bundle) as $instance) {
    $field_name = $instance['field_name'];
    if (_focal_point_supported_widget_type($instance['widget']['type'])) {
      $images = array();
      try {
        $wrapper = entity_metadata_wrapper($entity_type, $entity);
        $images = $wrapper->{$field_name}
          ->value();
      } catch (EntityMetadataWrapperException $e) {
        watchdog_exception('focal_point', $e);
      }
      if (!empty($images) && is_array($images)) {
        _focal_point_images_save($images);
      }
    }
  }
}

/**
 * Implements hook_file_presave().
 */
function focal_point_file_presave($file) {
  if (isset($file->fid) && isset($file->focal_point)) {
    focal_point_save($file->fid, $file->focal_point);
  }
}

/**
 * Implements hook_file_delete().
 */
function focal_point_file_delete($file) {
  focal_point_delete($file->fid);
}

/**
 * Get a list of methods that can be used to set the default focal point value.
 *
 * @return array
 *   An array of arrays with the keys "label" and "callback".
 *
 * @see image_focus_focal_point_default_method_info()
 */
function focal_point_get_default_method_info() {
  $info =& drupal_static(__FUNCTION__);
  if (!isset($info)) {
    $info = module_invoke_all('focal_point_default_method_info');
    drupal_alter('focal_point_default_method_info', $info);
  }
  return $info;
}

/**
 * Save the focal point data for a given file.
 *
 * @param int $fid
 *   The id of the image file in question.
 * @param string $focal_point
 *   In the form xx,yy where xx represents the left offset as a percent and yy
 *   represents the top offset as a percent.
 */
function focal_point_save($fid, $focal_point) {
  $existing_focal_point = focal_point_get($fid);
  $record = array(
    'fid' => $fid,
    'focal_point' => $focal_point,
  );

  // If the focal point has not changed, then there is nothing to see here.
  if ($existing_focal_point == $focal_point) {
    return;
  }

  // Create, update or delete the focal point.
  if ($existing_focal_point) {
    if (!empty($focal_point)) {

      // The focal point has changed to a non-empty value.
      _focal_point_save($record, 'fid');
    }
    else {

      // The focal point has changed to an empty value. Generated images will
      // be flushed in the delete function.
      focal_point_delete($fid);
    }
  }
  elseif (!empty($focal_point)) {

    // The focal point is both new and non-empty.
    _focal_point_save($record);
  }

  // Clear the static caches.
  $cached =& drupal_static('focal_point_get_multiple');
  unset($cached[$fid]);
  entity_get_controller('file')
    ->resetCache(array(
    $fid,
  ));
}

/**
 * Helper function to save a FocalPoint record, and invoke related hooks.
 *
 * @param array $record
 *   Array with records.
 * @param array $primary_keys
 *   Array with primary keys.
 */
function _focal_point_save($record, $primary_keys = array()) {

  // Give other modules a chance to change the focal point.
  drupal_alter('focal_point_pre_save', $focal_point, $fid, $existing_focal_point);
  drupal_write_record('focal_point', $record, $primary_keys);
  _focal_point_flush($record['fid']);

  // Invoke hook_focal_point_save hooks.
  module_invoke_all('focal_point_save', $record);
}

/**
 * Validate a given focal point.
 *
 * @param string $focal_point
 *   The focal point string to test.
 *
 * @return bool
 *   TRUE if the given focal point value is valid; FALSE otherwise.
 */
function focal_point_validate($focal_point) {
  if (empty($focal_point) || preg_match('/^(100|[0-9]{1,2})(,)(100|[0-9]{1,2})$/', $focal_point)) {
    return TRUE;
  }
  else {
    return FALSE;
  }
}

/**
 * Returns the focal points of the given images.
 *
 * @param array $fids
 *   An array of file IDs.
 *
 * @return array
 *   An array of focal points keyed by file IDs.
 *
 * @see focal_point_get()
 */
function focal_point_get_multiple($fids) {
  $focal_points =& drupal_static(__FUNCTION__, array());
  $missing = array_diff($fids, array_keys($focal_points));
  if ($missing) {
    $result = db_query('SELECT fid, focal_point FROM {focal_point} WHERE fid IN (:fids)', array(
      ':fids' => $missing,
    ))
      ->fetchAllKeyed();
    $focal_points += $result;
  }
  return array_intersect_key($focal_points, drupal_map_assoc($fids));
}

/**
 * Returns the focal point of the given image.
 *
 * The focal point is always returned in the form '12,34' where 12 is the
 * distance from the left edge in percents and 34 is the distance from the top
 * edge in percents. If no focal point is found an empty string is returned.
 *
 * @param int $fid
 *   The fid of the image field entity in question.
 *
 * @return string
 *   Ex. 35,65.
 */
function focal_point_get($fid) {
  $result = focal_point_get_multiple(array(
    $fid,
  ));
  return isset($result[$fid]) ? $result[$fid] : '';
}

/**
 * Parse the string representation of the focal point into an array.
 *
 * @param string $focal_point
 *   The focal point string to be parsed.
 *
 * @return array
 *   The x & y offsets (in percents) from the top left corner of the image.
 */
function focal_point_parse($focal_point = '') {
  if (empty($focal_point)) {
    $focal_point = FOCAL_POINT_DEFAULT;
  }
  return array_combine(array(
    'x-offset',
    'y-offset',
  ), explode(',', $focal_point));
}

/**
 * Deletes the focal point for the given file entity.
 *
 * @param int $fid
 *   The fid of the image field entity in question.
 */
function focal_point_delete($fid) {
  _focal_point_flush($fid);
  db_delete('focal_point')
    ->condition('fid', $fid)
    ->execute();

  // Invoke hook_focal_point_delete hooks.
  module_invoke_all('focal_point_delete', $fid);
}

/**
 * Make a best guess for the initial value of the focal point of the given file.
 *
 * If possible, guess at the initial value of the focal point. If all else
 * fails, return 50,50.
 *
 * @param int $fid
 *   The fid of the image file entity in question.
 *
 * @return string
 *   Ex. 45,23.
 */
function _focal_point_guess_default($fid) {
  $method = variable_get('focal_point_default_method', '');
  if ($method && ($file = file_load($fid)) && ($image = image_load($file->uri))) {
    $methods = focal_point_get_default_method_info();
    if (isset($methods[$method])) {
      if ($coords = call_user_func($methods[$method]['callback'], $image)) {

        // Convert coordinates to a percents of the image dimensions.
        list($x, $y) = $coords;
        $x = intval($x / $image->info['width'] * 100);
        $y = intval($y / $image->info['height'] * 100);
        return $x . ',' . $y;
      }
    }
  }

  // Default to the center of the image.
  return FOCAL_POINT_DEFAULT;
}

/**
 * Define the focal point text field.
 *
 * @param string $indicator_id
 *   (Optional) The id of the focal point indicator. This is needed to support
 *   image fields that have a cardinality greater than one, and forms in modals.
 * @param string $default_value
 *   The default value of the field.
 * @param bool $access
 *   (Optional) Whether or not the field should be accessible.
 *
 * @return array
 *   A FAPI field array for the focal point value.
 */
function _focal_point_field($indicator_id = 'focal-point', $default_value = FOCAL_POINT_DEFAULT, $access = TRUE) {
  return array(
    '#type' => 'textfield',
    '#title' => 'Focal Point',
    '#description' => t('Specify the focus of this image in the form "leftoffset,topoffset" where offsets are in percents. Ex: 25,75'),
    '#default_value' => $default_value,
    '#access' => $access,
    '#element_validate' => array(
      'focal_point_element_form_validate',
    ),
    '#attributes' => array(
      'class' => array(
        'focal-point',
      ),
      'data-focal-point-id' => $indicator_id,
    ),
    '#attached' => array(
      'js' => array(
        drupal_get_path('module', 'focal_point') . '/js/focal_point.js',
      ),
      'css' => array(
        drupal_get_path('module', 'focal_point') . '/css/focal_point.css',
      ),
    ),
  );
}

/**
 * Retrieve the help text for a focal point field.
 *
 * @return array
 *   A render array for the help text to display on a focal point field.
 */
function _focal_point_help() {
  return array(
    '#prefix' => '<div class="focal-point-help">',
    '#markup' => t('Click and drag the crosshair to target the most important portion of the image.  This portion of the image will never be cropped.'),
    '#suffix' => '</div>',
  );
}

/**
 * Save the focal point for the provided images.
 *
 * @param array $images
 *   An array of image field data arrays normally found attached to a loaded
 *   entity. This is typically loaded via an entity_metadata_wrapper.
 */
function _focal_point_images_save($images) {

  // If there is only one image, then the "fid" property will exist.
  $images = isset($images['fid']) ? array(
    $images,
  ) : $images;
  foreach ($images as $image) {
    if (isset($image['focal_point'])) {
      focal_point_save($image['fid'], $image['focal_point']);
    }
  }
}

/**
 * Determine whether or not the provided field can use focal point support.
 *
 * @param string $type
 *   A drupal field widget type.
 *
 * @return bool
 *   TRUE if the given widget type is supported by focal point.
 */
function _focal_point_supported_widget_type($type) {
  $supported = FALSE;
  if (_focal_point_supported_field_type('image')) {
    $supported_widget_types = array(
      'image_image',
      'image_miw',
    );
    drupal_alter('focal_point_supported_widget_types', $supported_widget_types);
    if (in_array($type, $supported_widget_types)) {
      $supported = TRUE;
    }
  }
  return $supported;
}

/**
 * Determine wether or not the given widget type is supported.
 *
 * Support is based on the site configuration.
 *
 * @param string $type
 *   The type of image field in question (image || media).
 *
 * @return bool
 *   TRUE if the given field type is supported by focal point.
 */
function _focal_point_supported_field_type($type) {
  $enabled_for = variable_get('focal_point_enabled_for', array(
    'image',
    'media',
  ));
  return in_array($type, $enabled_for, TRUE);
}

/**
 * Determine whether or not the provided file entity can support a focal_point.
 *
 * @param mixed $file
 *   Either a loaded file object or an fid.
 *
 * @return bool
 *   TRUE if the given file entity is of a supported type.
 */
function _focal_point_supported_file($file) {
  if (is_int($file)) {
    $file = file_load($file);
  }
  $supported_file_types = array(
    'image',
  );
  drupal_alter('focal_point_supported_file_types', $supported_file_types);
  return in_array($file->type, $supported_file_types);
}

/**
 * Flush derivitive images based on a file id.
 *
 * @param int $fid
 *   The file id of the file entity whose derivitive images are being flushed.
 */
function _focal_point_flush($fid) {
  if ($file = file_load($fid)) {
    image_path_flush($file->uri);
  }
}

/**
 * Build a render array for the focal point indicator crosshair.
 *
 * @param string $indicator_id
 *   (Optional) The id of the focal point indicator. This is needed to support
 *   image fields that have a cardinality greater than one, and forms in modals.
 *
 * @return array
 *   A render array for the focal point indicator crosshair.
 */
function _focal_point_indicator($indicator_id = 'focal-point') {
  $indicator = array(
    '#theme_wrappers' => array(
      'container',
    ),
    '#attributes' => array(
      'class' => array(
        'focal-point-indicator',
      ),
      'id' => $indicator_id,
    ),
    '#markup' => '',
    '#attached' => array(
      'library' => array(
        array(
          'system',
          'ui.draggable',
        ),
      ),
    ),
  );
  return $indicator;
}

/**
 * Get a list of all image styles that use a focal point effect.
 *
 * @return array
 *   A subset of the array returned by image_styles().
 *
 * @see image_styles()
 */
function _focal_point_get_image_styles() {

  // Load all image styles defined on this site and filter out those that do
  // not use a focal point effect.
  module_load_include('inc', 'focal_point', 'focal_point.effects');
  $focal_point_effects = array_keys(focal_point_image_effect_info());
  $focal_point_styles = array();
  $styles = image_styles();
  foreach ($styles as $isid => $style) {
    foreach ($style['effects'] as $effect) {
      $focal_point_style = in_array($effect['name'], $focal_point_effects, TRUE);
      if ($focal_point_style) {

        // We found at least one effect within this style that uses Focal Point.
        $focal_point_styles[$isid] = $style;
        break;
      }
    }
  }
  return $focal_point_styles;
}

/**
 * Allows previewing of derivitive images based on the given focal point.
 *
 * Return a render array that shows the derivative images of the given fid
 * using the given focal point for every style that uses a focal point effect.
 *
 * @param int $fid
 *   The fid of the file entity in question.
 * @param string $focal_point
 *   A focal point value.
 * @param bool $show_original
 *   (Optional) If TRUE the original image will be displayed above the preview
 *   images.
 *
 * @return array
 *   A render array to display the preview page.
 */
function _focal_point_preview($fid, $focal_point, $show_original = TRUE) {
  $file = is_numeric($fid) ? file_load($fid) : NULL;
  $output = array();

  // Using the example image, show every image style that uses a focal point
  // effect.
  $output['focal_point_examples'] = array(
    '#theme_wrappers' => array(
      'container',
    ),
    '#attributes' => array(
      'class' => array(
        'focal_point_examples',
      ),
    ),
  );
  if ($file) {
    if ($show_original) {
      $output['focal_point_examples']['original'] = array(
        '#type' => 'markup',
        '#prefix' => '<h2>' . t('Original Image') . '</h2>',
        '#theme' => 'image',
        '#path' => $file->uri,
        '#theme_wrappers' => array(
          'container',
        ),
        '#attributes' => array(
          'class' => array(
            'focal-point-preview--original',
          ),
        ),
      );
    }
    $styles = _focal_point_get_image_styles();
    if (!empty($styles)) {
      foreach ($styles as $isid => $style) {
        if (module_exists('borealis') && strpos($style['name'], 'borealis') === 0) {

          // Don't output borealis styles; there are just too many.
          continue;
        }

        // The 'label' property was not introduced until Drupal 7.23 so just in
        // case we provide a fallback.
        // @see https://www.drupal.org/node/2350147
        $label = isset($style['label']) ? $style['label'] : $style['name'];
        $output['focal_point_examples'][$isid] = array(
          '#type' => 'markup',
          '#prefix' => '<h2>' . $label . '</h2>',
          '#theme' => 'focal_point_image_style',
          '#style_name' => $style['name'],
          '#path' => $file->uri,
          '#focal_point' => $focal_point,
          '#theme_wrappers' => array(
            'container',
          ),
          '#attributes' => array(
            'class' => array(
              'focal-point-preview--' . $style['name'],
            ),
          ),
        );
      }
    }
    else {
      $output['focal_point_examples']['#markup'] = '<div class="messages warning">' . t('There are no styles defined that use a focal point effect. To see how this module will work you should <a href="@url">create a new image style</a> that uses one.', array(
        '@url' => url('/admin/config/media/image-styles'),
      )) . '</div>';
    }
  }
  return $output;
}

/**
 * Build a render array for the preview link.
 *
 * @param int $fid
 *   The fid of the file entity in question.
 * @param string $indicator_id
 *   (Optional) The id of the focal point indicator. This is needed to support
 *   image fields that have a cardinality greater than one, and forms in modals.
 * @param string $focal_point
 *   (Optional) In the form xx,yy where xx represents the left offset as a
 *   percent and yy represents the top offset as a percent.
 *
 * @return mixed
 *   A render array for the preview link.
 */
function _focal_point_preview_link($fid, $indicator_id = 'focal-point', $focal_point = '') {
  if (!user_access('preview focal point')) {
    return;
  }
  $focal_point = empty($focal_point) ? FOCAL_POINT_DEFAULT : $focal_point;
  $link_text = t('Image Preview');
  $link_path = 'focal_point/preview/' . $fid . '/' . $focal_point;
  return array(
    '#type' => 'markup',
    '#markup' => l($link_text, $link_path, array(
      'attributes' => array(
        'target' => '_blank',
        'class' => array(
          'focal-point-preview-link',
          'overlay-exclude',
        ),
        'data-focal-point-id' => $indicator_id,
      ),
    )),
  );
}

/**
 * Implements hook_focal_point_default_method_info().
 *
 * Defined on behalf of the image_focus module.
 */
function image_focus_focal_point_default_method_info() {
  $info['image_focus'] = array(
    'label' => t('Image Focus Crop module'),
    'callback' => 'image_focus_get_focal_point',
  );
  return $info;
}

/**
 * Implements hook_focal_point_default_method_info().
 *
 * DEfined on behalf of the smartcrop module.
 */
function smartcrop_focal_point_default_method_info() {
  $info['smartcrop'] = array(
    'label' => t('Smartcrop module'),
    'callback' => 'focal_point_get_smartcrop_focal_point',
  );
  return $info;
}

/**
 * Callback function.
 *
 * Used by modules implementing hook_focal_point_default_method_info().
 *
 * @see image_focus_focal_point_default_method_info()
 * @see smartcrop_focal_point_default_method_info()
 */
function focal_point_get_smartcrop_focal_point($image) {
  module_load_include('inc', 'focal_point', 'focal_point.smartcrop');
  return focal_point_smartcrop_estimation($image);
}

Functions

Namesort descending Description
focal_point_admin_paths Implements hook_admin_paths().
focal_point_delete Deletes the focal point for the given file entity.
focal_point_element_form_validate Validation function for the focal point widget.
focal_point_field_attach_presave Implements hook_field_attach_presave().
focal_point_field_widget_form_alter Implements hook_field_widget_form_alter().
focal_point_file_delete Implements hook_file_delete().
focal_point_file_load Implements hook_file_load().
focal_point_file_presave Implements hook_file_presave().
focal_point_form_file_entity_add_upload_alter Implements hook_form_FORM_ID_alter().
focal_point_form_file_entity_edit_alter Implements hook_form_FORM_ID_alter().
focal_point_form_validate Form validation function for the focal point form item.
focal_point_get Returns the focal point of the given image.
focal_point_get_default_method_info Get a list of methods that can be used to set the default focal point value.
focal_point_get_multiple Returns the focal points of the given images.
focal_point_get_smartcrop_focal_point Callback function.
focal_point_image_default_styles Implements hook_image_default_styles().
focal_point_menu Implements hook_menu().
focal_point_parse Parse the string representation of the focal point into an array.
focal_point_permission Implements hook_permission().
focal_point_preprocess_image_widget Implements template_preprocess_image_widget().
focal_point_save Save the focal point data for a given file.
focal_point_theme Implements hook_theme().
focal_point_validate Validate a given focal point.
focal_point_widget_process Field widget process function.
image_focus_focal_point_default_method_info Implements hook_focal_point_default_method_info().
smartcrop_focal_point_default_method_info Implements hook_focal_point_default_method_info().
_focal_point_field Define the focal point text field.
_focal_point_flush Flush derivitive images based on a file id.
_focal_point_form_append_focal_point_preview Append the focal point preview field to file edit forms.
_focal_point_get_image_styles Get a list of all image styles that use a focal point effect.
_focal_point_guess_default Make a best guess for the initial value of the focal point of the given file.
_focal_point_help Retrieve the help text for a focal point field.
_focal_point_images_save Save the focal point for the provided images.
_focal_point_indicator Build a render array for the focal point indicator crosshair.
_focal_point_preview Allows previewing of derivitive images based on the given focal point.
_focal_point_preview_link Build a render array for the preview link.
_focal_point_save Helper function to save a FocalPoint record, and invoke related hooks.
_focal_point_supported_field_type Determine wether or not the given widget type is supported.
_focal_point_supported_file Determine whether or not the provided file entity can support a focal_point.
_focal_point_supported_widget_type Determine whether or not the provided field can use focal point support.

Constants