Files
2026-09-15 10:26:34 +08:00

397 lines
14 KiB
PHP
Executable File

<?php
/**
* Magezon
*
* This source file is subject to the Magezon Software License, which is available at https://www.magezon.com/license/.
* Do not edit or add to this file if you wish to upgrade the to newer versions in the future.
* If you wish to customize this module for your needs.
* Please refer to https://www.magezon.com for more information.
*
* @category Magezon
* @package Magezon_QuickOrder
* @copyright Copyright (C) 2018 Magezon (https://www.magezon.com)
*/
namespace Magezon\QuickOrder\Model;
use Magento\Catalog\Helper\ImageFactory as HelperFactory;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\Product\Type;
use Magento\Catalog\Model\ProductRepository;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\NoSuchEntityException;
use Psr\Log\LoggerInterface;
class ProductManagement
{
const QUICKORDER_PRODUCT_LIST = 'QUICKORDER_PRODUCT_LIST';
/**
* @var HelperFactory
*/
protected $helperFactory;
/**
* @var \Magento\Catalog\Model\Config
*/
protected $_catalogConfig;
/**
* @var \Magento\Catalog\Model\Product\Visibility
*/
protected $catalogProductVisibility;
/**
* @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
*/
protected $productCollectionFactory;
/**
* @var \Magento\Framework\App\CacheInterface
*/
protected $cacheManager;
/**
* @var \Magento\Framework\View\LayoutInterface
*/
protected $layout;
/**
* @var \Magento\Framework\Pricing\PriceCurrencyInterface
*/
protected $priceCurrency;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $_storeManager;
/**
* @var \Magento\Framework\View\DesignInterface
*/
protected $_design;
/**
* @var \Magento\Framework\App\Http\Context
*/
protected $httpContext;
/**
* @var \Magezon\Core\Helper\Data
*/
protected $coreHelper;
private ProductRepository $productRepository;
private \Magento\Bundle\Model\Product\Type $bundle;
private Configurable $configurable;
protected LoggerInterface $logger;
/**
* @param HelperFactory $helperFactory
* @param \Magento\Catalog\Model\Config $catalogConfig
* @param \Magento\Catalog\Model\Product\Visibility $catalogProductVisibility
* @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
* @param \Magento\Framework\App\CacheInterface $cacheManager
* @param \Magento\Framework\View\LayoutInterface $layout
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\View\DesignInterface $design
* @param \Magento\Framework\App\Http\Context $httpContext
* @param \Magezon\Core\Helper\Data $coreHelper
*/
public function __construct(
HelperFactory $helperFactory,
\Magento\Catalog\Model\Config $catalogConfig,
\Magento\Catalog\Model\Product\Visibility $catalogProductVisibility,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Framework\App\CacheInterface $cacheManager,
\Magento\Framework\View\LayoutInterface $layout,
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\View\DesignInterface $design,
\Magento\Framework\App\Http\Context $httpContext,
\Magezon\Core\Helper\Data $coreHelper,
Configurable $configurable,
\Magento\Bundle\Model\Product\Type $bundle,
ProductRepository $productRepository
) {
$this->helperFactory = $helperFactory;
$this->_catalogConfig = $catalogConfig;
$this->catalogProductVisibility = $catalogProductVisibility;
$this->productCollectionFactory = $productCollectionFactory;
$this->cacheManager = $cacheManager;
$this->layout = $layout;
$this->coreHelper = $coreHelper;
$this->priceCurrency = $priceCurrency;
$this->_storeManager = $storeManager;
$this->_design = $design;
$this->httpContext = $httpContext;
$this->productRepository = $productRepository;
$this->configurable = $configurable;
$this->bundle = $bundle;
$this->logger = ObjectManager::getInstance()->get(LoggerInterface::class);
}
/**
* @return string
*/
public function getCacheKey()
{
$cache = [
self::QUICKORDER_PRODUCT_LIST,
$this->priceCurrency->getCurrency()->getCode(),
$this->_storeManager->getStore()->getId(),
$this->_design->getDesignTheme()->getId(),
$this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_GROUP)
];
return implode('_', $cache);
}
/**
* @param Product $product
* @param array
* @return array
*/
public function getProductData($product)
{
$sku = $product->getSku();
$options = $this->getProductOptions($product);
if (empty($options)) {
return [];
}
$product = $options['product'];
if (!$options['visible']) {
return [];
}
$canConfigure = $product->canConfigure();
if (!$canConfigure) {
$canConfigure = $product->getRequiredOptions();
}
$helper = $this->helperFactory->create()->init($product, 'product_thumbnail_image');
$priceHtml = $this->getProductPriceHtml(
$product,
\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE,
\Magento\Framework\Pricing\Render::ZONE_ITEM_LIST
);
if (!$priceHtml) {
$priceHtml = '';
}
return [
'label' => $product->getName() . ' ' . $product->getSku(),
'id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'status' => $product->isSalable(),
'value' => $product->getId(),
'img' => $helper->getUrl(),
'price' => $product->getPrice()==0? $product->getData('real_price'):$product->getPrice(),
'canConfigure' => $canConfigure && empty($options['options']),
'url' => $product->getProductUrl(),
'openmodal' => $this->isOpenModal($product),
'priceHtml' => $priceHtml,
'type' => $product->getTypeId(),
'realSku' => $product->getData('real_sku'),
'visible' => true,
'options' => $options['options'] ?? [],
'children' => $options['children'] ?? [],
];
}
protected function getProductOptions(Product $product): array
{
$data = [];
$optionsStr = '';
$child = $product;
$parentIds = $this->configurable->getParentIdsByChild($product->getId());
// $this->logger->info('configurable $parentIds: ', ['sku' => $product->getSku(), '$parentIds' => $parentIds]);
if (empty($parentIds)) {
$parentIds = $this->bundle->getParentIdsByChild($product->getId());
// $this->logger->info('bundle $parentIds: ', ['sku' => $product->getSku(), '$parentIds' => $parentIds]);
}
if (!empty($parentIds)) {
try {
$product = $this->productRepository->getById($parentIds[0]);
} catch (NoSuchEntityException $e) {
return $data;
}
}
$product->load($product->getId());
$data['visible'] = $product->getVisibility();
if ($data['visible'] == Product\Visibility::VISIBILITY_NOT_VISIBLE ) {
return [];
}
if ($product->getTypeId() == Type::TYPE_BUNDLE) {
/* @var $parentTypeInstance \Magento\Bundle\Model\Product\Type */
$parentTypeInstance = $product->getTypeInstance();
$bundleOptions = $parentTypeInstance->getSelectionsCollection($parentTypeInstance->getOptionsIds($product), $product);
foreach ($bundleOptions as $option) {
$optionsStr .= 'bundle_option['.$option->getOptionId().']['.$option->getSelectionId().']='
.$option->getSelectionId().'&';
// $data['options'][$option->getOptionId()][$option->getSelectionId()] = $option->getData();
}
}
$children = [];
if ($product->getTypeId()== Configurable::TYPE_CODE) {
/* @var $parentTypeInstance Configurable */
$parentTypeInstance = $product->getTypeInstance();
foreach ($parentTypeInstance->getConfigurableOptions($product) as $optionId => $options) {
foreach ($options as $option) {
// $option['option_id'] = $optionId;
// $data['options'][] = $option;
if ($option['sku'] == $child->getSku()) {
$optionsStr .= 'super_attribute['.$optionId.']='.$option['value_index'].'&';
}
$children[$option['sku']] = $option['sku'];
}
}
foreach($children as $sku =>$d){
$pr = $this->productRepository->get($sku);
$children[$sku] = ['sku'=>$sku, 'price' => number_format($pr->getPrice(), 2, '.', '')];
}
}
$product->setData('real_sku', $child->getSku());
$product->setSku($child->getSku());
$product->setName($child->getName());
$product->setData('real_price', number_format($child->getPrice(), 2, '.', ''));
$data['children'] = array_values($children);
$data['product'] = $product;
$data['options'] = $optionsStr ? $optionsStr.'product='.$product->getId().'&item='.$product->getId():'';
return $data;
}
/**
* @return array
*/
public function getProductList($params)
{
// if (!isset($params['search']) && !isset($params['skus'])) {
// $productList = $this->cacheManager->load($this->getCacheKey());
// if ($productList) {
// return $this->coreHelper->unserialize($productList);
// }
// }
$collection = $this->productCollectionFactory->create();
$collection = $this->_addProductAttributesAndPrices($collection);
$loadAllProducts = true;
if (isset($params['search'])) {
$collection->addAttributeToFilter(
'sku', trim($params['search'])
);
$loadAllProducts = false;
}
if (isset($params['skus'])) {
$collection->addAttributeToFilter('sku', ['in' => $params['skus']]);
$loadAllProducts = false;
}
if ($loadAllProducts) {
$collection->setVisibility($this->catalogProductVisibility->getVisibleInCatalogIds());
$collection = $this->_addProductAttributesAndPrices($collection)->addStoreFilter();
}
$collection->addAttributeToFilter('type_id', ['neq' => Product\Type::TYPE_VIRTUAL]);
$list = $temp = [];
foreach ($collection as $product) {
$productData = $this->getProductData($product);
if (!empty($product) && $productData['status']) {
$temp[$productData['realSku']] = $productData;
}
}
if (isset($params['skus'])) {
foreach ($params['skus'] as $sku) {
if (isset($temp[$sku])) {
$list[] = $temp[$sku];
}
}
} else {
$list = array_values($temp);
}
if (!isset($params['search'])) {
$this->cacheManager->save(
$this->coreHelper->serialize($list),
$this->getCacheKey(),
[
Product::CACHE_TAG,
\Magento\Framework\App\Cache\Type\Block::CACHE_TAG
]
);
}
return $list;
}
public function getProductPriceHtml(
Product $product,
$priceType,
$renderZone = \Magento\Framework\Pricing\Render::ZONE_ITEM_LIST,
array $arguments = []
) {
if (!isset($arguments['zone'])) {
$arguments['zone'] = $renderZone;
}
/** @var \Magento\Framework\Pricing\Render $priceRender */
$priceRender = $this->layout->getBlock('product.price.render.default');
$price = '';
if (!$priceRender) {
$priceRender = $this->layout->createBlock(
\Magento\Framework\Pricing\Render::class,
'product.price.render.default',
['data' => ['price_render_handle' => 'catalog_product_prices']]
);
}
$price = $priceRender->render($priceType, $product, $arguments);
return $price;
}
/**
* Add all attributes and apply pricing logic to products collection
* to get correct values in different products lists.
* E.g. crosssells, upsells, new products, recently viewed
*
* @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
* @return \Magento\Catalog\Model\ResourceModel\Product\Collection
*/
protected function _addProductAttributesAndPrices(
\Magento\Catalog\Model\ResourceModel\Product\Collection $collection
) {
return $collection
->addMinimalPrice()
->addFinalPrice()
->addTaxPercents()
->addAttributeToSelect($this->_catalogConfig->getProductAttributes())
->addUrlRewrite();
}
/**
* Extend for party extension
* @param Product $product
* @return boolean
*/
public function isOpenModal($product) {
return false;
}
}