![]() 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-swatches/Block/Product/Renderer/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types = 1); namespace Magento\Swatches\Block\Product\Renderer; use Magento\Catalog\Block\Product\Context; use Magento\Catalog\Helper\Product as CatalogProduct; use Magento\Catalog\Model\Product; use Magento\Catalog\Model\Product\Image\UrlBuilder; use Magento\ConfigurableProduct\Helper\Data; use Magento\ConfigurableProduct\Model\ConfigurableAttributeData; use Magento\Customer\Helper\Session\CurrentCustomer; use Magento\Framework\Json\EncoderInterface; use Magento\Framework\Pricing\PriceCurrencyInterface; use Magento\Framework\Stdlib\ArrayUtils; use Magento\Store\Model\ScopeInterface; use Magento\Swatches\Helper\Data as SwatchData; use Magento\Swatches\Helper\Media; use Magento\Swatches\Model\Swatch; use Magento\Framework\App\ObjectManager; use Magento\Swatches\Model\SwatchAttributesProvider; /** * Swatch renderer block * * @api * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @since 100.0.2 */ class Configurable extends \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable implements \Magento\Framework\DataObject\IdentityInterface { /** * Path to template file with Swatch renderer. */ const SWATCH_RENDERER_TEMPLATE = 'Magento_Swatches::product/view/renderer.phtml'; /** * Path to default template file with standard Configurable renderer. */ const CONFIGURABLE_RENDERER_TEMPLATE = 'Magento_ConfigurableProduct::product/view/type/options/configurable.phtml'; /** * Action name for ajax request */ const MEDIA_CALLBACK_ACTION = 'swatches/ajax/media'; /** * Name of swatch image for json config */ const SWATCH_IMAGE_NAME = 'swatchImage'; /** * Name of swatch thumbnail for json config */ const SWATCH_THUMBNAIL_NAME = 'swatchThumb'; /** * Config path which contains number of swatches per product */ private const XML_PATH_SWATCHES_PER_PRODUCT = 'catalog/frontend/swatches_per_product'; /** * @var Product */ protected $product; /** * @var SwatchData */ protected $swatchHelper; /** * @var Media */ protected $swatchMediaHelper; /** * Indicate if product has one or more Swatch attributes * * @deprecated 100.1.0 unused * * @var boolean */ protected $isProductHasSwatchAttribute; /** * @var SwatchAttributesProvider */ private $swatchAttributesProvider; /** * @var UrlBuilder */ private $imageUrlBuilder; /** * @SuppressWarnings(PHPMD.ExcessiveParameterList) * @param Context $context * @param ArrayUtils $arrayUtils * @param EncoderInterface $jsonEncoder * @param Data $helper * @param CatalogProduct $catalogProduct * @param CurrentCustomer $currentCustomer * @param PriceCurrencyInterface $priceCurrency * @param ConfigurableAttributeData $configurableAttributeData * @param SwatchData $swatchHelper * @param Media $swatchMediaHelper * @param array $data * @param SwatchAttributesProvider|null $swatchAttributesProvider * @param UrlBuilder|null $imageUrlBuilder */ public function __construct( Context $context, ArrayUtils $arrayUtils, EncoderInterface $jsonEncoder, Data $helper, CatalogProduct $catalogProduct, CurrentCustomer $currentCustomer, PriceCurrencyInterface $priceCurrency, ConfigurableAttributeData $configurableAttributeData, SwatchData $swatchHelper, Media $swatchMediaHelper, array $data = [], SwatchAttributesProvider $swatchAttributesProvider = null, UrlBuilder $imageUrlBuilder = null ) { $this->swatchHelper = $swatchHelper; $this->swatchMediaHelper = $swatchMediaHelper; $this->swatchAttributesProvider = $swatchAttributesProvider ?: ObjectManager::getInstance()->get(SwatchAttributesProvider::class); $this->imageUrlBuilder = $imageUrlBuilder ?? ObjectManager::getInstance()->get(UrlBuilder::class); parent::__construct( $context, $arrayUtils, $jsonEncoder, $helper, $catalogProduct, $currentCustomer, $priceCurrency, $configurableAttributeData, $data ); } /** * Get Key for caching block content * * @return string * @since 100.1.0 */ public function getCacheKey() { return parent::getCacheKey() . '-' . $this->getProduct()->getId(); } /** * Get block cache life time * * @return int * @since 100.1.0 */ protected function getCacheLifetime() { return parent::hasCacheLifetime() ? parent::getCacheLifetime() : 3600; } /** * Get Swatch config data * * @return string */ public function getJsonSwatchConfig() { $attributesData = $this->getSwatchAttributesData(); $allOptionIds = $this->getConfigurableOptionsIds($attributesData); $swatchesData = $this->swatchHelper->getSwatchesByOptionsId($allOptionIds); $config = []; foreach ($attributesData as $attributeId => $attributeDataArray) { if (isset($attributeDataArray['options'])) { $config[$attributeId] = $this->addSwatchDataForAttribute( $attributeDataArray['options'], $swatchesData, $attributeDataArray ); } if (isset($attributeDataArray['additional_data'])) { $config[$attributeId]['additional_data'] = $attributeDataArray['additional_data']; } } return $this->jsonEncoder->encode($config); } /** * Get number of swatches from config to show on product listing. * * Other swatches can be shown after click button 'Show more' * * @return string */ public function getNumberSwatchesPerProduct() { return $this->_scopeConfig->getValue( self::XML_PATH_SWATCHES_PER_PRODUCT, ScopeInterface::SCOPE_STORE ); } /** * Set product to block * * @param Product $product * @return $this */ public function setProduct(Product $product) { $this->product = $product; return $this; } /** * Override parent function * * @return Product */ public function getProduct() { if (!$this->product) { $this->product = parent::getProduct(); } return $this->product; } /** * Get swatch attributes data. * * @return array */ protected function getSwatchAttributesData() { return $this->swatchHelper->getSwatchAttributesAsArray($this->getProduct()); } /** * Init isProductHasSwatchAttribute. * * @deprecated 100.2.0 Method isProductHasSwatchAttribute() is used instead of this. * * @codeCoverageIgnore * @return void */ protected function initIsProductHasSwatchAttribute() { $this->isProductHasSwatchAttribute = $this->swatchHelper->isProductHasSwatch($this->getProduct()); } /** * Check that product has at least one swatch attribute * * @return bool * @since 100.1.5 */ protected function isProductHasSwatchAttribute() { $swatchAttributes = $this->swatchAttributesProvider->provide($this->getProduct()); return count($swatchAttributes) > 0; } /** * Add Swatch Data for attribute * * @param array $options * @param array $swatchesCollectionArray * @param array $attributeDataArray * @return array */ protected function addSwatchDataForAttribute( array $options, array $swatchesCollectionArray, array $attributeDataArray ) { $result = []; foreach ($options as $optionId => $label) { if (isset($swatchesCollectionArray[$optionId])) { $result[$optionId] = $this->extractNecessarySwatchData($swatchesCollectionArray[$optionId]); $result[$optionId] = $this->addAdditionalMediaData($result[$optionId], $optionId, $attributeDataArray); $result[$optionId]['label'] = $label; } } return $result; } /** * Add media from variation * * @param array $swatch * @param integer $optionId * @param array $attributeDataArray * @return array */ protected function addAdditionalMediaData(array $swatch, $optionId, array $attributeDataArray) { if (isset($attributeDataArray['use_product_image_for_swatch']) && $attributeDataArray['use_product_image_for_swatch'] ) { $variationMedia = $this->getVariationMedia($attributeDataArray['attribute_code'], $optionId); if (! empty($variationMedia)) { $swatch['type'] = Swatch::SWATCH_TYPE_VISUAL_IMAGE; $swatch = array_merge($swatch, $variationMedia); } } return $swatch; } /** * Retrieve Swatch data for config * * @param array $swatchDataArray * @return array */ protected function extractNecessarySwatchData(array $swatchDataArray) { $result['type'] = $swatchDataArray['type']; if ($result['type'] == Swatch::SWATCH_TYPE_VISUAL_IMAGE && !empty($swatchDataArray['value'])) { $result['value'] = $this->swatchMediaHelper->getSwatchAttributeImage( Swatch::SWATCH_IMAGE_NAME, $swatchDataArray['value'] ); $result['thumb'] = $this->swatchMediaHelper->getSwatchAttributeImage( Swatch::SWATCH_THUMBNAIL_NAME, $swatchDataArray['value'] ); } else { $result['value'] = $swatchDataArray['value']; } return $result; } /** * Generate Product Media array * * @param string $attributeCode * @param integer $optionId * @return array */ protected function getVariationMedia($attributeCode, $optionId) { $variationProduct = $this->swatchHelper->loadFirstVariationWithSwatchImage( $this->getProduct(), [$attributeCode => $optionId] ); if (!$variationProduct) { $variationProduct = $this->swatchHelper->loadFirstVariationWithImage( $this->getProduct(), [$attributeCode => $optionId] ); } $variationMediaArray = []; if ($variationProduct) { $variationMediaArray = [ 'value' => $this->getSwatchProductImage($variationProduct, Swatch::SWATCH_IMAGE_NAME), 'thumb' => $this->getSwatchProductImage($variationProduct, Swatch::SWATCH_THUMBNAIL_NAME), ]; } return $variationMediaArray; } /** * Get swatch product image. * * @param Product $childProduct * @param string $imageType * @return string */ protected function getSwatchProductImage(Product $childProduct, $imageType) { if ($this->isProductHasImage($childProduct, Swatch::SWATCH_IMAGE_NAME)) { $swatchImageId = $imageType; $imageAttributes = ['type' => Swatch::SWATCH_IMAGE_NAME]; } elseif ($this->isProductHasImage($childProduct, 'image')) { $swatchImageId = $imageType == Swatch::SWATCH_IMAGE_NAME ? 'swatch_image_base' : 'swatch_thumb_base'; $imageAttributes = ['type' => 'image']; } if (!empty($swatchImageId) && !empty($imageAttributes['type'])) { return $this->imageUrlBuilder->getUrl($childProduct->getData($imageAttributes['type']), $swatchImageId); } } /** * Check if product have image. * * @param Product $product * @param string $imageType * @return bool */ protected function isProductHasImage(Product $product, $imageType) { return $product->getData($imageType) !== null && $product->getData($imageType) != SwatchData::EMPTY_IMAGE_VALUE; } /** * Get configurable options ids. * * @param array $attributeData * @return array * @since 100.0.3 */ protected function getConfigurableOptionsIds(array $attributeData) { $ids = []; foreach ($this->getAllowProducts() as $product) { /** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute $attribute */ foreach ($this->helper->getAllowAttributes($this->getProduct()) as $attribute) { $productAttribute = $attribute->getProductAttribute(); $productAttributeId = $productAttribute->getId(); if (isset($attributeData[$productAttributeId])) { $ids[$product->getData($productAttribute->getAttributeCode())] = 1; } } } return array_keys($ids); } /** * Produce and return block's html output * * @return string * @since 100.2.0 */ public function toHtml() { $this->setTemplate( $this->getRendererTemplate() ); return parent::toHtml(); } /** * Return HTML code * * @return string */ protected function _toHtml() { return $this->getHtmlOutput(); } /** * Return renderer template * * Template for product with swatches is different from product without swatches * * @return string */ protected function getRendererTemplate() { return $this->isProductHasSwatchAttribute() ? self::SWATCH_RENDERER_TEMPLATE : self::CONFIGURABLE_RENDERER_TEMPLATE; } /** * @inheritDoc * @deprecated 100.1.5 Now is used _toHtml() directly */ protected function getHtmlOutput() { return parent::_toHtml(); } /** * Get media callback url. * * @return string */ public function getMediaCallback() { return $this->getUrl(self::MEDIA_CALLBACK_ACTION, ['_secure' => $this->getRequest()->isSecure()]); } /** * Return unique ID(s) for each object in system * * @return string[] * @since 100.1.0 */ public function getIdentities() { if ($this->product instanceof \Magento\Framework\DataObject\IdentityInterface) { return $this->product->getIdentities(); } else { return []; } } /** * Get Swatch image size config data. * * @return string * @since 100.2.5 */ public function getJsonSwatchSizeConfig() { $imageConfig = $this->swatchMediaHelper->getImageConfig(); $sizeConfig = []; $sizeConfig[self::SWATCH_IMAGE_NAME]['width'] = $imageConfig[Swatch::SWATCH_IMAGE_NAME]['width']; $sizeConfig[self::SWATCH_IMAGE_NAME]['height'] = $imageConfig[Swatch::SWATCH_IMAGE_NAME]['height']; $sizeConfig[self::SWATCH_THUMBNAIL_NAME]['height'] = $imageConfig[Swatch::SWATCH_THUMBNAIL_NAME]['height']; $sizeConfig[self::SWATCH_THUMBNAIL_NAME]['width'] = $imageConfig[Swatch::SWATCH_THUMBNAIL_NAME]['width']; return $this->jsonEncoder->encode($sizeConfig); } }