svg_image.module in Svg Image 7
Same filename and directory in other branches
File
svg_image.moduleView source
<?php
/**
* Provides SVG support to image fields.
*/
require_once 'includes/svg_image.field.inc';
define('SVG_IMAGE_DEFAULT_WIDTH', 200);
define('SVG_IMAGE_DEFAULT_HEIGHT', 200);
/**
* Preprocess function for theme_image_style().
*
* If theme_image_style() is called without setting explicit height/width for
* an SVG image, attempt to set those dimensions. This helps in particular when
* uploading an image for the first time in a content form.
*/
function svg_image_preprocess_image_style(&$variables) {
$uri = $variables['path'];
$is_svg = svg_image_is_svg($uri);
if ($is_svg && empty($variables['width']) && empty($variables['height'])) {
if ($dimensions = svg_image_get_dimensions($uri)) {
$variables['width'] = $dimensions['width'];
$variables['height'] = $dimensions['height'];
}
else {
$variables['width'] = SVG_IMAGE_DEFAULT_WIDTH;
$variables['height'] = SVG_IMAGE_DEFAULT_HEIGHT;
}
}
}
/**
* Implements hook_file_presave().
*
* Set the dimensions in the "metadata" property used by File Entity module.
*/
function svg_image_file_presave($file) {
if (svg_image_is_svg($file->uri) && isset($file->metadata)) {
$svg_dimensions = svg_image_get_dimensions($file->uri);
if ($svg_dimensions) {
$file->metadata['width'] = $svg_dimensions['width'];
$file->metadata['height'] = $svg_dimensions['height'];
}
}
}
/**
* Implements hook_field_attach_presave().
*
* When saving a entity, this hook is called to make any adjustments to the
* entire entity's fields before attempting to write to the database. When
* Image module encounters an SVG image, it sets the height and width values
* to be empty strings, which would cause a database constraint error when
* a string is inserted into an integer column.
*
* This implementation loops through all fields attached to an entity, finds
* those that are an image field, then sets the width and height values within
* that field. These changes are made by reference, so they are in the $entity
* object when Field module saves to the database.
*/
function svg_image_field_attach_presave($entity_type, $entity) {
// Get information about which fields are on this type of entity.
list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
$bundle_field_info = field_info_instances($entity_type, $bundle);
// Loop through each of the fields and find those that are image fields.
foreach ($bundle_field_info as $field_name => $instance_info) {
$field_info = field_info_field($field_name);
if ($field_info['type'] === 'image') {
// Rely on locale API to retrieve the correct langcode
$langcode = field_is_translatable($entity_type, $field_info) ? field_language($entity_type, $entity, $field_name) : LANGUAGE_NONE;
if (!isset($entity->{$field_name}[$langcode])) {
continue;
}
// Update the field values (by reference) for SVG images.
$field_values =& $entity->{$field_name}[$langcode];
foreach ($field_values as $delta => $field_value) {
if (!isset($field_value['fid'])) {
continue;
}
$file = file_load($field_value['fid']);
if ($file && svg_image_is_svg($file->uri)) {
// Set default 100x100 as a default values.
$field_values[$delta]['width'] = SVG_IMAGE_DEFAULT_WIDTH;
$field_values[$delta]['height'] = SVG_IMAGE_DEFAULT_HEIGHT;
if ($svg_dimensions = svg_image_get_dimensions($file->uri)) {
$field_values[$delta]['width'] = $svg_dimensions['width'];
$field_values[$delta]['height'] = $svg_dimensions['height'];
}
}
}
}
}
}
/**
* Implements hook_file_url_alter().
*
* Prevent image_style_url() from using a different URL for SVG images. Because
* image styles cannot operate on SVGs, set the URL back to the original image.
* This affects theme_image_style(), which normally would point to a new image.
*/
function svg_image_file_url_alter(&$url) {
// If this is an SVG image in the styles directory...
if (strpos($url, '/styles/') && strpos($url, '.svg')) {
// Remove the styles directory portions and use the original image URL.
$url = preg_replace('!/styles/.*?/.*?/!', '/', $url);
}
}
/**
* Get an SVG image's defined dimensions.
*
* @param string $uri
* The URI or path to an SVG image.
*
* @return array|FALSE
* An array containing the keys "width" and "height" as integer values. If the
* image is an SVG but no set dimensions are available, these keys will have
* NULL values. If the image is not an SVG, FALSE will be return.
*/
function svg_image_get_dimensions($uri) {
// Safety check.
if (!svg_image_is_svg($uri)) {
return FALSE;
}
// Return cached dimensions if already retrieved once this request.
$cached_images =& drupal_static(__FUNCTION__, array());
if (isset($cached_images[$uri])) {
return $cached_images[$uri];
}
// Workaround for a getting a width and height. It cannot be null and need to
// be defined for the every image. So - if we got SVG file without the
// dimensions defined in attributes it should be defined from our side to
// avoid an exception.
// @todo add a variable which defines this values.
$svg_dimensions = array(
'width' => SVG_IMAGE_DEFAULT_WIDTH,
'height' => SVG_IMAGE_DEFAULT_HEIGHT,
);
$file_contents = file_get_contents($uri);
if ($file_contents) {
$svg = simplexml_load_string($file_contents);
foreach ($svg
->attributes() as $attribute => $value) {
if ($attribute === 'width' || $attribute === 'height') {
$svg_dimensions[$attribute] = (int) $value;
}
}
}
// Save values to static cache.
$cached_images[$uri] = $svg_dimensions;
return $svg_dimensions;
}
/**
* Determine if a file URI is an SVG image based on its file extension.
*
* @param string $uri
* A path or URI to an image.
* @return bool
* TRUE if the image is an SVG. FALSE if it is not.
*/
function svg_image_is_svg($uri) {
$mimetype = file_get_mimetype($uri);
return $mimetype === 'image/svg+xml';
}
Functions
Name | Description |
---|---|
svg_image_field_attach_presave | Implements hook_field_attach_presave(). |
svg_image_file_presave | Implements hook_file_presave(). |
svg_image_file_url_alter | Implements hook_file_url_alter(). |
svg_image_get_dimensions | Get an SVG image's defined dimensions. |
svg_image_is_svg | Determine if a file URI is an SVG image based on its file extension. |
svg_image_preprocess_image_style | Preprocess function for theme_image_style(). |
Constants
Name | Description |
---|---|
SVG_IMAGE_DEFAULT_HEIGHT | |
SVG_IMAGE_DEFAULT_WIDTH |