Skip to content

Draft: Grouped products functionality #265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: beta
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions Controller/Product/Card.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Tweakwise\Magento2Tweakwise\Controller\Product;

use Magento\Catalog\Model\Product;
use Magento\PageCache\Model\Cache\Type as PageType;
use Tweakwise\Magento2Tweakwise\Helper\Cache;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\RequestInterface;
Expand Down Expand Up @@ -36,13 +38,24 @@ public function __construct(
*/
public function execute(): HttpInterface
{
$itemId = (string) $this->request->getParam('item_id');
$cardType = $this->request->getParam('card_type');
$itemHtml = $cardType ? $this->cacheHelper->load($itemId, $cardType) :
$this->cacheHelper->load($itemId);
$itemId = (string)$this->request->getParam('item_id');
$cacheKeyInfo = (string)$this->request->getParam('cache_key_info');
$itemHtml = $this->cacheHelper->load($cacheKeyInfo);

$response = $this->httpFactory->create();
$response->appendBody($itemHtml);

$response->setHeader(
'X-Magento-Tags',
implode(
',',
[
Product::CACHE_TAG,
sprintf('%s_%s', Product::CACHE_TAG, $itemId),
PageType::CACHE_TAG
]
)
);
$response->setPublicHeaders($this->config->getProductCardLifetime());
return $response;
}
Expand Down
88 changes: 57 additions & 31 deletions Helper/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@

namespace Tweakwise\Magento2Tweakwise\Helper;

use Magento\Customer\Model\Session;
use Magento\Catalog\Model\Product;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\View\DesignInterface;
use Magento\PageCache\Model\Config;
use Magento\Store\Model\StoreManagerInterface;
use Tweakwise\Magento2Tweakwise\Model\Config as TweakwiseConfig;

class Cache
Expand All @@ -27,49 +28,51 @@ class Cache
private ?bool $isHyvaTheme = null;

/**
* @param StoreManagerInterface $storeManager
* @param CacheInterface $cache
* @param Session $customerSession
* @param RequestInterface $request
* @param ScopeConfigInterface $scopeConfig
* @param TweakwiseConfig $config
* @param DesignInterface $viewDesign
* @param Json $jsonSerializer
*/
public function __construct(
private readonly StoreManagerInterface $storeManager,
private readonly CacheInterface $cache,
private readonly Session $customerSession,
private readonly RequestInterface $request,
private readonly ScopeConfigInterface $scopeConfig,
private readonly TweakwiseConfig $config,
private readonly DesignInterface $viewDesign
private readonly CacheInterface $cache,
private readonly RequestInterface $request,
private readonly ScopeConfigInterface $scopeConfig,
private readonly TweakwiseConfig $config,
private readonly DesignInterface $viewDesign,
private readonly Json $jsonSerializer
) {
}

/**
* @param string $itemId
* @param string $cardType
* @param string $hashedCacheKeyInfo
* @return string
* @throws LocalizedException
* @throws NoSuchEntityException
*/
public function load(string $itemId, string $cardType = 'default'): string
public function load(string $hashedCacheKeyInfo): string
{
$result = $this->cache->load($this->getCacheKey($itemId, $cardType));
$result = $this->cache->load($this->getCacheKey($hashedCacheKeyInfo));
return $result ? $result : '';
}

/**
* @param string $data
* @param string $itemId
* @param string $cardType
* @param string $hashedCacheKeyInfo
* @param array $tags
* @return void
* @throws LocalizedException
* @throws NoSuchEntityException
*/
public function save(string $data, string $itemId, string $cardType = 'default'): void
public function save(string $data, string $hashedCacheKeyInfo, array $tags = []): void
{
$this->cache->save($data, $this->getCacheKey($itemId, $cardType));
$this->cache->save(
$data,
$this->getCacheKey($hashedCacheKeyInfo),
$tags,
$this->config->getProductCardLifetime()
);
}

/**
Expand All @@ -88,6 +91,20 @@ public function isVarnishEnabled(): bool
return $this->scopeConfig->getValue(Config::XML_PAGECACHE_TYPE) === (string) Config::VARNISH;
}

/**
* @param Product $item
* @return string
* @throws LocalizedException
*/
public function getImage(Product $item): string
{
if (!$this->config->isGroupedProductsEnabled() || $item->getTypeId() !== Configurable::TYPE_CODE) {
return '';
}

return $item->getImage();
}

/**
* @return bool
*/
Expand Down Expand Up @@ -129,23 +146,32 @@ public function isHyvaTheme(): bool

/**
* @param string $itemId
* @param int $storeId
* @param int $customerGroupId
* @param string $image
* @param string $cardType
* @return string
* @throws LocalizedException
* @throws NoSuchEntityException
*/
private function getCacheKey(string $itemId, string $cardType): string
{
$storeId = $this->storeManager->getStore()->getId();
$customerGroupId = $this->customerSession->getCustomerGroupId();
public function hashCacheKeyInfo(
string $itemId,
int $storeId,
int $customerGroupId,
string $image = '',
string $cardType = 'default',
): string {
return sha1($this->jsonSerializer->serialize([$itemId, $storeId, $customerGroupId, $image, $cardType]));
}

/**
* @param string $hashedCacheKeyInfo
* @return string
*/
private function getCacheKey(string $hashedCacheKeyInfo): string
{
return sprintf(
'%s_%s_%s_%s_%s',
$storeId,
$customerGroupId,
$itemId,
$cardType,
self::REDIS_CACHE_KEY
'%s_%s',
self::REDIS_CACHE_KEY,
$hashedCacheKeyInfo
);
}
}
37 changes: 37 additions & 0 deletions Model/Catalog/Product/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace Tweakwise\Magento2Tweakwise\Model\Catalog\Product;

use Exception;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Tweakwise\Magento2Tweakwise\Model\Config;
use Tweakwise\Magento2Tweakwise\Model\Enum\ItemType;
use Tweakwise\Magento2Tweakwise\Api\Data\VisualInterface;
Expand Down Expand Up @@ -167,11 +168,33 @@ protected function _afterLoad()
parent::_afterLoad();

$this->applyCollectionSizeValues();
$this->applyProductImages();
$this->addVisuals();

return $this;
}

/**
* @return $this
*/
protected function applyProductImages(): AbstractCollection
{
foreach ($this->getProductImages() as $productId => $productImageUrl) {
if (
!isset($this->_items[$productId]) ||
$this->_items[$productId]->getTypeId() !== Configurable::TYPE_CODE
) {
continue;
}

$this->_items[$productId]->setData('image', $productImageUrl);
$this->_items[$productId]->setData('small_image', $productImageUrl);
$this->_items[$productId]->setData('thumbnail', $productImageUrl);
}

return $this;
}

/**
* @return void
*/
Expand Down Expand Up @@ -207,4 +230,18 @@ protected function getProductIds()
$response = $this->navigationContext->getResponse();
return $response->getProductIds() ?? [];
}

/**
* @return array
*/
protected function getProductImages(): array
{
try {
$response = $this->navigationContext->getResponse();
} catch (Exception $e) {
return [];
}

return $response->getProductImages() ?? [];
}
}
9 changes: 9 additions & 0 deletions Model/Client/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ class Request
*/
protected $path;

/**
* @var string
*/
protected $groupedPath;

/**
* @var array
*/
Expand Down Expand Up @@ -76,6 +81,10 @@ public function getResponseType()
*/
public function getPath()
{
if ($this->config->isGroupedProductsEnabled($this->storeManager->getStore()) && !empty($this->groupedPath)) {
return $this->groupedPath;
}

return $this->path;
}

Expand Down
5 changes: 5 additions & 0 deletions Model/Client/Request/AutocompleteRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ class AutocompleteRequest extends Request
*/
protected $path = 'autocomplete';

/**
* @var string
*/
protected $groupedPath = 'autocomplete/grouped';

/**
* {@inheritDoc}
*/
Expand Down
16 changes: 11 additions & 5 deletions Model/Client/Request/ProductNavigationRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,22 @@

namespace Tweakwise\Magento2Tweakwise\Model\Client\Request;

use Magento\Framework\Exception\LocalizedException;
use Tweakwise\Magento2Tweakwise\Model\Client\Request;
use Tweakwise\Magento2Tweakwise\Model\Client\Response\ProductNavigationResponse;

class ProductNavigationRequest extends Request
{
/**
* @var string
*/
protected $path = 'navigation';

/**
* @var string
*/
protected $groupedPath = 'navigation/grouped';

/**
* Maximum number of products returned for one request
*/
Expand All @@ -25,11 +36,6 @@ class ProductNavigationRequest extends Request
private const SORT_ASC = 'ASC';
private const SORT_DESC = 'DESC';

/**
* @var string
*/
protected $path = 'navigation';

/**
* @var array
*/
Expand Down
5 changes: 5 additions & 0 deletions Model/Client/Request/ProductSearchRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ class ProductSearchRequest extends ProductNavigationRequest implements SearchReq
* @var string
*/
protected $path = 'navigation-search';

/**
* @var string
*/
protected $groupedPath = 'navigation-search/grouped';
}
19 changes: 19 additions & 0 deletions Model/Client/Request/Recommendations/ProductRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public function getProduct()
public function setProduct(Product $product)
{
$this->product = $product;

if ($this->config->isGroupedProductsEnabled() && $product->getTypeId() === 'configurable') {
$this->product = $this->getSimpleProduct($product);
}

return $this;
}

Expand Down Expand Up @@ -63,4 +68,18 @@ public function getPathSuffix()

return '/' . $productTweakwiseId . parent::getPathSuffix();
}

/**
* @param Product $product
* @return Product
*/
private function getSimpleProduct(Product $product): Product
{
$children = $product->getTypeInstance()->getUsedProducts($product);
foreach ($children as $child) {
if ($child->isSaleable() && $child->getTypeId() === Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add as a use statement

return $child;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class ProductSuggestionsRequest extends Request implements SearchRequestInterfac
*/
protected $path = 'suggestions/products';

protected $groupedPath = 'suggestions/products/grouped';

/**
* @return string
*/
Expand Down
5 changes: 5 additions & 0 deletions Model/Client/Request/Suggestions/SuggestionsRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ class SuggestionsRequest extends Request implements SearchRequestInterface
*/
protected $path = 'suggestions';

/**
* @var string
*/
protected $groupedPath = 'suggestions/grouped';

/**
* @return string
*/
Expand Down
Loading