diff --git a/src/Model/Config.php b/src/Model/Config.php index be7ebb0..6215e81 100644 --- a/src/Model/Config.php +++ b/src/Model/Config.php @@ -14,6 +14,8 @@ class Config private const XML_PATH_MERCHANDISING_ENABLED = 'tweakwisejs/merchandising/enabled'; + private const XML_PATH_SEARCH_TYPE = 'tweakwisejs/search/type'; + /** * @param ScopeConfigInterface $scopeConfig */ @@ -45,4 +47,12 @@ public function isMerchandisingEnabled(): bool { return $this->scopeConfig->isSetFlag(self::XML_PATH_MERCHANDISING_ENABLED, ScopeInterface::SCOPE_STORE); } + + /** + * @return string + */ + public function getSearchType(): string + { + return $this->scopeConfig->getValue(self::XML_PATH_SEARCH_TYPE, ScopeInterface::SCOPE_STORE); + } } diff --git a/src/Observer/AddPageAssets.php b/src/Observer/AddPageAssets.php index 1470919..bedfb01 100644 --- a/src/Observer/AddPageAssets.php +++ b/src/Observer/AddPageAssets.php @@ -8,6 +8,7 @@ use Magento\Framework\Event\Observer; use Magento\Framework\View\Page\Config as PageConfig; use Tweakwise\TweakwiseJs\Model\Config; +use Tweakwise\TweakwiseJs\Model\Enum\SearchType; class AddPageAssets implements ObserverInterface { @@ -33,6 +34,20 @@ public function execute(Observer $observer) return; } + $this->addDefaultPageAssets(); + + if ($this->config->getSearchType() !== SearchType::SUGGESTIONS->value) { + return; + } + + $this->addSuggestionsPageAssets(); + } + + /** + * @return void + */ + private function addDefaultPageAssets(): void + { $instanceKey = $this->config->getInstanceKey(); $this->pageConfig->addRemotePageAsset( @@ -54,4 +69,25 @@ public function execute(Observer $observer) ]] ); } + + /** + * @return void + */ + private function addSuggestionsPageAssets(): void + { + $this->pageConfig->addRemotePageAsset( + 'https://gateway.tweakwisenavigator.net/js/suggestions.js', + 'link', + ['attributes' => ['rel' => 'preload', 'as' => 'script']] + ); + + $this->pageConfig->addRemotePageAsset( + 'https://gateway.tweakwisenavigator.net/js/suggestions.js', + 'js', + ['attributes' => [ + 'data-failover' => 'https://gateway.tweakwisenavigator.com/js/suggestions.js', + 'onerror' => 'window.tweakwiseFailover(this.dataset.failover)' + ]] + ); + } } diff --git a/src/Observer/ManageLayoutBlocks.php b/src/Observer/ManageLayoutBlocks.php index 5e51aaf..6ca7385 100644 --- a/src/Observer/ManageLayoutBlocks.php +++ b/src/Observer/ManageLayoutBlocks.php @@ -14,20 +14,24 @@ use Magento\Framework\View\Element\Template; use Magento\Framework\View\Layout; use Tweakwise\TweakwiseJs\Model\Config; -use Tweakwise\TweakwiseJs\ViewModel\TweakwiseJs; +use Tweakwise\TweakwiseJs\Model\Enum\SearchType; +use Tweakwise\TweakwiseJs\ViewModel\Merchandising; +use Tweakwise\TweakwiseJs\ViewModel\Search; class ManageLayoutBlocks implements ObserverInterface { /** * @param Http $request * @param Config $config - * @param TweakwiseJs $viewModel + * @param Merchandising $merchandisingViewModel + * @param Search $searchViewModel * @param Resolver $layerResolver */ public function __construct( private readonly Http $request, private readonly Config $config, - private readonly TweakwiseJs $viewModel, + private readonly Merchandising $merchandisingViewModel, + private readonly Search $searchViewModel, private readonly Resolver $layerResolver ) { } @@ -39,6 +43,7 @@ public function __construct( */ public function execute(Observer $observer) { + // TODO: CAN WE SPECIFY ON WHICH PAGE TYPES THE BLOCKS MUST BE LOADED? if (!$this->config->isEnabled()) { return; } @@ -47,6 +52,10 @@ public function execute(Observer $observer) $this->addDefaultBlock($layout); + if ($this->useTweakwiseJsSearch()) { + $this->addSearchBlock($layout); + } + if (!$this->isCategoryPage() || !$this->showTweakwiseJsCategoryViewBlock()) { return; } @@ -86,7 +95,7 @@ private function addTweakwiseJsCategoryViewBlock(Layout $layout): void $blockName, [ 'data' => [ - 'view_model' => $this->viewModel + 'view_model' => $this->merchandisingViewModel ] ] )->setTemplate('Tweakwise_TweakwiseJs::category/listing.phtml'); @@ -114,4 +123,31 @@ private function showTweakwiseJsCategoryViewBlock(): bool return true; } + + /** + * @return bool + */ + private function useTweakwiseJsSearch(): bool + { + return $this->config->getSearchType() !== SearchType::MAGENTO_DEFAULT->value; + } + + /** + * @param Layout $layout + * @return void + */ + private function addSearchBlock(Layout $layout): void + { + $blockName = 'tweakwise-js-search'; + $layout->createBlock( + Template::class, + $blockName, + [ + 'data' => [ + 'view_model' => $this->searchViewModel + ] + ] + )->setTemplate('Tweakwise_TweakwiseJs::search.phtml'); + $layout->setChild('after.body.start', $blockName, $blockName); + } } diff --git a/src/ViewModel/TweakwiseJs.php b/src/ViewModel/Merchandising.php similarity index 69% rename from src/ViewModel/TweakwiseJs.php rename to src/ViewModel/Merchandising.php index 516103e..4927114 100644 --- a/src/ViewModel/TweakwiseJs.php +++ b/src/ViewModel/Merchandising.php @@ -9,7 +9,7 @@ use Magento\Framework\View\Element\Block\ArgumentInterface; use Tweakwise\TweakwiseJs\Helper\Data; -class TweakwiseJs implements ArgumentInterface +class Merchandising implements ArgumentInterface { /** * @param Data $dataHelper @@ -22,10 +22,13 @@ public function __construct( /** * @param View $block * @return string - * @throws NoSuchEntityException */ public function getTweakwiseCategoryId(View $block): string { - return $this->dataHelper->getTweakwiseId((int) $block->getCurrentCategory()->getId()); + try { + return $this->dataHelper->getTweakwiseId((int)$block->getCurrentCategory()->getId()); + } catch (NoSuchEntityException $e) { + return '0'; + } } } diff --git a/src/ViewModel/Search.php b/src/ViewModel/Search.php new file mode 100644 index 0000000..d3bae75 --- /dev/null +++ b/src/ViewModel/Search.php @@ -0,0 +1,67 @@ +config->getSearchType(); + } + + /** + * @return string|null + */ + public function getInstanceKey(): ?string + { + return $this->config->getInstanceKey(); + } + + /** + * @return int + */ + public function getStoreRootCategory(): int + { + try { + return (int)$this->dataHelper->getTweakwiseId( + (int)$this->storeManager->getStore()->getRootCategoryId() + ); + } catch (NoSuchEntityException $e) { + return 0; + } + } + + /** + * @return string + */ + public function getSearchUrl(): string + { + return trim($this->urlBuilder->getUrl('twsearch#twn|'), '/'); + } +} diff --git a/src/etc/config.xml b/src/etc/config.xml index 3a1a001..efe156d 100644 --- a/src/etc/config.xml +++ b/src/etc/config.xml @@ -3,10 +3,15 @@ xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd"> + + 0 + - category.products.list - sidebar.main + 0 + + magento_default + diff --git a/src/view/frontend/templates/category/listing.phtml b/src/view/frontend/templates/category/listing.phtml index 94d5785..70d8aa6 100644 --- a/src/view/frontend/templates/category/listing.phtml +++ b/src/view/frontend/templates/category/listing.phtml @@ -2,9 +2,11 @@ declare(strict_types = 1); use Magento\Catalog\Block\Category\View; +use Tweakwise\TweakwiseJs\ViewModel\Merchandising; /** @var View $block */ +/** @var Merchandising $viewModel */ $viewModel = $block->getViewModel(); ?> diff --git a/src/view/frontend/templates/search.phtml b/src/view/frontend/templates/search.phtml new file mode 100644 index 0000000..8eabbcc --- /dev/null +++ b/src/view/frontend/templates/search.phtml @@ -0,0 +1,40 @@ +getViewModel(); +?> + +getSearchType() === SearchType::SUGGESTIONS->value): ?> + + + +