Skip to content

Commit e2854db

Browse files
committed
introduced product image metadata
size of images is stored in database
1 parent b5ff0b7 commit e2854db

File tree

6 files changed

+102
-30
lines changed

6 files changed

+102
-30
lines changed

app/code/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/Gallery/Content.php

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
*/
1414
namespace Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery;
1515

16-
use Magento\Framework\App\ObjectManager;
16+
use Magento\Backend\Block\DataProviders\ImageUploadConfig as ImageUploadConfigDataProvider;
1717
use Magento\Backend\Block\Media\Uploader;
18-
use Magento\Framework\View\Element\AbstractBlock;
1918
use Magento\Framework\App\Filesystem\DirectoryList;
19+
use Magento\Framework\App\ObjectManager;
2020
use Magento\Framework\Exception\FileSystemException;
21-
use Magento\Backend\Block\DataProviders\ImageUploadConfig as ImageUploadConfigDataProvider;
21+
use Magento\Framework\View\Element\AbstractBlock;
2222
use Magento\MediaStorage\Helper\File\Storage\Database;
2323

2424
/**
@@ -56,6 +56,11 @@ class Content extends \Magento\Backend\Block\Widget
5656
*/
5757
private $fileStorageDatabase;
5858

59+
/**
60+
* @var \Magento\Framework\Filesystem\Directory\ReadInterface
61+
*/
62+
private $mediaDirectory;
63+
5964
/**
6065
* @param \Magento\Backend\Block\Template\Context $context
6166
* @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
@@ -75,6 +80,7 @@ public function __construct(
7580
$this->_jsonEncoder = $jsonEncoder;
7681
$this->_mediaConfig = $mediaConfig;
7782
parent::__construct($context, $data);
83+
$this->mediaDirectory = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA);
7884
$this->imageUploadConfigDataProvider = $imageUploadConfigDataProvider
7985
?: ObjectManager::getInstance()->get(ImageUploadConfigDataProvider::class);
8086
$this->fileStorageDatabase = $fileStorageDatabase
@@ -157,6 +163,38 @@ public function getAddImagesButton()
157163
);
158164
}
159165

166+
/**
167+
* @param string $fileName
168+
*/
169+
private function syncImageToDatabase(string $fileName): void
170+
{
171+
if ($this->fileStorageDatabase->checkDbUsage() &&
172+
!$this->mediaDirectory->isFile($this->_mediaConfig->getMediaPath($fileName))
173+
) {
174+
$this->fileStorageDatabase->saveFileToFilesystem(
175+
$this->_mediaConfig->getMediaPath($fileName)
176+
);
177+
}
178+
}
179+
180+
/**
181+
* @param string $fileName
182+
* @return array
183+
*/
184+
private function getFileMetadata(string $fileName): array
185+
{
186+
$metadata = [];
187+
try {
188+
$fileHandler = $this->mediaDirectory->stat($this->_mediaConfig->getMediaPath($fileName));
189+
$metadata['size'] = $fileHandler['size'];
190+
} catch (FileSystemException $e) {
191+
$metadata['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('small_image');
192+
$metadata['size'] = 0;
193+
$this->_logger->warning($e);
194+
}
195+
return $metadata;
196+
}
197+
160198
/**
161199
* Returns image json
162200
*
@@ -170,24 +208,14 @@ public function getImagesJson()
170208
is_array($value['images']) &&
171209
count($value['images'])
172210
) {
173-
$mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA);
174211
$images = $this->sortImagesByPosition($value['images']);
175212
foreach ($images as &$image) {
176213
$image['url'] = $this->_mediaConfig->getMediaUrl($image['file']);
177-
if ($this->fileStorageDatabase->checkDbUsage() &&
178-
!$mediaDir->isFile($this->_mediaConfig->getMediaPath($image['file']))
179-
) {
180-
$this->fileStorageDatabase->saveFileToFilesystem(
181-
$this->_mediaConfig->getMediaPath($image['file'])
182-
);
183-
}
184-
try {
185-
$fileHandler = $mediaDir->stat($this->_mediaConfig->getMediaPath($image['file']));
186-
$image['size'] = $fileHandler['size'];
187-
} catch (FileSystemException $e) {
188-
$image['url'] = $this->getImageHelper()->getDefaultPlaceholderUrl('small_image');
189-
$image['size'] = 0;
190-
$this->_logger->warning($e);
214+
$this->syncImageToDatabase($image['file']);
215+
if (isset($image['image_metadata']) && is_array($image['image_metadata'])) {
216+
$image = array_replace_recursive($image, $image['image_metadata']);
217+
} else {
218+
$image = array_replace_recursive($image, $this->getFileMetadata($image['file']));
191219
}
192220
}
193221
return $this->_jsonEncoder->encode($images);

app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,8 @@ protected function processNewAndExistingImages($product, array &$images)
290290
$data['position'] = isset($image['position']) ? (int)$image['position'] : 0;
291291
$data['disabled'] = isset($image['disabled']) ? (int)$image['disabled'] : 0;
292292
$data['store_id'] = (int)$product->getStoreId();
293-
293+
$stat = $this->mediaDirectory->stat($this->mediaConfig->getMediaPath($image['file']));
294+
$data['image_metadata']['size'] = $stat['size'];
294295
$data[$this->metadata->getLinkField()] = (int)$product->getData($this->metadata->getLinkField());
295296

296297
$this->resourceModel->insertGalleryValueInStore($data);

app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Magento\Catalog\Model\Indexer\Product\Price\PriceTableResolver;
1313
use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus;
1414
use Magento\Catalog\Model\Product\Gallery\ReadHandler as GalleryReadHandler;
15+
use Magento\Catalog\Model\ResourceModel\Category;
1516
use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory;
1617
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
1718
use Magento\CatalogUrlRewrite\Model\Storage\DbStorage;
@@ -23,7 +24,6 @@
2324
use Magento\Framework\Indexer\DimensionFactory;
2425
use Magento\Store\Model\Indexer\WebsiteDimensionProvider;
2526
use Magento\Store\Model\Store;
26-
use Magento\Catalog\Model\ResourceModel\Category;
2727

2828
/**
2929
* Product collection

app/code/Magento/Catalog/Model/ResourceModel/Product/Gallery.php

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Magento\Catalog\Model\ResourceModel\Product;
88

9+
use Magento\Framework\DB\Select;
10+
use Magento\Framework\DB\Sql\ColumnValueExpression;
911
use Magento\Store\Model\Store;
1012

1113
/**
@@ -33,10 +35,12 @@ class Gallery extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
3335
protected $metadata;
3436

3537
/**
36-
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
37-
* @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
38-
* @param string $connectionName
39-
*/
38+
* Gallery constructor.
39+
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
40+
* @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
41+
* @param null $connectionName
42+
* @throws \Exception
43+
*/
4044
public function __construct(
4145
\Magento\Framework\Model\ResourceModel\Db\Context $context,
4246
\Magento\Framework\EntityManager\MetadataPool $metadataPool,
@@ -134,16 +138,18 @@ public function loadProductGalleryByAttributeId($product, $attributeId)
134138
$result = $this->getConnection()->fetchAll($select);
135139

136140
$this->removeDuplicates($result);
137-
138141
return $result;
139142
}
140143

141144
/**
142145
* Create base load select
143146
*
147+
* Misleading method, methods relies on autoincrement field instead of entity ID
148+
*
144149
* @param int $entityId
145150
* @param int $storeId
146151
* @param int $attributeId
152+
* @deprecated
147153
* @return \Magento\Framework\DB\Select
148154
* @throws \Magento\Framework\Exception\LocalizedException
149155
* @since 101.0.0
@@ -159,6 +165,34 @@ protected function createBaseLoadSelect($entityId, $storeId, $attributeId)
159165
return $select;
160166
}
161167

168+
/**
169+
* @param int $storeId
170+
* @param array $entityIds
171+
* @param bool $preserveSortOrder
172+
* @return array
173+
* @throws \Magento\Framework\Exception\LocalizedException
174+
* @throws \Zend_Db_Statement_Exception
175+
*/
176+
public function getMediaRecords(int $storeId, array $entityIds, bool $preserveSortOrder = false) : array
177+
{
178+
$output = [];
179+
$linkField = $this->metadata->getLinkField();
180+
$select = $this->createBatchBaseSelect($storeId)
181+
->where('cpe.' . $linkField . ' IN (?)', $entityIds);
182+
if (!$preserveSortOrder) {
183+
// due to performance consideration it is better to do not use sorting for this query
184+
$select->reset(Select::ORDER);
185+
}
186+
$cursor = $this->getConnection()->query($select);
187+
while ($row = $cursor->fetch()) {
188+
if (!empty($row['image_metadata'])) {
189+
$row['image_metadata'] = $this->getSerializer()->unserialize($row['image_metadata']);
190+
}
191+
$output[] = $row;
192+
}
193+
return $output;
194+
}
195+
162196
/**
163197
* Create batch base select
164198
*
@@ -191,6 +225,10 @@ public function createBatchBaseSelect($storeId, $attributeId)
191225
['entity' => $this->getTable(self::GALLERY_VALUE_TO_ENTITY_TABLE)],
192226
$mainTableAlias . '.value_id = entity.value_id',
193227
[$linkField]
228+
)->joinInner(
229+
['cpe' => $this->getTable('catalog_product_entity')],
230+
sprintf('cpe.%1$s = entity.%1$s', $linkField),
231+
['entity_id' => 'cpe.entity_id']
194232
)->joinLeft(
195233
['value' => $this->getTable(self::GALLERY_VALUE_TABLE)],
196234
implode(
@@ -219,11 +257,11 @@ public function createBatchBaseSelect($storeId, $attributeId)
219257
'disabled' => $this->getConnection()->getIfNullSql('`value`.`disabled`', '`default_value`.`disabled`'),
220258
'label_default' => 'default_value.label',
221259
'position_default' => 'default_value.position',
222-
'disabled_default' => 'default_value.disabled'
260+
'disabled_default' => 'default_value.disabled',
261+
'image_metadata' => new ColumnValueExpression(
262+
'JSON_MERGE_PATCH(default_value.image_metadata, value.image_metadata)'
263+
)
223264
])->where(
224-
$mainTableAlias . '.attribute_id = ?',
225-
$attributeId
226-
)->where(
227265
$mainTableAlias . '.disabled = 0'
228266
)->order(
229267
$positionCheckSql . ' ' . \Magento\Framework\DB\Select::SQL_ASC
@@ -357,6 +395,9 @@ public function insertGalleryValueInStore($data)
357395
$this->getTable(self::GALLERY_VALUE_TABLE)
358396
);
359397

398+
if ($data['image_metadata']) {
399+
$data['image_metadata'] = $this->getSerializer()->serialize($data['image_metadata']);
400+
}
360401
$this->getConnection()->insert(
361402
$this->getTable(self::GALLERY_VALUE_TABLE),
362403
$data

app/code/Magento/Catalog/etc/db_schema.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,7 @@
813813
default="0" comment="Is Disabled"/>
814814
<column xsi:type="int" name="record_id" padding="10" unsigned="true" nullable="false" identity="true"
815815
comment="Record ID"/>
816+
<column xsi:type="json" name="image_metadata" comment="Image metadata"/>
816817
<constraint xsi:type="primary" referenceId="PRIMARY">
817818
<column name="record_id"/>
818819
</constraint>

app/code/Magento/Catalog/etc/db_schema_whitelist.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@
479479
"label": true,
480480
"position": true,
481481
"disabled": true,
482-
"record_id": true
482+
"record_id": true,
483+
"image_metadata": true
483484
},
484485
"index": {
485486
"CATALOG_PRODUCT_ENTITY_MEDIA_GALLERY_VALUE_STORE_ID": true,

0 commit comments

Comments
 (0)