added missing module fixer and updated imagecache_actions

This commit is contained in:
Bachir Soussi Chiadmi
2018-03-21 17:06:08 +01:00
parent 3f7e130321
commit 0bcc558ed5
83 changed files with 6386 additions and 2517 deletions

View File

@@ -4,6 +4,40 @@
* image processing.
*/
/**
* Validates that the element is a positive number.
*
* This is a Form API #element_validate callback.
*
* @param array $element
* param array $form_status
*/
function imagecache_actions_validate_number_positive(&$element/*, &$form_status*/) {
$value = $element['#value'];
if ($value != '') {
if (!is_numeric($value) || (float) $value <= 0.0) {
form_error($element, t('%name must be a positive number.', array('%name' => $element['#title'])));
}
}
}
/**
* Validates that the element is a non negative number.
*
* This is a Form API #element_validate callback.
*
* @param array $element
* param array $form_status
*/
function imagecache_actions_validate_number_non_negative(&$element/*, &$form_status*/) {
$value = $element['#value'];
if ($value != '') {
if (!is_numeric($value) || (float) $value < 0.0) {
form_error($element, t('%name must be a non negative number.', array('%name' => $element['#title'])));
}
}
}
/*
* File field handling.
*/
@@ -12,7 +46,7 @@
*/
function imagecache_actions_file_field_description() {
return t('File is either a file with one of the valid schemes, an absolute path, or a relative path (relative to the current directory, probably the Drupal site root). Valid schemes are a.o. private://, public://, and if the !module module has been installed, also module:// and theme://.',
array('!module' => l('System Stream Wrapper', 'http://drupal.org/project/system_stream_wrapper', array('external' => TRUE))));
array('!module' => l('System Stream Wrapper', 'https://drupal.org/project/system_stream_wrapper', array('external' => TRUE))));
}
/**
@@ -21,33 +55,27 @@ function imagecache_actions_file_field_description() {
* This is a Form API #element_validate callback.
*
* @param array $element
* @param array $form_status
* param array $form_status
*/
function imagecache_actions_validate_file(&$element, &$form_status) {
function imagecache_actions_validate_file(&$element/*, &$form_status*/) {
if (!imagecache_actions_find_file($element['#value'])) {
form_error($element, t("Unable to find the file '%file'. Please check the path.", array('%file' => $element['#value'])) );
form_error($element, t("Unable to find the file '%file'. Please check the path.", array('%file' => $element['#value'])));
}
}
/**
* Looks up and returns the full path of the given file.
*
* We accept files with the following schemes:
* - private://
* - public://
* - temporary://
* - module://{module}/{component}
*
* Files without a scheme are looked up as are:
* - relative: relative to the current directory (probably $drupal_root).
* - absolute: as is.
*
* @param string $file
* A file name, with a scheme, relative, or absolute.
* A file name. We accept:
* - stream wrapper notation like: private://, public://, temporary:// and
* module:// (the latter provided by the system stream wrapper module).
* - relative: relative to the current directory (probably DRUPAL_ROOT).
* - absolute: as is.
*
* @return string|false
* The full file path of the file, so the image toolkit knows exactly where it
* is.
* is. False if the file cannot be found or is not readable.
*/
function imagecache_actions_find_file($file) {
$result = FALSE;
@@ -86,12 +114,43 @@ function imagecache_actions_image_load($file, $toolkit = FALSE) {
}
/**
* Return an array with context information about the image.
* Returns the label for the given style name.
*
* This information can e.g. be used by effects that allow custom PHP like
* As of D7.23 image styles can also have a human readable label besides their
* machine readable name. This function returns that label if available, or the
* name if the label is absent.
*
* @param string|null $style_name
* The name of the image style.
*
* @return string
* The label for the image style.
*/
function imagecache_actions_get_style_label($style_name) {
if (!empty($style_name)) {
$style = image_style_load($style_name);
$label = isset($style['label']) ? $style['label'] : $style['name'];
if (!empty($style)) {
return $label;
}
else {
return $label . ' ' . t('<span class="error">Invalid reference. The referenced image style may have been deleted!</span>');
}
}
else {
return t('none');
}
}
/**
* Returns an array with context information about the image.
*
* This information is called by effects that need contextual information or
* that allow custom PHP:
* - Custom action.
* - Text from image alt or title.
* - Text with tokens.
* - Text from PHP code.
* - Text from alt or title.
*
* @param object $image
* The image object.
@@ -99,55 +158,125 @@ function imagecache_actions_image_load($file, $toolkit = FALSE) {
* An associative array with the effect options.
*
* @return array
* An associative array with context information about the image.
* An associative array with context information about the image. It contains
* the following keys:
* - effect_data: array with the effect data.
* - managed_file: object|null, a managed file object for the current image.
* This may be (an extended) media/file_entity file object.
* - referring_entities: array, list of (loaded) entities that have an image
* field referring to the managed file.
* - entity: object|null, the 1st (and often only) entity that has an image
* field referring to the managed file.
* - image_field: array|null, the (1st and often only) image field item of
* entity that refers to the managed file (single field item, not the
* whole field value).
*/
function imagecache_actions_get_image_context($image, $data) {
// Store context about the image.
$image_context = array(
'effect_data' => $data,
'managed_file' => NULL,
'referring_entities' => array(),
'entity' => NULL,
'image_field' => NULL,
'effect_data' => $data,
'managed_file' => NULL,
'referring_entities' => array(),
'entity' => NULL,
'image_field' => NULL,
);
// Find the managed file object (at most 1 object as 'uri' is a unique index).
$managed_file = reset(file_load_multiple(array(), array('uri' => $image->source)));
$managed_file = file_load_multiple(array(), array('uri' => $image->source));
$managed_file = reset($managed_file);
if ($managed_file !== FALSE) {
$image_context['managed_file'] = $managed_file;
// And find the entities referring to this managed file.
$references = file_get_file_references($managed_file, NULL, FIELD_LOAD_CURRENT, 'image');
// And find the entities referring to this managed file, image fields first,
// then file fields (very specific use cases).
$references = file_get_file_references($managed_file, NULL, FIELD_LOAD_CURRENT, 'image')
+ file_get_file_references($managed_file, NULL, FIELD_LOAD_CURRENT, 'file');
if ($references) {
// Load referring entities.
// Load referring entities., keep track of 1st reference separately.
$entity_type_first = '';
$field_name_first = '';
foreach ($references as $field_name => $field_references) {
foreach ($field_references as $entity_type => $entity_stubs) {
$image_context['referring_entities'][$field_name][$entity_type] = entity_load($entity_type, array_keys($entity_stubs));
$entities = entity_load($entity_type, array_keys($entity_stubs));
if (!empty($entities)) {
$image_context['referring_entities'][$field_name][$entity_type] = $entities;
// Make it easy to access the '1st' entity and its referring image
// field, part 1: entity.
if (empty($entity_type_first)) {
$entity_type_first = $entity_type;
$field_name_first = $field_name;
$image_context['entity'] = reset($entities);
}
}
}
}
// Make it easy to access the '1st' entity and its referring image field.
reset($image_context['referring_entities']);
list($field_name, $field_references) = each($image_context['referring_entities']);
reset($field_references);
list($entity_type, $entities) = each($field_references);
reset($entities);
list(, $image_context['entity']) = each($entities);
$image_field = field_get_items($entity_type, $image_context['entity'], $field_name);
if ($image_field !== FALSE) {
// Get referring item
// Make it easy to access the '1st' entity and its referring image field,
// part 2: image field.
/** @var array|false $image_field */
$image_field = field_get_items($entity_type_first, $image_context['entity'], $field_name_first);
if ($image_field) {
// Get referring item.
foreach ($image_field as $image_field_value) {
if ($image_field_value['fid'] === $managed_file->fid) {
$image_context['image_field'] = $image_field_value;
break;
}
}
}
}
}
// @todo: support for media module, or is that based upon managed files?
return $image_context;
}
/**
* Returns information about the context, image style and image effect id, of
* the current image effect.
*
* Note that this information is not alterable, that is, it will not have any
* effect on the rest of the derivative image generation process including its
* subsequent effects.
*
* This information is called by effects that may need contextual information or
* that allow custom PHP:
* - Custom action.
* - Text from image alt or title.
* - Text with tokens.
* - Text from PHP code.
*
* This information is fetched by traversing the backtrace, looking for known
* functions that have the image style or effect as argument..
*
* @return array
* Array with keys 'image_style' and 'image_effect_id' pointing to the current
* image style (array) resp. image effect id (int).
*/
function imagecache_actions_get_image_effect_context() {
$result = array();
$backtrace = debug_backtrace();
foreach ($backtrace as $function_call) {
if ($function_call['function'] && $function_call['function'] === 'image_effect_apply') {
$result['image_effect_id'] = isset($function_call['args'][1]['ieid']) ? $function_call['args'][1]['ieid'] : NULL;
}
else if ($function_call['function'] && $function_call['function'] === 'image_style_create_derivative') {
$result['image_style'] = isset($function_call['args'][0]) ? $function_call['args'][0] : NULL;
}
if (count($result) === 2) {
break;
}
}
$result += array(
'image_effect_id' => NULL,
'image_style' => NULL,
);
return $result;
}
/**
* Given two imageapi objects with dimensions, and some positioning values,
* calculate a new x,y for the layer to be placed at.
@@ -172,8 +301,7 @@ function imagecache_actions_get_image_context($image, $data) {
* A keyed array of absolute x,y co-ordinates to place the layer at.
*/
function imagecache_actions_calculate_relative_position($base, $layer, $style) {
// both images should now have size info available.
// Both images should now have size info available.
if (isset($style['bottom'])) {
$ypos = imagecache_actions_calculate_offset('bottom', $style['bottom'], $base->info['height'], $layer->info['height']);
}
@@ -186,37 +314,55 @@ function imagecache_actions_calculate_relative_position($base, $layer, $style) {
if (isset($style['left'])) {
$xpos = imagecache_actions_calculate_offset('left', $style['left'], $base->info['width'], $layer->info['width']);
}
if (! isset($ypos)) {
// assume center
if (!isset($ypos)) {
// Assume center.
$ypos = ($base->info['height'] / 2) - ($layer->info['height'] / 2);
}
if (! isset($xpos)) {
// assume center
if (!isset($xpos)) {
// Assume center.
$xpos = ($base->info['width'] / 2) - ($layer->info['width'] / 2);
}
#dpm(__FUNCTION__ . " Calculated offsets");
#dpm(get_defined_vars());
// dpm(__FUNCTION__ . " Calculated offsets");
// dpm(get_defined_vars());
return array('x' => $xpos, 'y' => $ypos);
}
/**
* Calculates an offset from an edge.
*
* Positive numbers are IN from the edge, negative offsets are OUT.
*
* $keyword, $value, $base_size, $layer_size
* eg
* left,20 200, 100 = 20
* right,20 200, 100 = 80 (object 100 wide placed 20 px from the right = x=80)
*
* top,50%, 200, 100 = 50 (Object is centered when using %)
* top,20%, 200, 100 = -10
* bottom,-20, 200, 100 = 220
* right, -25%, 200, 100 = 200 (this ends up just off screen)
* Examples:
* - left, 20, 200, 100 = 20
* - right, 20, 200, 100 = 80 (object 100 wide placed 20px from the right)
* - top, 50%, 200, 100 = 50 (Object is centered when using %)
* - top, 20%, 200, 100 = -10
* - bottom, -20, 200, 100 = 220
* - right, -25%, 200, 100 = 200 (this ends up just off screen)
*
* Also, the value can be a string, eg "bottom-100", or "center+25%"
* @param string $keyword
* The edge to calculate the offset from. Can be one of: left, right, top,
* bottom, middle, center.
* @param string $value
* The value to offset with: can be:
* - a numeric value: offset in pixels
* - a percentage value: offset with a percentage of the $base_size.
* - a keyword indicating a pxiel size: left, right, top, bottom, middle,
* center.
* - an expression of the format: keyword +|- value[%], e.g. center+25%.
* @param int $base_size
* The size of the dimension. Used to calculate percentages of.
* @param int $layer_size
* The size of the canvas in the current dimension. The value to take for
* $keyword will be based on this value.
*
* @return int
*/
function imagecache_actions_calculate_offset($keyword, $value, $base_size, $layer_size) {
$offset = 0; // used to account for dimensions of the placed object
$offset = 0;
// Used to account for dimensions of the placed object.
$direction = 1;
$base = 0;
if ($keyword == 'right' || $keyword == 'bottom') {
@@ -229,16 +375,18 @@ function imagecache_actions_calculate_offset($keyword, $value, $base_size, $laye
$offset = -1 * ($layer_size / 2);
}
// Keywords may be used to stand in for numeric values
// Keywords may be used to stand in for numeric values.
switch ($value) {
case 'left':
case 'top':
$value = 0;
break;
case 'middle':
case 'center':
$value = $base_size / 2;
break;
case 'bottom':
case 'right':
$value = $base_size;
@@ -246,22 +394,24 @@ function imagecache_actions_calculate_offset($keyword, $value, $base_size, $laye
// Handle keyword-number cases like top+50% or bottom-100px,
// @see imagecache_actions_keyword_filter().
if (preg_match('/^(.+)([\+\-])(\d+)([^\d]*)$/', $value, $results)) {
if (preg_match('/^([a-z]+) *([+-]) *(\d+)((px|%)?)$/', $value, $results)) {
list(, $value_key, $value_mod, $mod_value, $mod_unit) = $results;
if ($mod_unit == '%') {
$mod_value = $mod_value / 100 * $base_size;
}
$mod_direction = ($value_mod == '-') ? -1 : + 1;
$mod_direction = ($value_mod == '-') ? -1 : +1;
switch ($value_key) {
case 'left':
case 'top':
default:
$mod_base = 0;
break;
case 'middle':
case 'center':
$mod_base = $base_size / 2;
break;
case 'bottom':
case 'right':
$mod_base = $base_size;
@@ -271,14 +421,17 @@ function imagecache_actions_calculate_offset($keyword, $value, $base_size, $laye
return $modified_value;
}
// handle % values
if (substr($value, strlen($value) -1, 1) == '%') {
$value = intval($value / 100 * $base_size);
// Handle % values.
if (substr($value, -1) === '%') {
// Explicitly convert $value to prevent warnings in PHP 7.1.
$value = intval((int) $value / 100 * $base_size);
$offset = -1 * ($layer_size / 2);
}
$value = $base + ($direction * $value);
// $value may contain 'px' at the end: explicitly convert to prevent warnings
// in PHP 7.1.
$value = $base + ($direction * (int) $value);
// Add any extra offset to position the item
// Add any extra offset to position the item.
return $value + $offset;
}
@@ -329,9 +482,9 @@ function imagecache_actions_hex2rgba($hex) {
$g = hexdec($g);
$b = hexdec($b);
$a = hexdec($a);
// alpha over 127 is illegal. assume they meant half that.
// Alpha over 127 is illegal. assume they meant half that.
if ($a > 127) {
$a = (int) $a/2;
$a = (int) $a / 2;
}
return array('red' => $r, 'green' => $g, 'blue' => $b, 'alpha' => $a);
}
@@ -358,8 +511,8 @@ function imagecache_actions_hex2rgba($hex) {
* @return int
*/
function imagecache_actions_keyword_filter($value, $base_size, $layer_size) {
// See above for the patterns this matches
if (! preg_match('/([a-z]*)([\+\-]?)(\d*)([^\d]*)/', $value, $results) ) {
// See above for the patterns this matches.
if (!preg_match('/([a-z]*) *([+-]?) *(\d*)((px|%)?)/', $value, $results)) {
trigger_error("imagecache_actions had difficulty parsing the string '$value' when calculating position. Please check the syntax.", E_USER_WARNING);
}
list(, $keyword, $plusminus, $value, $unit) = $results;
@@ -368,83 +521,28 @@ function imagecache_actions_keyword_filter($value, $base_size, $layer_size) {
}
/**
* @deprecated
* Computes a length based on a length specification and an actual length.
*
* Given a file path relative the default file scheme, tries to locate it and,
* is successful, finds all fields that use it.
* Examples:
* (50, 400) returns 50; (50px, 400) returns 50; (50%, 400) returns 200;
* (50, null) returns 50; (50%, null) returns null;
* (null, null) returns null; (null, 100) returns null.
*
* @param string $filepath
* Actually a Drupal file URI, probably.
* @param bool $load_entity
* Whether to return whole entities or just the identifying fields of them.
*
* @return array
* A nested array of basic entity data, grouped by entity type and field name.
* Empty array if no file fields are referring the given path.
*/
function imagecache_actions_fields_from_filepath($filepath, $load_entity = TRUE) {
if (!module_exists('file')) {
return array();
}
// Unsure if we are given a real filepath (the normal assumption) or a
// Drupal scheme URI. Resolve either.
if (!file_valid_uri($filepath)) {
$filepath = file_build_uri($filepath);
}
$files = file_load_multiple(array(), array('uri' => $filepath));
if ($files) {
$fields = array();
foreach ($files as $fid => $file) {
$references = file_get_file_references($file, NULL, FIELD_LOAD_CURRENT, 'image');
$fields[$fid] = $references;
}
if ($load_entity) {
// These references are pretty low on information. Load the actual nodes/entities too.
imagecache_actions_entities_from_references($fields);
}
return $fields;
}
return array();
}
/**
* @deprecated
*
* Load additional data - Fully load the entities that actually use the given file, with all their data.
*
* Replaces the full entity object in place of the placeholder object that file_get_file_references() gives us.
*/
function imagecache_actions_entities_from_references(&$fields) {
foreach ($fields as $fid => $field_ids) {
foreach ($field_ids as $field_id => $entity_types) {
foreach ($entity_types as $entity_type => $entity_instances) {
#$entities = entity_load($entity_type, array_keys($entity_instances));
foreach ($entity_instances as $entity_id => $entity) {
$entities = entity_load($entity_type, array($entity_id));
$entity = reset($entities);
// Add this extra data to the return info, replacing the lightweight version
$fields[$fid][$field_id][$entity_type][$entity_id] = $entity;
} // All actual entities
} // All types of entity that ref the file
} // All references to this file
} // All entries for this file found in the db (expected to be only 1)
}
/**
* @param string $value
* @param int|null $current_pixels
* @param string|null $length_specification
* The length specification. An integer constant optionally followed by 'px'
* or '%'.
* @param int|null $current_length
* The current length. May be null.
*
* @return int|null
*/
function imagecache_actions_percent_filter($value, $current_pixels) {
if (strpos($value, '%') !== FALSE) {
$value = $current_pixels !== NULL ? str_replace('%', '', $value) * 0.01 * $current_pixels : NULL;
function imagecache_actions_percent_filter($length_specification, $current_length) {
if (strpos($length_specification, '%') !== FALSE) {
$length_specification = $current_length !== NULL ? str_replace('%', '', $length_specification) * 0.01 * $current_length : NULL;
}
return $value;
else {
// Strips 'px' if available.
$length_specification = (int) $length_specification;
}
return $length_specification;
}