acquia_dam-1.0.0-rc1/src/EmbedCodeUrlBuilder.php
src/EmbedCodeUrlBuilder.php
<?php namespace Drupal\acquia_dam; /** * Create widen specific image url. */ final class EmbedCodeUrlBuilder { /** * Image formats available on the WIDEN end. */ const AVAILABLE_IMAGE_FORMATS = [ 'gif', 'jpg', 'png', 'web', 'webp', 'jpeg', ]; /** * Converts image effect plugin configuration to query parameters. * * @param array $effects * Array of effects from a particular style. * @param array $image_properties * Image properties. * @param string $uri * Image uri. * * @return array * Query parameters for embed code URL. * * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException */ public static function mapImageEffects(array $effects, array $image_properties, string $uri): array { $anchor_mapping = [ 'center-center' => 'c', 'top' => 'n', 'right-top' => 'ne', 'right' => 'e', 'right-bottom' => 'se', 'bottom' => 's', 'left-bottom' => 'sw', 'left' => 'w', 'left-top' => 'nw', ]; $values = []; $values['format'] = 'web'; foreach ($effects as $effect) { switch ($effect['id']) { case 'focal_point_scale_and_crop': $values['crop'] = 'yes'; $values['w'] = $effect['data']['width']; $values['h'] = $effect['data']['height']; break; case 'focal_point_crop': if (isset($effect['data']['crop_type'])) { /** @var \Drupal\crop\CropInterface $crop */ if (!$crop = \Drupal::entityTypeManager() ->getStorage('crop') ->getCrop($uri, $effect['data']['crop_type'])) { \Drupal::logger('acquia_dam')->error(sprintf('Cannot find crop entity for %s', $uri)); break; } $crop_width = $effect['data']['width']; $crop_height = $effect['data']['height']; /** @var \Drupal\acquia_dam\ImageStyleHelper $image_style_helper */ $image_style_helper = \Drupal::service('acquia_dam.image_style_support'); // Need to recalculate the values if those are higher than 2048. [$calculated_with, $calculated_height] = $image_style_helper->handleLargeImages($image_properties['width'], $image_properties['height']); // If cropped is bigger than calculated don't do anything. if ($crop_width >= $calculated_with || $crop_height >= $calculated_height) { break; } $position = $crop->position(); $values['crop'] = 'yes'; $values['w'] = $crop_width; $values['h'] = $crop_height; $values['a'] = self::calculateAnchorPointForWiden($position['x'], $crop_width, $calculated_with) . ',' . self::calculateAnchorPointForWiden($position['y'], $crop_height, $calculated_height); } break; case 'image_convert': if (in_array($effect['data']['extension'], self::AVAILABLE_IMAGE_FORMATS, TRUE)) { $values['format'] = $effect['data']['extension']; } break; case 'image_rotate': $values['r'] = $effect['data']['degrees']; if ($effect['data']['bgcolor'] !== "") { $values['color'] = str_replace('#', '', $effect['data']['bgcolor']); } break; case 'image_resize': $values['w'] = self::getDimensionValue($effect['data']['width']); $values['h'] = self::getDimensionValue($effect['data']['height']); break; case 'image_crop': $values['crop'] = 'yes'; $values['k'] = $anchor_mapping[$effect['data']['anchor']]; $values['w'] = self::getDimensionValue($effect['data']['width']); $values['h'] = self::getDimensionValue($effect['data']['height']); break; case 'image_scale': if ($effect['data']['width'] && $image_properties['aspect_ratio'] >= 1) { $values['w'] = self::calculateScaleDimensions( self::getDimensionValue($image_properties['width']), self::getDimensionValue($effect['data']['width']), $effect['data']['upscale'] ); break; } // If width is not set or set but ratio lower than 1. if ($effect['data']['height']) { $values['h'] = self::calculateScaleDimensions( self::getDimensionValue($image_properties['height']), self::getDimensionValue($effect['data']['height']), $effect['data']['upscale'] ); } break; case 'image_scale_and_crop': $values['crop'] = 'yes'; $values['k'] = $anchor_mapping[$effect['data']['anchor']] ?? 'c'; $values['w'] = self::calculateScaleDimensions( $image_properties['width'], self::getDimensionValue($effect['data']['width']), TRUE ); $values['h'] = self::calculateScaleDimensions( $image_properties['height'], self::getDimensionValue($effect['data']['height']), TRUE ); break; } } return $values; } /** * Scale dimension calculation. * * @param int $original_dimension * Original image dimension. * @param int $scale_dimension * Requested scale dimension. * @param bool $upscale * Allow upscale. * * @return int * Returns the correct scale dimension. */ protected static function calculateScaleDimensions(int $original_dimension, int $scale_dimension, bool $upscale): int { if ($original_dimension > $scale_dimension) { return $scale_dimension; } if ($upscale && $scale_dimension > $original_dimension) { return $scale_dimension; } return $original_dimension; } /** * Gets a dimension value. * * @param int $number * Current dimension value. * * @return int * Returns the current value or maximum allowed if the current is higher. */ protected static function getDimensionValue(int $number): int { return $number > 2048 ? 2048 : $number; } /** * Anchor point calculation. * * We use position coordinates to calculate the proper anchor point for WIDEN. * Using anchor() method returns position values since focal point does not * save crop with and height value. * * @param int $coordinate * Crop position x or y coordinate. * @param int $crop_length * Width or height of the cropped image. * @param int $origin_length * Width or height of the original image. * * @return int * Returns the calculated anchor point. */ protected static function calculateAnchorPointForWiden(int $coordinate, int $crop_length, int $origin_length): int { if ($coordinate - $crop_length / 2 <= 0) { return 0; } if ($coordinate + $crop_length / 2 > $origin_length) { return $origin_length - $crop_length; } return $coordinate - $crop_length / 2; } }