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; } }