![]() 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-wishlist/Model/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Wishlist\Model; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Model\AbstractModel; use Magento\Wishlist\Model\Item\Option; use Magento\Wishlist\Model\Item\OptionFactory; use Magento\Wishlist\Model\ResourceModel\Item\Option\CollectionFactory; use Magento\Catalog\Model\Product\Exception as ProductException; /** * Wishlist item model * * @method int getWishlistId() * @method \Magento\Wishlist\Model\Item setWishlistId(int $value) * @method int getProductId() * @method \Magento\Wishlist\Model\Item setProductId(int $value) * @method int getStoreId() * @method \Magento\Wishlist\Model\Item setStoreId(int $value) * @method string getAddedAt() * @method \Magento\Wishlist\Model\Item setAddedAt(string $value) * @method string getDescription() * @method \Magento\Wishlist\Model\Item setDescription(string $value) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * * @api * @since 100.0.2 */ class Item extends AbstractModel implements ItemInterface { /** * Custom path to download attached file * @var string */ protected $_customOptionDownloadUrl = 'wishlist/index/downloadCustomOption'; /** * Prefix of model events names * * @var string */ protected $_eventPrefix = 'wishlist_item'; /** * Parameter name in event * * In observe method you can use $observer->getEvent()->getItem() in this case * * @var string */ protected $_eventObject = 'item'; /** * Item options array * * @var Option[] */ protected $_options = []; /** * Item options by code cache * * @var array */ protected $_optionsByCode = []; /** * Not Represent options * * @var string[] */ protected $_notRepresentOptions = ['info_buyRequest']; /** * Flag stating that options were successfully saved * * @var bool|null */ protected $_flagOptionsSaved = null; /** * @var \Magento\Store\Model\StoreManagerInterface */ protected $_storeManager; /** * @var \Magento\Framework\Stdlib\DateTime\DateTime */ protected $_date; /** * @var \Magento\Catalog\Model\ResourceModel\Url */ protected $_catalogUrl; /** * @var OptionFactory */ protected $_wishlistOptFactory; /** * @var CollectionFactory */ protected $_wishlOptionCollectionFactory; /** * @var \Magento\Catalog\Model\ProductTypes\ConfigInterface */ protected $productTypeConfig; /** * @var ProductRepositoryInterface */ protected $productRepository; /** * Serializer interface instance. * * @var \Magento\Framework\Serialize\Serializer\Json */ private $serializer; /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\Stdlib\DateTime\DateTime $date * @param \Magento\Catalog\Model\ResourceModel\Url $catalogUrl * @param OptionFactory $wishlistOptFactory * @param CollectionFactory $wishlOptionCollectionFactory * @param \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig * @param ProductRepositoryInterface $productRepository * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( \Magento\Framework\Model\Context $context, \Magento\Framework\Registry $registry, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Framework\Stdlib\DateTime\DateTime $date, \Magento\Catalog\Model\ResourceModel\Url $catalogUrl, OptionFactory $wishlistOptFactory, CollectionFactory $wishlOptionCollectionFactory, \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig, ProductRepositoryInterface $productRepository, \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [], \Magento\Framework\Serialize\Serializer\Json $serializer = null ) { $this->productTypeConfig = $productTypeConfig; $this->_storeManager = $storeManager; $this->_date = $date; $this->_catalogUrl = $catalogUrl; $this->_wishlistOptFactory = $wishlistOptFactory; $this->_wishlOptionCollectionFactory = $wishlOptionCollectionFactory; $this->serializer = $serializer ?: \Magento\Framework\App\ObjectManager::getInstance() ->get(\Magento\Framework\Serialize\Serializer\Json::class); parent::__construct($context, $registry, $resource, $resourceCollection, $data); $this->productRepository = $productRepository; } /** * Initialize resource model * * @return void */ protected function _construct() { $this->_init(\Magento\Wishlist\Model\ResourceModel\Item::class); } /** * Set quantity. If quantity is less than 0 - set it to 1 * * @param int $qty * @return $this */ public function setQty($qty) { $this->setData('qty', $qty >= 0 ? $qty : 1); return $this; } /** * Check if two options array are identical * * @param array $options1 * @param array $options2 * @return bool */ protected function _compareOptions($options1, $options2) { $skipOptions = ['id', 'qty', 'return_url']; foreach ($options1 as $code => $value) { if (in_array($code, $skipOptions)) { continue; } if (!isset($options2[$code]) || $options2[$code] != $value) { return false; } } return true; } /** * Register option code * * @param Option $option * @return $this * @throws \Magento\Framework\Exception\LocalizedException */ protected function _addOptionCode($option) { if (!isset($this->_optionsByCode[$option->getCode()])) { $this->_optionsByCode[$option->getCode()] = $option; } else { throw new \Magento\Framework\Exception\LocalizedException( __('An item option with code %1 already exists.', $option->getCode()) ); } return $this; } /** * Checks that item model has data changes. * Call save item options if model isn't need to save in DB * * @return boolean */ protected function _hasModelChanged() { if (!$this->hasDataChanges()) { return false; } return $this->_getResource()->hasDataChanged($this); } /** * Save item options * * @return $this */ public function saveItemOptions() { foreach ($this->_options as $index => $option) { if ($option->isDeleted()) { $option->delete(); unset($this->_options[$index]); unset($this->_optionsByCode[$option->getCode()]); } else { $option->save(); } } $this->_flagOptionsSaved = true; // Report to watchers that options were saved return $this; } /** * Mark option save requirement * * @param bool $flag * @return void */ public function setIsOptionsSaved($flag) { $this->_flagOptionsSaved = $flag; } /** * Were options saved? * * @return bool */ public function isOptionsSaved() { return $this->_flagOptionsSaved; } /** * Save item options after item saved * * @return $this */ public function afterSave() { $this->saveItemOptions(); return parent::afterSave(); } /** * Validate wish list item data * * @return bool * @throws \Magento\Framework\Exception\LocalizedException */ public function validate() { if (!$this->getWishlistId()) { throw new \Magento\Framework\Exception\LocalizedException(__('We can\'t specify a wish list.')); } if (!$this->getProductId()) { throw new \Magento\Framework\Exception\LocalizedException(__('Cannot specify product.')); } return true; } /** * Check required data * * @return $this */ public function beforeSave() { parent::beforeSave(); // validate required item data $this->validate(); // set current store id if it is not defined if ($this->getStoreId() === null) { $this->setStoreId($this->_storeManager->getStore()->getId()); } // set current date if added at data is not defined if ($this->getAddedAt() === null) { $this->setAddedAt($this->_date->gmtDate()); } return $this; } /** * Load item by product, wishlist and shared stores * * @param int $wishlistId * @param int $productId * @param array $sharedStores * @return $this */ public function loadByProductWishlist($wishlistId, $productId, $sharedStores) { $this->_getResource()->loadByProductWishlist($this, $wishlistId, $productId, $sharedStores); $this->_afterLoad(); $this->setOrigData(); return $this; } /** * Retrieve item product instance * * @throws \Magento\Framework\Exception\LocalizedException * @return \Magento\Catalog\Model\Product */ public function getProduct() { $product = $this->_getData('product'); if ($product === null) { if (!$this->getProductId()) { throw new \Magento\Framework\Exception\LocalizedException(__('Cannot specify product.')); } try { $product = $this->productRepository->getById($this->getProductId(), false, $this->getStoreId(), true); } catch (NoSuchEntityException $e) { throw new \Magento\Framework\Exception\LocalizedException(__('Cannot specify product.'), $e); } $this->setData('product', $product); } /** * Reset product final price because it related to custom options */ $product->setFinalPrice(null); $product->setCustomOptions($this->_optionsByCode); return $product; } /** * Add or Move item product to shopping cart * * Return true if product was successful added or exception with code * Return false for disabled or unvisible products * * @param \Magento\Checkout\Model\Cart $cart * @param bool $delete delete the item after successful add to cart * @return bool * @throws \Magento\Catalog\Model\Product\Exception */ public function addToCart(\Magento\Checkout\Model\Cart $cart, $delete = false) { $product = $this->getProduct(); $storeId = $this->getStoreId(); if ($product->getStatus() != \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) { return false; } if (!$product->isVisibleInSiteVisibility()) { if ($product->getStoreId() == $storeId) { return false; } $urlData = $this->_catalogUrl->getRewriteByProductStore([$product->getId() => $storeId]); if (!isset($urlData[$product->getId()])) { return false; } $product->setUrlDataObject(new \Magento\Framework\DataObject($urlData)); $visibility = $product->getUrlDataObject()->getVisibility(); if (!in_array($visibility, $product->getVisibleInSiteVisibilities())) { return false; } } if (!$product->isSalable()) { throw new ProductException(__('Product is not salable.')); } $buyRequest = $this->getBuyRequest(); $cart->addProduct($product, $buyRequest); if (!$product->isVisibleInSiteVisibility()) { $cart->getQuote()->getItemByProduct($product)->setStoreId($storeId); } if ($delete) { $this->delete(); } return true; } /** * Retrieve Product View Page URL * * If product has required options add special key to URL * * @return string */ public function getProductUrl() { $product = $this->getProduct(); $query = []; if ($product->getTypeInstance()->hasRequiredOptions($product)) { $query['options'] = 'cart'; } return $product->getUrlModel()->getUrl($product, ['_query' => $query]); } /** * Returns formatted buy request - object, holding request received from * product view page with keys and options for configured product * * @return \Magento\Framework\DataObject */ public function getBuyRequest() { $option = $this->getOptionByCode('info_buyRequest'); $initialData = $option ? $this->serializer->unserialize($option->getValue()) : []; if ($initialData instanceof \Magento\Framework\DataObject) { $initialData = $initialData->getData(); } $buyRequest = new \Magento\Framework\DataObject($initialData); $buyRequest->setOriginalQty($buyRequest->getQty())->setQty($this->getQty() * 1); return $buyRequest; } /** * Merge data to item info_buyRequest option * * @param array|\Magento\Framework\DataObject $buyRequest * @return $this */ public function mergeBuyRequest($buyRequest) { if ($buyRequest instanceof \Magento\Framework\DataObject) { $buyRequest = $buyRequest->getData(); } if (empty($buyRequest) || !is_array($buyRequest)) { return $this; } $oldBuyRequest = $this->getBuyRequest()->getData(); $sBuyRequest = $this->serializer->serialize($buyRequest + $oldBuyRequest); $option = $this->getOptionByCode('info_buyRequest'); if ($option) { $option->setValue($sBuyRequest); } else { $this->addOption(['code' => 'info_buyRequest', 'value' => $sBuyRequest]); } return $this; } /** * Set buy request - object, holding request received from * product view page with keys and options for configured product * * @param \Magento\Framework\DataObject $buyRequest * @return $this */ public function setBuyRequest($buyRequest) { $buyRequest->setId($this->getId()); $_buyRequest = $this->serializer->serialize($buyRequest->getData()); $this->setData('buy_request', $_buyRequest); return $this; } /** * Check product representation in item * * @param \Magento\Catalog\Model\Product $product * @param \Magento\Framework\DataObject $buyRequest * @return bool */ public function isRepresent($product, $buyRequest) { if ($this->getProductId() != $product->getId()) { return false; } $selfOptions = $this->getBuyRequest()->getData(); if (empty($buyRequest) && !empty($selfOptions)) { return false; } if (empty($selfOptions) && !empty($buyRequest)) { if (!$product->isComposite()) { return true; } else { return false; } } $requestArray = $buyRequest->getData(); if (!$this->_compareOptions($requestArray, $selfOptions)) { return false; } if (!$this->_compareOptions($selfOptions, $requestArray)) { return false; } return true; } /** * Check product representation in item * * @param \Magento\Catalog\Model\Product $product * @return bool */ public function representProduct($product) { $itemProduct = $this->getProduct(); if ($itemProduct->getId() != $product->getId()) { return false; } $itemOptions = $this->getOptionsByCode(); $productOptions = $product->getCustomOptions(); if (!$this->compareOptions($itemOptions, $productOptions)) { return false; } if (!$this->compareOptions($productOptions, $itemOptions)) { return false; } return true; } /** * Check if two options array are identical * First options array is prerogative * Second options array checked against first one * * @param array $options1 * @param array $options2 * @return bool */ public function compareOptions($options1, $options2) { foreach ($options1 as $option) { $code = $option->getCode(); if (in_array($code, $this->_notRepresentOptions)) { continue; } if (!isset($options2[$code]) || $options2[$code]->getValue() != $option->getValue()) { return false; } } return true; } /** * Initialize item options * * @param array $options * @return $this */ public function setOptions($options) { foreach ($options as $option) { $this->addOption($option); } return $this; } /** * Get all item options * * @return Option[] */ public function getOptions() { return $this->_options; } /** * Get all item options as array with codes in array key * * @return array */ public function getOptionsByCode() { return $this->_optionsByCode; } /** * Add option to item * * @param Option|\Magento\Framework\DataObject|array $option * @return $this * @throws \Magento\Framework\Exception\LocalizedException */ public function addOption($option) { if (is_array($option)) { $option = $this->_wishlistOptFactory->create()->setData($option)->setItem($this); } elseif ($option instanceof Option) { $option->setItem($this); } elseif ($option instanceof \Magento\Framework\DataObject) { $option = $this->_wishlistOptFactory->create()->setData($option->getData()) ->setProduct($option->getProduct()) ->setItem($this); } else { throw new \Magento\Framework\Exception\LocalizedException(__('Invalid item option format.')); } $exOption = $this->getOptionByCode($option->getCode()); if ($exOption) { $exOption->addData($option->getData()); } else { $this->_addOptionCode($option); $this->_options[] = $option; } return $this; } /** * Remove option from item options * * @param string $code * @return $this */ public function removeOption($code) { $option = $this->getOptionByCode($code); if ($option) { $option->isDeleted(true); } return $this; } /** * Get item option by code * * @param string $code * @return Option|null */ public function getOptionByCode($code) { if (isset($this->_optionsByCode[$code]) && !$this->_optionsByCode[$code]->isDeleted()) { return $this->_optionsByCode[$code]; } return null; } /** * Returns whether Qty field is valid for this item * * @return bool */ public function canHaveQty() { $product = $this->getProduct(); return !$this->productTypeConfig->isProductSet($product->getTypeId()); } /** * Get current custom option download url * * @return string */ public function getCustomDownloadUrl() { return $this->_customOptionDownloadUrl; } /** * Sets custom option download url * * @param string $url * @return void */ public function setCustomDownloadUrl($url) { $this->_customOptionDownloadUrl = $url; } /** * Returns special download params (if needed) for custom option with type = 'file'. * Needed to implement \Magento\Catalog\Model\Product\Configuration\Item\Interface. * * We have to customize only controller url, so return it. * * @return null|\Magento\Framework\DataObject */ public function getFileDownloadParams() { $params = new \Magento\Framework\DataObject(); $params->setUrl($this->_customOptionDownloadUrl); return $params; } /** * Loads item together with its options (default load() method doesn't load options). * If we need to load only some of options, then option code or array of option codes * can be provided in $optionsFilter. * * @param int $id * @param null|string|array $optionsFilter * * @return $this */ public function loadWithOptions($id, $optionsFilter = null) { $this->load($id); if (!$this->getId()) { return $this; } $options = $this->_wishlOptionCollectionFactory->create()->addItemFilter($this); if ($optionsFilter) { $options->addFieldToFilter('code', $optionsFilter); } $this->setOptions($options->getOptionsByItem($this)); return $this; } }