![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-catalog/Model/Product/Gallery/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Catalog\Model\Product\Gallery; use Magento\Framework\Api\Data\ImageContentInterface; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\App\ObjectManager; /** * Catalog product Media Gallery attribute processor. * * @api * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 101.0.0 */ class Processor { /** * @var \Magento\Catalog\Api\Data\ProductAttributeInterface * @since 101.0.0 */ protected $attribute; /** * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface * @since 101.0.0 */ protected $attributeRepository; /** * @var \Magento\MediaStorage\Helper\File\Storage\Database * @since 101.0.0 */ protected $fileStorageDb; /** * @var \Magento\Catalog\Model\Product\Media\Config * @since 101.0.0 */ protected $mediaConfig; /** * @var \Magento\Framework\Filesystem\Directory\WriteInterface * @since 101.0.0 */ protected $mediaDirectory; /** * @var \Magento\Catalog\Model\ResourceModel\Product\Gallery * @since 101.0.0 */ protected $resourceModel; /** * @var \Magento\Framework\File\Mime */ private $mime; /** * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository * @param \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb * @param \Magento\Catalog\Model\Product\Media\Config $mediaConfig * @param \Magento\Framework\Filesystem $filesystem * @param \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel * @param \Magento\Framework\File\Mime|null $mime * @throws \Magento\Framework\Exception\FileSystemException */ public function __construct( \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository, \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageDb, \Magento\Catalog\Model\Product\Media\Config $mediaConfig, \Magento\Framework\Filesystem $filesystem, \Magento\Catalog\Model\ResourceModel\Product\Gallery $resourceModel, \Magento\Framework\File\Mime $mime = null ) { $this->attributeRepository = $attributeRepository; $this->fileStorageDb = $fileStorageDb; $this->mediaConfig = $mediaConfig; $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); $this->resourceModel = $resourceModel; $this->mime = $mime ?: ObjectManager::getInstance()->get(\Magento\Framework\File\Mime::class); } /** * Return media_gallery attribute * * @return \Magento\Catalog\Api\Data\ProductAttributeInterface * @since 101.0.0 */ public function getAttribute() { if (!$this->attribute) { $this->attribute = $this->attributeRepository->get('media_gallery'); } return $this->attribute; } /** * Validate media_gallery attribute data * * @param \Magento\Catalog\Model\Product $object * @return bool * @throws \Magento\Framework\Exception\LocalizedException * @since 101.0.0 */ public function validate($object) { if ($this->getAttribute()->getIsRequired()) { $value = $object->getData($this->getAttribute()->getAttributeCode()); if ($this->getAttribute()->isValueEmpty($value)) { return false; } } if ($this->getAttribute()->getIsUnique()) { if (!$this->getAttribute()->getEntity()->checkAttributeUniqueValue($this->getAttribute(), $object)) { $label = $this->getAttribute()->getFrontend()->getLabel(); throw new LocalizedException( __('The value of the "%1" attribute isn\'t unique. Set a unique value and try again.', $label) ); } } return true; } /** * Add image to media gallery and return new filename * * @param \Magento\Catalog\Model\Product $product * @param string $file file path of image in file system * @param string|string[] $mediaAttribute code of attribute with type 'media_image', * leave blank if image should be only in gallery * @param boolean $move if true, it will move source file * @param boolean $exclude mark image as disabled in product page view * @return string * @throws \Magento\Framework\Exception\LocalizedException * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) * @since 101.0.0 */ public function addImage( \Magento\Catalog\Model\Product $product, $file, $mediaAttribute = null, $move = false, $exclude = true ) { $file = $this->mediaDirectory->getRelativePath($file); if (!$this->mediaDirectory->isFile($file)) { throw new LocalizedException(__("The image doesn't exist.")); } // phpcs:ignore Magento2.Functions.DiscouragedFunction $pathinfo = pathinfo($file); $imgExtensions = ['jpg', 'jpeg', 'gif', 'png']; if (!isset($pathinfo['extension']) || !in_array(strtolower($pathinfo['extension']), $imgExtensions)) { throw new LocalizedException( __('The image type for the file is invalid. Enter the correct image type and try again.') ); } $fileName = \Magento\MediaStorage\Model\File\Uploader::getCorrectFileName($pathinfo['basename']); $dispersionPath = \Magento\MediaStorage\Model\File\Uploader::getDispersionPath($fileName); $fileName = $dispersionPath . '/' . $fileName; $fileName = $this->getNotDuplicatedFilename($fileName, $dispersionPath); $destinationFile = $this->mediaConfig->getTmpMediaPath($fileName); try { /** @var $storageHelper \Magento\MediaStorage\Helper\File\Storage\Database */ $storageHelper = $this->fileStorageDb; if ($move) { $this->mediaDirectory->renameFile($file, $destinationFile); //If this is used, filesystem should be configured properly $storageHelper->saveFile($this->mediaConfig->getTmpMediaShortUrl($fileName)); } else { $this->mediaDirectory->copyFile($file, $destinationFile); $storageHelper->saveFile($this->mediaConfig->getTmpMediaShortUrl($fileName)); } } catch (\Exception $e) { throw new LocalizedException(__('The "%1" file couldn\'t be moved.', $e->getMessage())); } $fileName = str_replace('\\', '/', $fileName); $attrCode = $this->getAttribute()->getAttributeCode(); $mediaGalleryData = $product->getData($attrCode); $position = 0; $absoluteFilePath = $this->mediaDirectory->getAbsolutePath($destinationFile); $imageMimeType = $this->mime->getMimeType($absoluteFilePath); $imageContent = $this->mediaDirectory->readFile($absoluteFilePath); $imageBase64 = base64_encode($imageContent); $imageName = $pathinfo['filename']; if (!is_array($mediaGalleryData)) { $mediaGalleryData = ['images' => []]; } foreach ($mediaGalleryData['images'] as &$image) { if (isset($image['position']) && $image['position'] > $position) { $position = $image['position']; } } $position++; $mediaGalleryData['images'][] = [ 'file' => $fileName, 'position' => $position, 'label' => '', 'disabled' => (int)$exclude, 'media_type' => 'image', 'types' => $mediaAttribute, 'content' => [ 'data' => [ ImageContentInterface::NAME => $imageName, ImageContentInterface::BASE64_ENCODED_DATA => $imageBase64, ImageContentInterface::TYPE => $imageMimeType, ] ] ]; $product->setData($attrCode, $mediaGalleryData); if ($mediaAttribute !== null) { $this->setMediaAttribute($product, $mediaAttribute, $fileName); } return $fileName; } /** * Update image in gallery * * @param \Magento\Catalog\Model\Product $product * @param string $file * @param array $data * @return $this * @since 101.0.0 */ public function updateImage(\Magento\Catalog\Model\Product $product, $file, $data) { $fieldsMap = [ 'label' => 'label', 'position' => 'position', 'disabled' => 'disabled', 'exclude' => 'disabled', 'media_type' => 'media_type', ]; $attrCode = $this->getAttribute()->getAttributeCode(); $mediaGalleryData = $product->getData($attrCode); if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) { return $this; } foreach ($mediaGalleryData['images'] as &$image) { if ($image['file'] == $file) { foreach ($fieldsMap as $mappedField => $realField) { if (isset($data[$mappedField])) { $image[$realField] = $data[$mappedField]; } } } } $product->setData($attrCode, $mediaGalleryData); return $this; } /** * Remove image from gallery * * @param \Magento\Catalog\Model\Product $product * @param string $file * @return $this * @since 101.0.0 */ public function removeImage(\Magento\Catalog\Model\Product $product, $file) { $attrCode = $this->getAttribute()->getAttributeCode(); $mediaGalleryData = $product->getData($attrCode); if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) { return $this; } foreach ($mediaGalleryData['images'] as &$image) { if ($image['file'] == $file) { $image['removed'] = 1; } } $product->setData($attrCode, $mediaGalleryData); return $this; } /** * Retrieve image from gallery * * @param \Magento\Catalog\Model\Product $product * @param string $file * @return array|boolean * @since 101.0.0 */ public function getImage(\Magento\Catalog\Model\Product $product, $file) { $attrCode = $this->getAttribute()->getAttributeCode(); $mediaGalleryData = $product->getData($attrCode); if (!isset($mediaGalleryData['images']) || !is_array($mediaGalleryData['images'])) { return false; } foreach ($mediaGalleryData['images'] as $image) { if ($image['file'] == $file) { return $image; } } return false; } /** * Clear media attribute value * * @param \Magento\Catalog\Model\Product $product * @param string|string[] $mediaAttribute * @return $this * @since 101.0.0 */ public function clearMediaAttribute(\Magento\Catalog\Model\Product $product, $mediaAttribute) { $mediaAttributeCodes = $this->mediaConfig->getMediaAttributeCodes(); if (is_array($mediaAttribute)) { foreach ($mediaAttribute as $attribute) { if (in_array($attribute, $mediaAttributeCodes)) { $product->setData($attribute, 'no_selection'); } } } elseif (in_array($mediaAttribute, $mediaAttributeCodes)) { $product->setData($mediaAttribute, 'no_selection'); } return $this; } /** * Set media attribute value * * @param \Magento\Catalog\Model\Product $product * @param string|string[] $mediaAttribute * @param string $value * @return $this * @since 101.0.0 */ public function setMediaAttribute(\Magento\Catalog\Model\Product $product, $mediaAttribute, $value) { $mediaAttributeCodes = $this->mediaConfig->getMediaAttributeCodes(); if (is_array($mediaAttribute)) { foreach ($mediaAttribute as $attribute) { if (in_array($attribute, $mediaAttributeCodes)) { $product->setData($attribute, $value); } } } elseif (in_array($mediaAttribute, $mediaAttributeCodes)) { $product->setData($mediaAttribute, $value); } return $this; } /** * Get media attribute codes * * @return array * @since 101.0.0 */ public function getMediaAttributeCodes() { return $this->mediaConfig->getMediaAttributeCodes(); } /** * Trim .tmp ending from filename * * @param string $file * @return string * @since 101.0.0 */ protected function getFilenameFromTmp($file) { return strrpos($file, '.tmp') == strlen($file) - 4 ? substr($file, 0, strlen($file) - 4) : $file; } /** * Duplicate temporary images * * @param string $file * @return string * @since 101.0.0 */ public function duplicateImageFromTmp($file) { $file = $this->getFilenameFromTmp((string)$file); $destinationFile = $this->getUniqueFileName($file, true); if ($this->fileStorageDb->checkDbUsage()) { $this->fileStorageDb->copyFile( $this->mediaDirectory->getAbsolutePath($this->mediaConfig->getTmpMediaShortUrl($file)), $this->mediaConfig->getTmpMediaShortUrl($destinationFile) ); } else { $this->mediaDirectory->copyFile( $this->mediaConfig->getTmpMediaPath($file), $this->mediaConfig->getTmpMediaPath($destinationFile) ); } return str_replace('\\', '/', $destinationFile); } /** * Check whether file to move exists. Getting unique name * * @param string $file * @param bool $forTmp * @return string * @since 101.0.0 */ protected function getUniqueFileName($file, $forTmp = false) { if ($this->fileStorageDb->checkDbUsage()) { $destFile = $this->fileStorageDb->getUniqueFilename( $this->mediaConfig->getBaseMediaUrlAddition(), $file ); } else { $destinationFile = $forTmp ? $this->mediaDirectory->getAbsolutePath($this->mediaConfig->getTmpMediaPath($file)) : $this->mediaDirectory->getAbsolutePath($this->mediaConfig->getMediaPath($file)); // phpcs:ignore Magento2.Functions.DiscouragedFunction $destFile = dirname($file) . '/' . \Magento\MediaStorage\Model\File\Uploader::getNewFileName($destinationFile); } return $destFile; } /** * Get filename which is not duplicated with other files in media temporary and media directories * * @param string $fileName * @param string $dispersionPath * @return string * @since 101.0.0 */ protected function getNotDuplicatedFilename($fileName, $dispersionPath) { $fileMediaName = $dispersionPath . '/' . \Magento\MediaStorage\Model\File\Uploader::getNewFileName($this->mediaConfig->getMediaPath($fileName)); $fileTmpMediaName = $dispersionPath . '/' . \Magento\MediaStorage\Model\File\Uploader::getNewFileName($this->mediaConfig->getTmpMediaPath($fileName)); if ($fileMediaName != $fileTmpMediaName) { if ($fileMediaName != $fileName) { return $this->getNotDuplicatedFilename( $fileMediaName, $dispersionPath ); } elseif ($fileTmpMediaName != $fileName) { return $this->getNotDuplicatedFilename( $fileTmpMediaName, $dispersionPath ); } } return $fileMediaName; } /** * Retrieve data for update attribute * * @param \Magento\Catalog\Model\Product $object * @return array * @since 101.0.0 */ public function getAffectedFields($object) { $data = []; $images = (array)$object->getData($this->getAttribute()->getName()); $tableName = $this->resourceModel->getMainTable(); foreach ($images['images'] as $value) { if (empty($value['value_id'])) { continue; } $data[$tableName][] = [ 'value_id' => $value['value_id'], 'attribute_id' => $this->getAttribute()->getAttributeId(), 'entity_id' => $object->getId(), ]; } return $data; } /** * Attribute value is not to be saved in a conventional way, separate table is used to store the complex value * * @since 101.0.0 */ public function isScalar() { return false; } }