Skip to content
Snippets Groups Projects
Verified Commit b98a997f authored by Dave Long's avatar Dave Long
Browse files

Issue #2350849 by mondrake, fietserwin, ankithashetty, jhedstrom: Deprecate image_filter_keyword()

(cherry picked from commit fa4cdaf3)
parent fb0ec10c
No related branches found
No related tags found
24 merge requests!11636Draft: Issue #3515643 by macsim: fieldNameExists method is inconsistent,!11515Issue #3480419 by mondrake, smustgrave, catch: Method...,!11380Issue #3490698 by catch, spokje: Bump MINIMUM_STABILITY back to 'stable' when...,!11281Use Drupal Core Leadership terminology in MAINTAINERS.txt,!11239Issue #3507548: Allow workspace changes listing to show all items, without a pager,!11238Fix issue #3051797,!11213Issue #3506743 by tomislav.matokovic: Increasing the color contrast for the navigation block title against the background of the navigation sidebar to at least 4.5:1,!11147Draft: Try to avoid manually setting required cache contexts,!11108Issue #3490298 by nicxvan: Profiles can be missed in OOP hooks,!11093Drupal on MongoDB 11.1.x,!11017Issue #3502540: Add date filter for moderated content.,!11009Issue #3486972 migrate feed icon,!10999Cleaning up Taxonomy hooks and updating baseline.,!10977Issue #3501457: Fix path used in a A11y Test Admin,!10881Issue #3489329 by mfb, casey: symfony/http-foundation commit 32310ff breaks PathValidator,!10570Issue #3494197: Convert Twig engine hooks,!10567Issue #3494154: Index is not added if entity doesn't support revisions,!10548Revert "Issue #3478621 by catch, longwave, nicxvan: Add filecache to OOP hook attribute parsing",!10404Margin has been added,!10391Issue #3485117 by nexusnovaz, godotislate, nicxvan: Fix return type on...,!10388Issue #3485117 by nexusnovaz, godotislate, nicxvan: Fix return type on...,!10376Issue #3485117 by nexusnovaz, godotislate, nicxvan: Fix return type on...,!10237Issue #3484105 by nicxvan, godotislate: Automatically included .inc files are no longer included,!10052\Drupal\Core\KeyValueStore\DatabaseStorage::doSetIfNotExists should be protected Primary tabs View(active tab)
Pipeline #327834 canceled
......@@ -56,4 +56,29 @@ public static function scaleDimensions(array &$dimensions, $width = NULL, $heigh
return TRUE;
}
/**
* Returns the offset in pixels from the anchor.
*
* @param string $anchor
* The anchor ('top', 'left', 'bottom', 'right', 'center').
* @param int $current_size
* The current size, in pixels.
* @param int $new_size
* The new size, in pixels.
*
* @return int
* The offset from the anchor, in pixels.
*
* @throws \InvalidArgumentException
* When the $anchor argument is not valid.
*/
public static function getKeywordOffset(string $anchor, int $current_size, int $new_size): int {
return match ($anchor) {
'bottom', 'right' => $current_size - $new_size,
'center' => (int) round($current_size / 2 - $new_size / 2),
'top', 'left' => 0,
default => throw new \InvalidArgumentException("Invalid anchor '{$anchor}' provided to getKeywordOffset()"),
};
}
}
......@@ -336,8 +336,14 @@ function template_preprocess_image_style(&$variables) {
* @return int|string
* The offset from the anchor, in pixels, or the anchor itself, if its value
* isn't one of the accepted values.
*
* @deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use
* \Drupal\Component\Utility\Image::getKeywordOffset() instead.
*
* @see https://www.drupal.org/node/3268441
*/
function image_filter_keyword($anchor, $current_size, $new_size) {
@trigger_error('image_filter_keyword() is deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use \Drupal\Component\Utility\Image::getKeywordOffset() instead. See https://www.drupal.org/node/3268441', E_USER_DEPRECATED);
switch ($anchor) {
case 'top':
case 'left':
......
......@@ -2,6 +2,7 @@
namespace Drupal\image\Plugin\ImageEffect;
use Drupal\Component\Utility\Image;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Image\ImageInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
......@@ -22,8 +23,8 @@ class CropImageEffect extends ResizeImageEffect {
*/
public function applyEffect(ImageInterface $image) {
[$x, $y] = explode('-', $this->configuration['anchor']);
$x = image_filter_keyword($x, $image->getWidth(), $this->configuration['width']);
$y = image_filter_keyword($y, $image->getHeight(), $this->configuration['height']);
$x = Image::getKeywordOffset($x, $image->getWidth(), (int) $this->configuration['width']);
$y = Image::getKeywordOffset($y, $image->getHeight(), (int) $this->configuration['height']);
if (!$image->crop($x, $y, $this->configuration['width'], $this->configuration['height'])) {
$this->logger->error('Image crop failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', ['%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->getMimeType(), '%dimensions' => $image->getWidth() . 'x' . $image->getHeight()]);
return FALSE;
......
......@@ -2,6 +2,7 @@
namespace Drupal\image\Plugin\ImageEffect;
use Drupal\Component\Utility\Image;
use Drupal\Core\Image\ImageInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\image\Attribute\ImageEffect;
......@@ -20,13 +21,13 @@ class ScaleAndCropImageEffect extends CropImageEffect {
* {@inheritdoc}
*/
public function applyEffect(ImageInterface $image) {
$width = $this->configuration['width'];
$height = $this->configuration['height'];
$width = (int) $this->configuration['width'];
$height = (int) $this->configuration['height'];
$scale = max($width / $image->getWidth(), $height / $image->getHeight());
[$x, $y] = explode('-', $this->configuration['anchor']);
$x = image_filter_keyword($x, $image->getWidth() * $scale, $width);
$y = image_filter_keyword($y, $image->getHeight() * $scale, $height);
$x = Image::getKeywordOffset($x, (int) round($image->getWidth() * $scale), $width);
$y = Image::getKeywordOffset($y, (int) round($image->getHeight() * $scale), $height);
if (!$image->apply('scale_and_crop', ['x' => $x, 'y' => $y, 'width' => $width, 'height' => $height])) {
$this->logger->error('Image scale and crop failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', ['%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->getMimeType(), '%dimensions' => $image->getWidth() . 'x' . $image->getHeight()]);
......
......@@ -18,7 +18,6 @@
* - image.module:
* image_style_options()
* \Drupal\image\ImageStyleInterface::flush()
* image_filter_keyword()
*/
/**
......
......@@ -87,7 +87,7 @@ public function testCropEffect(): void {
// @todo Test also keyword offsets in #3040887.
// @see https://www.drupal.org/project/drupal/issues/3040887
$this->assertImageEffect(['crop'], 'image_crop', [
'anchor' => 'top-1',
'anchor' => 'top-left',
'width' => 3,
'height' => 4,
]);
......@@ -97,7 +97,7 @@ public function testCropEffect(): void {
// X was passed correctly.
$this->assertEquals(0, $calls['crop'][0][0]);
// Y was passed correctly.
$this->assertEquals(1, $calls['crop'][0][1]);
$this->assertEquals(0, $calls['crop'][0][1]);
// Width was passed correctly.
$this->assertEquals(3, $calls['crop'][0][2]);
// Height was passed correctly.
......@@ -131,7 +131,7 @@ public function testScaleAndCropEffect(): void {
// Check the parameters.
$calls = $this->imageTestGetAllCalls();
// X was computed and passed correctly.
$this->assertEquals(7.5, $calls['scale_and_crop'][0][0]);
$this->assertEquals(8, $calls['scale_and_crop'][0][0]);
// Y was computed and passed correctly.
$this->assertEquals(0, $calls['scale_and_crop'][0][1]);
// Width was computed and passed correctly.
......@@ -145,7 +145,7 @@ public function testScaleAndCropEffect(): void {
*/
public function testScaleAndCropEffectWithAnchor(): void {
$this->assertImageEffect(['scale_and_crop'], 'image_scale_and_crop', [
'anchor' => 'top-1',
'anchor' => 'top-left',
'width' => 5,
'height' => 10,
]);
......@@ -155,7 +155,7 @@ public function testScaleAndCropEffectWithAnchor(): void {
// X was computed and passed correctly.
$this->assertEquals(0, $calls['scale_and_crop'][0][0]);
// Y was computed and passed correctly.
$this->assertEquals(1, $calls['scale_and_crop'][0][1]);
$this->assertEquals(0, $calls['scale_and_crop'][0][1]);
// Width was computed and passed correctly.
$this->assertEquals(5, $calls['scale_and_crop'][0][2]);
// Height was computed and passed correctly.
......
<?php
declare(strict_types=1);
namespace Drupal\Tests\image\Unit;
use Drupal\Tests\UnitTestCase;
/**
* @group Image
* @group legacy
*/
class ImageDeprecationTest extends UnitTestCase {
/**
* Tests deprecation of image_filter_keyword.
*/
public function testImageFilterKeywordDeprecation(): void {
include_once __DIR__ . '/../../../image.module';
$this->expectDeprecation('image_filter_keyword() is deprecated in drupal:11.1.0 and is removed from drupal:12.0.0. Use \Drupal\Component\Utility\Image::getKeywordOffset() instead. See https://www.drupal.org/node/3268441');
$this->assertSame('miss', image_filter_keyword('miss', 0, 0));
}
}
......@@ -157,4 +157,84 @@ public static function providerTestScaleDimensions() {
return $tests;
}
/**
* @covers ::getKeywordOffset
*/
public function testInvalidGetKeywordOffset(): void {
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid anchor \'foo\' provided to getKeywordOffset()');
Image::getKeywordOffset('foo', 0, 0);
}
/**
* @covers ::getKeywordOffset
*
* @dataProvider providerTestGetKeywordOffset
*/
public function testGetKeywordOffset(array $input, int $expected): void {
$this->assertSame($expected, Image::getKeywordOffset($input['anchor'], $input['current'], $input['new']));
}
/**
* Provides data for testGetKeywordOffset().
*
* @return \Generator
* Test scenarios.
*
* @see testGetKeywordOffset()
*/
public static function providerTestGetKeywordOffset(): \Generator {
yield "'left' => return 0" => [
'input' => [
'anchor' => 'left',
'current' => 100,
'new' => 20,
],
'expected' => 0,
];
yield "'top' => return 0" => [
'input' => [
'anchor' => 'top',
'current' => 100,
'new' => 20,
],
'expected' => 0,
];
yield "'right' => return (current - new)" => [
'input' => [
'anchor' => 'right',
'current' => 100,
'new' => 20,
],
'expected' => 80,
];
yield "'bottom' => return (current - new)" => [
'input' => [
'anchor' => 'bottom',
'current' => 100,
'new' => 30,
],
'expected' => 70,
];
yield "a) 'center' => return (current - new)/2" => [
'input' => [
'anchor' => 'center',
'current' => 100,
'new' => 20,
],
'expected' => 40,
];
yield "b) 'center' => return (current - new)/2" => [
'input' => [
'anchor' => 'center',
'current' => 100,
'new' => 91,
],
'expected' => 5,
];
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment