diff --git a/eZ/Publish/Core/FieldType/FieldType.php b/eZ/Publish/Core/FieldType/FieldType.php index db89120b752..bba5f148281 100644 --- a/eZ/Publish/Core/FieldType/FieldType.php +++ b/eZ/Publish/Core/FieldType/FieldType.php @@ -6,6 +6,7 @@ */ namespace eZ\Publish\Core\FieldType; +use eZ\Publish\SPI\FieldType\Comparable; use eZ\Publish\SPI\FieldType\FieldType as FieldTypeInterface; use eZ\Publish\Core\Persistence\TransformationProcessor; use eZ\Publish\SPI\FieldType\Value as SPIValue; @@ -30,7 +31,7 @@ * Field types are primed and pre-configured with the Field Definitions found in * Content Types. */ -abstract class FieldType implements FieldTypeInterface +abstract class FieldType implements FieldTypeInterface, Comparable { /** * The setting keys which are available on this field type. @@ -575,4 +576,9 @@ public function getRelations(SPIValue $fieldValue) { return []; } + + public function valuesEqual(SPIValue $value1, SPIValue $value2): bool + { + return $this->toHash($value1) === $this->toHash($value2); + } } diff --git a/eZ/Publish/Core/FieldType/Image/Type.php b/eZ/Publish/Core/FieldType/Image/Type.php index c67bf66d3cc..c053ecba0cb 100644 --- a/eZ/Publish/Core/FieldType/Image/Type.php +++ b/eZ/Publish/Core/FieldType/Image/Type.php @@ -365,4 +365,14 @@ public function fromPersistenceValue(FieldValue $fieldValue) return $result; } + + public function valuesEqual(SPIValue $value1, SPIValue $value2): bool + { + $hashValue1 = $this->toHash($value1); + $hashValue2 = $this->toHash($value2); + + unset($hashValue1['imageId'], $hashValue2['imageId']); + + return $hashValue1 === $hashValue2; + } } diff --git a/eZ/Publish/Core/FieldType/Tests/FieldTypeTest.php b/eZ/Publish/Core/FieldType/Tests/FieldTypeTest.php index efc31ea4850..c9106965764 100644 --- a/eZ/Publish/Core/FieldType/Tests/FieldTypeTest.php +++ b/eZ/Publish/Core/FieldType/Tests/FieldTypeTest.php @@ -511,6 +511,11 @@ public function provideInvalidDataForValidate() ]; } + public function provideInputForValuesEqual(): array + { + return $this->provideInputForFromHash(); + } + /** * Retrieves a test wide cached version of the field type under test. * @@ -974,5 +979,22 @@ protected function doValidate($fieldDefinitionData, $value) return $validationErrors; } + /** + * @dataProvider provideInputForValuesEqual + * + * @param mixed $inputValue1Hash + */ + public function testValuesEqual($inputValue1Hash, SPIValue $inputValue2): void + { + $fieldType = $this->getFieldTypeUnderTest(); + + $inputValue1 = $fieldType->fromHash($inputValue1Hash); + + self::assertTrue( + $fieldType->valuesEqual($inputValue1, $inputValue2), + 'valuesEqual() method did not create expected result.' + ); + } + // @todo: More test methods … } diff --git a/eZ/Publish/Core/FieldType/Tests/ImageTest.php b/eZ/Publish/Core/FieldType/Tests/ImageTest.php index 547d2051d40..04232d677a1 100644 --- a/eZ/Publish/Core/FieldType/Tests/ImageTest.php +++ b/eZ/Publish/Core/FieldType/Tests/ImageTest.php @@ -811,4 +811,39 @@ public function provideInvalidDataForValidate() ], ]; } + + /** + * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException + */ + public function provideInputForValuesEqual(): array + { + return [ + [ + [ + 'id' => $this->getImageInputPath(), + 'fileName' => 'Sindelfingen-Squirrels.jpg', + 'fileSize' => 23, + 'alternativeText' => 'This is so Sindelfingen!', + 'imageId' => '123-12345', + 'uri' => 'http://' . $this->getImageInputPath(), + 'width' => 123, + 'height' => 456, + ], + new ImageValue( + [ + 'id' => $this->getImageInputPath(), + 'path' => $this->getImageInputPath(), + 'fileName' => 'Sindelfingen-Squirrels.jpg', + 'fileSize' => 23, + 'alternativeText' => 'This is so Sindelfingen!', + 'imageId' => '123-12317', + 'uri' => 'http://' . $this->getImageInputPath(), + 'inputUri' => null, + 'width' => 123, + 'height' => 456, + ] + ), + ], + ]; + } } diff --git a/eZ/Publish/Core/Repository/ContentService.php b/eZ/Publish/Core/Repository/ContentService.php index 56beb95b6b1..ce55aead1c8 100644 --- a/eZ/Publish/Core/Repository/ContentService.php +++ b/eZ/Publish/Core/Repository/ContentService.php @@ -18,6 +18,9 @@ use eZ\Publish\Core\Repository\Values\Content\Content; use eZ\Publish\Core\Repository\Values\Content\Location; use eZ\Publish\API\Repository\Values\Content\Language; +use eZ\Publish\SPI\FieldType\Comparable; +use eZ\Publish\SPI\FieldType\FieldType; +use eZ\Publish\SPI\FieldType\Value; use eZ\Publish\SPI\Persistence\Handler; use eZ\Publish\API\Repository\Values\Content\ContentUpdateStruct as APIContentUpdateStruct; use eZ\Publish\API\Repository\Values\ContentType\ContentType; @@ -1723,7 +1726,8 @@ protected function copyTranslationsFromPublishedVersion(APIVersionInfo $versionI if ($newValue !== null && $field->value !== null - && $fieldType->toHash($newValue) === $fieldType->toHash($field->value)) { + && $this->fieldValuesAreEqual($fieldType, $newValue, $field->value) + ) { continue; } @@ -1743,6 +1747,26 @@ protected function copyTranslationsFromPublishedVersion(APIVersionInfo $versionI $this->internalUpdateContent($versionInfo, $updateStruct); } + protected function fieldValuesAreEqual(FieldType $fieldType, Value $value1, Value $value2): bool + { + if ($fieldType instanceof Comparable) { + return $fieldType->valuesEqual($value1, $value2); + } else { + @trigger_error( + \sprintf( + 'In eZ Platform 2.5 and 3.x %s should implement %s. ' . + 'Since the 4.0 major release FieldType\Comparable contract will be a part of %s', + get_class($fieldType), + Comparable::class, + FieldType::class + ), + E_USER_DEPRECATED + ); + + return $fieldType->toHash($value1) === $fieldType->toHash($value2); + } + } + /** * Publishes a content version. * diff --git a/eZ/Publish/SPI/FieldType/Comparable.php b/eZ/Publish/SPI/FieldType/Comparable.php new file mode 100644 index 00000000000..214318a90a4 --- /dev/null +++ b/eZ/Publish/SPI/FieldType/Comparable.php @@ -0,0 +1,14 @@ +