diff --git a/app/code/Magento/MediaGalleryMetadata/Model/GetIptcMetadata.php b/app/code/Magento/MediaGalleryMetadata/Model/GetIptcMetadata.php
index d7290f31ee34..e100a7f852e4 100644
--- a/app/code/Magento/MediaGalleryMetadata/Model/GetIptcMetadata.php
+++ b/app/code/Magento/MediaGalleryMetadata/Model/GetIptcMetadata.php
@@ -9,7 +9,6 @@
use Magento\MediaGalleryMetadataApi\Api\Data\MetadataInterface;
use Magento\MediaGalleryMetadataApi\Api\Data\MetadataInterfaceFactory;
-use Magento\MediaGalleryMetadataApi\Model\SegmentInterface;
/**
* Get metadata from IPTC block
@@ -42,8 +41,8 @@ public function __construct(
*/
public function execute(string $data): MetadataInterface
{
- $title = '';
- $description = '';
+ $title = null;
+ $description = null;
$keywords = [];
if (is_callable('iptcparse')) {
@@ -65,7 +64,7 @@ public function execute(string $data): MetadataInterface
return $this->metadataFactory->create([
'title' => $title,
'description' => $description,
- 'keywords' => $keywords
+ 'keywords' => !empty($keywords) ? $keywords : null
]);
}
}
diff --git a/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadExif.php b/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadExif.php
new file mode 100644
index 000000000000..b6c32296f3f7
--- /dev/null
+++ b/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadExif.php
@@ -0,0 +1,104 @@
+metadataFactory = $metadataFactory;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function execute(FileInterface $file): MetadataInterface
+ {
+ if (!is_callable('exif_read_data')) {
+ throw new LocalizedException(
+ __('exif_read_data() must be enabled in php configuration')
+ );
+ }
+
+ foreach ($file->getSegments() as $segment) {
+ if ($this->isExifSegment($segment)) {
+ return $this->getExifData($file->getPath());
+ }
+ }
+
+ return $this->metadataFactory->create([
+ 'title' => null,
+ 'description' => null,
+ 'keywords' => null
+ ]);
+ }
+
+ /**
+ * Parese exif data from segment
+ *
+ * @param string $filePath
+ */
+ private function getExifData(string $filePath): MetadataInterface
+ {
+ $title = null;
+ $description = null;
+ $keywords = null;
+
+ $data = exif_read_data($filePath);
+
+ if (!empty($data)) {
+ $title = isset($data['DocumentName']) ? $data['DocumentName'] : null;
+ $description = isset($data['ImageDescription']) ? $data['ImageDescription'] : null;
+ }
+
+ return $this->metadataFactory->create([
+ 'title' => $title,
+ 'description' => $description,
+ 'keywords' => $keywords
+ ]);
+ }
+
+ /**
+ * Does segment contain Exif data
+ *
+ * @param SegmentInterface $segment
+ * @return bool
+ */
+ private function isExifSegment(SegmentInterface $segment): bool
+ {
+ return $segment->getName() === self::EXIF_SEGMENT_NAME
+ && strncmp(
+ substr($segment->getData(), self::EXIF_DATA_START_POSITION, 5),
+ self::EXIF_SEGMENT_START,
+ 5
+ ) == 0;
+ }
+}
diff --git a/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadIptc.php b/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadIptc.php
index 94ccb400e5e0..e56993528a04 100644
--- a/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadIptc.php
+++ b/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadIptc.php
@@ -56,9 +56,9 @@ public function execute(FileInterface $file): MetadataInterface
}
}
return $this->metadataFactory->create([
- 'title' => '',
- 'description' => '',
- 'keywords' => []
+ 'title' => null,
+ 'description' => null,
+ 'keywords' => null
]);
}
diff --git a/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadXmp.php b/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadXmp.php
index 81ff7200c347..e68c86d35eb9 100644
--- a/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadXmp.php
+++ b/app/code/Magento/MediaGalleryMetadata/Model/Jpeg/Segment/ReadXmp.php
@@ -54,9 +54,9 @@ public function execute(FileInterface $file): MetadataInterface
}
}
return $this->metadataFactory->create([
- 'title' => '',
- 'description' => '',
- 'keywords' => []
+ 'title' => null,
+ 'description' => null,
+ 'keywords' => null
]);
}
diff --git a/app/code/Magento/MediaGalleryMetadata/Model/Png/Segment/ReadExif.php b/app/code/Magento/MediaGalleryMetadata/Model/Png/Segment/ReadExif.php
new file mode 100644
index 000000000000..09aeaf526443
--- /dev/null
+++ b/app/code/Magento/MediaGalleryMetadata/Model/Png/Segment/ReadExif.php
@@ -0,0 +1,97 @@
+metadataFactory = $metadataFactory;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function execute(FileInterface $file): MetadataInterface
+ {
+ if (!is_callable('exif_read_data')) {
+ throw new LocalizedException(
+ __('exif_read_data() must be enabled in php configuration')
+ );
+ }
+
+ foreach ($file->getSegments() as $segment) {
+ if ($this->isExifSegment($segment)) {
+ return $this->getExifData($segment);
+ }
+ }
+
+ return $this->metadataFactory->create([
+ 'title' => null,
+ 'description' => null,
+ 'keywords' => null
+ ]);
+ }
+
+ /**
+ * Parese exif data from segment
+ *
+ * @param SegmentInterface $segment
+ */
+ private function getExifData(SegmentInterface $segment): MetadataInterface
+ {
+ $title = null;
+ $description = null;
+ $keywords = [];
+
+ $data = exif_read_data('data://image/jpeg;base64,' . base64_encode($segment->getData()));
+
+ if ($data) {
+ $title = isset($data['DocumentName']) ? $data['DocumentName'] : null;
+ $description = isset($data['ImageDescription']) ? $data['ImageDescription'] : null;
+ }
+
+ return $this->metadataFactory->create([
+ 'title' => $title,
+ 'description' => $description,
+ 'keywords' => !empty($keywords) ? $keywords : null
+ ]);
+ }
+
+ /**
+ * Does segment contain Exif data
+ *
+ * @param SegmentInterface $segment
+ * @return bool
+ */
+ private function isExifSegment(SegmentInterface $segment): bool
+ {
+ return strcmp($segment->getName(), self::EXIF_SEGMENT_NAME) === 0;
+ }
+}
diff --git a/app/code/Magento/MediaGalleryMetadata/Model/Png/Segment/ReadXmp.php b/app/code/Magento/MediaGalleryMetadata/Model/Png/Segment/ReadXmp.php
index 83ba554f7bf5..518697d42147 100644
--- a/app/code/Magento/MediaGalleryMetadata/Model/Png/Segment/ReadXmp.php
+++ b/app/code/Magento/MediaGalleryMetadata/Model/Png/Segment/ReadXmp.php
@@ -55,9 +55,9 @@ public function execute(FileInterface $file): MetadataInterface
}
}
return $this->metadataFactory->create([
- 'title' => '',
- 'description' => '',
- 'keywords' => []
+ 'title' => null,
+ 'description' => null,
+ 'keywords' => null
]);
}
diff --git a/app/code/Magento/MediaGalleryMetadata/Test/Integration/Model/ExtractMetadataTest.php b/app/code/Magento/MediaGalleryMetadata/Test/Integration/Model/ExtractMetadataTest.php
index 982ccbb20fe2..ebe96183eb1f 100644
--- a/app/code/Magento/MediaGalleryMetadata/Test/Integration/Model/ExtractMetadataTest.php
+++ b/app/code/Magento/MediaGalleryMetadata/Test/Integration/Model/ExtractMetadataTest.php
@@ -37,14 +37,14 @@ protected function setUp(): void
* @param string $fileName
* @param string $title
* @param string $description
- * @param array $keywords
+ * @param null|array $keywords
* @throws LocalizedException
*/
public function testExecute(
string $fileName,
string $title,
string $description,
- array $keywords
+ ?array $keywords
): void {
$path = realpath(__DIR__ . '/../../_files/' . $fileName);
$metadata = $this->extractMetadata->execute($path);
@@ -62,6 +62,18 @@ public function testExecute(
public function filesProvider(): array
{
return [
+ [
+ 'exif_image.png',
+ 'Exif title png imge',
+ 'Exif description png imge',
+ null
+ ],
+ [
+ 'exif-image.jpeg',
+ 'Exif Magento title',
+ 'Exif description metadata',
+ null
+ ],
[
'macos-photos.jpeg',
'Title of the magento image',
diff --git a/app/code/Magento/MediaGalleryMetadata/Test/_files/empty_iptc.jpeg b/app/code/Magento/MediaGalleryMetadata/Test/_files/empty_iptc.jpeg
index 144a56dac2d3..1a345c2d33fd 100644
Binary files a/app/code/Magento/MediaGalleryMetadata/Test/_files/empty_iptc.jpeg and b/app/code/Magento/MediaGalleryMetadata/Test/_files/empty_iptc.jpeg differ
diff --git a/app/code/Magento/MediaGalleryMetadata/Test/_files/exif-image.jpeg b/app/code/Magento/MediaGalleryMetadata/Test/_files/exif-image.jpeg
new file mode 100644
index 000000000000..cfe27433fd9f
Binary files /dev/null and b/app/code/Magento/MediaGalleryMetadata/Test/_files/exif-image.jpeg differ
diff --git a/app/code/Magento/MediaGalleryMetadata/Test/_files/exif_image.png b/app/code/Magento/MediaGalleryMetadata/Test/_files/exif_image.png
new file mode 100644
index 000000000000..4a6bf30c2d51
Binary files /dev/null and b/app/code/Magento/MediaGalleryMetadata/Test/_files/exif_image.png differ
diff --git a/app/code/Magento/MediaGalleryMetadata/Test/_files/macos-preview.png b/app/code/Magento/MediaGalleryMetadata/Test/_files/macos-preview.png
index 966520f0d011..95eb45f69b3e 100644
Binary files a/app/code/Magento/MediaGalleryMetadata/Test/_files/macos-preview.png and b/app/code/Magento/MediaGalleryMetadata/Test/_files/macos-preview.png differ
diff --git a/app/code/Magento/MediaGalleryMetadata/etc/di.xml b/app/code/Magento/MediaGalleryMetadata/etc/di.xml
index d2f1f9051048..4cd9a34e43a9 100644
--- a/app/code/Magento/MediaGalleryMetadata/etc/di.xml
+++ b/app/code/Magento/MediaGalleryMetadata/etc/di.xml
@@ -112,6 +112,7 @@
- Magento\MediaGalleryMetadata\Model\Png\Segment\ReadXmp
- Magento\MediaGalleryMetadata\Model\Png\Segment\ReadIptc
+ - Magento\MediaGalleryMetadata\Model\Png\Segment\ReadExif
@@ -121,6 +122,7 @@
- Magento\MediaGalleryMetadata\Model\Jpeg\Segment\ReadXmp
- Magento\MediaGalleryMetadata\Model\Jpeg\Segment\ReadIptc
+ - Magento\MediaGalleryMetadata\Model\Jpeg\Segment\ReadExif