array( 'title' => t('Crop any image'), ), 'crop own images' => array( 'title' => t('Crop own images'), ), 'administer imagecrop' => array( 'title' => t('Administer imagecrop settings'), 'description' => t('Administer the basic settings from image javascript crop'), ), ); } /** * Implements hook_theme(). */ function imagecrop_theme() { return array( 'page-imagecrop' => array( 'variables' => array(), 'file' => 'includes/imagecrop.theme.inc', 'function' => 'imagecrop_page', ), 'html-imagecrop' => array( 'variables' => array(), 'template' => 'html-imagecrop', ), 'imagecrop_crop_ui' => array( 'variables' => array( 'style_selection' => array(), 'settings_form' => array(), 'scale_form' => array(), 'imagecrop' => NULL ), 'template' => 'imagecrop-crop-ui', ), 'imagecrop_overview' => array( 'variables' => array( 'style_selection' => array(), 'viewed_style' => NULL, 'edit_url' => NULL, ), 'template' => 'imagecrop-crop-overview', ), ); } /** * Implements hook_menu(). */ function imagecrop_menu() { $items = array(); $items['admin/config/media/imagecrop'] = array( 'title' => 'Image javascript crop', 'page callback' => 'drupal_get_form', 'page arguments' => array('imagecrop_settings_form'), 'access arguments' => array('administer imagecrop'), 'file' => 'includes/imagecrop.admin.inc', ); $items['imagecrop/overview/%'] = array( 'page callback' => 'imagecrop_image_styles_overview', 'page arguments' => array(2), 'type' => MENU_CALLBACK, 'access callback' => 'imagecrop_has_access', 'file' => 'includes/imagecrop.admin.inc', ); $items['imagecrop/crop/%/%'] = array( 'page callback' => 'imagecrop_cropping_page', 'page arguments' => array(2, 3), 'type' => MENU_CALLBACK, 'access callback' => 'imagecrop_has_access', 'file' => 'includes/imagecrop.admin.inc', ); $items['imagecrop/generate_image'] = array( 'page callback' => 'imagecrop_generate_cropready_image', 'access callback' => 'imagecrop_has_access', 'file' => 'includes/imagecrop.admin.inc', ); return $items; } /** * Implements hook_image_effect_info(). */ function imagecrop_image_effect_info() { $effects = array(); $effects['imagecrop_javascript'] = array( 'label' => t('Javascript crop'), 'help' => t('Create a crop with a javascript toolbox.'), 'effect callback' => 'imagecrop_effect', 'form callback' => 'imagecrop_effect_form', 'summary theme' => 'imagecrop_effect_summary', ); return $effects; } /** * Implements hook_imagecrop_popups(). */ function imagecrop_imagecrop_popups() { $popups = array(); if (module_exists('colorbox')) { $popups['imagecrop_colorbox'] = t('Colorbox'); } return $popups; } /** * Implements hook_form_field_ui_field_edit_form_alter(). * Add the imagecrop setting to an imagefield. */ function imagecrop_form_field_ui_field_edit_form_alter(&$form, $form_state) { if ($form['#field']['type'] == 'image') { $styles = get_imagecrop_styles(); if (count($styles) > 0) { $form['instance']['settings']['imagecrop'] = array( '#type' => 'checkboxes', '#options' => $styles, '#title' => t('Available imagecrop styles'), '#description' => t('Select which imagecrop styles should be available for this field'), '#weight' => 12, '#default_value' => isset($form_state['build_info']['args'][0]['settings']['imagecrop']) ? $form_state['build_info']['args'][0]['settings']['imagecrop'] : array(), ); } } } /** * Implements hook_element_info_alter(). */ function imagecrop_element_info_alter(&$type) { $type['managed_file']['#after_build'][] = 'process_imagecrop_form_element'; } /** * Process function for imagecrop-enabled fields. */ function process_imagecrop_form_element($element) { // Leave alone if we are on the field ui settings. if (!isset($element['#field_name'])) { return $element; } // Leave element when user doesn't have access. if (!user_access('crop images with toolbox')) { return $element; } $enabled_styles = imagecrop_get_fields_enabled_styles($element['#entity_type'], $element['#field_name'], $element['#bundle']); // Leave element when no image styles are found for current field. if (count($enabled_styles) == 0) { return $element; } $element['imagecrop'] = array( '#type' => 'markup', '#weight' => 10, '#suffix' => '', ); if ($element['fid']['#value']) { $element['imagecrop']['#prefix'] = '
'; $element['imagecrop']['#markup'] = imagecrop_linkitem($element['fid']['#value'], $element); } else { $element['imagecrop']['#prefix'] = '
'; $element['imagecrop']['#markup'] = t('After uploading an image you\'ll be able to crop it.'); } return $element; } /** * Implements hook_preprocess_page(). * Set the theme hook suggestion to page-imagecrop for imagecrop pages. */ function imagecrop_preprocess_page(&$variables) { if (arg(0) == 'imagecrop') { $variables['theme_hook_suggestion'] = 'page-imagecrop'; include_once(dirname(__FILE__) . '/includes/imagecrop.theme.inc'); } } /** * Implements hook_process_html(). * Set the theme hook suggestion to html-imagecrop for imagecrop pages. */ function imagecrop_process_html(&$variables) { if (arg(0) == 'imagecrop') { $js = drupal_add_js(); if (module_exists('admin_menu')) { $path = drupal_get_path('module', 'admin_menu'); if (isset($js[$path . '/admin_menu.js'])) { unset($js[$path . '/admin_menu.js']); $variables['scripts'] = drupal_get_js('header', $js); } } $variables['theme_hook_suggestion'] = 'html-imagecrop'; } } /** * Check if the current user has one of the required permissions. */ function imagecrop_has_access() { return (user_access('crop any image') || user_access('crop own images')); } /** * Helper function to get all the enabled styles for a given field. */ function imagecrop_get_fields_enabled_styles($entity_type, $field_name, $bundle) { $instance = field_info_instance($entity_type, $field_name, $bundle); // No imagecrop settings are found. if (!isset($instance['settings']['imagecrop'])) { return array(); } return array_filter($instance['settings']['imagecrop']); } /** * Helper function to add click link. * * @param $fid fid from the file to crop * @param $element the form element * * @return link for opening the imagecrop admin. */ function imagecrop_linkitem($fid, $element = '') { $popup_link_function = variable_get('imagecrop_popup', 'basic'); $width = variable_get('imagecrop_popup_width', 700); $height = variable_get('imagecrop_popup_height', 600); $url = url('imagecrop/overview/' . $fid . '/0/' . $element['#entity_type'] . '/' . $element['#bundle'] . '/' . $element['#field_name'], array('absolute' => TRUE)); if ($popup_link_function != 'basic' && function_exists($popup_link_function) && $link = $popup_link_function($url, $width, $height)) { return $link; } else { return '[' . t('Crop this image') . ']'; } } /** * Return a list of presets. * * @param $enabled_styles array of styles that are enabled for a field * @return $presets array with presetid to load and list of all other possible presets. */ function get_imagecrop_styles($enabled_styles = array()) { $apply_filter = (count($enabled_styles) > 0); $all_styles = image_styles(); $styles = array(); foreach ($all_styles as $key => $style) { foreach ($style['effects'] as $effect) { if ($effect['name'] == 'imagecrop_javascript') { // Skip if current style is not enabled. if ($apply_filter && !in_array($style['isid'], $enabled_styles)) { continue; } $styles[$style['isid']] = $style['name']; } } } return $styles; } /** * Image effect callback: Crop the image based on the javascript selected crop. * * @param $image An image object returned by image_load(). * @param $data An array of settings from the user for cropping the image. * @return TRUE on success. FALSE on failure to crop the image. * */ function imagecrop_effect(&$image, $data) { try { $imagecrop = new ImageCrop(); $imagecrop->loadFile($image->source, FALSE); // if a global presetid is been set, it meens the image is generated from the imagecrop module if (isset($GLOBALS['imagecrop_isid'])) { $isid = $GLOBALS['imagecrop_isid']; } // and if not, then get the id from list of all presets else { $isid = imagecrop_get_isid_from_url(); } $imagecrop->setImageStyle($isid); $imagecrop->loadCropSettings(); $imagecrop->applyCrop($image); } catch (Exception $e) { watchdog($e->getMessage(), 'error'); return FALSE; } return TRUE; } /** * Settings form for configuring a javascript imagecrop effect. */ function imagecrop_effect_form($data) { $form = image_resize_form($data); $form['xoffset'] = array( '#type' => 'textfield', '#title' => t('X offset'), '#default_value' => isset($data['xoffset']) ? $data['xoffset'] : '', '#description' => t('Enter an offset in pixels (without px) or use a keyword: left, center, or right.'), '#element_validate' => array('imagecrop_validate_offset'), ); $form['yoffset'] = array( '#type' => 'textfield', '#title' => t('Y offset'), '#default_value' => isset($data['yoffset']) ? $data['yoffset'] : '', '#description' => t('Enter an offset in pixels (without px) or use a keyword: top, center, or bottom.'), '#element_validate' => array('imagecrop_validate_offset'), ); $form['resizable'] = array( '#type' => 'checkbox', '#title' => t('Is the toolbox resizable or not?'), '#default_value' => isset($data['resizable']) ? $data['resizable'] : '', '#description' => t('If the toolbox is resized, the crop values won\'t be respected, so you should add a Scale action after the ImageCrop.'), ); $form['downscaling'] = array( '#type' => 'checkbox', '#title' => t('Do not allow down scaling'), '#default_value' => isset($data['downscaling']) ? $data['downscaling'] : FALSE, '#description' => t('If checked, you can\'t resize the toolbox smaller than width and height.'), ); $description = t('Enter an aspect ratio to preserve during resizing. This can take one of the following formats:'); $description .= ''; $description .= t('Leave blank for no aspect ratio constraints.'); $form['aspect_ratio'] = array( '#type' => 'textfield', '#title' => t('Aspect ratio'), '#default_value' => isset($data['aspect_ratio']) ? $data['aspect_ratio'] : '', '#description' => $description, '#element_validate' => array('imagecrop_validate_aspect'), ); $form['disable_if_no_data'] = array( '#type' => 'checkbox', '#title' => t('Don\'t crop if cropping region wasn\'t set.'), '#default_value' => isset($data['disable_if_no_data']) ? $data['disable_if_no_data'] : FALSE, ); return $form; } /** * Validation function to validate an entered offset value. (numbers or left / center / right) */ function imagecrop_validate_offset($element, &$form_state) { if ($element['#value'] == '') { return; } // numbers are allowed. if (is_numeric($element['#value'])) { return; } // if the value is a string, check on allowed strings if ($element['#value'] != 'center' && $element['#value'] != 'left' && $element['#value'] != 'right') { form_error($element, t('@name must be a correct offset value', array('@name' => $element['#title']))); } } /** * Validation function to validate an entered aspect value. */ function imagecrop_validate_aspect($element, &$form_state) { if ($element['#value'] == '') { return; } // numbers are allowed. if (is_numeric($element['#value'])) { return; } // if the value is a string, check on allowed strings if ($element['#value'] != 'KEEP' && $element['#value'] != 'CROP') { form_error($element, t('@name must be a correct aspect value', array('@name' => $element['#title']))); } } /** * Get the isid from the current requested url. */ function imagecrop_get_isid_from_url() { $args = explode('/', $_GET['q']); $key = array_search('styles', $args); if ($key != FALSE) { $key++; $stylename = $args[$key]; $styles = get_imagecrop_styles(); foreach ($styles as $isid => $style) { if ($style == $stylename) { return $isid; break; } } } return 0; } /** * Render the imagecrop links for colorbox. */ function imagecrop_colorbox($url, $width, $height) { if (!module_exists('colorbox')) { return FALSE; } // Force colorbox to load on this path. global $conf; $colorbox_pages = variable_get('colorbox_pages', "admin*\nimg_assist*\nimce*\nnode/add/*\nnode/*/edit"); $conf['colorbox_pages'] = 'none'; _colorbox_doheader(); drupal_add_js(drupal_get_path('module', 'colorbox') . '/js/colorbox_load.js'); $conf['colorbox_pages'] = $colorbox_pages; return '['. t('Crop this image') .']'; }