1 image.module | image_style_deliver($style, $scheme) |
Menu callback; Given a style and image path, generate a derivative.
After generating an image, transfer it to the requesting agent.
Parameters
$style: The image style
$scheme: The file scheme, for example 'public' for public files.
File
- core/
modules/ image/ image.module, line 691 - Exposes global functionality for creating image styles.
Code
function image_style_deliver($style, $scheme) {
// Check that the style is defined and the scheme is valid.
if (!$style || !file_stream_wrapper_valid_scheme($scheme)) {
backdrop_add_http_header('Status', '400 Bad Request');
backdrop_add_http_header('Content-Type', 'text/html; charset=utf-8');
print t('Invalid request.');
backdrop_exit();
}
$args = func_get_args();
array_shift($args);
array_shift($args);
$target = implode('/', $args);
$image_uri = $scheme . '://' . $target;
$image_uri = file_uri_normalize_dot_segments($image_uri);
$derivative_uri = image_style_path($style['name'], $image_uri);
$derivative_scheme = file_uri_scheme($derivative_uri);
// Image styles are not allowed to modify previously generated style images.
if (strpos($image_uri, $scheme . '://styles/') === 0) {
backdrop_add_http_header('Status', '400 Bad Request');
backdrop_add_http_header('Content-Type', 'text/html; charset=utf-8');
print t('Image styles are not allowed to modify images generated by other styles.');
backdrop_exit();
}
$core_schemes = array('public', 'private', 'temporary');
$additional_public_schemes = array_diff((array) config_get('system.core', 'file_additional_public_schemes'), $core_schemes);
$public_schemes = array_merge(array('public'), $additional_public_schemes);
$is_public = in_array($derivative_scheme, $public_schemes, TRUE);
if ($scheme == 'private' && file_exists($derivative_uri)) {
file_download($scheme, file_uri_target($derivative_uri));
}
// Other non-public schemes may add additional headers and control access to
// the file.
if (!$is_public) {
$headers = file_download_headers($image_uri);
if (empty($headers)) {
return MENU_ACCESS_DENIED;
}
if (count($headers)) {
foreach ($headers as $name => $value) {
backdrop_add_http_header($name, $value);
}
}
}
// Check if image_style_url() marked this image for creation.
$allowed_uris = image_style_get_allowed_uris();
if (!isset($allowed_uris[$derivative_uri])) {
// If an unknown request, limit using locking.
$flood_lock_name = image_style_flood_lock_name();
$flood_lock_acquired = (bool) $flood_lock_name;
if (!$flood_lock_acquired) {
backdrop_add_http_header('Status', '403 Access Denied');
backdrop_add_http_header('Content-Type', 'text/html; charset=utf-8');
print t('Image generation throttled after reaching maximum.');
backdrop_exit();
}
}
// Confirm that the original source image exists before trying to process it.
if (!_image_source_image_exists($image_uri)) {
watchdog('image', 'Source image at %source_image_path not found while trying to generate derivative image at %derivative_path.', array('%source_image_path' => $image_uri, '%derivative_path' => $derivative_uri));
backdrop_add_http_header('Status', '404 Not Found');
backdrop_add_http_header('Content-Type', 'text/html; charset=utf-8');
print t('Source image not found.');
backdrop_exit();
}
// Don't start generating the image if the derivative already exists or if
// generation is in progress in another thread.
$generation_lock_name = 'image_style_deliver:' . $style['name'] . ':' . backdrop_hash_base64($image_uri);
if (!file_exists($derivative_uri)) {
$generation_lock_acquired = lock_acquire($generation_lock_name);
if (!$generation_lock_acquired) {
// Tell client to retry again in 3 seconds. Currently no browsers are known
// to support Retry-After.
backdrop_add_http_header('Status', '503 Service Unavailable');
backdrop_add_http_header('Content-Type', 'text/html; charset=utf-8');
backdrop_add_http_header('Retry-After', 3);
print t('Image generation in progress. Try again shortly.');
backdrop_exit();
}
}
// Try to generate the image, unless another thread just did it while we were
// acquiring the lock.
$success = file_exists($derivative_uri) || image_style_create_derivative($style, $image_uri, $derivative_uri);
// Release all locks.
if (!empty($flood_lock_acquired)) {
lock_release($flood_lock_name);
}
if (!empty($generation_lock_acquired)) {
lock_release($generation_lock_name);
}
if ($success) {
image_style_remove_allowed_uri($derivative_uri);
$image = image_load($derivative_uri);
file_transfer($image->source, array('Content-Type' => $image->info['mime_type'], 'Content-Length' => $image->info['file_size']));
}
else {
watchdog('image', 'Unable to generate the derived image located at %path.', array('%path' => $derivative_uri));
backdrop_add_http_header('Status', '500 Internal Server Error');
backdrop_add_http_header('Content-Type', 'text/html; charset=utf-8');
print t('Error generating image.');
backdrop_exit();
}
}