diff --git a/focal_point.module b/focal_point.module index 2afa2df..d56ab61 100644 --- a/focal_point.module +++ b/focal_point.module @@ -29,8 +29,8 @@ function focal_point_entity_presave(EntityInterface $entity) { if (isset($item->focal_point)) { list($x, $y) = explode(',', $item->focal_point); $crop_type = \Drupal::config('focal_point.settings')->get('crop_type'); - \Drupal::service('focal_point.manager') - ->saveCropEntity($x, $y, $item->width, $item->height, $item->entity, $crop_type); + $crop = \Drupal::service('focal_point.manager')->getCropEntity($item->entity, $crop_type); + \Drupal::service('focal_point.manager')->saveCropEntity($x, $y, $item->width, $item->height, $crop); } } } diff --git a/src/FocalPointEffectBase.php b/src/FocalPointEffectBase.php index 3d13706..96476a9 100644 --- a/src/FocalPointEffectBase.php +++ b/src/FocalPointEffectBase.php @@ -169,28 +169,25 @@ abstract class FocalPointEffectBase extends ResizeImageEffect implements Contain * Array with two keys (x, y) and anchor coordinates as values. */ protected function calculateAnchor(ImageInterface $image, CropInterface $crop) { - // Ensure the anchor doesn't fall off the left/top edge of the image. $original_anchor = $crop->anchor(); - - // Make sure X is always first item. - ksort($original_anchor); - $new_anchor = $original_anchor; - $image_size = [$image->getWidth(), $image->getHeight()]; + + // Set the minimum number of pixels that must exist between the edge of the + // image and the anchor point (in both the x and y directions). $crop_size = $crop->size(); - $crop_offset_width = (int)ceil($crop_size['width'] / 2); - $crop_offset_height = (int)ceil($crop_size['height'] / 2); + $crop_offset_x = (int)ceil($crop_size['width'] / 2); + $crop_offset_y = (int)ceil($crop_size['height'] / 2); // Ensure that the crop area doesn't fall off the left or right side of the // image. - $left_bound = $crop_offset_width; - $right_bound = $image_size[0] - $crop_offset_width; + $left_bound = $crop_offset_x; + $right_bound = $image->getWidth() - $crop_offset_x; $new_anchor['x'] = max(min($original_anchor['x'], $right_bound), $left_bound); // Ensure that the crop area doesn't fall off the top or bottom of the // image. - $top_bound = $crop_offset_height; - $bottom_bound = $image_size[1] - $crop_offset_height; + $top_bound = $crop_offset_y; + $bottom_bound = $image->getHeight() - $crop_offset_y; $new_anchor['y'] = max(min($original_anchor['y'], $bottom_bound), $top_bound); return $new_anchor; diff --git a/src/FocalPointManager.php b/src/FocalPointManager.php index a21c32f..a685c10 100644 --- a/src/FocalPointManager.php +++ b/src/FocalPointManager.php @@ -8,6 +8,7 @@ namespace Drupal\focal_point; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\crop\CropInterface; use Drupal\crop\Entity\Crop; use Drupal\file\FileInterface; @@ -72,18 +73,10 @@ class FocalPointManager implements FocalPointManagerInterface { /** * {@inheritdoc} */ - public function saveCropEntity($x, $y, $width, $height, FileInterface $file, $crop_type, $save_entity = TRUE) { - $absolute = $this->relativeToAbsolute($x, $y, $width, $height); + public function getCropEntity(FileInterface $file, $crop_type) { if (Crop::cropExists($file->getFileUri(), $crop_type)) { /** @var \Drupal\crop\CropInterface $crop */ $crop = Crop::findCrop($file->getFileUri(), $crop_type); - if ($crop->x->value != $absolute['x'] || $crop->y->value != $absolute['y']) { - $crop->x = $absolute['x']; - $crop->y = $absolute['y']; - } - else { - $save_entity = FALSE; - } } else { $values = [ @@ -91,8 +84,6 @@ class FocalPointManager implements FocalPointManagerInterface { 'entity_id' => $file->id(), 'entity_type' => 'file', 'uri' => $file->getFileUri(), - 'x' => $absolute['x'], - 'y' => $absolute['y'], ]; $crop = \Drupal::entityTypeManager() @@ -100,7 +91,18 @@ class FocalPointManager implements FocalPointManagerInterface { ->create($values); } - if ($save_entity) { + return $crop; + } + + /** + * {@inheritdoc} + */ + public function saveCropEntity($x, $y, $width, $height, CropInterface $crop) { + $absolute = $this->relativeToAbsolute($x, $y, $width, $height); + + $anchor = $crop->anchor(); + if ($anchor['x'] != $absolute['x'] || $anchor['y'] != $absolute['y']) { + $crop->setPosition($absolute['x'], $absolute['y']); $crop->save(); } diff --git a/src/FocalPointManagerInterface.php b/src/FocalPointManagerInterface.php index 2c11246..2b40361 100644 --- a/src/FocalPointManagerInterface.php +++ b/src/FocalPointManagerInterface.php @@ -7,6 +7,7 @@ namespace Drupal\focal_point; use Drupal\file\FileInterface; +use Drupal\crop\CropInterface; /** * Defines an interface for focal point manager. @@ -61,6 +62,21 @@ interface FocalPointManagerInterface { public function absoluteToRelative($x, $y, $width, $height); /** + * Gets a crop entity for the given file. + * + * If an existing crop entity is not found then a new one is created. + * + * @param \Drupal\file\FileInterface $file + * File this focal point applies to. + * @param string $crop_type + * Crop type to be used. + * + * @return \Drupal\crop\CropInterface + * Created crop entity. + */ + public function getCropEntity(FileInterface $file, $crop_type); + + /** * Converts relative focal point coordinates as a crop entity. * * @param float $x @@ -71,16 +87,12 @@ interface FocalPointManagerInterface { * Width of the original image. * @param int $height * Height of the original image. - * @param \Drupal\file\FileInterface $file - * File this focal point applies to. - * @param string $crop_type - * Crop type to be used. - * @param bool $save_entity - * Entity will be saved if TRUE (default) or just created if FALSE. + * @param \Drupal\crop\CropInterface + * Crop entity for the given file. * * @return \Drupal\crop\CropInterface - * Created crop entity. + * Saved crop entity. */ - public function saveCropEntity($x, $y, $width, $height, FileInterface $file, $crop_type, $save_entity = TRUE); + public function saveCropEntity($x, $y, $width, $height, CropInterface $crop); } diff --git a/tests/src/Unit/Effects/FocalPointEffectsTest.php b/tests/src/Unit/Effects/FocalPointEffectsTest.php index 7ce11a5..ef8be9c 100644 --- a/tests/src/Unit/Effects/FocalPointEffectsTest.php +++ b/tests/src/Unit/Effects/FocalPointEffectsTest.php @@ -71,7 +71,7 @@ class FocalPointEffectsTest extends UnitTestCase { ->method('getHeight') ->will($this->returnValue($image_size[1])); - $crop = $this->getMockBuilder('Drupal\crop\Entity\Crop')->disableOriginalConstructor()->getMock(); + $crop = $this->getMockBuilder('Drupal\crop\CropInterface')->disableOriginalConstructor()->getMock(); $crop->expects($this->once()) ->method('anchor') ->will($this->returnValue( @@ -111,5 +111,4 @@ class FocalPointEffectsTest extends UnitTestCase { [[1000, 100], [75, 75], [0, 99], ['x' => 38, 'y' => 62]], ]; } - }