>|null */ private ?array $items = null; public function __construct( Context $context, private readonly ProductCollectionFactory $productCollectionFactory, private readonly VideoCollectionFactory $videoCollectionFactory, private readonly Visibility $productVisibility, private readonly PriceCurrencyInterface $priceCurrency, private readonly SerializerInterface $serializer, private readonly HttpContext $httpContext, private readonly CardPriceResolver $cardPriceResolver, array $data = [] ) { parent::__construct($context, $data); } /** * @return array> */ public function getItems(): array { if ($this->items !== null) { return $this->items; } $configuredItems = $this->getConfiguredItems(); if (!$configuredItems) { return $this->items = []; } $videoIds = []; $skus = []; foreach ($configuredItems as $item) { $videoId = (int) ($item['video_id'] ?? 0); $sku = trim((string) ($item['product_sku'] ?? '')); if ($videoId > 0) { $videoIds[$videoId] = $videoId; } if ($sku !== '') { $skus[strtolower($sku)] = $sku; } } $videosById = []; if ($videoIds) { $videoCollection = $this->videoCollectionFactory->create(); $videoCollection->addFieldToFilter('video_id', ['in' => array_values($videoIds)]); $videoCollection->addFieldToFilter('status', 1); foreach ($videoCollection as $video) { $videosById[(int) $video->getId()] = $video; } } $productsBySku = []; if ($skus) { $productCollection = $this->productCollectionFactory->create(); $productCollection->setStoreId((int) $this->_storeManager->getStore()->getId()); $this->_addProductAttributesAndPrices($productCollection); $productCollection->addStoreFilter(); $productCollection->addAttributeToFilter('sku', ['in' => array_values($skus)]); $productCollection->addAttributeToFilter( 'visibility', ['in' => $this->productVisibility->getVisibleInSiteIds()] ); $productCollection->addAttributeToFilter( 'status', Product\Attribute\Source\Status::STATUS_ENABLED ); foreach ($productCollection as $product) { $productsBySku[strtolower((string) $product->getSku())] = $product; } } $mediaBaseUrl = $this->_storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA); $this->items = []; foreach ($configuredItems as $item) { $videoId = (int) ($item['video_id'] ?? 0); $skuKey = strtolower(trim((string) ($item['product_sku'] ?? ''))); $video = $videosById[$videoId] ?? null; $product = $productsBySku[$skuKey] ?? null; if (!$video || !$product) { continue; } $this->items[] = [ 'title' => trim((string) ($item['title'] ?? '')), 'subtitle' => trim((string) ($item['subtitle'] ?? '')), 'sort_number' => (int) ($item['sort_number'] ?? 0), 'video_url' => $mediaBaseUrl . ltrim((string) $video->getData('video_path'), '/'), 'cover_url' => $mediaBaseUrl . ltrim((string) $video->getData('cover_path'), '/'), 'product' => $product, ]; } return $this->items; } public function getFormattedFinalPrice(Product $product): string { return $this->formatPrice($this->getFinalPriceValue($product)); } public function getFormattedRegularPrice(Product $product): string { return $this->formatPrice($this->getRegularPriceValue($product)); } public function hasRegularPrice(Product $product): bool { return $this->getRegularPriceValue($product) > $this->getFinalPriceValue($product); } public function getCacheKeyInfo(): array { return [ 'ESUN_HOMEPAGE_CREATE_ANYTHING', (int) $this->_storeManager->getStore()->getId(), (int) $this->httpContext->getValue(CustomerContext::CONTEXT_GROUP), sha1((string) $this->_scopeConfig->getValue( self::XML_PATH_ITEMS, ScopeInterface::SCOPE_STORE )), ]; } public function getIdentities(): array { $identities = []; foreach ($this->getItems() as $item) { $product = $item['product'] ?? null; if ($product instanceof Product) { $identities = array_merge($identities, $product->getIdentities()); } } return array_values(array_unique($identities)); } /** * @return array> */ private function getConfiguredItems(): array { $value = $this->_scopeConfig->getValue( self::XML_PATH_ITEMS, ScopeInterface::SCOPE_STORE ); if (is_array($value)) { return array_values($value); } if (!is_string($value) || trim($value) === '') { return []; } try { $items = $this->serializer->unserialize($value); } catch (\InvalidArgumentException) { return []; } return is_array($items) ? array_values($items) : []; } private function getFinalPriceValue(Product $product): float { return $this->cardPriceResolver->getFinalPrice($product); } private function getRegularPriceValue(Product $product): float { return $this->cardPriceResolver->getRegularPrice($product); } private function formatPrice(float $price): string { return $this->priceCurrency->format( $price, false, PriceCurrencyInterface::DEFAULT_PRECISION, $this->_storeManager->getStore() ); } }