There seems to be some assumptions in the fn_image_to_display function, as well as the exim get image one.
Here is a fix, such that when a product does not appear to have a 'detailed image', it will fall back to the 'icon image', rather than just no image, which it seems to do - why would we want no image if it has one?
/app/controllers/backend/exim.php - Line 1411 - replace function:
function fn_exim_get_image_url($product_id, $object_type, $pair_type, $get_icon, $get_detailed, $lang_code)
{
$image_pair = fn_get_image_pairs($product_id, $object_type, $pair_type, true, true, $lang_code);
$image_data = fn_image_to_display($image_pair, Registry::get('settings.Thumbnails.product_details_thumbnail_width'), Registry::get('settings.Thumbnails.product_details_thumbnail_height'));
$protocol = fn_get_storefront_protocol();
return !empty($image_data) ? $image_data[$protocol . '_detailed_image_path'] : '';
}
Then in /app/functions/fn.images.php - Line 872 - replace function:
function fn_image_to_display($images, $image_width = 0, $image_height = 0)
{
if (empty($images)) {
return array();
}
$image_data = array();
// image pair passed
if (!empty($images['icon']) || !empty($images['detailed'])) {
if (!empty($images['icon'])) {
$original_width = $images['icon']['image_x'];
$original_height = $images['icon']['image_y'];
$image_path = $images['icon']['image_path'];
$absolute_path = $images['icon']['absolute_path'];
$relative_path = $images['icon']['relative_path'];
} else {
$original_width = $images['detailed']['image_x'];
$original_height = $images['detailed']['image_y'];
$image_path = $images['detailed']['image_path'];
$absolute_path = $images['detailed']['absolute_path'];
$relative_path = $images['detailed']['relative_path'];
}
$detailed_image_path = !empty($images['detailed']['image_path']) ? $images['detailed']['http_image_path'] : $images['icon']['http_image_path'];
$https_detailed_image_path = !empty($images['detailed']['image_path']) ? $images['detailed']['https_image_path'] : $images['icon']['https_image_path'];
$alt = !empty($images['icon']['alt']) ? $images['icon']['alt'] : $images['detailed']['alt'];
// single image passed only
} else {
$original_width = $images['image_x'];
$original_height = $images['image_y'];
$image_path = $images['image_path'];
$alt = $images['alt'];
$detailed_image_path = '';
$https_detailed_image_path = '';
$absolute_path = $images['absolute_path'];
$relative_path = $images['relative_path'];
}
if (!empty($image_height) && empty($image_width) && !empty($original_height)) {
$image_width = intval($image_height * $original_width / $original_height);
}
if (!empty($image_width) && empty($image_height) && !empty($original_width)) {
$image_height = intval($image_width * $original_height / $original_width);
}
if (!empty($image_width) && !empty($relative_path) && !empty($absolute_path)) {
$image_path = fn_generate_thumbnail($relative_path, $image_width, $image_height, Registry::get('config.tweaks.lazy_thumbnails'));
} else {
$image_width = $original_width;
$image_height = $original_height;
}
if (!empty($image_path)) {
$image_data = array(
'image_path' => $image_path,
'http_detailed_image_path' => $detailed_image_path,
'https_detailed_image_path' => $https_detailed_image_path,
'alt' => $alt,
'width' => $image_width,
'height' => $image_height,
'absolute_path' => $absolute_path,
'generate_image' => strpos($image_path, '&image_path=') !== false // FIXME: dirty checking
);
}
/**
* Additionally processes image data
*
* @param array $image_data Image data
* @param array $images Array with initial images
* @param $image_width Result image width
* @param $image_height Result image height
*/
fn_set_hook('image_to_display_post', $image_data, $images, $image_width, $image_height);
return $image_data;
}
Anyone see any reason against this? If not, should this be sorted?