Issue #2350849 by mondrake, fietserwin, ankithashetty, jhedstrom: Deprecate image_filter_keyword()
(cherry picked from commit fa4cdaf3f2
)
merge-requests/10102/head
parent
fb0ec10cf6
commit
b98a997f10
|
@ -56,4 +56,29 @@ class Image {
|
||||||
return TRUE;
|
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
|
* @return int|string
|
||||||
* The offset from the anchor, in pixels, or the anchor itself, if its value
|
* The offset from the anchor, in pixels, or the anchor itself, if its value
|
||||||
* isn't one of the accepted values.
|
* 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) {
|
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) {
|
switch ($anchor) {
|
||||||
case 'top':
|
case 'top':
|
||||||
case 'left':
|
case 'left':
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Drupal\image\Plugin\ImageEffect;
|
namespace Drupal\image\Plugin\ImageEffect;
|
||||||
|
|
||||||
|
use Drupal\Component\Utility\Image;
|
||||||
use Drupal\Core\Form\FormStateInterface;
|
use Drupal\Core\Form\FormStateInterface;
|
||||||
use Drupal\Core\Image\ImageInterface;
|
use Drupal\Core\Image\ImageInterface;
|
||||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||||
|
@ -22,8 +23,8 @@ class CropImageEffect extends ResizeImageEffect {
|
||||||
*/
|
*/
|
||||||
public function applyEffect(ImageInterface $image) {
|
public function applyEffect(ImageInterface $image) {
|
||||||
[$x, $y] = explode('-', $this->configuration['anchor']);
|
[$x, $y] = explode('-', $this->configuration['anchor']);
|
||||||
$x = image_filter_keyword($x, $image->getWidth(), $this->configuration['width']);
|
$x = Image::getKeywordOffset($x, $image->getWidth(), (int) $this->configuration['width']);
|
||||||
$y = image_filter_keyword($y, $image->getHeight(), $this->configuration['height']);
|
$y = Image::getKeywordOffset($y, $image->getHeight(), (int) $this->configuration['height']);
|
||||||
if (!$image->crop($x, $y, $this->configuration['width'], $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()]);
|
$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;
|
return FALSE;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Drupal\image\Plugin\ImageEffect;
|
namespace Drupal\image\Plugin\ImageEffect;
|
||||||
|
|
||||||
|
use Drupal\Component\Utility\Image;
|
||||||
use Drupal\Core\Image\ImageInterface;
|
use Drupal\Core\Image\ImageInterface;
|
||||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||||
use Drupal\image\Attribute\ImageEffect;
|
use Drupal\image\Attribute\ImageEffect;
|
||||||
|
@ -20,13 +21,13 @@ class ScaleAndCropImageEffect extends CropImageEffect {
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function applyEffect(ImageInterface $image) {
|
public function applyEffect(ImageInterface $image) {
|
||||||
$width = $this->configuration['width'];
|
$width = (int) $this->configuration['width'];
|
||||||
$height = $this->configuration['height'];
|
$height = (int) $this->configuration['height'];
|
||||||
$scale = max($width / $image->getWidth(), $height / $image->getHeight());
|
$scale = max($width / $image->getWidth(), $height / $image->getHeight());
|
||||||
|
|
||||||
[$x, $y] = explode('-', $this->configuration['anchor']);
|
[$x, $y] = explode('-', $this->configuration['anchor']);
|
||||||
$x = image_filter_keyword($x, $image->getWidth() * $scale, $width);
|
$x = Image::getKeywordOffset($x, (int) round($image->getWidth() * $scale), $width);
|
||||||
$y = image_filter_keyword($y, $image->getHeight() * $scale, $height);
|
$y = Image::getKeywordOffset($y, (int) round($image->getHeight() * $scale), $height);
|
||||||
|
|
||||||
if (!$image->apply('scale_and_crop', ['x' => $x, 'y' => $y, 'width' => $width, 'height' => $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()]);
|
$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 @@ use Drupal\Tests\BrowserTestBase;
|
||||||
* - image.module:
|
* - image.module:
|
||||||
* image_style_options()
|
* image_style_options()
|
||||||
* \Drupal\image\ImageStyleInterface::flush()
|
* \Drupal\image\ImageStyleInterface::flush()
|
||||||
* image_filter_keyword()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -87,7 +87,7 @@ class ImageEffectsTest extends KernelTestBase {
|
||||||
// @todo Test also keyword offsets in #3040887.
|
// @todo Test also keyword offsets in #3040887.
|
||||||
// @see https://www.drupal.org/project/drupal/issues/3040887
|
// @see https://www.drupal.org/project/drupal/issues/3040887
|
||||||
$this->assertImageEffect(['crop'], 'image_crop', [
|
$this->assertImageEffect(['crop'], 'image_crop', [
|
||||||
'anchor' => 'top-1',
|
'anchor' => 'top-left',
|
||||||
'width' => 3,
|
'width' => 3,
|
||||||
'height' => 4,
|
'height' => 4,
|
||||||
]);
|
]);
|
||||||
|
@ -97,7 +97,7 @@ class ImageEffectsTest extends KernelTestBase {
|
||||||
// X was passed correctly.
|
// X was passed correctly.
|
||||||
$this->assertEquals(0, $calls['crop'][0][0]);
|
$this->assertEquals(0, $calls['crop'][0][0]);
|
||||||
// Y was passed correctly.
|
// Y was passed correctly.
|
||||||
$this->assertEquals(1, $calls['crop'][0][1]);
|
$this->assertEquals(0, $calls['crop'][0][1]);
|
||||||
// Width was passed correctly.
|
// Width was passed correctly.
|
||||||
$this->assertEquals(3, $calls['crop'][0][2]);
|
$this->assertEquals(3, $calls['crop'][0][2]);
|
||||||
// Height was passed correctly.
|
// Height was passed correctly.
|
||||||
|
@ -131,7 +131,7 @@ class ImageEffectsTest extends KernelTestBase {
|
||||||
// Check the parameters.
|
// Check the parameters.
|
||||||
$calls = $this->imageTestGetAllCalls();
|
$calls = $this->imageTestGetAllCalls();
|
||||||
// X was computed and passed correctly.
|
// 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.
|
// Y was computed and passed correctly.
|
||||||
$this->assertEquals(0, $calls['scale_and_crop'][0][1]);
|
$this->assertEquals(0, $calls['scale_and_crop'][0][1]);
|
||||||
// Width was computed and passed correctly.
|
// Width was computed and passed correctly.
|
||||||
|
@ -145,7 +145,7 @@ class ImageEffectsTest extends KernelTestBase {
|
||||||
*/
|
*/
|
||||||
public function testScaleAndCropEffectWithAnchor(): void {
|
public function testScaleAndCropEffectWithAnchor(): void {
|
||||||
$this->assertImageEffect(['scale_and_crop'], 'image_scale_and_crop', [
|
$this->assertImageEffect(['scale_and_crop'], 'image_scale_and_crop', [
|
||||||
'anchor' => 'top-1',
|
'anchor' => 'top-left',
|
||||||
'width' => 5,
|
'width' => 5,
|
||||||
'height' => 10,
|
'height' => 10,
|
||||||
]);
|
]);
|
||||||
|
@ -155,7 +155,7 @@ class ImageEffectsTest extends KernelTestBase {
|
||||||
// X was computed and passed correctly.
|
// X was computed and passed correctly.
|
||||||
$this->assertEquals(0, $calls['scale_and_crop'][0][0]);
|
$this->assertEquals(0, $calls['scale_and_crop'][0][0]);
|
||||||
// Y was computed and passed correctly.
|
// 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.
|
// Width was computed and passed correctly.
|
||||||
$this->assertEquals(5, $calls['scale_and_crop'][0][2]);
|
$this->assertEquals(5, $calls['scale_and_crop'][0][2]);
|
||||||
// Height was computed and passed correctly.
|
// Height was computed and passed correctly.
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?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 @@ class ImageTest extends TestCase {
|
||||||
return $tests;
|
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,
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue