Skip to content

Commit

Permalink
* More fixes for srcset generation.
Browse files Browse the repository at this point in the history
* Ability to turn off `ixlib` and `wpsize` query parameters for imgix image URLs.  To disable these query parameters, toggle *Remove Extra Query Variables* off in Imgix settings.
* You can now specify the default cropping mode and crop origin for imgix images in the *Imgix Settings*.  This crop mode and origin will be overridden for manually cropped images or images that have had their crop mode set in the *Image Editor*.
  • Loading branch information
jawngee committed May 5, 2021
1 parent 2d28cb3 commit dc901e6
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 62 deletions.
1 change: 1 addition & 0 deletions classes/Tools/Debugging/System/SystemCompatibilityTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class SystemCompatibilityTool extends Tool {
'wp_update_attachment_metadata',
'wp_handle_upload_prefilter',
'wp_handle_upload',
'wp_calculate_image_srcset',
];


Expand Down
39 changes: 37 additions & 2 deletions classes/Tools/Imgix/ImgixTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
use MediaCloud\Plugin\Wizard\WizardBuilder;
use MediaCloud\Vendor\FasterImage\FasterImage;
use MediaCloud\Vendor\Imgix\UrlBuilder;
use function MediaCloud\Plugin\Utilities\anyIsSet;
use function MediaCloud\Plugin\Utilities\arrayContainsAny;
use function MediaCloud\Plugin\Utilities\arrayPath;

if(!defined('ABSPATH')) {
Expand Down Expand Up @@ -239,6 +241,23 @@ private function buildImgixParams($params, $mimetype = '') {
unset($params['padding-width']);
unset($params['padding-color']);

if (!empty($this->settings->cropMode) && !anyIsSet($params, 'rect', 'fp-x', 'fp-y')) {
$position = $this->settings->cropPosition;

if (isset($params['crop'])) {
$cropParts = explode(',', $params['crop']);
if (arrayContainsAny($cropParts, ['faces', 'focalpoint', 'edges', 'entropy'])) {
return $params;
}

if (arrayContainsAny($cropParts, ['left', 'top', 'right', 'bottom', 'center'])) {
$position = $params['crop'];
}
}

$params['crop'] = str_replace('position', $position, $this->settings->cropMode);
}

return $params;
}

Expand Down Expand Up @@ -271,6 +290,10 @@ public function buildSizedImage($id, $size) {
$imgix->setSignKey($key);
}

if (!empty($this->settings->removeQueryVars)) {
$imgix->setIncludeLibraryParam(false);
}

if (isset($size['crop'])) {
$is_crop = !empty($size['crop']);
} else {
Expand Down Expand Up @@ -425,6 +448,10 @@ public function buildImage($id, $size, $params = null, $skipParams = false, $mer
$imgix->setSignKey($key);
}

if (!empty($this->settings->removeQueryVars)) {
$imgix->setIncludeLibraryParam(false);
}

if($size == 'full' && !$newSize) {
if(!isset($meta['width']) || !isset($meta['height'])) {
return false;
Expand Down Expand Up @@ -667,7 +694,7 @@ public function buildImage($id, $size, $params = null, $skipParams = false, $mer
$params = array_merge($params, $mergeParams);
}

if($size && !is_array($size)) {
if($size && !is_array($size) && empty($this->settings->removeQueryVars)) {
$params['wpsize'] = $size;
}

Expand Down Expand Up @@ -703,6 +730,10 @@ public function urlForStorageMedia($key, $params = []) {
$imgix->setSignKey($key);
}

if (!empty($this->settings->removeQueryVars)) {
$imgix->setIncludeLibraryParam(false);
}

return $imgix->createURL(str_replace(['%2F', '%2540', '%40'], ['/', '@', '@'], urlencode($key)), $params);
}

Expand Down Expand Up @@ -1031,7 +1062,11 @@ public function urlForKey($imageKey) {
$imgix->setSignKey($key);
}

return $imgix->createURL($imageKey, []);
if (!empty($this->settings->removeQueryVars)) {
$imgix->setIncludeLibraryParam(false);
}

return $imgix->createURL($imageKey, []);
}

//endregion
Expand Down
6 changes: 6 additions & 0 deletions classes/Tools/Imgix/ImgixToolSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
* @property bool renderSVG
* @property bool detectFaces
* @property bool generateThumbnails
* @property bool removeQueryVars
* @property ?string cropMode
* @property ?string cropPosition
*/
class ImgixToolSettings extends DynamicImagesToolSettings {
private $_imgixDomains = null;
Expand All @@ -50,6 +53,9 @@ class ImgixToolSettings extends DynamicImagesToolSettings {
'generateThumbnails' => ['mcloud-imgix-generate-thumbnails', null, true],
'imageQuality' => ['mcloud-imgix-default-quality', null, null],
'renderSVG' => ['mcloud-imgix-render-svg-files', null, false],
'removeQueryVars' => ['mcloud-imgix-remove-extra-variables', null, false],
'cropMode' => ['mcloud-imgix-crop-mode', null, null],
'cropPosition' => ['mcloud-imgix-crop-position', null, 'center'],
];

public function __construct() {
Expand Down
98 changes: 47 additions & 51 deletions classes/Tools/Storage/StorageContentHooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use MediaCloud\Plugin\Tools\Debugging\DebuggingToolSettings;
use MediaCloud\Plugin\Utilities\Environment;
use MediaCloud\Plugin\Utilities\Logging\Logger;
use function MediaCloud\Plugin\Utilities\anyEmpty;
use function MediaCloud\Plugin\Utilities\arrayPath;

if (!defined('ABSPATH')) { header('Location: /'); die; }
Expand Down Expand Up @@ -1074,6 +1075,17 @@ private function replaceImageInContent($id, $data, $content) {
//endregion

//region Srcset

private function getAspectRatio($width, $height) {
if ($width < $height) {
return 0;
} else if ($width == $height) {
return 1;
} else {
return 2;
}
}

/**
* Filters an image’s ‘srcset’ sources. (https://core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/media.php#L1203)
*
Expand Down Expand Up @@ -1103,79 +1115,63 @@ public function calculateSrcSet($sources, $size_array, $image_src, $image_meta,

$attachment_id = apply_filters('wpml_object_id', $attachment_id, 'attachment', true);

if ($this->allSizes == null) {
if (empty($this->allSizes)) {
$this->allSizes = ilab_get_image_sizes();
}

if ($size_array[0] < $size_array[1]) {
$srcAspect = 0;
} else if ($size_array[0] == $size_array[1]) {
$srcAspect = 1;
} else {
$srcAspect = 2;
$srcAspect = $this->getAspectRatio($size_array[0], $size_array[1]);

$imageWidth = intval($image_meta['width']);
$imageHeight = intval($image_meta['height']);

if (anyEmpty($imageWidth, $imageHeight)) {
return [];
}

$allSizesNames = array_keys($this->allSizes);
$newSources = [];

foreach($image_meta['sizes'] as $sizeName => $sizeData) {
$width = intval($sizeData['width']);
$height = intval($sizeData['height']);
$width = intval($this->allSizes[$sizeName]['width']);
$height = intval($this->allSizes[$sizeName]['height']);

if ($width < $height) {
$sizeAspect = 0;
} else if ($width == $height) {
$sizeAspect = 1;
$width = ($width === 0) ? 99999 : $width;
$height = ($height === 0) ? 99999 : $height;

if (empty($this->allSizes[$sizeName]['crop'])) {
$sizeDim = sizeToFitSize($imageWidth, $imageHeight, $width, $height);
} else {
$sizeAspect = 2;
$sizeDim = [$width, $height];
}

if (isset($sources[$width])) {
if (($sizeAspect == $srcAspect) && in_array($sizeName, $allSizesNames)) {
$src = wp_get_attachment_image_src($attachment_id, $sizeName);
$sizeAspect = $this->getAspectRatio($sizeDim[0], $sizeDim[1]);

if(is_array($src)) {
// fix for wpml
$url = preg_replace('/&lang=[aA-zZ0-9]+/m', '', $src[0]);
$sources[$width]['url'] = $url;
} else {
unset($sources[$width]);
}
} else {
unset($sources[$width]);
if (isset($sources["{$sizeDim[0]}"]) && ($sizeAspect == $srcAspect) && in_array($sizeName, $allSizesNames)) {
$src = wp_get_attachment_image_src($attachment_id, $sizeName);

if(is_array($src)) {
// fix for wpml
$url = preg_replace('/&lang=[aA-zZ0-9]+/m', '', $src[0]);
$newSources["{$sizeDim[0]}"] = $sources["{$sizeDim[0]}"];
$newSources["{$sizeDim[0]}"]['url'] = $url;
}
}
}

if(isset($image_meta['width'])) {
$width = intval($image_meta['width']);
$height = intval($image_meta['height']);

if ($width < $height) {
$sizeAspect = 0;
} else if ($width == $height) {
$sizeAspect = 1;
} else {
$sizeAspect = 2;
}
$imageAspect = $this->getAspectRatio($imageWidth, $imageHeight);

if(isset($sources[$width])) {
if ($sizeAspect == $srcAspect) {
$src = wp_get_attachment_image_src($attachment_id, 'full');
if(isset($sources["{$imageWidth}"]) && ($imageAspect == $srcAspect)) {
$src = wp_get_attachment_image_src($attachment_id, 'full');

if(is_array($src)) {
// fix for wpml
$url = preg_replace('/&lang=[aA-zZ0-9]+/m', '', $src[0]);
$sources[$width]['url'] = $url;
} else {
unset($sources[$width]);
}
} else {
unset($sources[$width]);
}
if(is_array($src)) {
// fix for wpml
$url = preg_replace('/&lang=[aA-zZ0-9]+/m', '', $src[0]);
$newSources["{$imageWidth}"] = $sources["{$imageWidth}"];
$newSources["{$imageWidth}"]['url'] = $url;
}
}

return $sources;
return $newSources;
}
//endregion
}
72 changes: 72 additions & 0 deletions classes/Utilities/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,78 @@ function anyEmpty(...$set) {
return false;
}

/**
* Insures all items are set
*
* @param array $array
* @param array $set
*
* @return bool
*/
function anyIsSet($array,...$set) {
foreach($set as $item) {
if (isset($array[$item])) {
return true;
}
}

return false;
}

/**
* Insures all items are set
* @param array $array
* @param array $set
*
* @return bool
*/
function allIsSet($array, ...$set) {
foreach($set as $item) {
if (!isset($array[$item])) {
return true;
}
}

return false;
}

/**
* Determines if an array contains any of the values in another array
*
* @param $array
* @param $values
*
* @return bool
*/
function arrayContainsAny($array, $values) {
foreach($values as $val) {
if (in_array($val, $array)) {
return true;
}
}

return false;
}

/**
* Determines if an array contains all of the values in another array
*
* @param $array
* @param $values
*
* @return bool
*/
function arrayContainsAll($array, $values) {
foreach($values as $val) {
if (!in_array($val, $array)) {
return false;
}
}

return true;
}

/**
* Determines if an array is a keyed array
*
Expand Down
35 changes: 35 additions & 0 deletions config/imgix.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,35 @@
"title" => "Imgix Image Settings",
"doc_link" => 'https://support.mediacloud.press/articles/documentation/imgix/imgix-image-settings',
"options" => [
"mcloud-imgix-crop-mode" => [
"title" => "Crop Mode",
"description" => "Controls the mode when rendering cropped images. Multiple crop modes means that the crop will first try to center the crop on any detected faces, but if no faces are detected than the next crop mode will be used. Note that any settings specified in the Image Size Manager or Image Editor will override this.",
"type" => "select",
"options" => [
"" => "Default",
'faces,position' => 'Faces, Position',
'faces,edges' => 'Faces, Edges',
'faces,entropy' => 'Faces, Entropy',
],
"default" => null
],
"mcloud-imgix-crop-position" => [
"title" => "Crop Position",
"description" => "Controls the default position of the crop.",
"type" => "select",
"options" => [
"center" => "Center",
'top,left' => "Top Left",
'top' => 'Top',
'top,right' => "Top Right",
'right' => 'Right',
'bottom,right' => 'Bottom Right',
'bottom' => 'Bottom',
'bottom, left' => 'Bottom Left',
'left' => 'Left',
],
"default" => 'center'
],
"mcloud-imgix-serve-private-images" => [
"title" => "Serve Private Images",
"description" => "When enabled, private images, or image sizes that have had their privacy level set to private, will be rendered through imgix. When disabled, any private images or private image sizes will be served from cloud storage using signed URLs, if enabled.",
Expand Down Expand Up @@ -119,6 +148,12 @@
"description" => "After each upload Media Cloud will use Imgix's face detection API to detect faces in the image. This can be used with Focus Crop in the image editor, or on the front-end however you choose. <strong>Note:</strong> If you are relying on this functionality, the better option would be to use the <a href='admin.php?page=media-cloud-settings&tab=vision'>Vision</a> tool. It is more accurate with less false positives. If Vision is enabled, this setting is ignored in favor of Vision's results.",
"type" => "checkbox",
"default" => false
],
"mcloud-imgix-remove-extra-variables" => [
"title" => "Remove Extra Query Variables",
"description" => "Removes extra query variables from the imgix URL such as the <code>ixlib</code> and <code>wpsize</code> variables.",
"type" => "checkbox",
"default" => false
]
]
],
Expand Down
Loading

0 comments on commit dc901e6

Please sign in to comment.