epsacrop.module in EPSA Crop - Image Cropping 7.2
Same filename and directory in other branches
The main file of module
@TODO Pass dialog popo throw theme functions @TODO Add the in place edition
File
epsacrop.moduleView source
<?php
/**
* @file
* The main file of module
*
* @TODO Pass dialog popo throw theme functions
* @TODO Add the in place edition
*/
/**
* Implements hook_permission.
*
* @access public
* @return void
*/
function epsacrop_permission() {
return array(
'epsacrop create crops' => array(
'title' => t("Create crops"),
'description' => t("Show the %label_link link in the field.", array(
'%label_link' => t("mangage image crops"),
)),
),
'epsacrop edit all crops' => array(
'title' => t("Edit crops"),
'description' => t("Allow the user to edit coordinates for each style (show the link field)."),
),
/*
'epsacrop edit my crops' => array(
'title' => t(""),
'description' => t("")
),
*/
'epsacrop delete all crops' => array(
'title' => t("Delete crops"),
'description' => t("Allow the user to delete coordinates and use the default style."),
),
/*
'epsacrop delete my crops' => array(
'title' => t(""),
'description' => t("")
),
'epsacrop view all crops' => array(
'title' => t(""),
'description' => t("")
),
'epsacrop view own crops' => array(
'title' => t(""),
'description' => t("")
),
'epsacrop edit my crops in place' => array(
'title' => t(""),
'description' => t("")
),
'epsacrop edit my crops with all styles' => array(
'title' => t(""),
'description' => t("")
),
'epsacrop edit all crops with all styles' => array(
'title' => t("Edit crop in place"),
'description' => t("When it's a image from EPSACrop, add a link that allow the user edit coordonates in place.")
),
*/
'epsacrop administer available crops' => array(
'title' => t("Administer available crops"),
'description' => t("Allow user to select which styles are shown in each field."),
),
);
}
/**
* Implements hook_menu.
*
* @access public
* @return array
*/
function epsacrop_menu() {
$items = array();
$items['crop/dialog/%/%/%/%'] = array(
'title' => 'Dialog Crop',
'page callback' => 'epsacrop_dialog',
'page arguments' => array(
2,
3,
4,
5,
),
'access callback' => '_epsacrop_access',
'type' => MENU_CALLBACK,
);
$items['crop/ajax/%/%/%'] = array(
'title' => 'Crop Dialog Ajax',
'page callback' => 'epsacrop_ajax',
'page arguments' => array(
2,
3,
),
'access callback' => '_epsacrop_ajax_access',
'access arguments' => array(
2,
3,
4,
),
'type' => MENU_CALLBACK,
);
$items['crop/ajaxinfo/%'] = array(
'title' => 'Crop File Info Ajax',
'page callback' => 'epsacrop_ajaxinfo',
'page arguments' => array(
2,
),
'access callback' => '_epsacrop_access',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* epsacrop_dialog function.
*
* @access public
* @param string $entity_name
* @param string $field_name
* @param string $bundle
* @param int $fid
* @return void
*/
function epsacrop_dialog($entity_name, $field_name, $bundle, $fid) {
$out = '';
//@TODO: If a method is added to determine if the image is used elsewhere (or number of instances), add that condition for the message
//related issue: http://drupal.org/node/1352722
if (module_exists('media')) {
$out .= '<p>For convenience, cropping applies to <strong>all</strong> current and future content which uses this image. (If the image is from the library, changing the cropping will affect all existing content which uses the image.)</p>';
}
$data = _epsacrop_get_coords_from_fid($fid);
if (!is_string($data)) {
$data = drupal_json_encode((object) $data);
$data = check_plain($data);
}
$out .= '<div class="epsacrop-global" data-token="' . drupal_get_token('epsacrop-put-' . $fid) . '" data-coordinates="' . urlencode($data) . '">' . "\n";
$out .= '<div class="epsacrop-image-crop">' . "\n";
$out .= '<img id="epsacrop-target" />' . "\n";
$out .= '</div>' . "\n";
$out .= '<div class="epsacrop-presets-menu">' . "\n";
$out .= '<ul class="epsacrop-presets-menu-ul">' . "\n";
$i = 0;
if ($entity_name == 'all' && $field_name == 'all' && $bundle == 'all') {
//When on the file edit page, there is no entity_name, field_name or bundle. So make all styles available for editing
$all_styles = array_keys(_epsacrop_load_styles());
$styles = array(
'styles' => array_combine($all_styles, $all_styles),
);
}
else {
$styles = _epsacrop_load_styles_by_instance($entity_name, $field_name, $bundle);
}
foreach ($styles['styles'] as $style_name) {
$style = _epsacrop_load_style($style_name);
$effect = _epsacrop_get_effect($style);
$effect = current($effect);
$id = 'epsacrop-' . $style_name;
$name = is_array($style) && !empty($style['label']) ? $style['label'] : $style_name;
$out .= '<li class="epsacrop-presets-menu-li"><a data-bgcolor="' . $effect['data']['jcrop_settings']['bgcolor'] . '" data-bgopacity="' . $effect['data']['jcrop_settings']['bgopacity'] . '" data-aspect-ratio="' . $effect['data']['jcrop_settings']['aspect_ratio'] . '" id="' . $id . '" href="javascript:Drupal.EPSACrop.crop(\'' . $id . '\');" rel="' . $effect['data']['width'] . 'x' . $effect['data']['height'] . '"' . ($i++ == 0 ? ' class="selected"' : '') . '>' . $name . '</a></li>';
}
$out .= '</ul>' . "\n";
$out .= '</div>' . "\n";
$out .= '<br style="clear:both;" />' . "\n";
$out .= '</div>' . "\n";
$GLOBALS['devel_shutdown'] = FALSE;
echo $out;
drupal_exit();
}
/**
* epsacrop_ajax function.
*
* @access public
* @param string $op
* @param string $fid
* @return void
*/
function epsacrop_ajax($op, $fid) {
$return = NULL;
switch ($op) {
case 'get':
$return = _epsacrop_get_coords_from_fid($fid);
if ($return == FALSE) {
$return = array();
}
break;
case 'put':
if (isset($_POST) && (isset($_POST['coords']) && !empty($_POST['coords']))) {
// If the json_decode returns null that means we got an invalid JSON or
// it reaches the recursion limit.
if (($values = drupal_json_decode($_POST['coords'])) === NULL) {
drupal_access_denied();
drupal_exit();
}
$coords = drupal_json_encode($values);
_epsacrop_save_coords($fid, $coords);
}
break;
case 'del':
break;
}
drupal_json_output($return);
drupal_exit();
}
/**
* epsacrop_ajaxinfo function
*
* @access public
* @param string $fid
* @return void
*/
function epsacrop_ajaxinfo($fid) {
$file = file_load($fid);
$url = image_style_url('epsacrop_thumb', $file->uri);
$info = image_get_info($file->uri);
$return = array(
'url' => $url,
'width' => $info['width'],
'height' => $info['height'],
);
drupal_json_output($return);
drupal_exit();
}
/**
* Implements hook_file_delete().
*
* @access public
* @param stdClass $file
* @return void
*/
function epsacrop_file_delete($file) {
_epsacrop_delete_file($file->fid);
}
/**
* Implements hook_image_default_styles().
*
* @access public
* @return array
*/
function epsacrop_image_default_styles() {
$styles = array();
$styles['epsacrop_thumb'] = array();
$styles['epsacrop_thumb']['effects'] = array(
array(
'name' => 'image_scale',
'data' => array(
'width' => 512,
'height' => 384,
'upscale' => 0,
),
'weight' => 0,
),
);
return $styles;
}
/**
* Implements hook_image_effect_info.
*
* @access public
* @return array
*/
function epsacrop_image_effect_info() {
$effects = array();
$effects['epsacrop_crop'] = array(
'label' => t("EPSA Image Crop"),
'help' => t(""),
'dimensions callback' => 'epsacrop_crop_dimensions',
'effect callback' => 'epsacrop_crop_image',
'form callback' => 'epsacrop_crop_image_form',
);
$effects['epsacrop_crop_reuse'] = array(
'label' => t("Reuse EPSA Image Crop"),
'help' => t("Use the image crop selection from another image style"),
'effect callback' => 'epsacrop_crop_image_reuse',
'form callback' => 'epsacrop_crop_image_reuse_form',
);
return $effects;
}
/**
* A wrapper around image_resize_dimensions.
*
* @access public
* @param array $dimensions
* @param array $data
* @return void
*/
function epsacrop_crop_dimensions(array &$dimensions, array $data) {
if (!$data['height']) {
$data['height'] = NULL;
}
if (!$data['width']) {
$data['width'] = NULL;
}
image_resize_dimensions($dimensions, $data);
}
/**
* Function that provide the effect form settings for dialog crop.
*
* @access public
* @param mixed $data
* @return void
*/
function epsacrop_crop_image_form($data) {
$data += array(
'jcrop_settings' => array(
'bgcolor' => 'black',
'bgopacity' => '0.6',
),
);
//@TODO Propose a alternative style (whitout Crop Dialog effect) instead of this
$form = image_crop_form($data);
// Override default
$form['width']['#required'] = FALSE;
$form['height']['#required'] = FALSE;
// Add validation callbacks to ensure that at least one value has been added
$form['height']['#element_validate'] = array(
'_epsacrop_height_validate',
);
$form['width']['#element_validate'] = array(
'_epsacrop_width_validate',
);
// Change description for the anchor
$form['anchor']['#description'] = t("The part of the image that will be retained during the crop if no coordinates are set.");
$form['disable_scale'] = array(
'#type' => 'checkbox',
'#title' => t('Disable image scaling'),
'#description' => t("Only crop the image to the selected area and don't scale it. When enabled the above dimensions are used only when the cropping area is not selected."),
'#default_value' => isset($data['disable_scale']) ? $data['disable_scale'] : 0,
);
$form['jcrop_settings'] = array(
'#type' => 'fieldset',
'#title' => t("Advanced settings"),
'#collapsed' => TRUE,
'#collapsible' => TRUE,
);
$form['jcrop_settings']['aspect_ratio'] = array(
'#type' => 'textfield',
'#title' => t('Aspect Ratio'),
'#description' => t("Aspect ratio of w/h (e.g. 1 for square)"),
'#default_value' => isset($data['jcrop_settings']['aspect_ratio']) ? $data['jcrop_settings']['aspect_ratio'] : '',
// '#field_suffix' => ' ' . t('pixels'),
// '#required' => TRUE,
'#size' => 10,
'#element_validate' => array(
'_epsacrop_aspect_ratio_validate',
),
);
/*
$form['jcrop_settings']['minsize'] = array();
$form['jcrop_settings']['maxsize'] = array();
*/
$form['jcrop_settings']['bgcolor'] = array(
'#type' => 'textfield',
'#title' => t('Background color'),
'#description' => t("Set color of background container"),
'#default_value' => isset($data['jcrop_settings']['bgcolor']) ? $data['jcrop_settings']['bgcolor'] : '',
// '#field_suffix' => ' ' . t('pixels'),
'#required' => TRUE,
'#size' => 10,
);
$form['jcrop_settings']['bgopacity'] = array(
'#type' => 'textfield',
'#title' => t('Background opacity'),
'#description' => t("Opacity of outer image when cropping"),
'#default_value' => isset($data['jcrop_settings']['bgopacity']) ? $data['jcrop_settings']['bgopacity'] : '',
// '#field_suffix' => ' ' . t('pixels'),
'#required' => TRUE,
'#size' => 10,
);
$form['jcrop_settings']['fallback'] = array(
'#type' => 'checkbox',
'#title' => t('Ignore if not manually set'),
'#description' => t("If a user does not manually set the crop, ignore these settings. This is useful if you want to use other effects to set a default crop, which may then be overridden manually using EPSA Crop. When this is checked, make sure the EPSA Crop effect is above any default cropping effects."),
'#default_value' => isset($data['jcrop_settings']['fallback']) ? $data['jcrop_settings']['fallback'] : FALSE,
);
return $form;
}
/**
* Apply the effect to the image.
*
* @access public
* @param stdClass $image
* @param array $settings
* @return void
*/
function epsacrop_crop_image(stdClass $image, $settings) {
$fid = _epsacrop_get_fid_from_uri($image->source);
if (!empty($fid) && $fid > 0) {
$coords = _epsacrop_get_coords_from_fid($fid);
if (is_string($coords)) {
$coords = drupal_json_decode($coords);
if (is_object($coords)) {
$coords = (array) $coords;
}
}
if (!empty($coords) && is_array($coords)) {
if (isset($GLOBALS['jcrop_style'])) {
$style_name = $GLOBALS['jcrop_style'];
}
else {
$style_name = _epsacrop_get_style_name_from_url();
}
if (!empty($style_name)) {
// Trigger presave hook.
module_invoke_all('epsacrop_crop_image_presave', $image, $settings, $coords, $style_name);
$style = _epsacrop_load_style($style_name);
if (!empty($style)) {
$effect = _epsacrop_get_effect($style);
if (!empty($effect)) {
$effect = current($effect);
$preset = 'epsacrop-' . $style_name;
$coord = isset($coords[$fid][$preset]) ? $coords[$fid][$preset] : '';
if (!empty($coord)) {
if (image_crop($image, $coord['x'], $coord['y'], $coord['w'], $coord['h'])) {
// Trigger postsave hook.
module_invoke_all('epsacrop_crop_image_postsave', $image, $settings, $coords, $style_name);
if (isset($settings['disable_scale']) && $settings['disable_scale']) {
return TRUE;
}
return image_scale($image, $settings['width'], $settings['height']);
}
}
}
}
}
}
}
return empty($settings['jcrop_settings']['fallback']) ? image_crop_effect($image, $settings) : TRUE;
}
/**
* Function that provide the effect form settings for reusing epsa crop.
*
* @access public
* @param mixed $data
* @return void
*/
function epsacrop_crop_image_reuse_form($data) {
$styles = array_keys(_epsacrop_load_styles());
$styles = array_combine($styles, $styles);
//exclude the current style
if ($key = array_search(arg(5), $styles)) {
unset($styles[$key]);
}
if (count($styles) > 0) {
$form['jcrop_reuse'] = array(
'#title' => t('Reuse the crop selection from'),
'#type' => 'select',
'#options' => $styles,
'#default_value' => isset($data['jcrop_reuse']) ? $data['jcrop_reuse'] : '',
);
}
else {
$form['jcrop_reuse_message'] = array(
'#value' => t('No styles were found currently using EPSA crop. Please create a style with EPSA crop first.'),
);
}
return $form;
}
/**
* Apply the effect to the image on reuse.
*
* @access public
* @param stdClass $image
* @param array $settings
* @return void
*/
function epsacrop_crop_image_reuse(stdClass $image, $settings) {
if (!isset($settings['jcrop_reuse'])) {
return;
}
$style = _epsacrop_load_style($settings['jcrop_reuse']);
foreach ($style['effects'] as $effect) {
if ($effect['name'] == 'epsacrop_crop') {
$GLOBALS['jcrop_style'] = $style['name'];
image_effect_apply($image, $effect);
return TRUE;
}
}
return FALSE;
}
/**
* Implements hook_form_FORM_ID_alter().
*
* @access public
* @param array &$form
* @param array $form_state
* @return void
*/
function epsacrop_form_field_ui_field_edit_form_alter(&$form, $form_state) {
if (user_access('epsacrop administer available crops')) {
$field = $form['#field'];
$settings = $form_state['build_info']['args'][0]['settings'];
if (isset($field) && in_array($field['type'], array(
'image',
'media',
'file',
))) {
$styles = _epsacrop_load_styles();
if (!empty($styles)) {
$options = array();
foreach ($styles as $style_name => $style) {
$options[$style_name] = $style['label'];
}
$form['instance']['settings']['epsacrop'] = array(
'#type' => 'fieldset',
'#title' => t("EPSACrop settings"),
'#collapsed' => FALSE,
'#collapsible' => TRUE,
'#tree' => TRUE,
);
$form['instance']['settings']['epsacrop']['styles'] = array(
'#type' => 'checkboxes',
'#title' => t("Availables EPSACrop styles"),
'#description' => t("Select which styles should be available for this field"),
'#options' => $options,
'#default_value' => isset($settings['epsacrop']['styles']) ? $settings['epsacrop']['styles'] : array(),
);
//@TODO Add the possibility to change the size of dialog (for example, for field with only one style)
/*
$form['instance']['settings']['epsacrop']['dialog_width'] = array(
'#type' => 'textfield',
'#title' => t('Dialog width'),
'#default_value' => isset($settings['epsacrop']['dialog_width']) ? $settings['epsacrop']['dialog_width'] : '512',
'#field_suffix' => ' ' . t('pixels'),
'#required' => TRUE,
'#size' => 10,
);
$form['instance']['settings']['epsacrop']['dialog_height'] = array(
'#type' => 'textfield',
'#title' => t('Dialog height'),
'#default_value' => isset($settings['epsacrop']['dialog_height']) ? $settings['epsacrop']['dialog_height'] : '384',
'#field_suffix' => ' ' . t('pixels'),
'#required' => TRUE,
'#size' => 10,
);
*/
}
}
}
}
/**
* Implements hook_form_media_edit_alter().
* Add epsacrop to media edit form.
*/
function epsacrop_form_media_edit_alter(&$form, $form_state) {
epsacrop_form_file_entity_edit_alter($form, $form_state);
}
/**
* Implements hook_form_file_entity_edit_alter().
* Add epsacrop to file_entity edit form.
*/
function epsacrop_form_file_entity_edit_alter(&$form, $form_state) {
if (!_epsacrop_access() || !isset($form['preview']['#file']) || $form['preview']['#file']->type != 'image') {
return;
}
_epsacrop_include_header_html();
$setting = array(
'entity_type' => 'all',
'field_name' => 'all',
'bundle' => 'all',
);
$file = $form['preview']['#file'];
$info = image_get_info($file->uri);
$setting['fid'] = $file->fid;
$setting['url'] = str_replace('%27', '\\%27', image_style_url('epsacrop_thumb', $file->uri));
$setting['size'] = array(
$info['width'],
$info['height'],
);
// Fix a strange bug when the image's name contains strange chars, like +
$preview_file = image_style_path('epsacrop_thumb', $file->uri);
if (!file_exists($preview_file)) {
image_style_create_derivative(image_style_load('epsacrop_thumb'), $file->uri, $preview_file);
}
$markup = "<a href=\"javascript:Drupal.EPSACrop.dialog('" . $setting['entity_type'] . "', '" . $setting['field_name'] . "', '" . $setting['bundle'] . "', '" . $setting['fid'] . "', '" . $setting['url'] . "', [" . $setting['size'][0] . "," . $setting['size'][1] . "]);\" class=\"button epsacrop\">" . t("manage image crops") . "</a>";
$form['epsacrop'] = array(
'#type' => 'markup',
'#markup' => $markup,
);
}
/**
* Implements hook_element_info_alter.
*
* @access public
* @param array &$type
* @return void
*/
function epsacrop_element_info_alter(&$type) {
$type['managed_file']['#process'][] = 'epsacrop_element_process';
if (module_exists('media')) {
$type['media']['#process'][] = 'epsacrop_element_process';
}
if (isset($type['mfw_managed_file'])) {
$type['mfw_managed_file']['#process'][] = 'epsacrop_element_process';
}
}
/**
* Helper function that add a link in image widget field to open a dialog for the crops.
*
* @access private
* @return void
*/
function epsacrop_element_process($element, $form_state, $form) {
if (!isset($element['#field_name']) || !_epsacrop_access()) {
return $element;
}
_epsacrop_include_header_html();
$styles = _epsacrop_load_styles_by_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
if (count($styles) == 0) {
return $element;
}
$setting = array(
'entity_type' => $element['#entity_type'],
'field_name' => $element['#field_name'],
'bundle' => $element['#bundle'],
);
if (isset($element['#file']) && is_object($element['#file']) && ($file = $element['#file'])) {
$info = image_get_info($file->uri);
$setting['fid'] = $file->fid;
$setting['url'] = str_replace('%27', '\\%27', image_style_url('epsacrop_thumb', $file->uri));
$setting['size'] = array(
$info['width'],
$info['height'],
);
// Fix a strange bug when the image's name contains strange chars, like +
$preview_file = image_style_path('epsacrop_thumb', $file->uri);
if (!file_exists($preview_file)) {
image_style_create_derivative(image_style_load('epsacrop_thumb'), $file->uri, $preview_file);
}
}
if ($element['#type'] == 'media') {
//for media, need to include the media elements even if the file is not defined, because it's not defined when file initially selected
$element['#attached']['js'][] = array(
'type' => 'setting',
'data' => array(
'epsacrop_dialog' => array(
$element['#id'] . '--widget' => $setting,
),
),
);
$element['#attached']['js'][] = drupal_get_path('module', 'epsacrop') . '/js/epsacrop-media.js';
$element['epsacrop'] = array(
'#type' => 'link',
'#href' => '',
'#title' => t('Manage image crops'),
'#attributes' => array(
'class' => array(
'button',
'manage-crop',
),
),
'#options' => array(
'fragment' => FALSE,
'external' => TRUE,
),
'#weight' => 0,
);
}
elseif (isset($setting['fid'])) {
$markup = "<a href=\"javascript:Drupal.EPSACrop.dialog('" . $setting['entity_type'] . "', '" . $setting['field_name'] . "', '" . $setting['bundle'] . "', '" . $setting['fid'] . "', '" . $setting['url'] . "', [" . $setting['size'][0] . "," . $setting['size'][1] . "]);\">" . t("manage image crops") . "</a>";
$element['epsacrop'] = array(
'#type' => 'markup',
'#markup' => $markup,
);
}
return $element;
}
/**
* Validate a aspect ration information.
*
* @access public
* @param array $element
* @param array &$form_state
* @return void
*/
function _epsacrop_aspect_ratio_validate($element, &$form_state) {
$value = $element['#value'];
if (!empty($value)) {
$parts = explode('/', $value);
if (count($parts) == 2) {
if (!is_numeric($parts[0]) || !is_numeric($parts[1])) {
form_error($element, t('Both parts of !name must be an integer.', array(
'!name' => check_plain($element['#title']),
)));
}
}
elseif (!is_numeric($value)) {
form_error($element, t('!name must be an integer.', array(
'!name' => check_plain($element['#title']),
)));
}
}
}
/**
* Validate width information.
*
* @access private
* @param array $element
* @param array &$form_state
* @return void
*/
function _epsacrop_width_validate($element, &$form_state) {
$value = $element['#value'];
if (empty($value)) {
if (empty($form_state['complete form']['data']['height']['#value'])) {
form_error($element, t('Width cannot be empty without a height value'));
}
}
}
/**
* Validate height information.
*
* @access private
* @param array $element
* @param array &$form_state
* @return void
*/
function _epsacrop_height_validate($element, &$form_state) {
$value = $element['#value'];
if (empty($value)) {
if (empty($form_state['complete form']['data']['width']['#value'])) {
form_error($element, t('Height cannot be empty without a width value'));
}
}
}
/**
* Helper function that get all styles with epsacrop effect.
*
* @access private
* @return array
*/
function _epsacrop_load_styles() {
$return = array();
$styles = image_styles();
foreach ($styles as $style_name => $style) {
foreach ($style['effects'] as $sid => $effect) {
if ($effect['module'] == 'epsacrop' && $effect['name'] == 'epsacrop_crop') {
$return[$style_name] = $style;
break;
}
}
}
return $return;
}
/**
* This function load only on style that implement epsacrop effect.
*
* @access private
* @param string $style_name
* @return bool
*/
function _epsacrop_load_style($style_name) {
if (empty($style_name)) {
return FALSE;
}
$styles = _epsacrop_load_styles();
if (isset($styles[$style_name]) && !empty($styles[$style_name])) {
return $styles[$style_name];
}
return FALSE;
}
/**
* Return the effect issue from the module.
*
* @access private
* @param mixed $style
* @return void
*/
function _epsacrop_get_effect($style) {
if (empty($style) || !is_array($style) || (!isset($style['effects']) || !is_array($style['effects']))) {
return FALSE;
}
foreach ($style['effects'] as $eid => $effect) {
if ($effect['module'] == 'epsacrop') {
return array(
$eid => $effect,
);
}
}
return FALSE;
}
/**
* Get all style that are attach to one instance of field.
*
* @access private
* @param string $entity_type
* @param string $field_name
* @param string $bundle_name
* @return array
*/
function _epsacrop_load_styles_by_instance($entity_type, $field_name, $bundle) {
$instance = field_info_instance($entity_type, $field_name, $bundle);
$styles = array();
if (isset($instance['settings']['epsacrop']) && is_array($instance['settings']['epsacrop']['styles'])) {
$instance['settings']['epsacrop']['styles'] = array_filter($instance['settings']['epsacrop']['styles']);
if (isset($instance['settings']['epsacrop']['styles']) && !empty($instance['settings']['epsacrop']['styles'])) {
$styles = $instance['settings']['epsacrop'];
}
}
// Allow other modules to alter list of styles
drupal_alter('epsacrop_load_styles', $styles, $entity_type, $field_name, $bundle);
return $styles;
}
/**
* Helper function that get the style name from image url.
*
* @access private
* @return void
*/
function _epsacrop_get_style_name_from_url() {
$split = explode('/', $_GET['q']);
$pointer = array_search('styles', $split);
if ($pointer !== FALSE) {
return $split[++$pointer];
}
return FALSE;
}
/**
* This function include all files (JavaScript & CSS) needed by the module.
*
* @access private
* @return void
*/
function _epsacrop_include_header_html() {
$module_path = drupal_get_path('module', 'epsacrop');
drupal_add_js(array(
'epsacrop' => array(
'path' => $module_path,
),
), 'setting');
drupal_add_library('system', 'ui.dialog');
drupal_add_js(libraries_get_path('Jcrop') . '/js/jquery.Jcrop.js');
drupal_add_js(libraries_get_path('json2') . '/json2.js', array(
'preprocess' => FALSE,
));
drupal_add_js($module_path . '/js/epsacrop.js');
drupal_add_css(libraries_get_path('Jcrop') . '/css/jquery.Jcrop.css');
drupal_add_css($module_path . '/css/epsacrop.css');
}
/**
* Return the version of jcrop library.
*
* @access public
* @return void
*/
function _epsacrop_jcrop_get_version() {
$version = 0;
$filepath = libraries_get_path('Jcrop') . '/js/jquery.Jcrop.js';
if (file_exists($filepath)) {
$lines = file($filepath);
array_shift($lines);
// First line is simple comment
if (preg_match('/v(.*)/', array_shift($lines), $matches)) {
$version = $matches[1];
}
else {
drupal_set_message(t('Could be give the version of Jcrop %path, check your install.', array(
'%path' => $filepath,
)), 'error');
$version = 0;
}
}
return $version;
}
/**
* Check if json2.js is findable.
*
* @access private
* @return void
*/
function _epsacrop_is_json2_exists($display_message = FALSE) {
$filepath = libraries_get_path('json2') . '/json2.js';
if (file_exists($filepath)) {
return TRUE;
}
if ($display_message) {
drupal_set_message(t('Could be find the json2.js file %path, check your install.', array(
'%path' => $filepath,
)), 'error');
}
}
/**
* Check if we've coordonates for one file.
*
* @access private
* @param int $fid
* @return bool
*/
function _epsacrop_fid_exists($fid) {
if (!empty($fid)) {
return count(db_select('epsacrop_files', 'e')
->fields('e')
->condition('fid', $fid)
->execute()
->fetchAll());
}
return 0;
}
/**
* Insert coordonates for one file in the database.
*
* @access private
* @param int $fid
* @param array $coords
* @return void
*/
function _epsacrop_add_file($fid, $coords) {
db_insert('epsacrop_files')
->fields(array(
'fid' => $fid,
'coords' => serialize($coords),
))
->execute();
}
/**
* Save the coordonates in the database.
*
* @access private
* @param int $fid
* @param array $coords
* @return void
*/
function _epsacrop_save_coords($fid, $coords) {
// Check fid is for a valid file.
if ($file = file_load($fid)) {
$info = image_get_info($file->uri);
// Not an image.
if (!$info) {
return FALSE;
}
$coords_data = drupal_json_decode($coords);
$field_coords = $coords_data[$fid];
foreach ($field_coords as $field_coord) {
// Check we have coordinates passed and that they are not larger
// than the image.
if (!empty($field_coord) && ($field_coord['x'] < 0 || $field_coord['y'] < 0 || $field_coord['x2'] > $info['width'] || $field_coord['y2'] > $info['height'])) {
return FALSE;
}
}
$affected = db_update('epsacrop_files')
->fields(array(
'coords' => serialize($coords),
))
->condition('fid', $fid)
->execute();
if ($affected == 0 && _epsacrop_fid_exists($fid) == 0) {
_epsacrop_add_file($fid, $coords);
}
image_path_flush(_epsacrop_get_uri_from_fid($fid));
}
}
/**
* Delete the coordonates in the database.
*
* @access private
* @param fid $fid
* @return void
*/
function _epsacrop_delete_file($fid) {
db_delete('epsacrop_files')
->condition('fid', $fid)
->execute();
}
/**
* Get all coordonates for one file.
*
* @access private
* @param int $fid
* @return array
*/
function _epsacrop_get_coords_from_fid($fid) {
$files =& drupal_static(__FUNCTION__);
if (empty($files[$fid])) {
$files[$fid] = new stdClass();
$has_coords = _epsacrop_fid_exists($fid);
if ($has_coords != 0) {
$result = db_select('epsacrop_files', 'e')
->fields('e', array(
'coords',
))
->condition('e.fid', $fid)
->execute()
->fetchField();
$files[$fid] = unserialize($result);
}
return $files[$fid];
}
return $files[$fid];
}
/**
* Try to find the fid from a uri.
*
* @access private
* @param string $path
* @return int
*/
function _epsacrop_get_fid_from_uri($uri) {
$fids =& drupal_static(__FUNCTION__);
$fids[$uri] = 0;
if (empty($fids[$uri])) {
$query = db_select('file_managed', 'f');
$query
->leftjoin('epsacrop_files', 'e', 'e.fid = f.fid');
$result = $query
->fields('f', array(
'fid',
))
->condition('f.uri', $uri)
->range(0, 1)
->execute()
->fetchField();
$fids[$uri] = (int) $result;
}
return $fids[$uri];
}
/**
* Try to get the uri from a fid.
*
* @access private
* @param mixed $fid
* @return void
*/
function _epsacrop_get_uri_from_fid($fid) {
if (!empty($fid) && is_numeric($fid)) {
return (string) db_select('file_managed', 'f')
->fields('f', array(
'uri',
))
->condition('f.fid', $fid)
->range(0, 1)
->execute()
->fetchField();
}
return FALSE;
}
/**
* Callback for hook_menu.
*
* @access public
* @param mixed $access
* @return void
*/
function _epsacrop_access() {
return user_access('epsacrop create crops') || user_access('epsacrop edit all crops');
}
/**
* Callback for Crop Dialog Ajax.
*
* @param string $op
* @param int $fid
* @param string $token
* @return bool
*/
function _epsacrop_ajax_access($op, $fid, $token) {
return _epsacrop_access() && drupal_valid_token($token, 'epsacrop-' . $op . '-' . $fid);
}
Functions
Name![]() |
Description |
---|---|
epsacrop_ajax | epsacrop_ajax function. |
epsacrop_ajaxinfo | epsacrop_ajaxinfo function |
epsacrop_crop_dimensions | A wrapper around image_resize_dimensions. |
epsacrop_crop_image | Apply the effect to the image. |
epsacrop_crop_image_form | Function that provide the effect form settings for dialog crop. |
epsacrop_crop_image_reuse | Apply the effect to the image on reuse. |
epsacrop_crop_image_reuse_form | Function that provide the effect form settings for reusing epsa crop. |
epsacrop_dialog | epsacrop_dialog function. |
epsacrop_element_info_alter | Implements hook_element_info_alter. |
epsacrop_element_process | Helper function that add a link in image widget field to open a dialog for the crops. |
epsacrop_file_delete | Implements hook_file_delete(). |
epsacrop_form_field_ui_field_edit_form_alter | Implements hook_form_FORM_ID_alter(). |
epsacrop_form_file_entity_edit_alter | Implements hook_form_file_entity_edit_alter(). Add epsacrop to file_entity edit form. |
epsacrop_form_media_edit_alter | Implements hook_form_media_edit_alter(). Add epsacrop to media edit form. |
epsacrop_image_default_styles | Implements hook_image_default_styles(). |
epsacrop_image_effect_info | Implements hook_image_effect_info. |
epsacrop_menu | Implements hook_menu. |
epsacrop_permission | Implements hook_permission. |
_epsacrop_access | Callback for hook_menu. |
_epsacrop_add_file | Insert coordonates for one file in the database. |
_epsacrop_ajax_access | Callback for Crop Dialog Ajax. |
_epsacrop_aspect_ratio_validate | Validate a aspect ration information. |
_epsacrop_delete_file | Delete the coordonates in the database. |
_epsacrop_fid_exists | Check if we've coordonates for one file. |
_epsacrop_get_coords_from_fid | Get all coordonates for one file. |
_epsacrop_get_effect | Return the effect issue from the module. |
_epsacrop_get_fid_from_uri | Try to find the fid from a uri. |
_epsacrop_get_style_name_from_url | Helper function that get the style name from image url. |
_epsacrop_get_uri_from_fid | Try to get the uri from a fid. |
_epsacrop_height_validate | Validate height information. |
_epsacrop_include_header_html | This function include all files (JavaScript & CSS) needed by the module. |
_epsacrop_is_json2_exists | Check if json2.js is findable. |
_epsacrop_jcrop_get_version | Return the version of jcrop library. |
_epsacrop_load_style | This function load only on style that implement epsacrop effect. |
_epsacrop_load_styles | Helper function that get all styles with epsacrop effect. |
_epsacrop_load_styles_by_instance | Get all style that are attach to one instance of field. |
_epsacrop_save_coords | Save the coordonates in the database. |
_epsacrop_width_validate | Validate width information. |