/**
* Choose an image variation based on the transformations and the original size of the image
*
* @param EventInterface $event The current event
*/
public function chooseVariation(EventInterface $event)
{
$request = $event->getRequest();
$response = $event->getResponse();
$publicKey = $request->getPublicKey();
$imageIdentifier = $request->getImageIdentifier();
// Fetch the original width / height of the image to use for ratio calculations
$image = $response->getModel();
$imageWidth = $image->getWidth();
$imageHeight = $image->getHeight();
// Fetch the transformations from the request and find the max width used in the set
$transformations = $request->getTransformations();
if (!$transformations) {
// No transformations in the request
return;
}
$maxWidth = $this->getMaxWidth($imageWidth, $imageHeight, $transformations);
if (!$maxWidth) {
// No need to use a variation based on the set of transformations
return;
}
// Fetch the index of the transformation that decided the max width, and the width itself
list($transformationIndex, $maxWidth) = each($maxWidth);
if ($maxWidth >= $imageWidth) {
// The width is the same or above the original, use the original
return;
}
// WE HAVE A WINNER! Find the best variation. The width of the variation is the first
// available one above the $maxWidth value
$variation = $this->database->getBestMatch($publicKey, $imageIdentifier, $maxWidth);
if (!$variation) {
// Could not find any :(
return;
}
// Now that we have a variation we can use we need to adjust some of the transformation
// parameters.
$event->getManager()->trigger('image.transformations.adjust', ['transformationIndex' => $transformationIndex, 'ratio' => $imageWidth / $variation['width']]);
// Fetch the image variation blob from the storage adapter
$imageBlob = $this->storage->getImageVariation($publicKey, $imageIdentifier, $variation['width']);
if (!$imageBlob) {
// The image blob does not exist in the storage, which it should. Trigger an error and
// return
trigger_error('Image variation storage is not in sync with the image variation database', E_USER_WARNING);
return;
}
// Set some data that the storage operations listener usually sets, since that will be
// skipped since we have an image variation
$lastModified = $event->getStorage()->getLastModified($publicKey, $imageIdentifier);
$response->setLastModified($lastModified);
// Update the model
$model = $response->getModel();
$model->setBlob($imageBlob)->setWidth($variation['width'])->setHeight($variation['height']);
// Set a HTTP header that informs the user agent on which image variation that was used in
// the transformations
$response->headers->set('X-Imbo-ImageVariation', $variation['width'] . 'x' . $variation['height']);
// Stop the propagation of this event
$event->stopPropagation();
$event->getManager()->trigger('image.loaded');
}