![]() 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/Controller/Adminhtml/Product/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Catalog\Controller\Adminhtml\Product; use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface; use Magento\Backend\App\Action; use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Controller\Adminhtml\Product; use Magento\Framework\App\ObjectManager; use Magento\Store\Model\StoreManagerInterface; use Magento\Framework\App\Request\DataPersistorInterface; /** * Product save controller * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Save extends \Magento\Catalog\Controller\Adminhtml\Product implements HttpPostActionInterface { /** * @var Initialization\Helper */ protected $initializationHelper; /** * @var \Magento\Catalog\Model\Product\Copier */ protected $productCopier; /** * @var \Magento\Catalog\Model\Product\TypeTransitionManager */ protected $productTypeManager; /** * @var \Magento\Catalog\Api\CategoryLinkManagementInterface */ protected $categoryLinkManagement; /** * @var \Magento\Catalog\Api\ProductRepositoryInterface */ protected $productRepository; /** * @var DataPersistorInterface */ protected $dataPersistor; /** * @var StoreManagerInterface */ private $storeManager; /** * @var \Magento\Framework\Escaper */ private $escaper; /** * @var \Psr\Log\LoggerInterface */ private $logger; /** * Save constructor. * * @param Action\Context $context * @param Builder $productBuilder * @param Initialization\Helper $initializationHelper * @param \Magento\Catalog\Model\Product\Copier $productCopier * @param \Magento\Catalog\Model\Product\TypeTransitionManager $productTypeManager * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository * @param \Magento\Framework\Escaper $escaper * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement * @param StoreManagerInterface $storeManager * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Backend\App\Action\Context $context, Product\Builder $productBuilder, Initialization\Helper $initializationHelper, \Magento\Catalog\Model\Product\Copier $productCopier, \Magento\Catalog\Model\Product\TypeTransitionManager $productTypeManager, \Magento\Catalog\Api\ProductRepositoryInterface $productRepository, \Magento\Framework\Escaper $escaper = null, \Psr\Log\LoggerInterface $logger = null, \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement = null, \Magento\Store\Model\StoreManagerInterface $storeManager = null ) { parent::__construct($context, $productBuilder); $this->initializationHelper = $initializationHelper; $this->productCopier = $productCopier; $this->productTypeManager = $productTypeManager; $this->productRepository = $productRepository; $this->escaper = $escaper ?: ObjectManager::getInstance() ->get(\Magento\Framework\Escaper::class); $this->logger = $logger ?: ObjectManager::getInstance() ->get(\Psr\Log\LoggerInterface::class); $this->categoryLinkManagement = $categoryLinkManagement ?: ObjectManager::getInstance() ->get(\Magento\Catalog\Api\CategoryLinkManagementInterface::class); $this->storeManager = $storeManager ?: ObjectManager::getInstance() ->get(\Magento\Store\Model\StoreManagerInterface::class); } /** * Save product action * * @return \Magento\Backend\Model\View\Result\Redirect * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute() { $storeId = $this->getRequest()->getParam('store', 0); $store = $this->storeManager->getStore($storeId); $this->storeManager->setCurrentStore($store->getCode()); $redirectBack = $this->getRequest()->getParam('back', false); $productId = $this->getRequest()->getParam('id'); $resultRedirect = $this->resultRedirectFactory->create(); $data = $this->getRequest()->getPostValue(); $productAttributeSetId = $this->getRequest()->getParam('set'); $productTypeId = $this->getRequest()->getParam('type'); if ($data) { try { $product = $this->initializationHelper->initialize( $this->productBuilder->build($this->getRequest()) ); $this->productTypeManager->processProduct($product); if (isset($data['product'][$product->getIdFieldName()])) { throw new \Magento\Framework\Exception\LocalizedException( __('The product was unable to be saved. Please try again.') ); } $originalSku = $product->getSku(); $canSaveCustomOptions = $product->getCanSaveCustomOptions(); $product->save(); $this->handleImageRemoveError($data, $product->getId()); $productId = $product->getEntityId(); $productAttributeSetId = $product->getAttributeSetId(); $productTypeId = $product->getTypeId(); $extendedData = $data; $extendedData['can_save_custom_options'] = $canSaveCustomOptions; $this->copyToStores($extendedData, $productId); $this->messageManager->addSuccessMessage(__('You saved the product.')); $this->getDataPersistor()->clear('catalog_product'); if ($product->getSku() != $originalSku) { $this->messageManager->addNoticeMessage( __( 'SKU for product %1 has been changed to %2.', $this->escaper->escapeHtml($product->getName()), $this->escaper->escapeHtml($product->getSku()) ) ); } $this->_eventManager->dispatch( 'controller_action_catalog_product_save_entity_after', ['controller' => $this, 'product' => $product] ); if ($redirectBack === 'duplicate') { $product->unsetData('quantity_and_stock_status'); $newProduct = $this->productCopier->copy($product); $this->checkUniqueAttributes($product); $this->messageManager->addSuccessMessage(__('You duplicated the product.')); } } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->logger->critical($e); $this->messageManager->addExceptionMessage($e); $data = isset($product) ? $this->persistMediaData($product, $data) : $data; $this->getDataPersistor()->set('catalog_product', $data); $redirectBack = $productId ? true : 'new'; } catch (\Exception $e) { $this->logger->critical($e); $this->messageManager->addErrorMessage($e->getMessage()); $data = isset($product) ? $this->persistMediaData($product, $data) : $data; $this->getDataPersistor()->set('catalog_product', $data); $redirectBack = $productId ? true : 'new'; } } else { $resultRedirect->setPath('catalog/*/', ['store' => $storeId]); $this->messageManager->addErrorMessage('No data to save'); return $resultRedirect; } if ($redirectBack === 'new') { $resultRedirect->setPath( 'catalog/*/new', ['set' => $productAttributeSetId, 'type' => $productTypeId] ); } elseif ($redirectBack === 'duplicate' && isset($newProduct)) { $resultRedirect->setPath( 'catalog/*/edit', ['id' => $newProduct->getEntityId(), 'back' => null, '_current' => true] ); } elseif ($redirectBack) { $resultRedirect->setPath( 'catalog/*/edit', ['id' => $productId, '_current' => true, 'set' => $productAttributeSetId] ); } else { $resultRedirect->setPath('catalog/*/', ['store' => $storeId]); } return $resultRedirect; } /** * Notify customer when image was not deleted in specific case. * * TODO: temporary workaround must be eliminated in MAGETWO-45306 * * @param array $postData * @param int $productId * @return void */ private function handleImageRemoveError($postData, $productId) { if (isset($postData['product']['media_gallery']['images'])) { $removedImagesAmount = 0; foreach ($postData['product']['media_gallery']['images'] as $image) { if (!empty($image['removed'])) { $removedImagesAmount++; } } if ($removedImagesAmount) { $expectedImagesAmount = count($postData['product']['media_gallery']['images']) - $removedImagesAmount; $product = $this->productRepository->getById($productId); $images = $product->getMediaGallery('images'); if (is_array($images) && $expectedImagesAmount != count($images)) { $this->messageManager->addNoticeMessage( __('The image cannot be removed as it has been assigned to the other image role') ); } } } } /** * Do copying data to stores * * @param array $data * @param int $productId * * @return void */ protected function copyToStores($data, $productId) { if (!empty($data['product']['copy_to_stores'])) { foreach ($data['product']['copy_to_stores'] as $websiteId => $group) { if (isset($data['product']['website_ids'][$websiteId]) && (bool)$data['product']['website_ids'][$websiteId]) { foreach ($group as $store) { $this->copyToStore($data, $productId, $store); } } } } } /** * Do copying data to stores * * If the 'copy_from' field is not specified in the input data, * the store fallback mechanism will automatically take the admin store's default value. * * @param array $data * @param int $productId * @param array $store */ private function copyToStore($data, $productId, $store) { if (isset($store['copy_from'])) { $copyFrom = $store['copy_from']; $copyTo = (isset($store['copy_to'])) ? $store['copy_to'] : 0; if ($copyTo) { $this->_objectManager->create(\Magento\Catalog\Model\Product::class) ->setStoreId($copyFrom) ->load($productId) ->setStoreId($copyTo) ->setCanSaveCustomOptions($data['can_save_custom_options']) ->setCopyFromView(true) ->save(); } } } /** * Retrieve data persistor * * @return DataPersistorInterface|mixed * @deprecated 101.0.0 */ protected function getDataPersistor() { if (null === $this->dataPersistor) { $this->dataPersistor = $this->_objectManager->get(DataPersistorInterface::class); } return $this->dataPersistor; } /** * Persist media gallery on error, in order to show already saved images on next run. * * @param ProductInterface $product * @param array $data * @return array */ private function persistMediaData(ProductInterface $product, array $data) { $mediaGallery = $product->getData('media_gallery'); if (!empty($mediaGallery['images'])) { foreach ($mediaGallery['images'] as $key => $image) { if (!isset($image['new_file'])) { //Remove duplicates. unset($mediaGallery['images'][$key]); } } $data['product']['media_gallery'] = $mediaGallery; $fields = [ 'image', 'small_image', 'thumbnail', 'swatch_image', ]; foreach ($fields as $field) { $data['product'][$field] = $product->getData($field); } } return $data; } /** * Check unique attributes and add error to message manager * * @param \Magento\Catalog\Model\Product $product */ private function checkUniqueAttributes(\Magento\Catalog\Model\Product $product) { $uniqueLabels = []; foreach ($product->getAttributes() as $attribute) { if ($attribute->getIsUnique() && $attribute->getIsUserDefined() && $product->getData($attribute->getAttributeCode()) !== null ) { $uniqueLabels[] = $attribute->getDefaultFrontendLabel(); } } if ($uniqueLabels) { $uniqueLabels = implode('", "', $uniqueLabels); $this->messageManager->addErrorMessage(__('The value of attribute(s) "%1" must be unique', $uniqueLabels)); } } }