From d0920d67efefd521a5d676d80bd2f3d513db895d Mon Sep 17 00:00:00 2001 From: Cid Lopes Date: Tue, 12 May 2020 14:08:42 +0300 Subject: [PATCH 01/35] Add #nosto_cmp url fragment --- Plugin/Catalog/Model/Product.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Plugin/Catalog/Model/Product.php b/Plugin/Catalog/Model/Product.php index 9b3be5ce..18a70b92 100644 --- a/Plugin/Catalog/Model/Product.php +++ b/Plugin/Catalog/Model/Product.php @@ -44,6 +44,7 @@ class Product const NOSTO_SOURCE_PARAMETER_NAME = 'nosto_source'; const NOSTO_PRODUCT_ID_PARAMETER_VALUE = 'nosto_pid'; const NOSTO_SOURCE_PARAMETER_VALUE = 'cmp'; + const NOSTO_OVERRIDABLE_ATTR_PARAM = 'nosto_cmp'; /** * @param MagentoProduct $product @@ -59,7 +60,13 @@ public function afterGetProductUrl(MagentoProduct $product, $url) self::NOSTO_SOURCE_PARAMETER_NAME => self::NOSTO_SOURCE_PARAMETER_VALUE ]; $params = array_merge($existingParams, $nostoParam); - $url = $product->getUrlModel()->getUrl($product, ['_query' => $params]); + $url = $product->getUrlModel()->getUrl( + $product, + [ + '_query' => $params, + '_fragment' => self::NOSTO_OVERRIDABLE_ATTR_PARAM + ] + ); } return $url; } From 4d52812f5630c0326bb26a0fba422b067d0e48ac Mon Sep 17 00:00:00 2001 From: Mridang Agarwalla Date: Wed, 13 May 2020 14:38:09 +0530 Subject: [PATCH 02/35] Added support for Github Actions (#38) --- .github/workflows/action.yml | 156 + .github/workflows/phan.yml | 87 + .gitignore | 2 + Block/SegmentMapping.php | 6 +- Helper/CategorySorting.php | 2 +- Model/Filter/FilterBuilder.php | 5 +- Model/Service/Recommendation/Category.php | 8 +- Observer/App/Action/Action.php | 2 +- Plugin/Catalog/Block/AbstractBlock.php | 10 +- .../Block/DefaultParameterResolver.php | 2 +- Plugin/Catalog/Block/Pager.php | 43 +- .../Block/ParameterResolverInterface.php | 1 - Plugin/Catalog/Block/Toolbar.php | 17 +- Plugin/Catalog/Model/Config.php | 7 +- Plugin/Catalog/Model/Product.php | 2 + Plugin/Catalog/Model/Sortby.php | 8 +- Plugin/Http/Context.php | 51 +- Utils/Debug/Product.php | 2 +- Utils/Debug/ServerTiming.php | 4 +- composer.json | 33 +- composer.lock | 3682 ++++++++++++++++- phan.php | 84 + ruleset.xml | 57 + .../templates/category_merchandising.phtml | 8 +- 24 files changed, 4185 insertions(+), 94 deletions(-) create mode 100644 .github/workflows/action.yml create mode 100644 .github/workflows/phan.yml create mode 100644 phan.php create mode 100644 ruleset.xml diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml new file mode 100644 index 00000000..1255f4f3 --- /dev/null +++ b/.github/workflows/action.yml @@ -0,0 +1,156 @@ +name: PHP CI + +on: [push] + +jobs: + + phpcs: + name: Code Sniffer + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + + ############################################################################ + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '7.2' + tools: composer, prestissimo + extensions: ast + coverage: none + + #https://github.com/actions/cache/blob/master/examples.md#php---composer + - name: Cache composer packages + id: composer-cache + run: | + composer config cache-files-dir + echo "::set-output name=dir::$(composer config cache-files-dir)" + - uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Update project dependencies + env: + REPO_USR: ${{ secrets.REPO_USR }} + REPO_PSW: ${{ secrets.REPO_PSW }} + run: | + composer config repositories.0 composer https://repo.magento.com + composer config http-basic.repo.magento.com "$REPO_USR" "$REPO_PSW" + composer install --prefer-dist --no-progress --no-suggest + ############################################################################ + + - name: Run the sniffer + run: | + ./vendor/bin/phpcs --config-set ignore_errors_on_exit 1 + ./vendor/bin/phpcs --config-set ignore_warnings_on_exit 1 + ./vendor/bin/phpcs --standard=ruleset.xml --report=checkstyle --report-file=chkphpcs.xml + + - name: Archive code sniffing results + uses: actions/upload-artifact@v1 + with: + name: phpcs-xml-result + path: chkphpcs.xml + + - name: Report annotations + id: report-annotations + run: ./vendor/bin/cs2pr chkphpcs.xml + + phpmd: + name: Mess Detect + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + + ############################################################################ + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '7.2' + tools: composer, prestissimo + extensions: ast + coverage: none + + #https://github.com/actions/cache/blob/master/examples.md#php---composer + - name: Cache composer packages + id: composer-cache + run: | + composer config cache-files-dir + echo "::set-output name=dir::$(composer config cache-files-dir)" + - uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Update project dependencies + env: + REPO_USR: ${{ secrets.REPO_USR }} + REPO_PSW: ${{ secrets.REPO_PSW }} + run: | + composer config repositories.0 composer https://repo.magento.com + composer config http-basic.repo.magento.com "$REPO_USR" "$REPO_PSW" + composer install --prefer-dist --no-progress --no-suggest + ############################################################################ + + - name: Run the mess detector + run: ./vendor/bin/phpmd . xml codesize,naming,unusedcode,controversial,design --exclude vendor,var,build,tests --reportfile pmdphpmd.xml --ignore-violations-on-exit + + - name: Archive mess detection results + uses: actions/upload-artifact@v1 + with: + name: phpmd-xml-result + path: pmdphpmd.xml + + - name: Report annotations + id: report-annotations + run: ./vendor/bin/pmd2pr --graceful-warnings pmdphpmd.xml + + package: + name: Package + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + + ############################################################################ + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '7.2' + tools: composer, prestissimo + extensions: ast + coverage: none + + #https://github.com/actions/cache/blob/master/examples.md#php---composer + - name: Cache composer packages + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + - uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Update project dependencies + env: + REPO_USR: ${{ secrets.REPO_USR }} + REPO_PSW: ${{ secrets.REPO_PSW }} + run: | + composer config repositories.0 composer https://repo.magento.com + composer config http-basic.repo.magento.com "$REPO_USR" "$REPO_PSW" + composer install --prefer-dist --no-progress --no-suggest + ############################################################################ + + - name: Build archive using composer + run: composer archive --format=zip --file=archive + + - name: Archive built arhive + uses: actions/upload-artifact@v1 + with: + name: composer-zip-archive + path: archive.zip diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml new file mode 100644 index 00000000..34c6f221 --- /dev/null +++ b/.github/workflows/phan.yml @@ -0,0 +1,87 @@ +name: Phan + +on: [push] + +jobs: + + phan: + name: Phan Analysis + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + + ############################################################################ + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '7.2' + tools: composer, prestissimo, pecl + coverage: none + + - name: Install AST extension + run: sudo pecl install -f ast + + #https://github.com/actions/cache/blob/master/examples.md#php---composer + - name: Cache composer packages + id: composer-cache + run: | + composer config cache-files-dir + echo "::set-output name=dir::$(composer config cache-files-dir)" + - uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Update project dependencies + env: + REPO_USR: ${{ secrets.REPO_USR }} + REPO_PSW: ${{ secrets.REPO_PSW }} + run: | + composer config repositories.0 composer https://repo.magento.com + composer config http-basic.repo.magento.com "$REPO_USR" "$REPO_PSW" + composer install --prefer-dist --no-progress --no-suggest + ############################################################################ + + # Not removing HHVM will lead to the following error: + # > Installation request for hhvm 4.49.0 -> satisfiable by hhvm[4.49.0]. + - name: Remove HHVM + id: remove-hhvm + run: sudo apt remove hhvm + + - name: Install Magento + id: install-magento + run: | + composer create-project magento/community-edition=2.3.2 magento + cd magento + composer config repositories.0 composer https://repo.magento.com + composer config http-basic.repo.magento.com "$REPO_USR" "$REPO_PSW" + composer config minimum-stability dev + composer config prefer-stable true + composer require --no-update nosto/module-nostotagging-cmp:dev-${GITHUB_REF#refs/heads/}#${GITHUB_SHA} + composer update --no-dev + bin/magento module:enable --all + bin/magento setup:di:compile + cd .. + cp -r magento/generated vendor/magento/ + rm -rf magento + env: + GITHUB_BRANCH: ${{ github.base_ref }} + + - name: Run Phan analysis + id: phan-analysis + run: | + ./vendor/bin/phan --config-file=phan.php --output-mode=checkstyle --output=chkphan.xml --processes=4 + continue-on-error: true + + - name: Archive static analysis results + uses: actions/upload-artifact@v1 + with: + name: phan-analysis-results + path: chkphan.xml + + - name: Report annotations + id: report-annotations + run: ./vendor/bin/cs2pr chkphan.xml diff --git a/.gitignore b/.gitignore index 3ce5adbb..23c51f5a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .idea vendor +magento + diff --git a/Block/SegmentMapping.php b/Block/SegmentMapping.php index c0148265..b8550e9c 100644 --- a/Block/SegmentMapping.php +++ b/Block/SegmentMapping.php @@ -44,6 +44,7 @@ use Nosto\Tagging\Helper\Account as NostoHelperAccount; use Nosto\Tagging\Logger\Logger as NostoLogger; use Nosto\Tagging\Model\Customer\Customer as NostoCustomer; +use Magento\Store\Model\Store; class SegmentMapping extends Template { @@ -86,10 +87,11 @@ public function getNostoAccount() try { $store = $this->storeManager->getStore(); } catch (\Exception $e) { - $this->logger->exception("Could not get Nosto account ID"); + $this->logger->error($e->getMessage() . 'Could not get Nosto account ID'); return null; } - return $this->nostoHelperAccount->getAccountName($store); + /** @var Store $store */ + return $this->nostoHelperAccount->getAccountName($store); //@phan-suppress-current-line PhanTypeMismatchArgument } /** diff --git a/Helper/CategorySorting.php b/Helper/CategorySorting.php index 58f42cff..b66128d3 100644 --- a/Helper/CategorySorting.php +++ b/Helper/CategorySorting.php @@ -76,7 +76,7 @@ public function __construct( public static function getNostoSortingOptions() { return [ - self::NOSTO_PERSONALIZED_KEY => __('Relevance') + self::NOSTO_PERSONALIZED_KEY => __(['Relevance']) ]; } diff --git a/Model/Filter/FilterBuilder.php b/Model/Filter/FilterBuilder.php index fa921285..df45772d 100644 --- a/Model/Filter/FilterBuilder.php +++ b/Model/Filter/FilterBuilder.php @@ -151,9 +151,8 @@ public function mapIncludeFilter(Item $item) try { $this->mapValueToFilter($filterName, $value); } catch (NostoException $e) { - $this->logger->info($e); + $this->logger->info($e->getMessage()); } - } /** @@ -173,7 +172,7 @@ private function mapValueToFilter(string $name, $value) $this->includeFilters->setPrice(min($value), max($value)); break; case 'new': - $this->includeFilters->setFresh($value); + $this->includeFilters->setFresh((bool)$value); break; default: $this->includeFilters->setCustomFields($name, $this->makeArrayFromValue($value)); diff --git a/Model/Service/Recommendation/Category.php b/Model/Service/Recommendation/Category.php index 731fdda1..9ca5537f 100644 --- a/Model/Service/Recommendation/Category.php +++ b/Model/Service/Recommendation/Category.php @@ -36,12 +36,10 @@ namespace Nosto\Cmp\Model\Service\Recommendation; -use Exception; use Nosto\Object\Signup\Account as NostoAccount; use Nosto\Operation\AbstractGraphQLOperation; use Nosto\Service\FeatureAccess; use Nosto\Operation\Recommendation\CategoryMerchandising; -use Nosto\Tagging\Logger\Logger as NostoLogger; use Magento\Framework\Stdlib\CookieManagerInterface; use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; use Nosto\Cmp\Model\Filter\FilterBuilder; @@ -53,20 +51,16 @@ class Category const NOSTO_PREVIEW_COOKIE = 'nostopreview'; const MAX_PRODUCT_AMOUNT = 100; - private $logger; private $cookieManager; /** * Category constructor. * @param CookieManagerInterface $cookieManager - * @param NostoLogger $logger */ public function __construct( - CookieManagerInterface $cookieManager, - NostoLogger $logger + CookieManagerInterface $cookieManager ) { $this->cookieManager = $cookieManager; - $this->logger = $logger; } /** diff --git a/Observer/App/Action/Action.php b/Observer/App/Action/Action.php index 771ae020..3f8963f5 100644 --- a/Observer/App/Action/Action.php +++ b/Observer/App/Action/Action.php @@ -61,7 +61,7 @@ public function __construct(HttpResponse $response) /** * @param Observer $observer */ - public function execute(Observer $observer) + public function execute(Observer $observer) // phpcs:ignore { if (!ServerTiming::getInstance()->isEmpty()) { $this->response->setHeader( diff --git a/Plugin/Catalog/Block/AbstractBlock.php b/Plugin/Catalog/Block/AbstractBlock.php index b38fd136..65d9f9dc 100644 --- a/Plugin/Catalog/Block/AbstractBlock.php +++ b/Plugin/Catalog/Block/AbstractBlock.php @@ -41,7 +41,6 @@ use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\View\Element\Template; use Magento\Theme\Block\Html\Pager as MagentoPager; -use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; use Nosto\Cmp\Helper\CategorySorting as NostoHelperSorting; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; @@ -112,18 +111,17 @@ public function __construct( public function isCmpCurrentSortOrder() { try { - /* @var Store $store */ $store = $this->storeManager->getStore(); } catch (NoSuchEntityException $e) { $this->logger->info('Cannot get store'); return false; } - $currentOrder = $this->getCurrentOrder(); if ($currentOrder === null) { return false; } if ($currentOrder === NostoHelperSorting::NOSTO_PERSONALIZED_KEY + //@phan-suppress-next-line PhanTypeMismatchArgument && $this->nostoHelperAccount->nostoInstalledAndEnabled($store) && $this->nostoCmpHelperData->isCategorySortingEnabled($store) ) { @@ -215,7 +213,7 @@ public function afterGetLastNum($block, $result) if ($this->isCmpTakingOverCatalog()) { $pageSize = $block->getCollection()->getPageSize(); $currentPage = $this->getCurrentPageNumber(); - $totalResultOfPage = $block->getCollection()->count(); + $totalResultOfPage = $block->getCollection()->getSize(); return $pageSize * ($currentPage - 1) + $totalResultOfPage; } return $result; @@ -226,7 +224,7 @@ public function afterGetLastNum($block, $result) * @param $result * @return int */ - public function afterGetTotalNum($block, $result) + public function afterGetTotalNum($block, $result) // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter { if ($this->isCmpTakingOverCatalog()) { return $this->getTotalProducts(); @@ -239,7 +237,7 @@ public function afterGetTotalNum($block, $result) * @param $result * @return int */ - public function afterGetLastPageNum($block, $result) + public function afterGetLastPageNum($block, $result) // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter { if ($this->isCmpTakingOverCatalog()) { return $this->getLastPageNumber(); diff --git a/Plugin/Catalog/Block/DefaultParameterResolver.php b/Plugin/Catalog/Block/DefaultParameterResolver.php index 5976783e..668dc785 100644 --- a/Plugin/Catalog/Block/DefaultParameterResolver.php +++ b/Plugin/Catalog/Block/DefaultParameterResolver.php @@ -92,7 +92,7 @@ private function getDefaultCategorySorting() * @var Category $category * @noinspection PhpDeprecationInspection */ - $category = $this->registry->registry('current_category'); + $category = $this->registry->registry('current_category'); //@phan-suppress-current-line PhanDeprecatedFunction if ($category instanceof Category) { return $category->getDefaultSortBy(); } diff --git a/Plugin/Catalog/Block/Pager.php b/Plugin/Catalog/Block/Pager.php index 3a1cd54e..ea375eec 100644 --- a/Plugin/Catalog/Block/Pager.php +++ b/Plugin/Catalog/Block/Pager.php @@ -63,15 +63,17 @@ public function __construct( parent::__construct($context, $parameterResolver, $nostoCmpHelperData, $nostoHelperAccount, $logger); } - /** * @param MagentoPager $pager * @param $result * @param $param * @return bool */ - public function afterIsPageCurrent(MagentoPager $pager, $result, $param) - { + public function afterIsPageCurrent( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + MagentoPager $pager, + $result, + $param + ) { if ($this->isCmpTakingOverCatalog()) { return $this->getCurrentPageNumber() === (int) $param; } @@ -95,24 +97,27 @@ public function afterGetFramePages(MagentoPager $pager, $result) $frameLength = $pager->getFrameLength(); // If total number of pages is smaller than frameLength, display them all - if ($this->getLastPageNumber() <= $frameLength) { + $lastPageNum = $this->getLastPageNumber(); + if ($lastPageNum <= $frameLength) { $start = 1; - $end = $this->getLastPageNumber(); + $end = $lastPageNum; //else display only as much as frameLength } else { $half = ceil($frameLength / 2); - if ($this->getCurrentPageNumber() >= $half && $this->getCurrentPageNumber() <= $this->getLastPageNumber() - $half) { - $start = $this->getCurrentPageNumber() - $half + 1; + $curPageNum = $this->getCurrentPageNumber(); + if ($curPageNum >= $half + && $curPageNum <= $lastPageNum - $half) { + $start = $curPageNum - $half + 1; $end = $start + $frameLength - 1; - } elseif ($this->getCurrentPageNumber() < $half) { + } elseif ($curPageNum < $half) { $start = 1; $end = $frameLength; - } elseif ($this->getCurrentPageNumber() > $this->getLastPageNumber() - $half) { - $end = $this->getLastPageNumber(); + } elseif ($curPageNum > $lastPageNum - $half) { + $end = $lastPageNum; $start = $end - $frameLength + 1; } } - return range($start,$end); + return range($start, $end); } return $result; } @@ -122,8 +127,10 @@ public function afterGetFramePages(MagentoPager $pager, $result) * @param $result * @return bool */ - public function afterIsFirstPage(MagentoPager $pager, $result) - { + public function afterIsFirstPage( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + MagentoPager $pager, + $result + ) { if ($this->isCmpTakingOverCatalog()) { return $this->getCurrentPageNumber() === 1; } @@ -135,8 +142,10 @@ public function afterIsFirstPage(MagentoPager $pager, $result) * @param $result * @return bool */ - public function afterIsLastPage(MagentoPager $pager, $result) - { + public function afterIsLastPage(// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + MagentoPager $pager, + $result + ) { if ($this->isCmpTakingOverCatalog()) { return $this->getLastPageNumber() === $this->getCurrentPageNumber(); } @@ -151,7 +160,7 @@ public function afterIsLastPage(MagentoPager $pager, $result) public function afterGetNextPageUrl(MagentoPager $pager, $result) { if ($this->isCmpTakingOverCatalog()) { - return $pager->getPageUrl($this->getCurrentPageNumber() + 1); + return $pager->getPageUrl((string)($this->getCurrentPageNumber() + 1)); } return $result; } @@ -164,7 +173,7 @@ public function afterGetNextPageUrl(MagentoPager $pager, $result) public function afterGetPreviousPageUrl(MagentoPager $pager, $result) { if ($this->isCmpTakingOverCatalog()) { - return $pager->getPageUrl($this->getCurrentPageNumber() - 1); + return $pager->getPageUrl((string)($this->getCurrentPageNumber() - 1)); } return $result; } diff --git a/Plugin/Catalog/Block/ParameterResolverInterface.php b/Plugin/Catalog/Block/ParameterResolverInterface.php index ca7f68b4..5b2b9314 100644 --- a/Plugin/Catalog/Block/ParameterResolverInterface.php +++ b/Plugin/Catalog/Block/ParameterResolverInterface.php @@ -43,7 +43,6 @@ interface ParameterResolverInterface */ public function getSortingOrder(); - /** * @return int */ diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index 89e71d2e..ddb5a3b0 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -53,7 +53,6 @@ use Nosto\Cmp\Utils\Debug\ServerTiming; use Nosto\Cmp\Model\Service\Recommendation\Category as CategoryRecommendation; use Nosto\Cmp\Plugin\Catalog\Model\Product as NostoProductPlugin; -use Nosto\Exception\TokenException\MissingAppsTokenException; use Nosto\Helper\ArrayHelper as NostoHelperArray; use Nosto\NostoException; use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; @@ -132,7 +131,7 @@ public function __construct( * @return MagentoToolbar * @throws NoSuchEntityException */ - public function afterSetCollection( + public function afterSetCollection( // phpcs:ignore EcgM2.Plugins.Plugin.PluginWarning MagentoToolbar $subject ) { if (self::$isProcessed) { @@ -150,7 +149,7 @@ public function afterSetCollection( ); } $this->setLimit($subjectCollection->getPageSize()); - $result = $this->getCmpResult($store); + $result = $this->getCmpResult($store); //@phan-suppress-current-line PhanTypeMismatchArgument //Get ids of products to order $nostoProductIds = $this->parseProductIds($result); if (!empty($nostoProductIds) @@ -165,7 +164,7 @@ public function afterSetCollection( } else { $this->logger->info(sprintf( "CMP result is empty for category: %s", - $this->getCurrentCategory($store) + $this->getCurrentCategory($store) //@phan-suppress-current-line PhanTypeMismatchArgument )); } } catch (Exception $e) { @@ -180,7 +179,6 @@ public function afterSetCollection( * @param Store $store * @return CategoryMerchandisingResult * @throws NostoException - * @throws MissingAppsTokenException * @throws LocalizedException */ private function getCmpResult(Store $store) @@ -215,9 +213,10 @@ function () use ($nostoAccount, $store) { * Get the current category * @return null|string */ - private function getCurrentCategory(Store $store) { + private function getCurrentCategory(Store $store) + { /** @noinspection PhpDeprecationInspection */ - $category = $this->registry->registry('current_category'); + $category = $this->registry->registry('current_category'); //@phan-suppress-current-line PhanDeprecatedFunction return $this->categoryBuilder->getCategory($category, $store); } @@ -243,7 +242,7 @@ private function whereInProductIds(ProductCollection $collection, array $nostoPr { $select = $collection->getSelect(); $zendExpression = new Zend_Db_Expr( - 'e.entity_id IN (' . implode(',', $nostoProductIds ) . ')' + 'e.entity_id IN (' . implode(',', $nostoProductIds) . ')' ); $select->where($zendExpression); } @@ -290,6 +289,6 @@ private function addTrackParamToProduct(ProductCollection $collection, $trackCod */ private function getSecondarySort() { - return 'cat_index_position ASC'; // ToDo - must be selectable by the merchant + return 'cat_index_position ASC'; } } diff --git a/Plugin/Catalog/Model/Config.php b/Plugin/Catalog/Model/Config.php index f1d6f11b..4df74e7b 100644 --- a/Plugin/Catalog/Model/Config.php +++ b/Plugin/Catalog/Model/Config.php @@ -85,10 +85,13 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @throws NoSuchEntityException */ - public function afterGetAttributeUsedForSortByArray(MagentoConfig $catalogConfig, $options) - { + public function afterGetAttributeUsedForSortByArray( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + MagentoConfig $catalogConfig, + $options + ) { /* @var Store $store */ $store = $this->storeManager->getStore(); + //@phan-suppress-next-line PhanTypeMismatchArgument if ($this->nostoHelperAccount->nostoInstalledAndEnabled($store) && $this->nostoCmpHelperData->isCategorySortingEnabled($store) ) { diff --git a/Plugin/Catalog/Model/Product.php b/Plugin/Catalog/Model/Product.php index 18a70b92..5995c47b 100644 --- a/Plugin/Catalog/Model/Product.php +++ b/Plugin/Catalog/Model/Product.php @@ -79,7 +79,9 @@ public function afterGetProductUrl(MagentoProduct $product, $url) */ private function parseExistingQueryParams($url) { + // phpcs:ignore Magento2.Functions.DiscouragedFunction.Discouraged, Ecg.Security.ForbiddenFunction.Found $parsed = parse_url($url, PHP_URL_QUERY); + // phpcs:ignore Magento2.Functions.DiscouragedFunction.Discouraged, Ecg.Security.ForbiddenFunction.Found parse_str($parsed, $result); return $result; } diff --git a/Plugin/Catalog/Model/Sortby.php b/Plugin/Catalog/Model/Sortby.php index 37c50532..b9796634 100644 --- a/Plugin/Catalog/Model/Sortby.php +++ b/Plugin/Catalog/Model/Sortby.php @@ -90,8 +90,10 @@ public function __construct( * @throws NoSuchEntityException * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterGetAllOptions(MagentoSortby $sortBy, $options) - { + public function afterGetAllOptions( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + MagentoSortby $sortBy, + $options + ) { $id = (int)$this->request->getParam('store'); $store = $this->storeManager->getStore($id); @@ -100,7 +102,7 @@ public function afterGetAllOptions(MagentoSortby $sortBy, $options) ) { // new option $customOption = [ - ['label' => __('Relevance'), 'value' => NostoHelperSorting::NOSTO_PERSONALIZED_KEY] + ['label' => __(['Relevance']), 'value' => NostoHelperSorting::NOSTO_PERSONALIZED_KEY] ]; // merge default sorting options with custom options diff --git a/Plugin/Http/Context.php b/Plugin/Http/Context.php index db3e9060..7fa115a3 100644 --- a/Plugin/Http/Context.php +++ b/Plugin/Http/Context.php @@ -85,7 +85,23 @@ class Context /** @var NostoLogger */ private $logger; + /** + * @var Session + */ + private $customerSession; + /** + * Context constructor. + * @param Session $customerSession + * @param CookieManagerInterface $cookieManager + * @param CategoryFactory $categoryFactory + * @param CategoryBuilder $categoryBuilder + * @param StoreManagerInterface $storeManager + * @param NostoHelperAccount $nostoHelperAccount + * @param NostoCmpHelperData $nostoCmpHelperData + * @param Http $request + * @param NostoLogger $logger + */ public function __construct( Session $customerSession, CookieManagerInterface $cookieManager, @@ -112,6 +128,7 @@ public function __construct( * @param MagentoContext $subject * @return MagentoContext */ + // phpcs:ignore EcgM2.Plugins.Plugin public function beforeGetVaryString(MagentoContext $subject) { try { @@ -119,10 +136,10 @@ public function beforeGetVaryString(MagentoContext $subject) } catch (Exception $e) { $this->logger->exception($e); } - + $sortingParameter = $this->request->getParam(ParamResolver::DEFAULT_SORTING_ORDER_PARAM); if ($this->isCategoryPage() && - $this->request->getParam(ParamResolver::DEFAULT_SORTING_ORDER_PARAM) && - $this->request->getParam(ParamResolver::DEFAULT_SORTING_ORDER_PARAM) === NostoHelperSorting::NOSTO_PERSONALIZED_KEY && + $sortingParameter && + $sortingParameter === NostoHelperSorting::NOSTO_PERSONALIZED_KEY && $this->nostoHelperAccount->nostoInstalledAndEnabled($this->store) && $this->nostoCmpHelperData->isCategorySortingEnabled($this->store)) { @@ -132,7 +149,6 @@ public function beforeGetVaryString(MagentoContext $subject) } $subject->setValue('CONTEXT_NOSTO', $variation, $defaultValue = ""); } - return $subject; } @@ -140,7 +156,8 @@ public function beforeGetVaryString(MagentoContext $subject) * Get segment id from cookie * @return string */ - private function getSegmentFromCookie() { + private function getSegmentFromCookie() + { //Read cookie $cookie = $this->cookieManager->getCookie(SegmentMapping::COOKIE_CATEGORY_MAP); if ($cookie === null) { @@ -150,7 +167,6 @@ private function getSegmentFromCookie() { )); return ''; } - //Parse value $stdClass = json_decode($cookie); if ($stdClass === null) { @@ -161,22 +177,19 @@ private function getSegmentFromCookie() { return ''; } $segmentMap = get_object_vars($stdClass); - $signedInteger = crc32($this->categoryString); $unsignedInteger = (int) sprintf("%u", $signedInteger); $hashedCategory = dechex($unsignedInteger); - //Check if current category is part of segment mapping if (array_key_exists($hashedCategory, $segmentMap) && is_numeric($segmentMap[$hashedCategory])) { - $index = $segmentMap[$hashedCategory]; $indexedIds = $this->cookieManager->getCookie(SegmentMapping::COOKIE_SEGMENT_MAP); if ($indexedIds === null || $indexedIds === '') { return ''; } $indexedIds = json_decode($indexedIds); - return $indexedIds[$index]; + return $indexedIds[$index]; //@phan-suppress-current-line PhanTypeArraySuspiciousNullable } return ''; } @@ -184,7 +197,8 @@ private function getSegmentFromCookie() { /** * @throws NoSuchEntityException */ - private function setCategoryAndStore() { + private function setCategoryAndStore() + { $category = $this->getCategory(); if ($category) { $this->store = $this->storeManager->getStore(); @@ -198,7 +212,8 @@ private function setCategoryAndStore() { * Checks if the current page is a category page * @return bool */ - private function isCategoryPage() { + private function isCategoryPage() + { if (is_string($this->categoryString)) { return true; } @@ -209,7 +224,8 @@ private function isCategoryPage() { * Return category object or false if not found * @return null|Category */ - private function getCategory() { + private function getCategory() + { $categoryFactory = $this->categoryFactory->create(); $urlPath = $this->getUrlPath(); if (!is_string($urlPath)) { @@ -221,22 +237,19 @@ private function getCategory() { /** * @return null|string */ - private function getUrlPath() { - $path = $this->request->getUri()->getPath(); + private function getUrlPath() + { + $path = $this->request->getUri()->getPath(); //@phan-suppress-current-line PhanUndeclaredMethod if ($path === null) { return null; } - //Remove leading slash $path = substr($path, 1); if (!is_string($path)) { return null; } - - //Remove . ending $path = explode(".", $path)[0]; - return $path; } } diff --git a/Utils/Debug/Product.php b/Utils/Debug/Product.php index f0d828ea..f4ef05cb 100644 --- a/Utils/Debug/Product.php +++ b/Utils/Debug/Product.php @@ -53,7 +53,7 @@ class Product /** * Product constructor. */ - private function __construct() + private function __construct() // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedFunction { // Private } diff --git a/Utils/Debug/ServerTiming.php b/Utils/Debug/ServerTiming.php index 9c94737c..adc3990b 100644 --- a/Utils/Debug/ServerTiming.php +++ b/Utils/Debug/ServerTiming.php @@ -53,7 +53,7 @@ class ServerTiming /** * ServerTiming constructor. */ - private function __construct() + private function __construct() // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedFunction { // Private } @@ -62,7 +62,7 @@ private function __construct() * Call user function, measure how long it takes and add time to array * @param callable $fn * @param string $name - * @return mixed; + * @return mixed */ public function instrument(callable $fn, $name) { diff --git a/composer.json b/composer.json index 1e9c3d04..3d7f69a1 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,20 @@ "type": "magento2-module", "version": "1.1.0", "require-dev": { - "php": ">=7.1.0" + "php": ">=7.1.0", + "magento-ecg/coding-standard": "3.*", + "magento/module-store": "101.0.4", + "magento/zendframework1": "1.14.3", + "mridang/pmd-annotations": "^0.0.2", + "staabm/annotate-pull-request-from-checkstyle": "^1.1", + "magento/magento-coding-standard": "^5.0", + "phan/phan": "2.6", + "phpmd/phpmd": "^2.6", + "sebastian/phpcpd": "4.1.0", + "drenso/phan-extensions": "^2.5", + "phing/phing": "2.*", + "squizlabs/php_codesniffer": "^3.5", + "magento/module-layered-navigation": "100.3.1" }, "license": [ "OSL-3.0" @@ -19,18 +32,6 @@ { "type": "composer", "url": "https://repo.magento.com/" - }, - { - "type": "package", - "package": { - "name": "magento/marketplace-tools", - "version": "dev-master", - "source": { - "url": "https://github.com/magento/marketplace-tools", - "type": "git", - "reference": "origin/master" - } - } } ], "autoload": { @@ -40,5 +41,11 @@ "files": [ "registration.php" ] + }, + "archive": { + "exclude": ["Jenkinsfile", "Dockerfile", ".DS_STORE", ".idea", ".phan", ".docker", "ruleset.xml", "phan.*", ".gitignore", "build.xml", ".github", "supervisord.conf", "entrypoint.sh", "/magento"] + }, + "config": { + "process-timeout":0 } } diff --git a/composer.lock b/composer.lock index a946210c..c43b2a36 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "83583b7d5e51a9a4d2d54be23f347f9f", + "content-hash": "3e6a5a8e7a7c31c4b3ada60fa7ff4ec8", "packages": [ { "name": "colinmollenhour/credis", @@ -3580,7 +3580,3685 @@ "time": "2019-11-06T18:30:11+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "drenso/phan-extensions", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/Drenso/PhanExtensions.git", + "reference": "cedef1c214c259bfaab0652256abf931b00c2781" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Drenso/PhanExtensions/zipball/cedef1c214c259bfaab0652256abf931b00c2781", + "reference": "cedef1c214c259bfaab0652256abf931b00c2781", + "shasum": "" + }, + "require-dev": { + "phan/phan": "~1|~2" + }, + "type": "project", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bob van de Vijver", + "email": "bob@drenso.nl" + }, + { + "name": "Tobias Feijten", + "email": "tobias@drenso.nl" + } + ], + "description": "This project contains several extensions (stubs/plugins) to be used with Phan for static PHP analysis", + "homepage": "https://github.com/Drenso/PhanExtensions", + "keywords": [ + "phan", + "plugin", + "plugins", + "stub", + "stubs", + "symfony" + ], + "time": "2019-05-31T15:22:44+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "0ed363f8de17d284d479ec813c9ad3f6834b5c40" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/0ed363f8de17d284d479ec813c9ad3f6834b5c40", + "reference": "0ed363f8de17d284d479ec813c9ad3f6834b5c40", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0", + "php": ">=7.0", + "phpdocumentor/reflection-docblock": "^4.0.0 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "time": "2020-03-11T15:21:41+00:00" + }, + { + "name": "laminas/laminas-captcha", + "version": "dev-develop", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-captcha.git", + "reference": "0f5930a887d54354ca13692555feae63491ce77f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-captcha/zipball/0f5930a887d54354ca13692555feae63491ce77f", + "reference": "0f5930a887d54354ca13692555feae63491ce77f", + "shasum": "" + }, + "require": { + "laminas/laminas-math": "^2.7 || ^3.0", + "laminas/laminas-stdlib": "^3.2.1", + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-captcha": "^2.9.0" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~1.0.0", + "laminas/laminas-recaptcha": "^3.0", + "laminas/laminas-session": "^2.8", + "laminas/laminas-text": "^2.6", + "laminas/laminas-validator": "^2.10.1", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2" + }, + "suggest": { + "laminas/laminas-i18n-resources": "Translations of captcha messages", + "laminas/laminas-recaptcha": "Laminas\\ReCaptcha component", + "laminas/laminas-session": "Laminas\\Session component", + "laminas/laminas-text": "Laminas\\Text component", + "laminas/laminas-validator": "Laminas\\Validator component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.9.x-dev", + "dev-develop": "2.10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Captcha\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Generate and validate CAPTCHAs using Figlets, images, ReCaptcha, and more", + "homepage": "https://laminas.dev", + "keywords": [ + "captcha", + "laminas" + ], + "time": "2020-04-15T19:19:36+00:00" + }, + { + "name": "laminas/laminas-db", + "version": "dev-develop", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-db.git", + "reference": "69f932b85317f68a4d2025392b54a41c1474cf03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-db/zipball/69f932b85317f68a4d2025392b54a41c1474cf03", + "reference": "69f932b85317f68a4d2025392b54a41c1474cf03", + "shasum": "" + }, + "require": { + "laminas/laminas-stdlib": "^2.7 || ^3.0", + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-db": "^2.11.0" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~1.0.0", + "laminas/laminas-eventmanager": "^2.6.2 || ^3.0", + "laminas/laminas-hydrator": "^1.1 || ^2.1 || ^3.0", + "laminas/laminas-servicemanager": "^2.7.5 || ^3.0.3", + "phpunit/phpunit": "^5.7.27 || ^6.5.14" + }, + "suggest": { + "laminas/laminas-eventmanager": "Laminas\\EventManager component", + "laminas/laminas-hydrator": "Laminas\\Hydrator component for using HydratingResultSets", + "laminas/laminas-servicemanager": "Laminas\\ServiceManager component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.11.x-dev", + "dev-develop": "2.12.x-dev" + }, + "laminas": { + "component": "Laminas\\Db", + "config-provider": "Laminas\\Db\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Db\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Database abstraction layer, SQL abstraction, result set abstraction, and RowDataGateway and TableDataGateway implementations", + "homepage": "https://laminas.dev", + "keywords": [ + "db", + "laminas" + ], + "time": "2020-04-16T14:53:56+00:00" + }, + { + "name": "laminas/laminas-session", + "version": "dev-develop", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-session.git", + "reference": "9207c4e6a875e4e76be3d801e8c4ba60a0295127" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-session/zipball/9207c4e6a875e4e76be3d801e8c4ba60a0295127", + "reference": "9207c4e6a875e4e76be3d801e8c4ba60a0295127", + "shasum": "" + }, + "require": { + "laminas/laminas-eventmanager": "^2.6.2 || ^3.0", + "laminas/laminas-stdlib": "^3.2.1", + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-session": "^2.9.1" + }, + "require-dev": { + "container-interop/container-interop": "^1.1", + "laminas/laminas-cache": "^2.6.1", + "laminas/laminas-coding-standard": "~1.0.0", + "laminas/laminas-db": "^2.7", + "laminas/laminas-http": "^2.5.4", + "laminas/laminas-servicemanager": "^2.7.5 || ^3.0.3", + "laminas/laminas-validator": "^2.6", + "mongodb/mongodb": "^1.0.1", + "php-mock/php-mock-phpunit": "^1.1.2 || ^2.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20" + }, + "suggest": { + "laminas/laminas-cache": "Laminas\\Cache component", + "laminas/laminas-db": "Laminas\\Db component", + "laminas/laminas-http": "Laminas\\Http component", + "laminas/laminas-servicemanager": "Laminas\\ServiceManager component", + "laminas/laminas-validator": "Laminas\\Validator component", + "mongodb/mongodb": "If you want to use the MongoDB session save handler" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.9.x-dev", + "dev-develop": "2.10.x-dev" + }, + "laminas": { + "component": "Laminas\\Session", + "config-provider": "Laminas\\Session\\ConfigProvider" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Session\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Object-oriented interface to PHP sessions and storage", + "homepage": "https://laminas.dev", + "keywords": [ + "laminas", + "session" + ], + "time": "2020-04-15T19:32:59+00:00" + }, + { + "name": "magento-ecg/coding-standard", + "version": "3.1", + "source": { + "type": "git", + "url": "https://github.com/magento-ecg/coding-standard.git", + "reference": "fbeeb7ad68de02b15753d56dda9493af9c35bcaf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/magento-ecg/coding-standard/zipball/fbeeb7ad68de02b15753d56dda9493af9c35bcaf", + "reference": "fbeeb7ad68de02b15753d56dda9493af9c35bcaf", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Magento Expert Consulting Group", + "homepage": "http://magentocommerce.com/consulting", + "role": "Maintainer" + } + ], + "description": "A set of PHP_CodeSniffer rules and sniffs.", + "homepage": "https://github.com/magento-ecg/coding-standard", + "time": "2017-06-30T19:00:28+00:00" + }, + { + "name": "magento/framework-bulk", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/framework-bulk/magento-framework-bulk-100.3.5.0.zip", + "shasum": "509ad2894d5fbbd0648aa84ddd83442a09b03676" + }, + "require": { + "magento/framework": "102.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-library", + "autoload": { + "psr-4": { + "Magento\\Framework\\Bulk\\": "" + }, + "files": [ + "registration.php" + ] + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/magento-coding-standard", + "version": "5", + "source": { + "type": "git", + "url": "https://github.com/magento/magento-coding-standard.git", + "reference": "da46c5d57a43c950dfa364edc7f1f0436d5353a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/magento/magento-coding-standard/zipball/da46c5d57a43c950dfa364edc7f1f0436d5353a5", + "reference": "da46c5d57a43c950dfa364edc7f1f0436d5353a5", + "shasum": "" + }, + "require": { + "php": ">=5.6.0", + "squizlabs/php_codesniffer": "^3.4", + "webonyx/graphql-php": ">=0.12.6 <1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "classmap": [ + "PHP_CodeSniffer/Tokenizers/" + ], + "psr-4": { + "Magento2\\": "Magento2/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "A set of Magento specific PHP CodeSniffer rules.", + "time": "2019-11-04T22:08:27+00:00" + }, + { + "name": "magento/module-asynchronous-operations", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-asynchronous-operations/magento-module-asynchronous-operations-100.3.5.0.zip", + "shasum": "33c0400729a05e80a0911d9f5a1de38743011aeb" + }, + "require": { + "magento/framework": "102.0.*", + "magento/framework-bulk": "100.3.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-admin-notification": "100.3.*", + "magento/module-logging": "101.1.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\AsynchronousOperations\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-authorization", + "version": "100.3.4-p2", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-authorization/magento-module-authorization-100.3.4.0-patch2.zip", + "shasum": "f3f1344ddd308e90d7fbddc106ecf85795bab3bb" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Authorization\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "Authorization module provides access to Magento ACL functionality." + }, + { + "name": "magento/module-backend", + "version": "101.0.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-backend/magento-module-backend-101.0.5.0.zip", + "shasum": "97b6ba680497709af06b6f650fde3a40612238e7" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backup": "100.3.*", + "magento/module-catalog": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-developer": "100.3.*", + "magento/module-directory": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-quote": "101.1.*", + "magento/module-reports": "100.3.*", + "magento/module-require-js": "100.3.*", + "magento/module-sales": "102.0.*", + "magento/module-security": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-translation": "100.3.*", + "magento/module-ui": "101.1.*", + "magento/module-user": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-theme": "101.0.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Backend\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-backup", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-backup/magento-module-backup-100.3.5.0.zip", + "shasum": "3621daf8868f8e571119c8a1da505d196198c67c" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-cron": "100.3.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Backup\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-bundle", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-bundle/magento-module-bundle-100.3.5.0.zip", + "shasum": "b0bd30f204434536591a9d884fcb642e878bac5b" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-catalog-rule": "101.1.*", + "magento/module-checkout": "100.3.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-eav": "102.0.*", + "magento/module-gift-message": "100.3.*", + "magento/module-media-storage": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-sales": "102.0.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-bundle-sample-data": "Sample Data version: 100.3.*", + "magento/module-sales-rule": "101.1.*", + "magento/module-webapi": "100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Bundle\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-captcha", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-captcha/magento-module-captcha-100.3.5.0.zip", + "shasum": "add6039b2f8aae8e902146d35591f2be6c1ed70d" + }, + "require": { + "laminas/laminas-captcha": "^2.7.1", + "laminas/laminas-db": "^2.8.2", + "laminas/laminas-session": "^2.7.3", + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-checkout": "100.3.*", + "magento/module-customer": "102.0.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Captcha\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-catalog", + "version": "103.0.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-catalog/magento-module-catalog-103.0.5.0.zip", + "shasum": "0e61c6128447e8565ec51dccbd184987cbc16c91" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-asynchronous-operations": "100.3.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-catalog-rule": "101.1.*", + "magento/module-catalog-url-rewrite": "100.3.*", + "magento/module-checkout": "100.3.*", + "magento/module-cms": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-directory": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-indexer": "100.3.*", + "magento/module-media-storage": "100.3.*", + "magento/module-msrp": "100.3.*", + "magento/module-page-cache": "100.3.*", + "magento/module-product-alert": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "magento/module-theme": "101.0.*", + "magento/module-ui": "101.1.*", + "magento/module-url-rewrite": "101.1.*", + "magento/module-widget": "101.1.*", + "magento/module-wishlist": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-catalog-sample-data": "Sample Data version: 100.3.*", + "magento/module-cookie": "100.3.*", + "magento/module-sales": "102.0.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Catalog\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-catalog-import-export", + "version": "101.0.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-catalog-import-export/magento-module-catalog-import-export-101.0.5.0.zip", + "shasum": "a2aea6d8f53c2a0bf6805faa2b9e0f64f25a3c7a" + }, + "require": { + "ext-ctype": "*", + "magento/framework": "102.0.*", + "magento/module-authorization": "100.3.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-catalog-url-rewrite": "100.3.*", + "magento/module-customer": "102.0.*", + "magento/module-eav": "102.0.*", + "magento/module-import-export": "100.3.*", + "magento/module-media-storage": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\CatalogImportExport\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-catalog-inventory", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-catalog-inventory/magento-module-catalog-inventory-100.3.5.0.zip", + "shasum": "7b1508cce56fac131a6bbe02d633762f7c05787b" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-eav": "102.0.*", + "magento/module-quote": "101.1.*", + "magento/module-store": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\CatalogInventory\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-catalog-rule", + "version": "101.1.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-catalog-rule/magento-module-catalog-rule-101.1.5.0.zip", + "shasum": "03cc677562434e6792fce263e40da07221640018" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-customer": "102.0.*", + "magento/module-eav": "102.0.*", + "magento/module-rule": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-catalog-rule-sample-data": "Sample Data version: 100.3.*", + "magento/module-import-export": "100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\CatalogRule\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-catalog-url-rewrite", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-catalog-url-rewrite/magento-module-catalog-url-rewrite-100.3.5.0.zip", + "shasum": "8bf1d252e0f51973ee7cbff07f11dfe87e71bc30" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-import-export": "101.0.*", + "magento/module-eav": "102.0.*", + "magento/module-import-export": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-ui": "101.1.*", + "magento/module-url-rewrite": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-webapi": "100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\CatalogUrlRewrite\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-checkout", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-checkout/magento-module-checkout-100.3.5.0.zip", + "shasum": "f089321ca5b08026baaa1ca08505fd22c3bc95b5" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-captcha": "100.3.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-directory": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-msrp": "100.3.*", + "magento/module-page-cache": "100.3.*", + "magento/module-payment": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-sales": "102.0.*", + "magento/module-sales-rule": "101.1.*", + "magento/module-shipping": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "magento/module-theme": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-cookie": "100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Checkout\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-cms", + "version": "103.0.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-cms/magento-module-cms-103.0.5.0.zip", + "shasum": "506da640118fc223d9e8c89b9bdeecc24b2d8de1" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-email": "101.0.*", + "magento/module-media-storage": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-theme": "101.0.*", + "magento/module-ui": "101.1.*", + "magento/module-variable": "100.3.*", + "magento/module-widget": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-cms-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Cms\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-cms-url-rewrite", + "version": "100.3.4", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-cms-url-rewrite/magento-module-cms-url-rewrite-100.3.4.0.zip", + "shasum": "7df716cbc611cd6a5017129be80e80303334da58" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-cms": "103.0.*", + "magento/module-store": "101.0.*", + "magento/module-url-rewrite": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\CmsUrlRewrite\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-config", + "version": "101.1.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-config/magento-module-config-101.1.5.0.zip", + "shasum": "76f1db08a792f3d263a46e2e2fcb7c775891de4c" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-cron": "100.3.*", + "magento/module-deploy": "100.3.*", + "magento/module-directory": "100.3.*", + "magento/module-email": "101.0.*", + "magento/module-media-storage": "100.3.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Config\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-contact", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-contact/magento-module-contact-100.3.5.0.zip", + "shasum": "ac90db3add4bae0f07f6fcd13f6096fcc89b3dda" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-cms": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Contact\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-cron", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-cron/magento-module-cron-100.3.5.0.zip", + "shasum": "23bc93a34e4cd0353bb1156b7d20f47b0ff901d9" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-config": "101.1.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Cron\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-customer", + "version": "102.0.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-customer/magento-module-customer-102.0.5.0.zip", + "shasum": "d0ac50edf69a2c9b27914607807d9bb67c49e3d1" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-checkout": "100.3.*", + "magento/module-config": "101.1.*", + "magento/module-directory": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-integration": "100.3.*", + "magento/module-media-storage": "100.3.*", + "magento/module-newsletter": "100.3.*", + "magento/module-page-cache": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-review": "100.3.*", + "magento/module-sales": "102.0.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "magento/module-theme": "101.0.*", + "magento/module-ui": "101.1.*", + "magento/module-wishlist": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-cookie": "100.3.*", + "magento/module-customer-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Customer\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-deploy", + "version": "100.3.4", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-deploy/magento-module-deploy-100.3.4.0.zip", + "shasum": "95d79bef2bf03ff18e4c6feedff80acc9ba2ba76" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-config": "101.1.*", + "magento/module-require-js": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-user": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "cli_commands.php", + "registration.php" + ], + "psr-4": { + "Magento\\Deploy\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-developer", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-developer/magento-module-developer-100.3.5.0.zip", + "shasum": "eb60581bc7c5089c42afb0e05804e275b1ab2c26" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-config": "101.1.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Developer\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-directory", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-directory/magento-module-directory-100.3.5.0.zip", + "shasum": "bb83cfae5ee7af13c3b001fb0ae7291027677b2c" + }, + "require": { + "lib-libxml": "*", + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-config": "101.1.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Directory\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-downloadable", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-downloadable/magento-module-downloadable-100.3.5.0.zip", + "shasum": "aa959dc1139294d14b46dc49fa303d2b012bdbe9" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-checkout": "100.3.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-directory": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-gift-message": "100.3.*", + "magento/module-media-storage": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-sales": "102.0.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "magento/module-theme": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-downloadable-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Downloadable\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-eav", + "version": "102.0.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-eav/magento-module-eav-102.0.5.0.zip", + "shasum": "d673598cb27104689beb0b8afc086b6ca7bed1e9" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-media-storage": "100.3.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Eav\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-email", + "version": "101.0.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-email/magento-module-email-101.0.5.0.zip", + "shasum": "0625386382db4eeca3ba27eb9b5d7f38fc883c20" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-cms": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-media-storage": "100.3.*", + "magento/module-require-js": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-theme": "101.0.*", + "magento/module-variable": "100.3.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-theme": "101.0.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Email\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-gift-message", + "version": "100.3.4-p2", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-gift-message/magento-module-gift-message-100.3.4.0-patch2.zip", + "shasum": "62dd2c2a3277f09c7e5bdf3682a380e9316e7d7a" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-checkout": "100.3.*", + "magento/module-customer": "102.0.*", + "magento/module-quote": "101.1.*", + "magento/module-sales": "102.0.*", + "magento/module-store": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-eav": "102.0.*", + "magento/module-multishipping": "100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\GiftMessage\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-import-export", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-import-export/magento-module-import-export-100.3.5.0.zip", + "shasum": "b5233cd6e72f88cdd9c4057a0a8d3a0bf8d5fe5d" + }, + "require": { + "ext-ctype": "*", + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-eav": "102.0.*", + "magento/module-media-storage": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\ImportExport\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-indexer", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-indexer/magento-module-indexer-100.3.5.0.zip", + "shasum": "97f2e2ab30599c77ded2b8a4e86370a1c0d93496" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Indexer\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-integration", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-integration/magento-module-integration-100.3.5.0.zip", + "shasum": "387845cc77de287199043f222d397d858d359dad" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-customer": "102.0.*", + "magento/module-security": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-user": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Integration\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-layered-navigation", + "version": "100.3.1", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-layered-navigation/magento-module-layered-navigation-100.3.1.0.zip", + "shasum": "32c5d1e9d21dd98adabe7083ddb3b39ab49d2bde" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-config": "101.1.*", + "php": "~7.1.3||~7.2.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\LayeredNavigation\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-media-storage", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-media-storage/magento-module-media-storage-100.3.5.0.zip", + "shasum": "770765c3219f6e9b2a9219bda5f323c9a2bbe67f" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-store": "101.0.*", + "magento/module-theme": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\MediaStorage\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-msrp", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-msrp/magento-module-msrp-100.3.5.0.zip", + "shasum": "e655270c64d4a59042216354fba54f7ea0f79970" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-downloadable": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-bundle": "100.3.*", + "magento/module-msrp-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Msrp\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-newsletter", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-newsletter/magento-module-newsletter-100.3.5.0.zip", + "shasum": "d4016f9448165145b33c27f1f362924f7046b3ec" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-cms": "103.0.*", + "magento/module-customer": "102.0.*", + "magento/module-eav": "102.0.*", + "magento/module-email": "101.0.*", + "magento/module-require-js": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-widget": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Newsletter\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-page-cache", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-page-cache/magento-module-page-cache-100.3.5.0.zip", + "shasum": "471c6c14cdef8f95272ef5464a188015e222f75a" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-config": "101.1.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\PageCache\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-payment", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-payment/magento-module-payment-100.3.5.0.zip", + "shasum": "2ba5a4fc32d0abc41a9ee15c9fd951b60a14f279" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-checkout": "100.3.*", + "magento/module-config": "101.1.*", + "magento/module-directory": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-sales": "102.0.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Payment\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-product-alert", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-product-alert/magento-module-product-alert-100.3.5.0.zip", + "shasum": "09671613f8eed2b5df5502addae25a92146aca9b" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-customer": "102.0.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-config": "101.1.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\ProductAlert\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-quote", + "version": "101.1.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-quote/magento-module-quote-101.1.5.0.zip", + "shasum": "3e155895b482f01197c841eecde3c4bd159d992e" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-checkout": "100.3.*", + "magento/module-customer": "102.0.*", + "magento/module-directory": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-payment": "100.3.*", + "magento/module-sales": "102.0.*", + "magento/module-sales-sequence": "100.3.*", + "magento/module-shipping": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-webapi": "100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Quote\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-reports", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-reports/magento-module-reports-100.3.5.0.zip", + "shasum": "21d76a652705a242465f9d62649cd8e1413cb131" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-cms": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-downloadable": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-quote": "101.1.*", + "magento/module-review": "100.3.*", + "magento/module-sales": "102.0.*", + "magento/module-sales-rule": "101.1.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "magento/module-widget": "101.1.*", + "magento/module-wishlist": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Reports\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-require-js", + "version": "100.3.4", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-require-js/magento-module-require-js-100.3.4.0.zip", + "shasum": "e79dc717bc6dd757edeed64bf241e5cdfdde9657" + }, + "require": { + "magento/framework": "102.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\RequireJs\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-review", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-review/magento-module-review-100.3.5.0.zip", + "shasum": "1d8c8db3b53d09be9619e08d539da30a9a84ca98" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-customer": "102.0.*", + "magento/module-eav": "102.0.*", + "magento/module-newsletter": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-theme": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-cookie": "100.3.*", + "magento/module-review-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Review\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-rss", + "version": "100.3.4", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-rss/magento-module-rss-100.3.4.0.zip", + "shasum": "1b0679e071ce56735e0cde92aadb11e5aad23a6e" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-customer": "102.0.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Rss\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-rule", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-rule/magento-module-rule-100.3.5.0.zip", + "shasum": "c9ca9297c916a1138eb8c2c132356716202d397b" + }, + "require": { + "lib-libxml": "*", + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-eav": "102.0.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Rule\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-sales", + "version": "102.0.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-sales/magento-module-sales-102.0.5.0.zip", + "shasum": "4b4f42cb0d3cc86b8db60b4da22bc47be52648bc" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-bundle": "100.3.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-checkout": "100.3.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-directory": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-gift-message": "100.3.*", + "magento/module-media-storage": "100.3.*", + "magento/module-payment": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-reports": "100.3.*", + "magento/module-sales-rule": "101.1.*", + "magento/module-sales-sequence": "100.3.*", + "magento/module-shipping": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "magento/module-theme": "101.0.*", + "magento/module-ui": "101.1.*", + "magento/module-widget": "101.1.*", + "magento/module-wishlist": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-sales-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Sales\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-sales-rule", + "version": "101.1.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-sales-rule/magento-module-sales-rule-101.1.5.0.zip", + "shasum": "c69b5ff1a1740574f5f212deb985709e5dcebb9d" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-captcha": "100.3.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-rule": "101.1.*", + "magento/module-checkout": "100.3.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-directory": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-payment": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-reports": "100.3.*", + "magento/module-rule": "100.3.*", + "magento/module-sales": "102.0.*", + "magento/module-shipping": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-ui": "101.1.*", + "magento/module-widget": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-sales-rule-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\SalesRule\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-sales-sequence", + "version": "100.3.4-p2", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-sales-sequence/magento-module-sales-sequence-100.3.4.0-patch2.zip", + "shasum": "f6a9c3573ad6cad3f8420895767504a7379f4194" + }, + "require": { + "magento/framework": "102.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\SalesSequence\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-security", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-security/magento-module-security-100.3.5.0.zip", + "shasum": "6a595272d5f8e90f4fd1e6201044e82b369bbc5f" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-store": "101.0.*", + "magento/module-user": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-customer": "102.0.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Security\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "Security management module" + }, + { + "name": "magento/module-shipping", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-shipping/magento-module-shipping-100.3.5.0.zip", + "shasum": "de9a53127d4efcfb40167279c3412da81dfd907d" + }, + "require": { + "ext-gd": "*", + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-contact": "100.3.*", + "magento/module-customer": "102.0.*", + "magento/module-directory": "100.3.*", + "magento/module-payment": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-sales": "102.0.*", + "magento/module-store": "101.0.*", + "magento/module-tax": "100.3.*", + "magento/module-ui": "101.1.*", + "magento/module-user": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-config": "101.1.*", + "magento/module-fedex": "100.3.*", + "magento/module-ups": "100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Shipping\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-store", + "version": "101.0.4", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-store/magento-module-store-101.0.4.0.zip", + "shasum": "6a824c36cc10790142e6481f8523361276f5a3e7" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-directory": "100.3.*", + "magento/module-media-storage": "100.3.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-deploy": "100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Store\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-tax", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-tax/magento-module-tax-100.3.5.0.zip", + "shasum": "f610f8ae48e1d193187a270df28f8d1614cc656e" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-checkout": "100.3.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-directory": "100.3.*", + "magento/module-eav": "102.0.*", + "magento/module-page-cache": "100.3.*", + "magento/module-quote": "101.1.*", + "magento/module-reports": "100.3.*", + "magento/module-sales": "102.0.*", + "magento/module-shipping": "100.3.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-tax-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Tax\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-theme", + "version": "101.0.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-theme/magento-module-theme-101.0.5.0.zip", + "shasum": "d7485f7189914fe59a490dcd89867cfe53447dea" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-cms": "103.0.*", + "magento/module-config": "101.1.*", + "magento/module-customer": "102.0.*", + "magento/module-eav": "102.0.*", + "magento/module-media-storage": "100.3.*", + "magento/module-require-js": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-ui": "101.1.*", + "magento/module-widget": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-deploy": "100.3.*", + "magento/module-directory": "100.3.*", + "magento/module-theme-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Theme\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-translation", + "version": "100.3.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-translation/magento-module-translation-100.3.5.0.zip", + "shasum": "22f0c984fabba7ee04a953ee9a2e6e4f76a97665" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-developer": "100.3.*", + "magento/module-store": "101.0.*", + "magento/module-theme": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-deploy": "100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Translation\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-ui", + "version": "101.1.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-ui/magento-module-ui-101.1.5.0.zip", + "shasum": "ae1eefd94eb62e8e0ce32d24b96f5b6099b4a607" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-cms": "103.0.*", + "magento/module-eav": "102.0.*", + "magento/module-store": "101.0.*", + "magento/module-user": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-config": "101.1.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Ui\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-url-rewrite", + "version": "101.1.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-url-rewrite/magento-module-url-rewrite-101.1.5.0.zip", + "shasum": "77bf148c934c944e8922c15f404c1ace69d45e3c" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-url-rewrite": "100.3.*", + "magento/module-cms": "103.0.*", + "magento/module-cms-url-rewrite": "100.3.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\UrlRewrite\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-user", + "version": "101.1.5", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-user/magento-module-user-101.1.5.0.zip", + "shasum": "423be90044cb3c3c8c5239f0a8a2fa1eef26fa8c" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-authorization": "100.3.*", + "magento/module-backend": "101.0.*", + "magento/module-email": "101.0.*", + "magento/module-integration": "100.3.*", + "magento/module-security": "100.3.*", + "magento/module-store": "101.0.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\User\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-variable", + "version": "100.3.4-p2", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-variable/magento-module-variable-100.3.4.0-patch2.zip", + "shasum": "a63c275c02121b512998e52e91b48e8e96fe9bc7" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-config": "101.1.*", + "magento/module-store": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Variable\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-widget", + "version": "101.1.4-p2", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-widget/magento-module-widget-101.1.4.0-patch2.zip", + "shasum": "59cc20d35012657cc10d1ca9ca146077ad3cdf3d" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-catalog": "103.0.*", + "magento/module-cms": "103.0.*", + "magento/module-store": "101.0.*", + "magento/module-theme": "101.0.*", + "magento/module-variable": "100.3.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-widget-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Widget\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "magento/module-wishlist", + "version": "101.1.5-p1", + "dist": { + "type": "zip", + "url": "https://repo.magento.com/archives/magento/module-wishlist/magento-module-wishlist-101.1.5.0-patch1.zip", + "shasum": "c46ebc8f64eeaea996729ae56800c3ef6c303fbf" + }, + "require": { + "magento/framework": "102.0.*", + "magento/module-backend": "101.0.*", + "magento/module-captcha": "100.3.*", + "magento/module-catalog": "103.0.*", + "magento/module-catalog-inventory": "100.3.*", + "magento/module-checkout": "100.3.*", + "magento/module-customer": "102.0.*", + "magento/module-rss": "100.3.*", + "magento/module-sales": "102.0.*", + "magento/module-store": "101.0.*", + "magento/module-theme": "101.0.*", + "magento/module-ui": "101.1.*", + "php": "~7.1.3||~7.2.0||~7.3.0" + }, + "suggest": { + "magento/module-bundle": "100.3.*", + "magento/module-configurable-product": "100.3.*", + "magento/module-cookie": "100.3.*", + "magento/module-downloadable": "100.3.*", + "magento/module-grouped-product": "100.3.*", + "magento/module-wishlist-sample-data": "Sample Data version: 100.3.*" + }, + "type": "magento2-module", + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\Wishlist\\": "" + } + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "description": "N/A" + }, + { + "name": "microsoft/tolerant-php-parser", + "version": "v0.0.20", + "source": { + "type": "git", + "url": "https://github.com/microsoft/tolerant-php-parser.git", + "reference": "c5e2bf5d8c9f4f27eef1370bd39ea2d1f374eeb4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/microsoft/tolerant-php-parser/zipball/c5e2bf5d8c9f4f27eef1370bd39ea2d1f374eeb4", + "reference": "c5e2bf5d8c9f4f27eef1370bd39ea2d1f374eeb4", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Microsoft\\PhpParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Lourens", + "email": "roblou@microsoft.com" + } + ], + "description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios", + "time": "2020-02-18T02:57:19+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "0d4d1b48d682a93b6bfedf60b88c7750e9cb0b06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/0d4d1b48d682a93b6bfedf60b88c7750e9cb0b06", + "reference": "0d4d1b48d682a93b6bfedf60b88c7750e9cb0b06", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4", + "squizlabs/php_codesniffer": "~1.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "time": "2019-08-15T19:41:25+00:00" + }, + { + "name": "pdepend/pdepend", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/pdepend/pdepend.git", + "reference": "24b0636bcc8b77709ffe1b78d351e31e3187c4b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/24b0636bcc8b77709ffe1b78d351e31e3187c4b3", + "reference": "24b0636bcc8b77709ffe1b78d351e31e3187c4b3", + "shasum": "" + }, + "require": { + "php": ">=5.3.7", + "symfony/config": "^2.3.0|^3|^4|^5", + "symfony/dependency-injection": "^2.3.0|^3|^4|^5", + "symfony/filesystem": "^2.3.0|^3|^4|^5" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0 || ^1.2.3", + "gregwar/rst": "^1.0", + "phpunit/phpunit": "^4.8.35|^5.7", + "squizlabs/php_codesniffer": "^2.0.0" + }, + "bin": [ + "src/bin/pdepend" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "PDepend\\": "src/main/php/PDepend" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Official version of pdepend to be handled with Composer", + "time": "2020-04-04T12:17:19+00:00" + }, + { + "name": "phan/phan", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/phan/phan.git", + "reference": "d082d19370ff87e6036073eaccda7c06ddc3f53e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phan/phan/zipball/d082d19370ff87e6036073eaccda7c06ddc3f53e", + "reference": "d082d19370ff87e6036073eaccda7c06ddc3f53e", + "shasum": "" + }, + "require": { + "composer/semver": "^1.4", + "composer/xdebug-handler": "^1.3.2", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.0.4", + "microsoft/tolerant-php-parser": "0.0.20", + "netresearch/jsonmapper": "^1.6.0", + "php": "^7.1.0", + "sabre/event": "^5.0", + "symfony/console": "^2.3|^3.0|^4.0|^5.0", + "symfony/polyfill-mbstring": "^1.11.0" + }, + "require-dev": { + "brianium/paratest": "^4.0.0", + "phpunit/phpunit": "^7.5.0" + }, + "suggest": { + "ext-ast": "Needed for parsing ASTs (unless --use-fallback-parser is used). 1.0.1+ is needed, 1.0.6+ is recommended.", + "ext-iconv": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-igbinary": "Improves performance of polyfill when ext-ast is unavailable", + "ext-mbstring": "Either iconv or mbstring is needed to ensure issue messages are valid utf-8", + "ext-tokenizer": "Needed for fallback/polyfill parser support and file/line-based suppressions." + }, + "bin": [ + "phan", + "phan_client", + "tocheckstyle" + ], + "type": "project", + "autoload": { + "psr-4": { + "Phan\\": "src/Phan" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tyson Andre" + }, + { + "name": "Rasmus Lerdorf" + }, + { + "name": "Andrew S. Morrison" + } + ], + "description": "A static analyzer for PHP", + "keywords": [ + "analyzer", + "php", + "static" + ], + "time": "2020-03-07T19:01:06+00:00" + }, + { + "name": "phing/phing", + "version": "2.16.3", + "source": { + "type": "git", + "url": "https://github.com/phingofficial/phing.git", + "reference": "b34c2bf9cd6abd39b4287dee31e68673784c8567" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phingofficial/phing/zipball/b34c2bf9cd6abd39b4287dee31e68673784c8567", + "reference": "b34c2bf9cd6abd39b4287dee31e68673784c8567", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "ext-pdo_sqlite": "*", + "mikey179/vfsstream": "^1.6", + "pdepend/pdepend": "2.x", + "pear/archive_tar": "1.4.x", + "pear/http_request2": "dev-trunk", + "pear/net_growl": "dev-trunk", + "pear/pear-core-minimal": "1.10.1", + "pear/versioncontrol_git": "@dev", + "pear/versioncontrol_svn": "~0.5", + "phpdocumentor/phpdocumentor": "2.x", + "phploc/phploc": "~2.0.6", + "phpmd/phpmd": "~2.2", + "phpunit/phpunit": ">=3.7", + "sebastian/git": "~1.0", + "sebastian/phpcpd": "2.x", + "siad007/versioncontrol_hg": "^1.0", + "simpletest/simpletest": "^1.1", + "squizlabs/php_codesniffer": "~2.2", + "symfony/yaml": "^2.8 || ^3.1 || ^4.0" + }, + "suggest": { + "pdepend/pdepend": "PHP version of JDepend", + "pear/archive_tar": "Tar file management class", + "pear/versioncontrol_git": "A library that provides OO interface to handle Git repository", + "pear/versioncontrol_svn": "A simple OO-style interface for Subversion, the free/open-source version control system", + "phpdocumentor/phpdocumentor": "Documentation Generator for PHP", + "phploc/phploc": "A tool for quickly measuring the size of a PHP project", + "phpmd/phpmd": "PHP version of PMD tool", + "phpunit/php-code-coverage": "Library that provides collection, processing, and rendering functionality for PHP code coverage information", + "phpunit/phpunit": "The PHP Unit Testing Framework", + "sebastian/phpcpd": "Copy/Paste Detector (CPD) for PHP code", + "siad007/versioncontrol_hg": "A library for interfacing with Mercurial repositories.", + "tedivm/jshrink": "Javascript Minifier built in PHP" + }, + "bin": [ + "bin/phing" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.16.x-dev" + } + }, + "autoload": { + "classmap": [ + "classes/phing/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "classes" + ], + "license": [ + "LGPL-3.0-only" + ], + "authors": [ + { + "name": "Michiel Rook", + "email": "mrook@php.net" + }, + { + "name": "Phing Community", + "homepage": "https://www.phing.info/trac/wiki/Development/Contributors" + } + ], + "description": "PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant.", + "homepage": "https://www.phing.info/", + "keywords": [ + "build", + "phing", + "task", + "tool" + ], + "time": "2020-02-03T18:50:54+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "985f414b55eca4296ffc99db960a97b3cc8fbcea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/985f414b55eca4296ffc99db960a97b3cc8fbcea", + "reference": "985f414b55eca4296ffc99db960a97b3cc8fbcea", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2020-04-27T09:34:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", + "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e", + "shasum": "" + }, + "require": { + "ext-filter": "^7.1", + "php": "^7.2", + "phpdocumentor/reflection-common": "^2.0", + "phpdocumentor/type-resolver": "^1.0", + "webmozart/assert": "^1" + }, + "require-dev": { + "doctrine/instantiator": "^1", + "mockery/mockery": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2020-02-22T12:28:44+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "6be94d5733839a52492da96f57c6a3b062a8f97a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6be94d5733839a52492da96f57c6a3b062a8f97a", + "reference": "6be94d5733839a52492da96f57c6a3b062a8f97a", + "shasum": "" + }, + "require": { + "php": "^7.2", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "^7.2", + "mockery/mockery": "~1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2020-04-27T19:13:53+00:00" + }, + { + "name": "phpmd/phpmd", + "version": "2.8.x-dev", + "source": { + "type": "git", + "url": "https://github.com/phpmd/phpmd.git", + "reference": "685550627f3727f96eabb98e0aaaf1cbf9b0b224" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/685550627f3727f96eabb98e0aaaf1cbf9b0b224", + "reference": "685550627f3727f96eabb98e0aaaf1cbf9b0b224", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.0", + "ext-xml": "*", + "pdepend/pdepend": "^2.7.1", + "php": ">=5.3.9" + }, + "require-dev": { + "easy-doc/easy-doc": "0.0.0 || ^1.3.2", + "gregwar/rst": "^1.0", + "mikey179/vfsstream": "^1.6.4", + "phpunit/phpunit": "^4.8.36 || ^5.7.27", + "squizlabs/php_codesniffer": "^2.0" + }, + "bin": [ + "src/bin/phpmd" + ], + "type": "library", + "autoload": { + "psr-0": { + "PHPMD\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Manuel Pichler", + "email": "github@manuel-pichler.de", + "homepage": "https://github.com/manuelpichler", + "role": "Project Founder" + }, + { + "name": "Marc Würth", + "email": "ravage@bluewin.ch", + "homepage": "https://github.com/ravage84", + "role": "Project Maintainer" + }, + { + "name": "Other contributors", + "homepage": "https://github.com/phpmd/phpmd/graphs/contributors", + "role": "Contributors" + } + ], + "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.", + "homepage": "https://phpmd.org/", + "keywords": [ + "mess detection", + "mess detector", + "pdepend", + "phpmd", + "pmd" + ], + "time": "2020-04-29T00:08:01+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2019-06-07T04:22:29+00:00" + }, + { + "name": "sabre/event", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sabre-io/event.git", + "reference": "d00a17507af0e7544cfe17096372f5d733e3b276" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabre-io/event/zipball/d00a17507af0e7544cfe17096372f5d733e3b276", + "reference": "d00a17507af0e7544cfe17096372f5d733e3b276", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.16.1", + "phpunit/phpunit": "^7 || ^8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sabre\\Event\\": "lib/" + }, + "files": [ + "lib/coroutine.php", + "lib/Loop/functions.php", + "lib/Promise/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Evert Pot", + "email": "me@evertpot.com", + "homepage": "http://evertpot.com/", + "role": "Developer" + } + ], + "description": "sabre/event is a library for lightweight event-based programming", + "homepage": "http://sabre.io/event/", + "keywords": [ + "EventEmitter", + "async", + "coroutine", + "eventloop", + "events", + "hooks", + "plugin", + "promise", + "reactor", + "signal" + ], + "time": "2020-01-31T18:52:29+00:00" + }, + { + "name": "sebastian/finder-facade", + "version": "1.2.x-dev", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/finder-facade.git", + "reference": "bc7d1a6fd93418155da6ea721bc0f8eb8efc0d78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/finder-facade/zipball/bc7d1a6fd93418155da6ea721bc0f8eb8efc0d78", + "reference": "bc7d1a6fd93418155da6ea721bc0f8eb8efc0d78", + "shasum": "" + }, + "require": { + "php": "^7.1", + "symfony/finder": "^2.3|^3.0|^4.0|^5.0", + "theseer/fdomdocument": "^1.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", + "homepage": "https://github.com/sebastianbergmann/finder-facade", + "time": "2020-02-08T06:24:54+00:00" + }, + { + "name": "sebastian/phpcpd", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpcpd.git", + "reference": "0d9afa762f2400de077b2192f4a9d127de0bb78e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpcpd/zipball/0d9afa762f2400de077b2192f4a9d127de0bb78e", + "reference": "0d9afa762f2400de077b2192f4a9d127de0bb78e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": "^7.1", + "phpunit/php-timer": "^2.0", + "sebastian/finder-facade": "^1.1", + "sebastian/version": "^1.0|^2.0", + "symfony/console": "^2.7|^3.0|^4.0" + }, + "bin": [ + "phpcpd" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Copy/Paste Detector (CPD) for PHP code.", + "homepage": "https://github.com/sebastianbergmann/phpcpd", + "time": "2018-09-17T17:17:27+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "ce62dee92da3b038a399a99353fc055b39d2853e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ce62dee92da3b038a399a99353fc055b39d2853e", + "reference": "ce62dee92da3b038a399a99353fc055b39d2853e", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2020-05-01T04:18:46+00:00" + }, + { + "name": "staabm/annotate-pull-request-from-checkstyle", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/staabm/annotate-pull-request-from-checkstyle.git", + "reference": "7d3bcdf21e4b30b14c8ca0a7ef39f4b856d3fbfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/annotate-pull-request-from-checkstyle/zipball/7d3bcdf21e4b30b14c8ca0a7ef39f4b856d3fbfb", + "reference": "7d3bcdf21e4b30b14c8ca0a7ef39f4b856d3fbfb", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "php": "^7.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.16.1" + }, + "bin": [ + "cs2pr" + ], + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Markus Staab" + } + ], + "time": "2020-02-26T08:24:03+00:00" + }, + { + "name": "symfony/config", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "ebbc66e965a33c287b2d657cceb9228dd945de51" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/ebbc66e965a33c287b2d657cceb9228dd945de51", + "reference": "ebbc66e965a33c287b2d657cceb9228dd945de51", + "shasum": "" + }, + "require": { + "php": "^7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/filesystem": "^4.4|^5.0", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "symfony/finder": "<4.4" + }, + "require-dev": { + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/messenger": "^4.4|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/yaml": "^4.4|^5.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2020-05-08T12:36:29+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "eea0773bf080ff982e560d75437c9b7601b3c2b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/eea0773bf080ff982e560d75437c9b7601b3c2b3", + "reference": "eea0773bf080ff982e560d75437c9b7601b3c2b3", + "shasum": "" + }, + "require": { + "php": "^7.2.5", + "psr/container": "^1.0", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1.6|^2" + }, + "conflict": { + "symfony/config": "<5.1", + "symfony/finder": "<4.4", + "symfony/proxy-manager-bridge": "<4.4", + "symfony/yaml": "<4.4" + }, + "provide": { + "psr/container-implementation": "1.0", + "symfony/service-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "^5.1", + "symfony/expression-language": "^4.4|^5.0", + "symfony/yaml": "^4.4|^5.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "time": "2020-05-08T06:17:45+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "ede224dcbc36138943a296107db2b8b2a690ac1c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/ede224dcbc36138943a296107db2b8b2a690ac1c", + "reference": "ede224dcbc36138943a296107db2b8b2a690ac1c", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "time": "2020-02-14T07:31:56+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "c4bdcb0490a6c0e12c51e9d771fda5867e908fd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/c4bdcb0490a6c0e12c51e9d771fda5867e908fd2", + "reference": "c4bdcb0490a6c0e12c51e9d771fda5867e908fd2", + "shasum": "" + }, + "require": { + "php": ">=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.16-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2020-05-08T16:50:20+00:00" + }, + { + "name": "theseer/fdomdocument", + "version": "1.6.6", + "source": { + "type": "git", + "url": "https://github.com/theseer/fDOMDocument.git", + "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/fDOMDocument/zipball/6e8203e40a32a9c770bcb62fe37e68b948da6dca", + "reference": "6e8203e40a32a9c770bcb62fe37e68b948da6dca", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "lib-libxml": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "lead" + } + ], + "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", + "homepage": "https://github.com/theseer/fDOMDocument", + "time": "2017-06-30T11:53:12+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6", + "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2020-04-18T12:12:48+00:00" + }, + { + "name": "webonyx/graphql-php", + "version": "0.13.x-dev", + "source": { + "type": "git", + "url": "https://github.com/webonyx/graphql-php.git", + "reference": "6829ae58f4c59121df1f86915fb9917a2ec595e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webonyx/graphql-php/zipball/6829ae58f4c59121df1f86915fb9917a2ec595e8", + "reference": "6829ae58f4c59121df1f86915fb9917a2ec595e8", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "php": "^7.1||^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "phpbench/phpbench": "^0.14.0", + "phpstan/phpstan": "^0.11.4", + "phpstan/phpstan-phpunit": "^0.11.0", + "phpstan/phpstan-strict-rules": "^0.11.0", + "phpunit/phpcov": "^5.0", + "phpunit/phpunit": "^7.2", + "psr/http-message": "^1.0", + "react/promise": "2.*" + }, + "suggest": { + "psr/http-message": "To use standard GraphQL server", + "react/promise": "To leverage async resolving on React PHP platform" + }, + "type": "library", + "autoload": { + "psr-4": { + "GraphQL\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP port of GraphQL reference implementation", + "homepage": "https://github.com/webonyx/graphql-php", + "keywords": [ + "api", + "graphql" + ], + "time": "2019-08-25T10:32:47+00:00" + } + ], "aliases": [], "minimum-stability": "dev", "stability-flags": [], diff --git a/phan.php b/phan.php new file mode 100644 index 00000000..dee75d75 --- /dev/null +++ b/phan.php @@ -0,0 +1,84 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +return [ + 'backward_compatibility_checks' => false, + 'signature-compatibility' => true, + 'progress-bar' => true, + 'simplify_ast' => false, + 'dead_code_detection' => false, + 'exclude_file_regex' => '@^vendor/.*/(tests|test|Tests|Test)/@', + 'directory_list' => [ + 'Api', + 'Block', + 'Console', + 'Controller', + 'Cron', + 'CustomerData', + 'Helper', + 'Logger', + 'Model', + 'Observer', + 'Plugin', + 'Utils', + 'vendor/nosto', + 'vendor/vlucas', + 'vendor/phpseclib', + 'vendor/magento', + 'vendor/monolog', + 'vendor/zendframework', + 'vendor/psr', + 'vendor/symfony/console', + 'magento/generated' + ], + 'exclude_file_list' => [ + 'vendor/magento/zendframework1/library/Zend/Validate/Hostname/Biz.php', + 'vendor/magento/zendframework1/library/Zend/Validate/Hostname/Cn.php', + 'vendor/magento/zendframework1/library/Zend/Validate/Hostname/Com.php', + 'vendor/magento/zendframework1/library/Zend/Validate/Hostname/Jp.php', + ], + 'exclude_analysis_directory_list' => [ + 'vendor/', + 'magento' + ], + 'suppress_issue_types' => [ + 'PhanParamSignatureMismatch', + ], + "color_issue_messages_if_supported" => true, + 'plugins' => [ + 'vendor/drenso/phan-extensions/Plugin/DocComment/InlineVarPlugin.php' + ] +]; diff --git a/ruleset.xml b/ruleset.xml new file mode 100644 index 00000000..6efbd1f8 --- /dev/null +++ b/ruleset.xml @@ -0,0 +1,57 @@ + + + + + + ./Block + ./Helper + ./Model + ./Observer + ./Plugin + ./Utils + ./view + *.js + *.css + + The Magento coding standard. + + + + + + + diff --git a/view/frontend/templates/category_merchandising.phtml b/view/frontend/templates/category_merchandising.phtml index 4bcfef50..ac51db5b 100644 --- a/view/frontend/templates/category_merchandising.phtml +++ b/view/frontend/templates/category_merchandising.phtml @@ -41,10 +41,10 @@ { "*": { "Nosto_Cmp/js/cmp": { - "merchant": "getNostoAccount(); ?>", - "categoryCookie": "getCategoryMappingCookieName(); ?>", - "segmentCookie": "getSegmentMappingCookieName(); ?>", - "baseUrl": "getNostoBaseUrl(); ?>" + "merchant": "escapeHtml($block->getNostoAccount()); ?>", + "categoryCookie": "escapeHtml($block->getCategoryMappingCookieName()); ?>", + "segmentCookie": "escapeHtml($block->getSegmentMappingCookieName()); ?>", + "baseUrl": "escapeHtml($block->getNostoBaseUrl()); ?>" } } } From 2b202c61ab23b309ef7cbabdeaf202ff6bb2db3a Mon Sep 17 00:00:00 2001 From: Olsi Qose <44775916+olsi-qose@users.noreply.github.com> Date: Thu, 14 May 2020 14:24:07 +0300 Subject: [PATCH 03/35] Fix exception handling (#46) * Re-order exception catching * Fix error handling * Fix cs issues * Fix phan issues * Fix phpcs issue on template * Suppress warning --- Block/CategoryMapping.php | 23 +++++++++---------- Plugin/Catalog/Helper/Category.php | 14 +++++++---- phan.php | 7 ++++-- .../frontend/templates/category_mapping.phtml | 2 +- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/Block/CategoryMapping.php b/Block/CategoryMapping.php index 15259ad8..941a0ce8 100644 --- a/Block/CategoryMapping.php +++ b/Block/CategoryMapping.php @@ -36,6 +36,8 @@ namespace Nosto\Cmp\Block; +use Exception; +use Magento\Catalog\Model\Category; use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\View\Element\Template; @@ -44,8 +46,6 @@ use Magento\Store\Model\StoreManagerInterface; use Nosto\Tagging\Logger\Logger as NostoLogger; use Nosto\Tagging\Model\Service\Product\Category\DefaultCategoryService as CategoryBuilder; -use Magento\Catalog\Model\Category; -use Magento\Framework\Exception\LocalizedException; class CategoryMapping extends Template { @@ -81,7 +81,8 @@ public function __construct( /** * @return false|string */ - public function getCategoryMap() { + public function getCategoryMap() + { $array = []; try { @@ -90,7 +91,7 @@ public function getCategoryMap() { $array = $this->getMagentoCategories($store); } } catch (NoSuchEntityException $e) { - $this->logger->exception('Could not get store'); + $this->logger->exception($e); } return json_encode((object) $array, JSON_UNESCAPED_SLASHES); @@ -99,8 +100,10 @@ public function getCategoryMap() { /** * @param Store $store * @return array + * @suppress PhanTypeMismatchArgument */ - private function getMagentoCategories(Store $store) { + private function getMagentoCategories(Store $store) + { $baseUrl = ''; $categoriesArray = []; @@ -110,7 +113,7 @@ private function getMagentoCategories(Store $store) { $categories = $this->collectionFactory->create() ->addAttributeToSelect('*') - ->addAttributeToFilter('include_in_menu', array('eq' => 1)) + ->addAttributeToFilter('include_in_menu', ['eq' => 1]) ->addIsActiveFilter() ->setStore($store); @@ -124,12 +127,8 @@ private function getMagentoCategories(Store $store) { $categoriesArray[$nostoCategoryString] = $categoryUrl; } } - } catch (\Exception $e) { - $this->logger->exception(sprintf("Could not fetch base url for store %s", - $store->getName()) - ); - } catch (LocalizedException $e) { - $this->logger->exception('Could not filter category collection'); + } catch (Exception $e) { + $this->logger->exception($e); } return $categoriesArray; diff --git a/Plugin/Catalog/Helper/Category.php b/Plugin/Catalog/Helper/Category.php index a2486ee1..b6f5cb17 100644 --- a/Plugin/Catalog/Helper/Category.php +++ b/Plugin/Catalog/Helper/Category.php @@ -37,7 +37,6 @@ namespace Nosto\Cmp\Plugin\Catalog\Helper; use Magento\Catalog\Helper\Category as CategoryHelper; -use Nosto\Cmp\Utils\Url as NostoUtilsUrl; use Purl\Url; class Category @@ -46,12 +45,17 @@ class Category const NOSTO_CMP_FRAGMENT = 'nosto_cmp'; /** - * @param CategoryHelper $navigation - * @param $categoryString + * @param CategoryHelper $categoryHelper + * @param $categoryUrl * @return string + * @suppress PhanUndeclaredMethod */ - public function afterGetCategoryUrl(CategoryHelper $categoryHelper, $categoryUrl) - { + // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter -- unused $categoryHelper + public function afterGetCategoryUrl( + CategoryHelper $categoryHelper, + $categoryUrl + ) { + /** @var Url $url */ $url = (new Url($categoryUrl)) ->set('fragment', self::NOSTO_CMP_FRAGMENT); diff --git a/phan.php b/phan.php index dee75d75..2cb3b19c 100644 --- a/phan.php +++ b/phan.php @@ -62,7 +62,9 @@ 'vendor/zendframework', 'vendor/psr', 'vendor/symfony/console', - 'magento/generated' + 'magento/generated', + '../../../generated', + 'vendor/jwage' ], 'exclude_file_list' => [ 'vendor/magento/zendframework1/library/Zend/Validate/Hostname/Biz.php', @@ -72,7 +74,8 @@ ], 'exclude_analysis_directory_list' => [ 'vendor/', - 'magento' + 'magento', + '../../../generated' ], 'suppress_issue_types' => [ 'PhanParamSignatureMismatch', diff --git a/view/frontend/templates/category_mapping.phtml b/view/frontend/templates/category_mapping.phtml index 2e944f39..4adb8b3b 100644 --- a/view/frontend/templates/category_mapping.phtml +++ b/view/frontend/templates/category_mapping.phtml @@ -38,6 +38,6 @@ ?> From 12ff17196f9505fa09b15d2eae6e0f8cf19eb370 Mon Sep 17 00:00:00 2001 From: Cid Lopes Date: Tue, 19 May 2020 16:43:32 +0300 Subject: [PATCH 04/35] Bugfix and hash category mapping keys (#48) * Fix sorting key parameter type, array to string conversion bug * Remove secondary sorting query * Check if nosto sorting is used on the URL before setting URL fragment in category URLs * Bump Version and Update Changelog * Downrgade module version * Returned hashed mapping * Define script type Co-authored-by: Olsi Qose --- Block/CategoryMapping.php | 19 +++++++++--- CHANGELOG.md | 3 +- Helper/CategorySorting.php | 3 +- Plugin/Catalog/Block/Toolbar.php | 13 +-------- Plugin/Catalog/Helper/Category.php | 29 ++++++++++++++----- .../frontend/templates/category_mapping.phtml | 5 ++-- 6 files changed, 44 insertions(+), 28 deletions(-) diff --git a/Block/CategoryMapping.php b/Block/CategoryMapping.php index 941a0ce8..60b3bc51 100644 --- a/Block/CategoryMapping.php +++ b/Block/CategoryMapping.php @@ -119,12 +119,12 @@ private function getMagentoCategories(Store $store) /** @var Category $category $item */ foreach ($categories->getItems() as $category) { - $nostoCategoryString = strtolower( + $hashedCategoryString = $this->hashCategoryString(strtolower( $this->categoryBuilder->getCategory($category, $store) - ); + )); $categoryUrl = $baseUrl . '' . $category->getUrlPath(); - if ($nostoCategoryString) { - $categoriesArray[$nostoCategoryString] = $categoryUrl; + if ($hashedCategoryString) { + $categoriesArray[$hashedCategoryString] = $categoryUrl; } } } catch (Exception $e) { @@ -133,4 +133,15 @@ private function getMagentoCategories(Store $store) return $categoriesArray; } + + /** + * @param String $categoryString + * @return string + */ + private function hashCategoryString($categoryString) + { + $signedInteger = crc32($categoryString); + $unsignedInteger = (int) sprintf("%u", $signedInteger); + return dechex($unsignedInteger); + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d0d775b..6091d16f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,9 @@ All notable changes to this project will be documented in this file. This projec * Add tagging for module version * Add fragment to product urls served by CMP * Add fragment to category urls -* Add block for categories mapping +* Add block for hashed categories mapping * Add sort order tagging +* Remove secondary sorting query ### 1.1.0 * Enable support for Full Page Cache using cache variation diff --git a/Helper/CategorySorting.php b/Helper/CategorySorting.php index b66128d3..df0ba4b9 100644 --- a/Helper/CategorySorting.php +++ b/Helper/CategorySorting.php @@ -72,11 +72,12 @@ public function __construct( * Return array that contains all sorting options offered by Nosto * * @return array + * @suppress PhanTypeMismatchArgument */ public static function getNostoSortingOptions() { return [ - self::NOSTO_PERSONALIZED_KEY => __(['Relevance']) + self::NOSTO_PERSONALIZED_KEY => __('Relevance') ]; } diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index ddb5a3b0..804a46d1 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -228,8 +228,7 @@ private function sortByProductIds(ProductCollection $collection, array $nostoPro { $select = $collection->getSelect(); $zendExpression = [ - new Zend_Db_Expr('FIELD(e.entity_id,' . implode(',', $nostoProductIds) . ') DESC'), - new Zend_Db_Expr($this->getSecondarySort()) + new Zend_Db_Expr('FIELD(e.entity_id,' . implode(',', $nostoProductIds) . ') DESC') ]; $select->order($zendExpression); } @@ -281,14 +280,4 @@ private function addTrackParamToProduct(ProductCollection $collection, $trackCod } }); } - - /** - * Returns the secondary sort defined by the merchant - * - * @return string - */ - private function getSecondarySort() - { - return 'cat_index_position ASC'; - } } diff --git a/Plugin/Catalog/Helper/Category.php b/Plugin/Catalog/Helper/Category.php index b6f5cb17..59e6ea5b 100644 --- a/Plugin/Catalog/Helper/Category.php +++ b/Plugin/Catalog/Helper/Category.php @@ -37,6 +37,9 @@ namespace Nosto\Cmp\Plugin\Catalog\Helper; use Magento\Catalog\Helper\Category as CategoryHelper; +use Nosto\Cmp\Plugin\Catalog\Block\DefaultParameterResolver; +use Magento\Framework\UrlInterface; +use Nosto\Cmp\Helper\CategorySorting; use Purl\Url; class Category @@ -44,21 +47,33 @@ class Category const NOSTO_CMP_FRAGMENT = 'nosto_cmp'; + /** @var UrlInterface */ + private $url; + + public function __construct(UrlInterface $url) + { + $this->url = $url; + } /** * @param CategoryHelper $categoryHelper * @param $categoryUrl * @return string * @suppress PhanUndeclaredMethod */ - // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter -- unused $categoryHelper - public function afterGetCategoryUrl( + public function afterGetCategoryUrl( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter CategoryHelper $categoryHelper, $categoryUrl ) { - /** @var Url $url */ - $url = (new Url($categoryUrl)) - ->set('fragment', self::NOSTO_CMP_FRAGMENT); - - return $url->getUrl(); + $currentUrl = $this->url->getCurrentUrl(); + $nostoSortParam = sprintf( + '%s=%s', + DefaultParameterResolver::DEFAULT_SORTING_ORDER_PARAM, + CategorySorting::NOSTO_PERSONALIZED_KEY + ); + // phpcs:ignore Ecg.Strings.StringPosition.ImproperValueTesting,Magento2.PHP.ReturnValueCheck.ImproperValueTesting + if (strpos($currentUrl, $nostoSortParam)) { + return (new Url($categoryUrl))->set('fragment', self::NOSTO_CMP_FRAGMENT); + } + return new Url($categoryUrl); } } diff --git a/view/frontend/templates/category_mapping.phtml b/view/frontend/templates/category_mapping.phtml index 4adb8b3b..149b1522 100644 --- a/view/frontend/templates/category_mapping.phtml +++ b/view/frontend/templates/category_mapping.phtml @@ -37,7 +37,6 @@ /** @var \Nosto\Cmp\Block\CategoryMapping $block */ ?> - - From c45b0a54556cfc42398b481b93155e9f5254216b Mon Sep 17 00:00:00 2001 From: Olsi Qose <44775916+olsi-qose@users.noreply.github.com> Date: Mon, 25 May 2020 10:48:01 +0300 Subject: [PATCH 05/35] Use getUrl() method (#49) --- Block/CategoryMapping.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Block/CategoryMapping.php b/Block/CategoryMapping.php index 60b3bc51..8916517a 100644 --- a/Block/CategoryMapping.php +++ b/Block/CategoryMapping.php @@ -122,9 +122,8 @@ private function getMagentoCategories(Store $store) $hashedCategoryString = $this->hashCategoryString(strtolower( $this->categoryBuilder->getCategory($category, $store) )); - $categoryUrl = $baseUrl . '' . $category->getUrlPath(); if ($hashedCategoryString) { - $categoriesArray[$hashedCategoryString] = $categoryUrl; + $categoriesArray[$hashedCategoryString] = $category->getUrl(); } } } catch (Exception $e) { From e99cab75abc83adff9e9e4f20db1c52fc2501c98 Mon Sep 17 00:00:00 2001 From: Olsi Qose <44775916+olsi-qose@users.noreply.github.com> Date: Thu, 28 May 2020 14:39:45 +0300 Subject: [PATCH 06/35] Remove product attribute from url (#51) * Remove nosto attribute * Remove nosto_cmp fragment from category urls --- Plugin/Catalog/Block/Toolbar.php | 9 ++-- Plugin/Catalog/Helper/Category.php | 79 ------------------------------ Plugin/Catalog/Model/Product.php | 16 ++---- composer.json | 1 - etc/di.xml | 3 -- 5 files changed, 7 insertions(+), 101 deletions(-) delete mode 100644 Plugin/Catalog/Helper/Category.php diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index 804a46d1..2987903b 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -160,7 +160,7 @@ public function afterSetCollection( // phpcs:ignore EcgM2.Plugins.Plugin.PluginW $nostoProductIds = array_reverse($nostoProductIds); $this->sortByProductIds($subjectCollection, $nostoProductIds); $this->whereInProductIds($subjectCollection, $nostoProductIds); - $this->addTrackParamToProduct($subjectCollection, $result->getTrackingCode(), $nostoProductIds); + $this->addTrackParamToProduct($subjectCollection, $nostoProductIds); } else { $this->logger->info(sprintf( "CMP result is empty for category: %s", @@ -268,15 +268,14 @@ private function parseProductIds(CategoryMerchandisingResult $result) /** * @param ProductCollection $collection - * @param $trackCode * @param array $nostoProductIds */ - private function addTrackParamToProduct(ProductCollection $collection, $trackCode, array $nostoProductIds) + private function addTrackParamToProduct(ProductCollection $collection, array $nostoProductIds) { - $collection->each(static function ($product) use ($nostoProductIds, $trackCode) { + $collection->each(static function ($product) use ($nostoProductIds) { /* @var Product $product */ if (in_array($product->getId(), $nostoProductIds, true)) { - $product->setData(NostoProductPlugin::NOSTO_TRACKING_PARAMETER_NAME, $trackCode); + $product->setData(NostoProductPlugin::NOSTO_TRACKING_PARAMETER_NAME, true); } }); } diff --git a/Plugin/Catalog/Helper/Category.php b/Plugin/Catalog/Helper/Category.php deleted file mode 100644 index 59e6ea5b..00000000 --- a/Plugin/Catalog/Helper/Category.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @copyright 2019 Nosto Solutions Ltd - * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause - * - */ - -namespace Nosto\Cmp\Plugin\Catalog\Helper; - -use Magento\Catalog\Helper\Category as CategoryHelper; -use Nosto\Cmp\Plugin\Catalog\Block\DefaultParameterResolver; -use Magento\Framework\UrlInterface; -use Nosto\Cmp\Helper\CategorySorting; -use Purl\Url; - -class Category -{ - - const NOSTO_CMP_FRAGMENT = 'nosto_cmp'; - - /** @var UrlInterface */ - private $url; - - public function __construct(UrlInterface $url) - { - $this->url = $url; - } - /** - * @param CategoryHelper $categoryHelper - * @param $categoryUrl - * @return string - * @suppress PhanUndeclaredMethod - */ - public function afterGetCategoryUrl( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter - CategoryHelper $categoryHelper, - $categoryUrl - ) { - $currentUrl = $this->url->getCurrentUrl(); - $nostoSortParam = sprintf( - '%s=%s', - DefaultParameterResolver::DEFAULT_SORTING_ORDER_PARAM, - CategorySorting::NOSTO_PERSONALIZED_KEY - ); - // phpcs:ignore Ecg.Strings.StringPosition.ImproperValueTesting,Magento2.PHP.ReturnValueCheck.ImproperValueTesting - if (strpos($currentUrl, $nostoSortParam)) { - return (new Url($categoryUrl))->set('fragment', self::NOSTO_CMP_FRAGMENT); - } - return new Url($categoryUrl); - } -} diff --git a/Plugin/Catalog/Model/Product.php b/Plugin/Catalog/Model/Product.php index 5995c47b..60a0eb88 100644 --- a/Plugin/Catalog/Model/Product.php +++ b/Plugin/Catalog/Model/Product.php @@ -40,11 +40,7 @@ class Product { - const NOSTO_TRACKING_PARAMETER_NAME = 'nosto'; - const NOSTO_SOURCE_PARAMETER_NAME = 'nosto_source'; - const NOSTO_PRODUCT_ID_PARAMETER_VALUE = 'nosto_pid'; - const NOSTO_SOURCE_PARAMETER_VALUE = 'cmp'; - const NOSTO_OVERRIDABLE_ATTR_PARAM = 'nosto_cmp'; + const NOSTO_TRACKING_PARAMETER_NAME = 'nosto_cmp'; /** * @param MagentoProduct $product @@ -54,17 +50,11 @@ class Product public function afterGetProductUrl(MagentoProduct $product, $url) { if ($product->getData(self::NOSTO_TRACKING_PARAMETER_NAME) !== null) { - $existingParams = $this->parseExistingQueryParams($url); - $nostoParam = [ - self::NOSTO_TRACKING_PARAMETER_NAME => $product->getData(self::NOSTO_TRACKING_PARAMETER_NAME), - self::NOSTO_SOURCE_PARAMETER_NAME => self::NOSTO_SOURCE_PARAMETER_VALUE - ]; - $params = array_merge($existingParams, $nostoParam); $url = $product->getUrlModel()->getUrl( $product, [ - '_query' => $params, - '_fragment' => self::NOSTO_OVERRIDABLE_ATTR_PARAM + '_query' => $this->parseExistingQueryParams($url), + '_fragment' => self::NOSTO_TRACKING_PARAMETER_NAME ] ); } diff --git a/composer.json b/composer.json index 72a6381c..18865f03 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,6 @@ "require": { "nosto/module-nostotagging": ">=4.0.0", "nosto/php-sdk": ">=4.1.0", - "jwage/purl": "0.0.9", "php": ">=7.0.0" }, "repositories": [ diff --git a/etc/di.xml b/etc/di.xml index fe2d5dba..ababb348 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -54,7 +54,4 @@ - - - \ No newline at end of file From 5251cd785c5412644389e3959fd8d76f10287939 Mon Sep 17 00:00:00 2001 From: Olsi Qose <44775916+olsi-qose@users.noreply.github.com> Date: Thu, 28 May 2020 15:59:00 +0300 Subject: [PATCH 07/35] Lock dependency version for SDK and main Nosto module (#50) * Lock dependency version * Update composer.lock file --- composer.json | 4 +- composer.lock | 328 ++++++++++++++++++++++---------------------------- 2 files changed, 147 insertions(+), 185 deletions(-) diff --git a/composer.json b/composer.json index 18865f03..13014911 100644 --- a/composer.json +++ b/composer.json @@ -24,8 +24,8 @@ ], "minimum-stability": "dev", "require": { - "nosto/module-nostotagging": ">=4.0.0", - "nosto/php-sdk": ">=4.1.0", + "nosto/module-nostotagging": "4.0.*", + "nosto/php-sdk": "4.1.*", "php": ">=7.0.0" }, "repositories": [ diff --git a/composer.lock b/composer.lock index 21db1076..4df16bc8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2239640cae9b17c1678b13da5a449173", + "content-hash": "5bbc67ebc3801826c6919632d59b1208", "packages": [ { "name": "colinmollenhour/credis", @@ -145,12 +145,12 @@ "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "42fc372e5208522fc8bafafde916a455c53807d6" + "reference": "f7abfc9d7fb8437f1dee87f00c037d13279a6d16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/42fc372e5208522fc8bafafde916a455c53807d6", - "reference": "42fc372e5208522fc8bafafde916a455c53807d6", + "url": "https://api.github.com/repos/composer/composer/zipball/f7abfc9d7fb8437f1dee87f00c037d13279a6d16", + "reference": "f7abfc9d7fb8437f1dee87f00c037d13279a6d16", "shasum": "" }, "require": { @@ -158,7 +158,7 @@ "composer/semver": "^1.0", "composer/spdx-licenses": "^1.2", "composer/xdebug-handler": "^1.1", - "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", + "justinrainbow/json-schema": "^5.2.10", "php": "^5.3.2 || ^7.0", "psr/log": "^1.0", "seld/jsonlint": "^1.4", @@ -218,7 +218,7 @@ "dependency", "package" ], - "time": "2020-05-08T18:53:43+00:00" + "time": "2020-05-27T20:07:55+00:00" }, { "name": "composer/semver", @@ -287,12 +287,12 @@ "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "960a9f51c10bf73dd16c21a24223ef7ed29271b5" + "reference": "5a22999026e9d9bddbb2bc51d838b1efa48d627c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/960a9f51c10bf73dd16c21a24223ef7ed29271b5", - "reference": "960a9f51c10bf73dd16c21a24223ef7ed29271b5", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/5a22999026e9d9bddbb2bc51d838b1efa48d627c", + "reference": "5a22999026e9d9bddbb2bc51d838b1efa48d627c", "shasum": "" }, "require": { @@ -339,7 +339,7 @@ "spdx", "validator" ], - "time": "2020-05-03T18:45:12+00:00" + "time": "2020-05-20T14:05:41+00:00" }, { "name": "composer/xdebug-handler", @@ -423,12 +423,12 @@ "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e" + "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/aab4ebd862aa7d04f01a4b51849d657db56d882e", - "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a4a1b6930528a8f7ee03518e6442ec7a44155d9d", + "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d", "shasum": "" }, "require": { @@ -436,7 +436,7 @@ "guzzlehttp/promises": "^1.0", "guzzlehttp/psr7": "^1.6.1", "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.11" + "symfony/polyfill-intl-idn": "1.17.0" }, "require-dev": { "ext-curl": "*", @@ -482,7 +482,7 @@ "rest", "web service" ], - "time": "2020-04-18T10:38:46+00:00" + "time": "2020-05-25T19:35:05+00:00" }, { "name": "guzzlehttp/promises", @@ -541,12 +541,12 @@ "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "c247bf84e343f0b95927fa86cf23b7ffc9af04f3" + "reference": "188cc82398f157483976ccf61bd04ee80afcf29c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/c247bf84e343f0b95927fa86cf23b7ffc9af04f3", - "reference": "c247bf84e343f0b95927fa86cf23b7ffc9af04f3", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/188cc82398f157483976ccf61bd04ee80afcf29c", + "reference": "188cc82398f157483976ccf61bd04ee80afcf29c", "shasum": "" }, "require": { @@ -604,76 +604,20 @@ "uri", "url" ], - "time": "2020-05-13T14:56:52+00:00" - }, - { - "name": "jeremykendall/php-domain-parser", - "version": "1.4.6", - "source": { - "type": "git", - "url": "https://github.com/jeremykendall/php-domain-parser.git", - "reference": "66379578432e85f764f4f9d587d61e48d66c2082" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jeremykendall/php-domain-parser/zipball/66379578432e85f764f4f9d587d61e48d66c2082", - "reference": "66379578432e85f764f4f9d587d61e48d66c2082", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-intl": "*", - "ext-mbstring": "*", - "php": ">=5.3.0" - }, - "require-dev": { - "mikey179/vfsstream": "1.2.*", - "phpunit/phpunit": "4.*" - }, - "bin": [ - "bin/parse", - "bin/pdp-psl" - ], - "type": "library", - "autoload": { - "psr-0": { - "Pdp\\": "library/" - }, - "files": [ - "library/mb-parse-url.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jeremy Kendall", - "homepage": "http://about.me/jeremykendall", - "role": "Developer" - } - ], - "description": "Public Suffix List based URL parsing implemented in PHP.", - "keywords": [ - "Public Suffix List", - "domain parsing", - "url parsing" - ], - "time": "2014-07-28T18:36:24+00:00" + "time": "2020-05-17T20:05:25+00:00" }, { "name": "justinrainbow/json-schema", - "version": "5.2.9", + "version": "5.x-dev", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "44c6787311242a979fa15c704327c20e7221a0e4" + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4", - "reference": "44c6787311242a979fa15c704327c20e7221a0e4", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", "shasum": "" }, "require": { @@ -726,52 +670,7 @@ "json", "schema" ], - "time": "2019-09-25T14:49:45+00:00" - }, - { - "name": "jwage/purl", - "version": "v0.0.9", - "source": { - "type": "git", - "url": "https://github.com/jwage/purl.git", - "reference": "60e2055531941aae6eacb1b513bbb2fc75743f91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jwage/purl/zipball/60e2055531941aae6eacb1b513bbb2fc75743f91", - "reference": "60e2055531941aae6eacb1b513bbb2fc75743f91", - "shasum": "" - }, - "require": { - "jeremykendall/php-domain-parser": "^1.3.1", - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8|^5.5|^6.5|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Purl\\": "src/Purl" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jonathan H. Wage", - "email": "jonwage@gmail.com" - } - ], - "description": "URL Manipulation for PHP 5.3", - "homepage": "http://github.com/jwage/purl", - "keywords": [ - "manipulation", - "url" - ], - "time": "2018-05-17T15:22:38+00:00" + "time": "2020-05-27T16:41:55+00:00" }, { "name": "laminas/laminas-code", @@ -1198,12 +1097,12 @@ "source": { "type": "git", "url": "https://github.com/laminas/laminas-form.git", - "reference": "9325df32a09b1b6a49e02c3dfdbf46152abffbb0" + "reference": "f7aed79d037debab5a47a01d5f90c645c25d89da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-form/zipball/9325df32a09b1b6a49e02c3dfdbf46152abffbb0", - "reference": "9325df32a09b1b6a49e02c3dfdbf46152abffbb0", + "url": "https://api.github.com/repos/laminas/laminas-form/zipball/f7aed79d037debab5a47a01d5f90c645c25d89da", + "reference": "f7aed79d037debab5a47a01d5f90c645c25d89da", "shasum": "" }, "require": { @@ -1272,7 +1171,7 @@ "form", "laminas" ], - "time": "2020-05-07T06:34:48+00:00" + "time": "2020-05-18T13:39:37+00:00" }, { "name": "laminas/laminas-http", @@ -2088,12 +1987,12 @@ "source": { "type": "git", "url": "https://github.com/laminas/laminas-zendframework-bridge.git", - "reference": "9c9c3bfd86f3d496cc1cc4e4d4bbb72b50ed09c3" + "reference": "881b3786014058a7c7a9926bbad376bac8f9375a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/9c9c3bfd86f3d496cc1cc4e4d4bbb72b50ed09c3", - "reference": "9c9c3bfd86f3d496cc1cc4e4d4bbb72b50ed09c3", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/881b3786014058a7c7a9926bbad376bac8f9375a", + "reference": "881b3786014058a7c7a9926bbad376bac8f9375a", "shasum": "" }, "require": { @@ -2132,7 +2031,7 @@ "laminas", "zf" ], - "time": "2020-04-15T19:17:48+00:00" + "time": "2020-05-20T16:49:09+00:00" }, { "name": "magento/framework", @@ -2246,12 +2145,12 @@ "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "74f92ea154eed179700960111970234f00b1a56b" + "reference": "3022efff205e2448b560c833c6fbbf91c3139168" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/74f92ea154eed179700960111970234f00b1a56b", - "reference": "74f92ea154eed179700960111970234f00b1a56b", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/3022efff205e2448b560c833c6fbbf91c3139168", + "reference": "3022efff205e2448b560c833c6fbbf91c3139168", "shasum": "" }, "require": { @@ -2315,7 +2214,7 @@ "logging", "psr-3" ], - "time": "2020-05-11T19:42:25+00:00" + "time": "2020-05-22T07:31:27+00:00" }, { "name": "mridang/pmd-annotations", @@ -2362,16 +2261,16 @@ }, { "name": "nosto/module-nostotagging", - "version": "dev-master", + "version": "4.0.9", "source": { "type": "git", "url": "https://github.com/Nosto/nosto-magento2.git", - "reference": "351e64a38a4752aab9361bd73ca805b14749fc65" + "reference": "1b3cb108c351f659e1fed7bdba17ab364301af77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nosto/nosto-magento2/zipball/351e64a38a4752aab9361bd73ca805b14749fc65", - "reference": "351e64a38a4752aab9361bd73ca805b14749fc65", + "url": "https://api.github.com/repos/Nosto/nosto-magento2/zipball/1b3cb108c351f659e1fed7bdba17ab364301af77", + "reference": "1b3cb108c351f659e1fed7bdba17ab364301af77", "shasum": "" }, "require": { @@ -2423,7 +2322,7 @@ "OSL-3.0" ], "description": "Increase your conversion rate and average order value by delivering your customers personalized product recommendations throughout their shopping journey.", - "time": "2020-03-31T13:17:01+00:00" + "time": "2020-05-28T11:49:56+00:00" }, { "name": "nosto/php-sdk", @@ -2483,12 +2382,12 @@ "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "be3ba85c4c0e1543233df1feaafd7fe31ea26584" + "reference": "25228897fb1f571d1dc857be2f9af062a95b7bea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/be3ba85c4c0e1543233df1feaafd7fe31ea26584", - "reference": "be3ba85c4c0e1543233df1feaafd7fe31ea26584", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/25228897fb1f571d1dc857be2f9af062a95b7bea", + "reference": "25228897fb1f571d1dc857be2f9af062a95b7bea", "shasum": "" }, "require": { @@ -2530,7 +2429,7 @@ "php", "type" ], - "time": "2020-05-02T14:39:07+00:00" + "time": "2020-05-27T00:05:32+00:00" }, { "name": "phpseclib/phpseclib", @@ -2909,18 +2808,19 @@ "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "01b7bd3b00401f03bcd88525dc5940d23f83a15c" + "reference": "6b456a744a1f92cc016fba7e6b1f4056e4953661" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/01b7bd3b00401f03bcd88525dc5940d23f83a15c", - "reference": "01b7bd3b00401f03bcd88525dc5940d23f83a15c", + "url": "https://api.github.com/repos/symfony/console/zipball/6b456a744a1f92cc016fba7e6b1f4056e4953661", + "reference": "6b456a744a1f92cc016fba7e6b1f4056e4953661", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.15", "symfony/service-contracts": "^1.1|^2" }, "conflict": { @@ -2977,7 +2877,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2020-05-08T10:54:34+00:00" + "time": "2020-05-24T08:33:35+00:00" }, { "name": "symfony/filesystem", @@ -2985,16 +2885,16 @@ "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "835ca5e2692d3baf424b6db3a1a85d56abf8725d" + "reference": "31f0a3601a6fd6570cd7038d3a38f80f4e2cb820" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/835ca5e2692d3baf424b6db3a1a85d56abf8725d", - "reference": "835ca5e2692d3baf424b6db3a1a85d56abf8725d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/31f0a3601a6fd6570cd7038d3a38f80f4e2cb820", + "reference": "31f0a3601a6fd6570cd7038d3a38f80f4e2cb820", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.1.3", "symfony/polyfill-ctype": "~1.8" }, "type": "library", @@ -3027,7 +2927,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2020-05-04T14:02:18+00:00" + "time": "2020-05-20T08:37:50+00:00" }, { "name": "symfony/finder", @@ -3138,7 +3038,7 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "dev-master", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -3370,18 +3270,80 @@ ], "time": "2020-05-12T16:47:27+00:00" }, + { + "name": "symfony/polyfill-php80", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "5e30b2799bc1ad68f7feb62b60a73743589438dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/5e30b2799bc1ad68f7feb62b60a73743589438dd", + "reference": "5e30b2799bc1ad68f7feb62b60a73743589438dd", + "shasum": "" + }, + "require": { + "php": ">=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2020-05-12T16:47:27+00:00" + }, { "name": "symfony/process", "version": "4.4.x-dev", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "4b6a9a4013baa65d409153cbb5a895bf093dc7f4" + "reference": "3bc410c407cba1ef8a03ca46de69a08c8b04f54a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/4b6a9a4013baa65d409153cbb5a895bf093dc7f4", - "reference": "4b6a9a4013baa65d409153cbb5a895bf093dc7f4", + "url": "https://api.github.com/repos/symfony/process/zipball/3bc410c407cba1ef8a03ca46de69a08c8b04f54a", + "reference": "3bc410c407cba1ef8a03ca46de69a08c8b04f54a", "shasum": "" }, "require": { @@ -3417,7 +3379,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2020-04-15T15:56:18+00:00" + "time": "2020-05-23T19:47:49+00:00" }, { "name": "symfony/service-contracts", @@ -3898,12 +3860,12 @@ "source": { "type": "git", "url": "https://github.com/laminas/laminas-session.git", - "reference": "9207c4e6a875e4e76be3d801e8c4ba60a0295127" + "reference": "3b7181caa8770a3886b83a8859569765d8b16c0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-session/zipball/9207c4e6a875e4e76be3d801e8c4ba60a0295127", - "reference": "9207c4e6a875e4e76be3d801e8c4ba60a0295127", + "url": "https://api.github.com/repos/laminas/laminas-session/zipball/3b7181caa8770a3886b83a8859569765d8b16c0d", + "reference": "3b7181caa8770a3886b83a8859569765d8b16c0d", "shasum": "" }, "require": { @@ -3961,7 +3923,7 @@ "laminas", "session" ], - "time": "2020-04-15T19:32:59+00:00" + "time": "2020-05-19T19:29:02+00:00" }, { "name": "magento-ecg/coding-standard", @@ -6268,12 +6230,12 @@ "source": { "type": "git", "url": "https://github.com/pdepend/pdepend.git", - "reference": "24b0636bcc8b77709ffe1b78d351e31e3187c4b3" + "reference": "1aa2302c2185357f026e91c0fb9cf48af5bec39e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/24b0636bcc8b77709ffe1b78d351e31e3187c4b3", - "reference": "24b0636bcc8b77709ffe1b78d351e31e3187c4b3", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/1aa2302c2185357f026e91c0fb9cf48af5bec39e", + "reference": "1aa2302c2185357f026e91c0fb9cf48af5bec39e", "shasum": "" }, "require": { @@ -6307,7 +6269,7 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", - "time": "2020-04-04T12:17:19+00:00" + "time": "2020-05-25T12:19:20+00:00" }, { "name": "phan/phan", @@ -6944,12 +6906,12 @@ "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ce62dee92da3b038a399a99353fc055b39d2853e" + "reference": "75ff420b23c0866c99c350099381a93b8602ebe6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ce62dee92da3b038a399a99353fc055b39d2853e", - "reference": "ce62dee92da3b038a399a99353fc055b39d2853e", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/75ff420b23c0866c99c350099381a93b8602ebe6", + "reference": "75ff420b23c0866c99c350099381a93b8602ebe6", "shasum": "" }, "require": { @@ -6987,7 +6949,7 @@ "phpcs", "standards" ], - "time": "2020-05-01T04:18:46+00:00" + "time": "2020-05-21T06:41:29+00:00" }, { "name": "staabm/annotate-pull-request-from-checkstyle", @@ -7031,16 +6993,16 @@ "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "929993f48470dd06543a6398ba549fb9b414096d" + "reference": "395f6e09e1dc6ac9c1a5eea3b7f44f7a820a5504" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/929993f48470dd06543a6398ba549fb9b414096d", - "reference": "929993f48470dd06543a6398ba549fb9b414096d", + "url": "https://api.github.com/repos/symfony/config/zipball/395f6e09e1dc6ac9c1a5eea3b7f44f7a820a5504", + "reference": "395f6e09e1dc6ac9c1a5eea3b7f44f7a820a5504", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.1.3", "symfony/filesystem": "^3.4|^4.0|^5.0", "symfony/polyfill-ctype": "~1.8" }, @@ -7087,7 +7049,7 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2020-05-08T10:54:34+00:00" + "time": "2020-05-23T09:11:46+00:00" }, { "name": "symfony/dependency-injection", @@ -7095,16 +7057,16 @@ "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "ef5bab90fda309de5da35e12b4e5d181b0600a0b" + "reference": "81ebfa04da818d708ca40ab933fbc749a3b9a048" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ef5bab90fda309de5da35e12b4e5d181b0600a0b", - "reference": "ef5bab90fda309de5da35e12b4e5d181b0600a0b", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/81ebfa04da818d708ca40ab933fbc749a3b9a048", + "reference": "81ebfa04da818d708ca40ab933fbc749a3b9a048", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.1.3", "psr/container": "^1.0", "symfony/service-contracts": "^1.1.6|^2" }, @@ -7160,7 +7122,7 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2020-05-04T15:32:48+00:00" + "time": "2020-05-23T17:20:05+00:00" }, { "name": "theseer/fdomdocument", From ae813e6811d3b2fffef4fdf43b9f9004501eee75 Mon Sep 17 00:00:00 2001 From: Cid Lopes Date: Wed, 17 Jun 2020 17:01:23 +0300 Subject: [PATCH 08/35] Add MSI, Nostotagging and ITP modules to project deps step (#59) --- .github/workflows/action.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index 1255f4f3..d02aaca7 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -143,6 +143,9 @@ jobs: run: | composer config repositories.0 composer https://repo.magento.com composer config http-basic.repo.magento.com "$REPO_USR" "$REPO_PSW" + composer require --no-update nosto/module-nostotagging:@stable + composer require --no-update nosto/module-nosto-msi:@stable + composer require --no-update nosto/module-nosto-itp:@stable composer install --prefer-dist --no-progress --no-suggest ############################################################################ From e7502349e9b51a58c32a8199cd30633c43f9f8b7 Mon Sep 17 00:00:00 2001 From: Olsi Qose Date: Thu, 18 Jun 2020 16:10:37 +0300 Subject: [PATCH 09/35] Update copyright year --- Block/CategoryMapping.php | 4 +-- Block/SegmentMapping.php | 4 +-- Block/SortOrder.php | 4 +-- Helper/CategorySorting.php | 4 +-- Helper/Data.php | 4 +-- Model/Config/Frontend/CategorySorting.php | 4 +-- Model/Config/Source/CategorySorting.php | 4 +-- Model/Filter/FilterBuilder.php | 4 +-- Model/Service/Recommendation/Category.php | 4 +-- Observer/App/Action/Action.php | 4 +-- Plugin/Catalog/Block/AbstractBlock.php | 4 +-- .../Block/DefaultParameterResolver.php | 4 +-- Plugin/Catalog/Block/Pager.php | 4 +-- .../Block/ParameterResolverInterface.php | 4 +-- Plugin/Catalog/Block/Toolbar.php | 4 +-- Plugin/Catalog/Model/Config.php | 4 +-- Plugin/Catalog/Model/Product.php | 4 +-- Plugin/Catalog/Model/Sortby.php | 4 +-- Plugin/Http/Context.php | 4 +-- Utils/Debug/Product.php | 4 +-- Utils/Debug/ServerTiming.php | 4 +-- etc/adminhtml/system.xml | 4 +-- etc/config.xml | 35 +++++++++++++++++++ etc/di.xml | 4 +-- etc/events.xml | 4 +-- etc/module.xml | 4 +-- registration.php | 4 +-- view/frontend/layout/default.xml | 35 +++++++++++++++++++ .../frontend/templates/category_mapping.phtml | 4 +-- .../templates/category_merchandising.phtml | 4 +-- view/frontend/templates/meta.phtml | 4 +-- 31 files changed, 128 insertions(+), 58 deletions(-) diff --git a/Block/CategoryMapping.php b/Block/CategoryMapping.php index 8916517a..426a93c8 100644 --- a/Block/CategoryMapping.php +++ b/Block/CategoryMapping.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Block/SegmentMapping.php b/Block/SegmentMapping.php index b8550e9c..dc773b5b 100644 --- a/Block/SegmentMapping.php +++ b/Block/SegmentMapping.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Block/SortOrder.php b/Block/SortOrder.php index a9bb80c4..7dbaad4b 100644 --- a/Block/SortOrder.php +++ b/Block/SortOrder.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Helper/CategorySorting.php b/Helper/CategorySorting.php index df0ba4b9..d29d0154 100644 --- a/Helper/CategorySorting.php +++ b/Helper/CategorySorting.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Helper/Data.php b/Helper/Data.php index 2883677f..bf9147e7 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Model/Config/Frontend/CategorySorting.php b/Model/Config/Frontend/CategorySorting.php index fbd05195..56797ef1 100644 --- a/Model/Config/Frontend/CategorySorting.php +++ b/Model/Config/Frontend/CategorySorting.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Model/Config/Source/CategorySorting.php b/Model/Config/Source/CategorySorting.php index 31122327..837846e7 100644 --- a/Model/Config/Source/CategorySorting.php +++ b/Model/Config/Source/CategorySorting.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Model/Filter/FilterBuilder.php b/Model/Filter/FilterBuilder.php index df45772d..9e71d7ad 100644 --- a/Model/Filter/FilterBuilder.php +++ b/Model/Filter/FilterBuilder.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Model/Service/Recommendation/Category.php b/Model/Service/Recommendation/Category.php index 9ca5537f..a3282849 100644 --- a/Model/Service/Recommendation/Category.php +++ b/Model/Service/Recommendation/Category.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Observer/App/Action/Action.php b/Observer/App/Action/Action.php index 3f8963f5..7961fdfb 100644 --- a/Observer/App/Action/Action.php +++ b/Observer/App/Action/Action.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Plugin/Catalog/Block/AbstractBlock.php b/Plugin/Catalog/Block/AbstractBlock.php index 65d9f9dc..44205432 100644 --- a/Plugin/Catalog/Block/AbstractBlock.php +++ b/Plugin/Catalog/Block/AbstractBlock.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Plugin/Catalog/Block/DefaultParameterResolver.php b/Plugin/Catalog/Block/DefaultParameterResolver.php index 668dc785..8ca45750 100644 --- a/Plugin/Catalog/Block/DefaultParameterResolver.php +++ b/Plugin/Catalog/Block/DefaultParameterResolver.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Plugin/Catalog/Block/Pager.php b/Plugin/Catalog/Block/Pager.php index ea375eec..92c2dc6b 100644 --- a/Plugin/Catalog/Block/Pager.php +++ b/Plugin/Catalog/Block/Pager.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Plugin/Catalog/Block/ParameterResolverInterface.php b/Plugin/Catalog/Block/ParameterResolverInterface.php index 5b2b9314..1469d28b 100644 --- a/Plugin/Catalog/Block/ParameterResolverInterface.php +++ b/Plugin/Catalog/Block/ParameterResolverInterface.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index 2987903b..37c21b88 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Plugin/Catalog/Model/Config.php b/Plugin/Catalog/Model/Config.php index 4df74e7b..80c05576 100644 --- a/Plugin/Catalog/Model/Config.php +++ b/Plugin/Catalog/Model/Config.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Plugin/Catalog/Model/Product.php b/Plugin/Catalog/Model/Product.php index 60a0eb88..bec0a8a3 100644 --- a/Plugin/Catalog/Model/Product.php +++ b/Plugin/Catalog/Model/Product.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Plugin/Catalog/Model/Sortby.php b/Plugin/Catalog/Model/Sortby.php index 09124c74..7a5c58d6 100644 --- a/Plugin/Catalog/Model/Sortby.php +++ b/Plugin/Catalog/Model/Sortby.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Plugin/Http/Context.php b/Plugin/Http/Context.php index 7fa115a3..075c2984 100644 --- a/Plugin/Http/Context.php +++ b/Plugin/Http/Context.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Utils/Debug/Product.php b/Utils/Debug/Product.php index f4ef05cb..512ee4fd 100644 --- a/Utils/Debug/Product.php +++ b/Utils/Debug/Product.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/Utils/Debug/ServerTiming.php b/Utils/Debug/ServerTiming.php index adc3990b..7d1605c9 100644 --- a/Utils/Debug/ServerTiming.php +++ b/Utils/Debug/ServerTiming.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 2abe8fb3..b6cea983 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -1,6 +1,6 @@ diff --git a/etc/config.xml b/etc/config.xml index b4c7404f..a019ab6c 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -1,4 +1,39 @@ + + diff --git a/etc/di.xml b/etc/di.xml index ababb348..2bc3c803 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -1,6 +1,6 @@ diff --git a/etc/events.xml b/etc/events.xml index a1e80088..6da58303 100644 --- a/etc/events.xml +++ b/etc/events.xml @@ -1,6 +1,6 @@ diff --git a/etc/module.xml b/etc/module.xml index 203a61c0..b90df656 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,6 +1,6 @@ diff --git a/registration.php b/registration.php index a1d30e8b..b72e6c04 100755 --- a/registration.php +++ b/registration.php @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/view/frontend/layout/default.xml b/view/frontend/layout/default.xml index fd684b4a..5804c6ee 100644 --- a/view/frontend/layout/default.xml +++ b/view/frontend/layout/default.xml @@ -1,4 +1,39 @@ + + diff --git a/view/frontend/templates/category_mapping.phtml b/view/frontend/templates/category_mapping.phtml index 149b1522..ddc96315 100644 --- a/view/frontend/templates/category_mapping.phtml +++ b/view/frontend/templates/category_mapping.phtml @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/view/frontend/templates/category_merchandising.phtml b/view/frontend/templates/category_merchandising.phtml index ac51db5b..415bc0f6 100644 --- a/view/frontend/templates/category_merchandising.phtml +++ b/view/frontend/templates/category_merchandising.phtml @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ diff --git a/view/frontend/templates/meta.phtml b/view/frontend/templates/meta.phtml index aaf4fdc6..a8aa8a0f 100644 --- a/view/frontend/templates/meta.phtml +++ b/view/frontend/templates/meta.phtml @@ -1,6 +1,6 @@ - * @copyright 2019 Nosto Solutions Ltd + * @copyright 2020 Nosto Solutions Ltd * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause * */ From 5deef2a18067b05f4ae3da26a2c50219e1d33ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Thu, 9 Jul 2020 12:08:47 +0300 Subject: [PATCH 10/35] Scaffolding for the Elasticsearch support --- Helper/SearchEngine.php | 81 ++++++++++++++++++ .../Block/ParameterResolverInterface.php | 1 + Plugin/Catalog/Block/Toolbar.php | 12 ++- .../Search/Request/BinderMutator.php | 76 +++++++++++++++++ .../Search/Request/RequestCleaner.php | 82 +++++++++++++++++++ Utils/Search.php | 79 ++++++++++++++++++ etc/di.xml | 6 ++ 7 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 Helper/SearchEngine.php create mode 100644 Plugin/Framework/Search/Request/BinderMutator.php create mode 100644 Plugin/Framework/Search/Request/RequestCleaner.php create mode 100644 Utils/Search.php diff --git a/Helper/SearchEngine.php b/Helper/SearchEngine.php new file mode 100644 index 00000000..6cf81fe7 --- /dev/null +++ b/Helper/SearchEngine.php @@ -0,0 +1,81 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Helper; + +use bovigo\vfs\visitor\BaseVisitor; +use Magento\Framework\Search\EngineResolverInterface; + +class SearchEngine +{ + const ENGINE_MYSQL = 'mysql'; + + /** + * @var EngineResolverInterface + */ + private $engineResolver; + + /** + * Data constructor. + * @param EngineResolverInterface $engineResolver + */ + public function __construct( + EngineResolverInterface $engineResolver + + ) { + $this->engineResolver = $engineResolver; + } + + /** + * Returns the current search engine used for catalog search + * + * @return string + */ + public function getCurrentEngine() + { + return $this->engineResolver->getCurrentSearchEngine(); + } + + /** + * Shortcut method for determining if the engine is MySQL + * + * @return boolean + */ + public function isMysql() + { + return $this->engineResolver->getCurrentSearchEngine() === self::ENGINE_MYSQL; + } +} diff --git a/Plugin/Catalog/Block/ParameterResolverInterface.php b/Plugin/Catalog/Block/ParameterResolverInterface.php index 1469d28b..f3998e32 100644 --- a/Plugin/Catalog/Block/ParameterResolverInterface.php +++ b/Plugin/Catalog/Block/ParameterResolverInterface.php @@ -36,6 +36,7 @@ namespace Nosto\Cmp\Plugin\Catalog\Block; +//TODO - move under helper or somewhere else. It's not necessarily related to any block. interface ParameterResolverInterface { /** diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index 37c21b88..1c222197 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -49,6 +49,7 @@ use Magento\LayeredNavigation\Block\Navigation\State; use Magento\Store\Model\Store; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; +use Nosto\Cmp\Helper\SearchEngine; use Nosto\Cmp\Utils\Debug\Product as ProductDebug; use Nosto\Cmp\Utils\Debug\ServerTiming; use Nosto\Cmp\Model\Service\Recommendation\Category as CategoryRecommendation; @@ -85,6 +86,9 @@ class Toolbar extends AbstractBlock /** @var NostoFilterBuilder */ private $nostoFilterBuilder; + /** @var SearchEngine */ + private $searchEngineHelper; + private static $isProcessed = false; /** @@ -100,6 +104,7 @@ class Toolbar extends AbstractBlock * @param NostoFilterBuilder $nostoFilterBuilder * @param Registry $registry * @param State $state + * @param SearchEngine $searchEngineHelper */ public function __construct( Context $context, @@ -112,7 +117,8 @@ public function __construct( NostoLogger $logger, NostoFilterBuilder $nostoFilterBuilder, Registry $registry, - State $state + State $state, + SearchEngine $searchEngineHelper ) { $this->categoryBuilder = $builder; $this->storeManager = $context->getStoreManager(); @@ -121,6 +127,7 @@ public function __construct( $this->nostoFilterBuilder = $nostoFilterBuilder; $this->registry = $registry; $this->state = $state; + $this->searchEngineHelper = $searchEngineHelper; parent::__construct($context, $parameterResolver, $nostoCmpHelperData, $nostoHelperAccount, $logger); } @@ -134,6 +141,9 @@ public function __construct( public function afterSetCollection( // phpcs:ignore EcgM2.Plugins.Plugin.PluginWarning MagentoToolbar $subject ) { + if (!$this->searchEngineHelper->isMysql()) { + return $subject; + } if (self::$isProcessed) { return $subject; } diff --git a/Plugin/Framework/Search/Request/BinderMutator.php b/Plugin/Framework/Search/Request/BinderMutator.php new file mode 100644 index 00000000..bc4a0ff4 --- /dev/null +++ b/Plugin/Framework/Search/Request/BinderMutator.php @@ -0,0 +1,76 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Plugin\Framework\Search\Request; + +use Magento\Framework\Search\Request\Binder; +use Nosto\Cmp\Plugin\Catalog\Block\ParameterResolverInterface; +use Nosto\Cmp\Utils\Search; + +class BinderMutator +{ + /** + * @var ParameterResolverInterface + */ + private $parameterResolver; + + /** + * @param ParameterResolverInterface $parameterResolver + */ + public function __construct(ParameterResolverInterface $parameterResolver) + { + $this->parameterResolver = $parameterResolver; + } + + /** + * Calls Nosto's API to get CMP result & sets product ids returned by Nosto to the bind data + * + * @param Binder $binder + * @param array $data + * @return array + */ + public function afterBind(Binder $binder, array $data) + { + if (!Search::isNostoSortingByResolver($this->parameterResolver)) { + return $data; + } + // TODO + // - fetch Nosto data from Graphql + // - add the product ids to the data & return + // - double check if we should remove some of the existing bindings + return $data; + } +} \ No newline at end of file diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php new file mode 100644 index 00000000..b7219c4c --- /dev/null +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -0,0 +1,82 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Plugin\Framework\Search\Request; + +use Magento\Framework\Search\Request\Cleaner; +use Nosto\Cmp\Plugin\Catalog\Block\ParameterResolverInterface; +use Nosto\Cmp\Utils\Search; + +class RequestCleaner +{ + /** + * @var ParameterResolverInterface + */ + private $parameterResolver; + + /** + * @param ParameterResolverInterface $parameterResolver + */ + public function __construct(ParameterResolverInterface $parameterResolver) + { + $this->parameterResolver = $parameterResolver; + } + + /** + * Cleans non persisted sorting parameters etc. for the request data + * + * @param Cleaner $cleaner + * @param array $requestData + * @return array + */ + public function afterClean(Cleaner $cleaner, array $requestData) + { + return $this->cleanNostoSorting($requestData); + } + + /** + * @param array $requestData + * @return array + */ + private function cleanNostoSorting(array $requestData) + { + if (!Search::isNostoSorting($requestData)) { + return $requestData; + } + unset($requestData['sort'][Search::findNostoSortingIndex($requestData)]); + return $requestData; + } +} \ No newline at end of file diff --git a/Utils/Search.php b/Utils/Search.php new file mode 100644 index 00000000..6a2d24a0 --- /dev/null +++ b/Utils/Search.php @@ -0,0 +1,79 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Utils; + +use Nosto\Cmp\Helper\CategorySorting; +use Nosto\Cmp\Plugin\Catalog\Block\ParameterResolverInterface; + +class Search +{ + /** + * @param array $requestData + * @return bool + */ + public static function isNostoSorting(array $requestData) + { + return self::findNostoSortingIndex($requestData) !== null; + } + + /** + * @param ParameterResolverInterface $parameterResolver + * @return bool + */ + public static function isNostoSortingByResolver(ParameterResolverInterface $parameterResolver) + { + return $parameterResolver->getSortingOrder() === CategorySorting::NOSTO_PERSONALIZED_KEY; + } + + /** + * @param array $requestData + * @return int|string|null + */ + public static function findNostoSortingIndex(array $requestData) + { + if (empty($requestData['sort'])) { + return null; + } + $sorting = $requestData['sort']; + foreach ($sorting as $index => $sort) { + if (!empty($sort['field']) && $sort['field'] === CategorySorting::NOSTO_PERSONALIZED_KEY) { + return $index; + } + } + return null; + } +} diff --git a/etc/di.xml b/etc/di.xml index 2bc3c803..5efd593f 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -54,4 +54,10 @@ + + + + + + \ No newline at end of file From 6b93ac04d2c832b5487529104c294ab989686961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Fri, 14 Aug 2020 11:59:49 +0300 Subject: [PATCH 11/35] Remove redundant files (wrongful merge) --- Block/SegmentMapping.php | 131 --------- Plugin/Http/Context.php | 255 ------------------ .../templates/category_merchandising.phtml | 51 ---- 3 files changed, 437 deletions(-) delete mode 100644 Block/SegmentMapping.php delete mode 100644 Plugin/Http/Context.php delete mode 100644 view/frontend/templates/category_merchandising.phtml diff --git a/Block/SegmentMapping.php b/Block/SegmentMapping.php deleted file mode 100644 index dc773b5b..00000000 --- a/Block/SegmentMapping.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @copyright 2020 Nosto Solutions Ltd - * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause - * - */ - -namespace Nosto\Cmp\Block; - -use Magento\Framework\Stdlib\CookieManagerInterface; -use Magento\Framework\View\Element\Template; -use Magento\Framework\View\Element\Template\Context; -use Magento\Store\Model\StoreManagerInterface; -use Nosto\Nosto; -use Nosto\Tagging\Helper\Account as NostoHelperAccount; -use Nosto\Tagging\Logger\Logger as NostoLogger; -use Nosto\Tagging\Model\Customer\Customer as NostoCustomer; -use Magento\Store\Model\Store; - -class SegmentMapping extends Template -{ - const COOKIE_CATEGORY_MAP = "n_cmp_mapping"; - - const COOKIE_SEGMENT_MAP = "n_cmp_indexes"; - - /** @var NostoHelperAccount */ - private $nostoHelperAccount; - - /** @var CookieManagerInterface */ - private $cookieManager; - - /** @var StoreManagerInterface */ - private $storeManager; - - /** @var NostoLogger */ - private $logger; - - public function __construct( - StoreManagerInterface $storeManager, - NostoHelperAccount $nostoHelperAccount, - CookieManagerInterface $cookieManager, - Context $context, - NostoLogger $logger - ) { - parent::__construct($context); - $this->storeManager = $storeManager; - $this->nostoHelperAccount = $nostoHelperAccount; - $this->cookieManager = $cookieManager; - $this->logger = $logger; - } - - /** - * Return Nosto merchant id - * @return null|string - */ - public function getNostoAccount() - { - try { - $store = $this->storeManager->getStore(); - } catch (\Exception $e) { - $this->logger->error($e->getMessage() . 'Could not get Nosto account ID'); - return null; - } - /** @var Store $store */ - return $this->nostoHelperAccount->getAccountName($store); //@phan-suppress-current-line PhanTypeMismatchArgument - } - - /** - * Return customer id - * @return null|string - */ - public function getCustomerId() - { - return $this->cookieManager->getCookie(NostoCustomer::COOKIE_NAME); - } - - /** - * Return the mapping cookie name - * @return string - */ - public function getCategoryMappingCookieName() - { - return self::COOKIE_CATEGORY_MAP; - } - - /** - * Return the mapping cookie name - * @return string - */ - public function getSegmentMappingCookieName() - { - return self::COOKIE_SEGMENT_MAP; - } - - /** - * @return mixed - */ - public function getNostoBaseUrl() - { - return Nosto::getBaseUrl(); - } -} diff --git a/Plugin/Http/Context.php b/Plugin/Http/Context.php deleted file mode 100644 index 075c2984..00000000 --- a/Plugin/Http/Context.php +++ /dev/null @@ -1,255 +0,0 @@ - - * @copyright 2020 Nosto Solutions Ltd - * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause - * - */ - -namespace Nosto\Cmp\Plugin\Http; - -use Exception; -use Magento\Catalog\Model\Category; -use Magento\Catalog\Model\CategoryFactory; -use Magento\Customer\Model\Session; -use Magento\Framework\App\Http\Context as MagentoContext; -use Magento\Framework\App\Request\Http; -use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Stdlib\CookieManagerInterface; -use Magento\Store\Model\Store; -use Magento\Store\Model\StoreManagerInterface; -use Nosto\Cmp\Block\SegmentMapping; -use Nosto\Cmp\Helper\CategorySorting as NostoHelperSorting; -use Nosto\Cmp\Helper\Data as NostoCmpHelperData; -use Nosto\Cmp\Plugin\Catalog\Block\DefaultParameterResolver as ParamResolver; -use Nosto\Tagging\Helper\Account as NostoHelperAccount; -use Nosto\Tagging\Logger\Logger as NostoLogger; -use Nosto\Tagging\Model\Service\Product\Category\DefaultCategoryService as CategoryBuilder; - -class Context -{ - /** @var CookieManagerInterface */ - private $cookieManager; - - /** @var Http */ - private $request; - - /** @var CategoryFactory */ - private $categoryFactory; - - /** @var String */ - private $categoryString; - - /** @var CategoryBuilder */ - private $categoryBuilder; - - /** @var StoreManagerInterface */ - private $storeManager; - - /** @var NostoHelperAccount */ - private $nostoHelperAccount; - - /** @var NostoCmpHelperData */ - private $nostoCmpHelperData; - - /** @var Store */ - private $store; - - /** @var NostoLogger */ - private $logger; - /** - * @var Session - */ - private $customerSession; - - /** - * Context constructor. - * @param Session $customerSession - * @param CookieManagerInterface $cookieManager - * @param CategoryFactory $categoryFactory - * @param CategoryBuilder $categoryBuilder - * @param StoreManagerInterface $storeManager - * @param NostoHelperAccount $nostoHelperAccount - * @param NostoCmpHelperData $nostoCmpHelperData - * @param Http $request - * @param NostoLogger $logger - */ - public function __construct( - Session $customerSession, - CookieManagerInterface $cookieManager, - CategoryFactory $categoryFactory, - CategoryBuilder $categoryBuilder, - StoreManagerInterface $storeManager, - NostoHelperAccount $nostoHelperAccount, - NostoCmpHelperData $nostoCmpHelperData, - Http $request, - NostoLogger $logger - ) { - $this->customerSession = $customerSession; - $this->cookieManager = $cookieManager; - $this->categoryFactory = $categoryFactory; - $this->categoryBuilder = $categoryBuilder; - $this->storeManager = $storeManager; - $this->nostoHelperAccount = $nostoHelperAccount; - $this->nostoCmpHelperData = $nostoCmpHelperData; - $this->request = $request; - $this->logger = $logger; - } - - /** - * @param MagentoContext $subject - * @return MagentoContext - */ - // phpcs:ignore EcgM2.Plugins.Plugin - public function beforeGetVaryString(MagentoContext $subject) - { - try { - $this->setCategoryAndStore(); - } catch (Exception $e) { - $this->logger->exception($e); - } - $sortingParameter = $this->request->getParam(ParamResolver::DEFAULT_SORTING_ORDER_PARAM); - if ($this->isCategoryPage() && - $sortingParameter && - $sortingParameter === NostoHelperSorting::NOSTO_PERSONALIZED_KEY && - $this->nostoHelperAccount->nostoInstalledAndEnabled($this->store) && - $this->nostoCmpHelperData->isCategorySortingEnabled($this->store)) { - - $variation = $this->getSegmentFromCookie(); - if ($variation === '') { - $this->logger->debug('Variation key is empty'); - } - $subject->setValue('CONTEXT_NOSTO', $variation, $defaultValue = ""); - } - return $subject; - } - - /** - * Get segment id from cookie - * @return string - */ - private function getSegmentFromCookie() - { - //Read cookie - $cookie = $this->cookieManager->getCookie(SegmentMapping::COOKIE_CATEGORY_MAP); - if ($cookie === null) { - $this->logger->debug(sprintf( - 'Cookie %s is not present', - SegmentMapping::COOKIE_CATEGORY_MAP - )); - return ''; - } - //Parse value - $stdClass = json_decode($cookie); - if ($stdClass === null) { - $this->logger->debug(sprintf( - 'Cookie %s has no value', - SegmentMapping::COOKIE_CATEGORY_MAP - )); - return ''; - } - $segmentMap = get_object_vars($stdClass); - $signedInteger = crc32($this->categoryString); - $unsignedInteger = (int) sprintf("%u", $signedInteger); - $hashedCategory = dechex($unsignedInteger); - //Check if current category is part of segment mapping - if (array_key_exists($hashedCategory, $segmentMap) && - is_numeric($segmentMap[$hashedCategory])) { - $index = $segmentMap[$hashedCategory]; - $indexedIds = $this->cookieManager->getCookie(SegmentMapping::COOKIE_SEGMENT_MAP); - if ($indexedIds === null || $indexedIds === '') { - return ''; - } - $indexedIds = json_decode($indexedIds); - return $indexedIds[$index]; //@phan-suppress-current-line PhanTypeArraySuspiciousNullable - } - return ''; - } - - /** - * @throws NoSuchEntityException - */ - private function setCategoryAndStore() - { - $category = $this->getCategory(); - if ($category) { - $this->store = $this->storeManager->getStore(); - $this->categoryString = strtolower( - $this->categoryBuilder->getCategory($category, $this->store) - ); - } - } - - /** - * Checks if the current page is a category page - * @return bool - */ - private function isCategoryPage() - { - if (is_string($this->categoryString)) { - return true; - } - return false; - } - - /** - * Return category object or false if not found - * @return null|Category - */ - private function getCategory() - { - $categoryFactory = $this->categoryFactory->create(); - $urlPath = $this->getUrlPath(); - if (!is_string($urlPath)) { - return null; - } - return $categoryFactory->loadByAttribute('url_path', $urlPath); - } - - /** - * @return null|string - */ - private function getUrlPath() - { - $path = $this->request->getUri()->getPath(); //@phan-suppress-current-line PhanUndeclaredMethod - if ($path === null) { - return null; - } - //Remove leading slash - $path = substr($path, 1); - if (!is_string($path)) { - return null; - } - //Remove . ending - $path = explode(".", $path)[0]; - return $path; - } -} diff --git a/view/frontend/templates/category_merchandising.phtml b/view/frontend/templates/category_merchandising.phtml deleted file mode 100644 index 415bc0f6..00000000 --- a/view/frontend/templates/category_merchandising.phtml +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright 2020 Nosto Solutions Ltd - * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause - * - */ - -/** @var \Nosto\Cmp\Block\SegmentMapping $block */ -?> - - From 1f328c849d8c4fe2e86b0c23ccbead2fa9d50490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Thu, 20 Aug 2020 16:16:47 +0300 Subject: [PATCH 12/35] WIP - Remove redundant binder mutator, apply the product ids to the ES query --- .../Search/Request/BinderMutator.php | 76 ------- .../Search/Request/RequestCleaner.php | 199 +++++++++++++++++- etc/di.xml | 3 - 3 files changed, 190 insertions(+), 88 deletions(-) delete mode 100644 Plugin/Framework/Search/Request/BinderMutator.php diff --git a/Plugin/Framework/Search/Request/BinderMutator.php b/Plugin/Framework/Search/Request/BinderMutator.php deleted file mode 100644 index bc4a0ff4..00000000 --- a/Plugin/Framework/Search/Request/BinderMutator.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright 2020 Nosto Solutions Ltd - * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause - * - */ - -namespace Nosto\Cmp\Plugin\Framework\Search\Request; - -use Magento\Framework\Search\Request\Binder; -use Nosto\Cmp\Plugin\Catalog\Block\ParameterResolverInterface; -use Nosto\Cmp\Utils\Search; - -class BinderMutator -{ - /** - * @var ParameterResolverInterface - */ - private $parameterResolver; - - /** - * @param ParameterResolverInterface $parameterResolver - */ - public function __construct(ParameterResolverInterface $parameterResolver) - { - $this->parameterResolver = $parameterResolver; - } - - /** - * Calls Nosto's API to get CMP result & sets product ids returned by Nosto to the bind data - * - * @param Binder $binder - * @param array $data - * @return array - */ - public function afterBind(Binder $binder, array $data) - { - if (!Search::isNostoSortingByResolver($this->parameterResolver)) { - return $data; - } - // TODO - // - fetch Nosto data from Graphql - // - add the product ids to the data & return - // - double check if we should remove some of the existing bindings - return $data; - } -} \ No newline at end of file diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index b7219c4c..63689b67 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -37,22 +37,79 @@ namespace Nosto\Cmp\Plugin\Framework\Search\Request; use Magento\Framework\Search\Request\Cleaner; +use Magento\Store\Model\StoreManagerInterface; +use Magento\TestFramework\Store\StoreManager; +use Nosto\Cmp\Helper\SearchEngine; +use Nosto\Cmp\Model\Filter\FilterBuilder; use Nosto\Cmp\Plugin\Catalog\Block\ParameterResolverInterface; +use Nosto\Cmp\Utils\Debug\ServerTiming; use Nosto\Cmp\Utils\Search; +use Nosto\NostoException; +use Nosto\Tagging\Helper\Account as NostoHelperAccount; +use Nosto\Tagging\Logger\Logger; +use Nosto\Tagging\Model\Customer\Customer as NostoCustomer; class RequestCleaner { + const KEY_ES_PRODUCT_ID = '_id'; + const KEY_MYSQL_PRODUCT_ID = 'entity_id'; + const KEY_BIND_TO_QUERY = 'catalog_view_container'; + const KEY_QUERIES = 'queries'; + const KEY_FILTERS = 'filters'; + const KEY_CMP = 'nosto_cmp_id_search'; + /** * @var ParameterResolverInterface */ private $parameterResolver; + /** + * @var Logger + */ + private $logger; + + /** + * @var SearchEngine + */ + private $searchEngineHelper; + + /** + * @var StoreManager + */ + private $storeManager; + + /** + * @var NostoHelperAccount + */ + private $accountHelper; + + /** + * @var FilterBuilder + */ + private $filterBuilder; + /** * @param ParameterResolverInterface $parameterResolver + * @param SearchEngine $searchEngineHelper + * @param StoreManagerInterface $storeManager + * @param NostoHelperAccount $nostoHelperAccount + * @param FilterBuilder $filterBuilder + * @param Logger $logger */ - public function __construct(ParameterResolverInterface $parameterResolver) - { + public function __construct( + ParameterResolverInterface $parameterResolver, + SearchEngine $searchEngineHelper, + StoreManagerInterface $storeManager, + NostoHelperAccount $nostoHelperAccount, + FilterBuilder $filterBuilder, + Logger $logger + ) { $this->parameterResolver = $parameterResolver; + $this->logger = $logger; + $this->searchEngineHelper = $searchEngineHelper; + $this->storeManager = $storeManager; + $this->accountHelper = $nostoHelperAccount; + $this->filterBuilder = $filterBuilder; } /** @@ -64,19 +121,143 @@ public function __construct(ParameterResolverInterface $parameterResolver) */ public function afterClean(Cleaner $cleaner, array $requestData) { - return $this->cleanNostoSorting($requestData); + if (!Search::isNostoSorting($requestData)) { + return $requestData; + } + try { + if (!isset($requestData[self::KEY_QUERIES][self::KEY_BIND_TO_QUERY]) + || !isset($requestData[self::KEY_QUERIES][self::KEY_BIND_TO_QUERY]['queryReference']) + ) { + $this->logger->debugWithSource( + sprintf( + 'Could not find %s from ES request data', + self::KEY_BIND_TO_QUERY + ), + $requestData, + $this + ); + return $requestData; + } + $origData = $requestData; //TODO - remove me, only for debugging purposes + $this->resetRequestData($requestData); + $this->applyCmpFilter($requestData, $this->getCmpProductIds()); + $this->applyCmpSort($requestData, $this->getCmpProductIds()); + } catch (\Exception $e) { + $this->logger->debugWithSource( + 'Failed to apply CMP - see exception log(s) for datails', + $requestData, + $this + ); + $this->logger->exception($e); + } finally { + return $requestData; + } } + /** + * Removes the Nosto sorting key as it's not indexed + * * @param array $requestData - * @return array + * @param $productIds */ - private function cleanNostoSorting(array $requestData) + private function applyCmpSort(array &$requestData, $productIds) { - if (!Search::isNostoSorting($requestData)) { - return $requestData; - } unset($requestData['sort'][Search::findNostoSortingIndex($requestData)]); - return $requestData; + + //TODO: check if we can use script for sorting the results } + + /** + * Applies given product ids to the query & filters + * + * @param array $requestData + * @param array $productIds + */ + private function applyCmpFilter(array &$requestData, array $productIds) + { + $requestData[self::KEY_QUERIES][self::KEY_BIND_TO_QUERY]['queryReference'][] = [ + 'clause' =>'must', + 'ref' => 'nosto_cmp_id_search' + ]; + $requestData[self::KEY_QUERIES][self::KEY_CMP] = [ + 'name' => 'nosto_cmp', + 'filterReference' => [ + [ + 'clause' => 'must', + 'ref' => 'prod_id', + ], + ], + 'type' => 'filteredQuery', + ]; + $requestData['filters']['prod_id'] = [ + 'name' => 'prod_id', + 'filterReference' => [ + [ + 'clause' => 'must', + 'ref' => 'prod_ids', + ], + ], + 'type' => 'boolFilter', + ]; + $requestData['filters']['prod_ids'] = [ + 'name' => 'prod_ids', + 'field' => $this->getProductIdField(), + 'type' => 'termFilter', + 'value' => $productIds + ]; + } + + /** + * @return int[] + */ + private function getCmpProductIds() + { + // TODO + // - inject CMP operation + // - build the filters + // - fetch the product ids from Nosto + return [5, 11, 401, 2023, 1]; + } + + /** + * Removes queries & filters from the request data + * + * @param array $requestData + */ + private function resetRequestData(array &$requestData) + { + $removedQueries = []; + foreach ($requestData[self::KEY_QUERIES] as $key => $definition) { + if ($key !== self::KEY_BIND_TO_QUERY) { + $removedQueries[$key] = $key; + unset($requestData[self::KEY_QUERIES][$key]); + } + } + $removedRefs = []; + // Also referencing definitions + foreach ($requestData[self::KEY_QUERIES][self::KEY_BIND_TO_QUERY]['queryReference'] as $refIndex => $ref) { + $refStr = $ref['ref']; + if (isset($removedQueries[$refStr])) { + $removedRefs[$refStr] = $refStr; + unset($requestData[self::KEY_QUERIES][self::KEY_BIND_TO_QUERY]['queryReference'][$refIndex]); + } + } + $requestData['filters'] = []; + } + + /** + * Return the product id field + * + * @return string + */ + private function getProductIdField() + { + if ($this->searchEngineHelper->isMysql()) { + return self::KEY_MYSQL_PRODUCT_ID; + } else { + return self::KEY_ES_PRODUCT_ID; + } + } + } \ No newline at end of file diff --git a/etc/di.xml b/etc/di.xml index 5efd593f..7e5657a8 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -57,7 +57,4 @@ - - - \ No newline at end of file From fb6a90af74221e862027717c51081ccd0360cc57 Mon Sep 17 00:00:00 2001 From: Olsi Qose Date: Tue, 1 Sep 2020 15:15:57 +0300 Subject: [PATCH 13/35] CM is disabled by default --- etc/config.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/config.xml b/etc/config.xml index a019ab6c..4d48e393 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -40,7 +40,7 @@ - 1 + 0 From e3369e3b090eeff46007a3b727f6fe6c71f67ed4 Mon Sep 17 00:00:00 2001 From: Olsi Qose Date: Wed, 2 Sep 2020 09:27:28 +0300 Subject: [PATCH 14/35] Fix the xml config --- etc/config.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/config.xml b/etc/config.xml index 4d48e393..60105e6f 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -38,10 +38,10 @@ - + 0 - + From 2ac7c0f39ad3772778ccec7203607a0b2a125887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Wed, 2 Sep 2020 10:46:11 +0300 Subject: [PATCH 15/35] Apply sorting to search results --- Plugin/Api/Search/SearchResultSorter.php | 91 +++++++++++++++++++ .../Search/Request/RequestCleaner.php | 17 ++-- etc/di.xml | 3 + 3 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 Plugin/Api/Search/SearchResultSorter.php diff --git a/Plugin/Api/Search/SearchResultSorter.php b/Plugin/Api/Search/SearchResultSorter.php new file mode 100644 index 00000000..0acfdf01 --- /dev/null +++ b/Plugin/Api/Search/SearchResultSorter.php @@ -0,0 +1,91 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Plugin\Api\Search; + +use Magento\Framework\Api\Search\Document; +use Magento\Framework\Api\Search\SearchResult; +use Nosto\Cmp\Plugin\Framework\Search\Request\RequestCleaner; + +class SearchResultSorter +{ + + /** + * @param SearchResult $subject + * @param $result + * @return array + */ + public function beforeSetItems(SearchResult $subject, $result) + { + + $cmpSort = $this->getCmpSort(); + if (empty($cmpSort)) { + return [$result]; + } + $sorted = []; + foreach ($cmpSort as $productId) { + $document = $this->findDocumentByProductId($result, $productId); + if ($document) { + $sorted[] = $document; + } + } + return [$sorted]; + } + + /** + * @param Document[] $result + * @param $productId + * @return Document|null + */ + private function findDocumentByProductId(array &$result, $productId) + { + foreach ($result as $document) { + if ($document->getId() == $productId) { + return $document; + } + } + return null; + } + /** + * Returns the product ids sorted by Nosto + * @return int[] + */ + private function getCmpSort() + { + // TODO - use the service + return RequestCleaner::$nostoTmpSort; + } +} \ No newline at end of file diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index 63689b67..b6230afc 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -42,12 +42,9 @@ use Nosto\Cmp\Helper\SearchEngine; use Nosto\Cmp\Model\Filter\FilterBuilder; use Nosto\Cmp\Plugin\Catalog\Block\ParameterResolverInterface; -use Nosto\Cmp\Utils\Debug\ServerTiming; use Nosto\Cmp\Utils\Search; -use Nosto\NostoException; use Nosto\Tagging\Helper\Account as NostoHelperAccount; use Nosto\Tagging\Logger\Logger; -use Nosto\Tagging\Model\Customer\Customer as NostoCustomer; class RequestCleaner { @@ -58,6 +55,8 @@ class RequestCleaner const KEY_FILTERS = 'filters'; const KEY_CMP = 'nosto_cmp_id_search'; + public static $nostoTmpSort = [5, 11, 401, 2023, 1]; + /** * @var ParameterResolverInterface */ @@ -141,7 +140,7 @@ public function afterClean(Cleaner $cleaner, array $requestData) $origData = $requestData; //TODO - remove me, only for debugging purposes $this->resetRequestData($requestData); $this->applyCmpFilter($requestData, $this->getCmpProductIds()); - $this->applyCmpSort($requestData, $this->getCmpProductIds()); + $this->cleanUpCmpSort($requestData, $this->getCmpProductIds()); } catch (\Exception $e) { $this->logger->debugWithSource( 'Failed to apply CMP - see exception log(s) for datails', @@ -161,11 +160,9 @@ public function afterClean(Cleaner $cleaner, array $requestData) * @param array $requestData * @param $productIds */ - private function applyCmpSort(array &$requestData, $productIds) + private function cleanUpCmpSort(array &$requestData, $productIds) { unset($requestData['sort'][Search::findNostoSortingIndex($requestData)]); - - //TODO: check if we can use script for sorting the results } /** @@ -213,11 +210,13 @@ private function applyCmpFilter(array &$requestData, array $productIds) */ private function getCmpProductIds() { + // TODO - // - inject CMP operation + // - inject CMP service // - build the filters // - fetch the product ids from Nosto - return [5, 11, 401, 2023, 1]; + // - pagination? + return self::$nostoTmpSort; } /** diff --git a/etc/di.xml b/etc/di.xml index 7e5657a8..50515ca9 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -57,4 +57,7 @@ + + + \ No newline at end of file From ccf40f6f066299c7f225a4de08d2f0766a5a8b93 Mon Sep 17 00:00:00 2001 From: Olsi Qose Date: Thu, 3 Sep 2020 13:04:59 +0300 Subject: [PATCH 16/35] Add flag to map all categories in the json --- Block/CategoryMapping.php | 11 ++++++++++- Helper/Data.php | 16 ++++++++++++++++ etc/adminhtml/system.xml | 8 ++++++++ etc/config.xml | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Block/CategoryMapping.php b/Block/CategoryMapping.php index 426a93c8..445aa3dd 100644 --- a/Block/CategoryMapping.php +++ b/Block/CategoryMapping.php @@ -46,6 +46,7 @@ use Magento\Store\Model\StoreManagerInterface; use Nosto\Tagging\Logger\Logger as NostoLogger; use Nosto\Tagging\Model\Service\Product\Category\DefaultCategoryService as CategoryBuilder; +use Nosto\Cmp\Helper\Data as NostoHelperData; class CategoryMapping extends Template { @@ -58,6 +59,9 @@ class CategoryMapping extends Template /** @var CategoryBuilder */ private $categoryBuilder; + /** @var NostoHelperData */ + private $nostoHelperData; + /** @var NostoLogger */ private $logger; @@ -68,6 +72,7 @@ public function __construct( StoreManagerInterface $storeManager, CollectionFactory $collectionFactory, CategoryBuilder $categoryBuilder, + NostoHelperData $nostoHelperData, Context $context, NostoLogger $logger ) { @@ -75,6 +80,7 @@ public function __construct( $this->storeManager = $storeManager; $this->collectionFactory = $collectionFactory; $this->categoryBuilder = $categoryBuilder; + $this->nostoHelperData = $nostoHelperData; $this->logger = $logger; } @@ -113,10 +119,13 @@ private function getMagentoCategories(Store $store) $categories = $this->collectionFactory->create() ->addAttributeToSelect('*') - ->addAttributeToFilter('include_in_menu', ['eq' => 1]) ->addIsActiveFilter() ->setStore($store); + if (!$this->nostoHelperData->isAllCategoriesMapEnabled($store)) { + $categories->addAttributeToFilter('include_in_menu', ['eq' => 1]); + } + /** @var Category $category $item */ foreach ($categories->getItems() as $category) { $hashedCategoryString = $this->hashCategoryString(strtolower( diff --git a/Helper/Data.php b/Helper/Data.php index bf9147e7..c5f1336c 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -55,6 +55,11 @@ class Data extends AbstractHelper */ const XML_PATH_CATEGORY_SORTING = 'nosto_cmp/flags/category_sorting'; + /** + * Path to the configuration object that stores category sorting + */ + const XML_PATH_CATEGORY_MAPPING = 'nosto_cmp/flags/category_map'; + /** @var ModuleListInterface */ private $moduleList; @@ -85,6 +90,17 @@ public function isCategorySortingEnabled(StoreInterface $store = null) return (bool)$this->getStoreConfig(self::XML_PATH_CATEGORY_SORTING, $store); } + /** + * Returns if category sorting is enabled + * + * @param StoreInterface|null $store the store model or null. + * @return bool the configuration value + */ + public function isAllCategoriesMapEnabled(StoreInterface $store = null) + { + return (bool)$this->getStoreConfig(self::XML_PATH_CATEGORY_MAPPING, $store); + } + /** * @param string $path * @param StoreInterface|Store|null $store diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index b6cea983..23cd0f96 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -55,6 +55,14 @@ Nosto\Cmp\Model\Config\Source\CategorySorting Nosto\Cmp\Model\Config\Frontend\CategorySorting + + + + + + Magento\Config\Model\Config\Source\Yesno + diff --git a/etc/config.xml b/etc/config.xml index 60105e6f..aceabb1c 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -41,6 +41,7 @@ 0 + 0 From 947c2ee79d1eb10df9f8d5a5cf1bb49e297a9d4a Mon Sep 17 00:00:00 2001 From: Olsi Qose Date: Thu, 3 Sep 2020 14:25:48 +0300 Subject: [PATCH 17/35] Update the flag name --- etc/adminhtml/system.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 23cd0f96..78da7c37 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -57,9 +57,9 @@ - + - + Magento\Config\Model\Config\Source\Yesno From c5b8a1f3a752b49327fa3e130be332fa3c92b030 Mon Sep 17 00:00:00 2001 From: Olsi Qose Date: Thu, 3 Sep 2020 14:35:45 +0300 Subject: [PATCH 18/35] Rename variable --- Helper/Data.php | 2 +- etc/adminhtml/system.xml | 2 +- etc/config.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Helper/Data.php b/Helper/Data.php index c5f1336c..63d2f5a2 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -58,7 +58,7 @@ class Data extends AbstractHelper /** * Path to the configuration object that stores category sorting */ - const XML_PATH_CATEGORY_MAPPING = 'nosto_cmp/flags/category_map'; + const XML_PATH_CATEGORY_MAPPING = 'nosto_cmp/flags/map_all_categories'; /** @var ModuleListInterface */ private $moduleList; diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 78da7c37..7905b263 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -55,7 +55,7 @@ Nosto\Cmp\Model\Config\Source\CategorySorting Nosto\Cmp\Model\Config\Frontend\CategorySorting - diff --git a/etc/config.xml b/etc/config.xml index aceabb1c..7f4c1b6c 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -41,7 +41,7 @@ 0 - 0 + 0 From 5ad093f90b4702f70f46c5038cf12f26fa823d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Tue, 8 Sep 2020 15:41:00 +0300 Subject: [PATCH 19/35] Add sorting by CMP results, introduce state aware category service --- Model/Service/Recommendation/Category.php | 9 +- .../StateAwareCategoryService.php | 214 ++++++++++++++++++ .../StateAwareCategoryServiceInterface.php | 54 +++++ Plugin/Api/Search/SearchResultSorter.php | 44 +++- Plugin/Catalog/Block/Pager.php | 8 +- Plugin/Catalog/Block/Toolbar.php | 59 ++--- .../Search/Request/RequestCleaner.php | 78 +++++-- Utils/CategoryMerchandising.php | 58 +++++ etc/di.xml | 4 +- 9 files changed, 451 insertions(+), 77 deletions(-) create mode 100644 Model/Service/Recommendation/StateAwareCategoryService.php create mode 100644 Model/Service/Recommendation/StateAwareCategoryServiceInterface.php create mode 100644 Utils/CategoryMerchandising.php diff --git a/Model/Service/Recommendation/Category.php b/Model/Service/Recommendation/Category.php index bbe8980e..b4d5baa7 100644 --- a/Model/Service/Recommendation/Category.php +++ b/Model/Service/Recommendation/Category.php @@ -69,8 +69,11 @@ public function __construct( * @param $category * @param int $pageNumber * @param int $limit + * @param bool $previewMode * @return CategoryMerchandisingResult * @throws NostoException + * @throws \Nosto\Request\Http\Exception\AbstractHttpException + * @throws \Nosto\Request\Http\Exception\HttpResponseException */ public function getPersonalisationResult( NostoAccount $nostoAccount, @@ -78,14 +81,13 @@ public function getPersonalisationResult( $nostoCustomerId, $category, $pageNumber, - $limit = self::MAX_PRODUCT_AMOUNT + $limit, + $previewMode = false ) { - $limit = self::MAX_PRODUCT_AMOUNT < $limit ? self::MAX_PRODUCT_AMOUNT : $limit; $featureAccess = new FeatureAccess($nostoAccount); if (!$featureAccess->canUseGraphql()) { throw new NostoException('Missing Nosto API_APPS token'); } - $previewMode = (bool)$this->cookieManager->getCookie(self::NOSTO_PREVIEW_COOKIE); $categoryMerchandising = new CategoryMerchandising( $nostoAccount, $nostoCustomerId, @@ -98,7 +100,6 @@ public function getPersonalisationResult( $previewMode, $limit ); - return $categoryMerchandising->execute(); } } diff --git a/Model/Service/Recommendation/StateAwareCategoryService.php b/Model/Service/Recommendation/StateAwareCategoryService.php new file mode 100644 index 00000000..dc52dd88 --- /dev/null +++ b/Model/Service/Recommendation/StateAwareCategoryService.php @@ -0,0 +1,214 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Model\Service\Recommendation; + +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Registry; +use Magento\Framework\Stdlib\CookieManagerInterface; +use Magento\LayeredNavigation\Block\Navigation\State; +use Magento\Store\Api\Data\StoreInterface; +use Magento\Store\Model\StoreManagerInterface; +use Nosto\Cmp\Model\Filter\FilterBuilder; +use Nosto\NostoException; +use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; +use Nosto\Service\FeatureAccess; +use Nosto\Tagging\Helper\Account; +use Nosto\Tagging\Logger\Logger; +use Nosto\Tagging\Model\Customer\Customer as NostoCustomer; +use Nosto\Tagging\Model\Service\Product\Category\DefaultCategoryService as CategoryBuilder; + +class StateAwareCategoryService implements StateAwareCategoryServiceInterface +{ + const NOSTO_PREVIEW_COOKIE = 'nostopreview'; + const MAX_PRODUCT_AMOUNT = 100; + + /** + * @var Category + */ + private $categoryService; + + /** + * @var CookieManagerInterface + */ + private $cookieManager; + + /** + * @var State + */ + private $state; + + /** + * @var FilterBuilder + */ + private $filterBuilder; + + /** + * @var Account + */ + private $accountHelper; + + /** + * @var Logger + */ + private $logger; + + /** + * @var StoreManagerInterface + */ + private $storeManager; + + /** + * @var Registry + */ + private $registry; + + /** + * @var Builder + */ + private $categoryBuilder; + + /** + * @var CategoryMerchandisingResult|null + */ + private $lastResult = null; + + /** + * Category constructor. + * @param CookieManagerInterface $cookieManager + * @param Category $categoryService + * @param State $state + * @param FilterBuilder $filterBuilder + * @param Account $nostoHelperAccount + * @param StoreManagerInterface $storeManager + * @param Registry $registry + * @param CategoryBuilder $categoryBuilder + * @param Logger $logger + */ + public function __construct( + CookieManagerInterface $cookieManager, + Category $categoryService, + State $state, + FilterBuilder $filterBuilder, + Account $nostoHelperAccount, + StoreManagerInterface $storeManager, + Registry $registry, + CategoryBuilder $categoryBuilder, + Logger $logger + ) { + $this->cookieManager = $cookieManager; + $this->categoryService = $categoryService; + $this->state = $state; + $this->filterBuilder = $filterBuilder; + $this->cookieManager = $cookieManager; + $this->accountHelper = $nostoHelperAccount; + $this->logger = $logger; + $this->storeManager = $storeManager; + $this->registry = $registry; + $this->categoryBuilder = $categoryBuilder; + } + + /** + * @inheritDoc + * @throws NostoException + */ + public function getPersonalisationResult( + $pageNumber, + $limit + ): ?CategoryMerchandisingResult { + //TODO - add the store as a parameter or get it from the state / store manager + // build filters & call the unredlying layer + // remember to tag this as 3.0.0 + try { + $store = $this->storeManager->getStore(); + } catch (NoSuchEntityException $e) { + $this->logger->exception($e); + return null; + } + $category = $this->getCurrentCategoryString($store); + $nostoAccount = $this->accountHelper->findAccount($store); + $featureAccess = new FeatureAccess($nostoAccount); + if (!$featureAccess->canUseGraphql()) { + throw new NostoException('Missing Nosto API_APPS token'); + } + $nostoAccount = $this->accountHelper->findAccount($store); + if ($nostoAccount === null) { + throw new NostoException('Account cannot be null'); + } + // Build filters + $this->filterBuilder->init($store); + try { + $this->filterBuilder->buildFromSelectedFilters( + $this->state->getActiveFilters() + ); + } catch (LocalizedException $e) { + $this->logger->exception($e); + } + + $previewMode = (bool)$this->cookieManager->getCookie(self::NOSTO_PREVIEW_COOKIE); + $this->lastResult = $this->categoryService->getPersonalisationResult( + $nostoAccount, + $this->filterBuilder, + $this->cookieManager->getCookie(NostoCustomer::COOKIE_NAME), + $category, + $pageNumber, + $limit, + $previewMode + ); + return $this->lastResult; + } + + /** + * @inheritDoc + */ + public function getLastResult(): ?CategoryMerchandisingResult + { + return $this->lastResult; + } + + /** + * Get the current category + * @param StoreInterface $store + * @return null|string + */ + private function getCurrentCategoryString(StoreInterface $store) + { + /** @noinspection PhpDeprecationInspection */ + $category = $this->registry->registry('current_category'); //@phan-suppress-current-line PhanDeprecatedFunction + return $this->categoryBuilder->getCategory($category, $store); + } +} diff --git a/Model/Service/Recommendation/StateAwareCategoryServiceInterface.php b/Model/Service/Recommendation/StateAwareCategoryServiceInterface.php new file mode 100644 index 00000000..7536b469 --- /dev/null +++ b/Model/Service/Recommendation/StateAwareCategoryServiceInterface.php @@ -0,0 +1,54 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Model\Service\Recommendation; + +use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; + +interface StateAwareCategoryServiceInterface +{ + /** + * @param int $pageNumber + * @param int $limit + * @return CategoryMerchandisingResult + */ + public function getPersonalisationResult($pageNumber, $limit): ?CategoryMerchandisingResult; + + /** + * @return CategoryMerchandisingResult|null + */ + public function getLastResult(): ?CategoryMerchandisingResult; +} diff --git a/Plugin/Api/Search/SearchResultSorter.php b/Plugin/Api/Search/SearchResultSorter.php index 0acfdf01..76246471 100644 --- a/Plugin/Api/Search/SearchResultSorter.php +++ b/Plugin/Api/Search/SearchResultSorter.php @@ -38,10 +38,25 @@ use Magento\Framework\Api\Search\Document; use Magento\Framework\Api\Search\SearchResult; -use Nosto\Cmp\Plugin\Framework\Search\Request\RequestCleaner; +use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryServiceInterface; +use Nosto\Cmp\Utils\CategoryMerchandising; class SearchResultSorter { + /** + * @var StateAwareCategoryServiceInterface + */ + private $categoryService; + + /** + * SearchResultSorter constructor. + * @param StateAwareCategoryServiceInterface $categoryService + */ + public function __construct( + StateAwareCategoryServiceInterface $categoryService + ) { + $this->categoryService = $categoryService; + } /** * @param SearchResult $subject @@ -50,7 +65,6 @@ class SearchResultSorter */ public function beforeSetItems(SearchResult $subject, $result) { - $cmpSort = $this->getCmpSort(); if (empty($cmpSort)) { return [$result]; @@ -62,6 +76,7 @@ public function beforeSetItems(SearchResult $subject, $result) $sorted[] = $document; } } + $subject->setTotalCount($this->getTotalPrimaryCount()); return [$sorted]; } @@ -79,13 +94,32 @@ private function findDocumentByProductId(array &$result, $productId) } return null; } + /** * Returns the product ids sorted by Nosto * @return int[] */ private function getCmpSort() { - // TODO - use the service - return RequestCleaner::$nostoTmpSort; + $categoryMerchandisingResult = $this->categoryService->getLastResult(); + if ($categoryMerchandisingResult !== null) { + return CategoryMerchandising::parseProductIds( + $categoryMerchandisingResult + ); + } + return null; + } + + /** + * Returns the product ids sorted by Nosto + * @return int|null + */ + private function getTotalPrimaryCount() + { + $categoryMerchandisingResult = $this->categoryService->getLastResult(); + if ($categoryMerchandisingResult !== null) { + return $categoryMerchandisingResult->getTotalPrimaryCount(); + } + return null; } -} \ No newline at end of file +} diff --git a/Plugin/Catalog/Block/Pager.php b/Plugin/Catalog/Block/Pager.php index 92c2dc6b..bee81797 100644 --- a/Plugin/Catalog/Block/Pager.php +++ b/Plugin/Catalog/Block/Pager.php @@ -36,9 +36,9 @@ namespace Nosto\Cmp\Plugin\Catalog\Block; -use Magento\Theme\Block\Html\Pager as MagentoPager; - use Magento\Backend\Block\Template\Context; + +use Magento\Theme\Block\Html\Pager as MagentoPager; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; use Nosto\Tagging\Helper\Account as NostoHelperAccount; use Nosto\Tagging\Logger\Logger as NostoLogger; @@ -69,7 +69,7 @@ public function __construct( * @param $param * @return bool */ - public function afterIsPageCurrent( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + public function afterIsPageCurrent(// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter MagentoPager $pager, $result, $param @@ -127,7 +127,7 @@ public function afterGetFramePages(MagentoPager $pager, $result) * @param $result * @return bool */ - public function afterIsFirstPage( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + public function afterIsFirstPage(// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter MagentoPager $pager, $result ) { diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index 8389a089..f47df9bf 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -51,6 +51,9 @@ use Magento\Store\Model\Store; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; use Nosto\Cmp\Helper\SearchEngine; +use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryService; +use Nosto\Cmp\Utils\CategoryMerchandising; +use Nosto\Cmp\Utils\CategoryMerchandisingResult as CategoryMerchandisingResultUtil; use Nosto\Cmp\Utils\Debug\Product as ProductDebug; use Nosto\Cmp\Utils\Debug\ServerTiming; use Nosto\Cmp\Model\Service\Recommendation\Category as CategoryRecommendation; @@ -81,8 +84,8 @@ class Toolbar extends AbstractBlock /** @var State */ private $state; - /** @var CategoryRecommendation */ - private $categoryRecommendation; + /** @var StateAwareCategoryService */ + private $categoryService; /** @var NostoFilterBuilder */ private $nostoFilterBuilder; @@ -98,7 +101,7 @@ class Toolbar extends AbstractBlock * @param NostoCmpHelperData $nostoCmpHelperData * @param NostoHelperAccount $nostoHelperAccount * @param CategoryBuilder $builder - * @param CategoryRecommendation $categoryRecommendation + * @param StateAwareCategoryService $categoryService * @param CookieManagerInterface $cookieManager * @param ParameterResolverInterface $parameterResolver * @param NostoLogger $logger @@ -112,7 +115,7 @@ public function __construct( NostoCmpHelperData $nostoCmpHelperData, NostoHelperAccount $nostoHelperAccount, CategoryBuilder $builder, - CategoryRecommendation $categoryRecommendation, + StateAwareCategoryService $categoryService, CookieManagerInterface $cookieManager, ParameterResolverInterface $parameterResolver, NostoLogger $logger, @@ -124,7 +127,7 @@ public function __construct( $this->categoryBuilder = $builder; $this->storeManager = $context->getStoreManager(); $this->cookieManager = $cookieManager; - $this->categoryRecommendation = $categoryRecommendation; + $this->categoryService = $categoryService; $this->nostoFilterBuilder = $nostoFilterBuilder; $this->registry = $registry; $this->state = $state; @@ -194,47 +197,17 @@ public function afterSetCollection( // phpcs:ignore EcgM2.Plugins.Plugin.PluginW * @param Store $store * @return CategoryMerchandisingResult * @throws NostoException - * @throws LocalizedException */ private function getCmpResult(Store $store) { - $nostoAccount = $this->nostoHelperAccount->findAccount($store); - if ($nostoAccount === null) { - throw new NostoException('Account cannot be null'); - } - - // Build filters - $this->nostoFilterBuilder->init($store); - $this->nostoFilterBuilder->buildFromSelectedFilters( - $this->state->getActiveFilters() - ); - return ServerTiming::getInstance()->instrument( - function () use ($nostoAccount, $store) { - return $this->categoryRecommendation->getPersonalisationResult( - $nostoAccount, - $this->nostoFilterBuilder, - $this->cookieManager->getCookie(NostoCustomer::COOKIE_NAME), - $this->getCurrentCategoryString($store), - $this->getCurrentPageNumber() - 1, - $this->getLimit() - ); - }, - self::TIME_PROF_GRAPHQL_QUERY + $this->categoryService->getPersonalisationResult( + $this->getCurrentPageNumber() - 1, + $this->getLimit() + ) ); } - /** - * Get the current category - * @return null|string - */ - private function getCurrentCategoryString(Store $store) - { - /** @noinspection PhpDeprecationInspection */ - $category = $this->registry->registry('current_category'); //@phan-suppress-current-line PhanDeprecatedFunction - return $this->categoryBuilder->getCategory($category, $store); - } - /** * @param ProductCollection $collection * @param array $nostoProductIds @@ -268,17 +241,11 @@ private function whereInProductIds(ProductCollection $collection, array $nostoPr */ private function parseProductIds(CategoryMerchandisingResult $result) { - $productIds = []; try { - foreach ($result->getResultSet() as $item) { - if ($item->getProductId() && is_numeric($item->getProductId())) { - $productIds[] = $item->getProductId(); - } - } + return CategoryMerchandising::parseProductIds($result); } catch (Exception $e) { $this->logger->exception($e); } - return $productIds; } diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index b6230afc..7afeb07b 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -41,7 +41,10 @@ use Magento\TestFramework\Store\StoreManager; use Nosto\Cmp\Helper\SearchEngine; use Nosto\Cmp\Model\Filter\FilterBuilder; +use Nosto\Cmp\Model\Service\Recommendation\Category; +use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryServiceInterface; use Nosto\Cmp\Plugin\Catalog\Block\ParameterResolverInterface; +use Nosto\Cmp\Utils\CategoryMerchandising; use Nosto\Cmp\Utils\Search; use Nosto\Tagging\Helper\Account as NostoHelperAccount; use Nosto\Tagging\Logger\Logger; @@ -54,6 +57,8 @@ class RequestCleaner const KEY_QUERIES = 'queries'; const KEY_FILTERS = 'filters'; const KEY_CMP = 'nosto_cmp_id_search'; + const KEY_RESULTS_FROM = 'from'; + const KEY_RESULT_SIZE = 'size'; public static $nostoTmpSort = [5, 11, 401, 2023, 1]; @@ -87,12 +92,18 @@ class RequestCleaner */ private $filterBuilder; + /** + * @var Category + */ + private $categoryService; + /** * @param ParameterResolverInterface $parameterResolver * @param SearchEngine $searchEngineHelper * @param StoreManagerInterface $storeManager * @param NostoHelperAccount $nostoHelperAccount * @param FilterBuilder $filterBuilder + * @param StateAwareCategoryServiceInterface $categoryService * @param Logger $logger */ public function __construct( @@ -101,6 +112,7 @@ public function __construct( StoreManagerInterface $storeManager, NostoHelperAccount $nostoHelperAccount, FilterBuilder $filterBuilder, + StateAwareCategoryServiceInterface $categoryService, Logger $logger ) { $this->parameterResolver = $parameterResolver; @@ -109,6 +121,7 @@ public function __construct( $this->storeManager = $storeManager; $this->accountHelper = $nostoHelperAccount; $this->filterBuilder = $filterBuilder; + $this->categoryService = $categoryService; } /** @@ -137,10 +150,24 @@ public function afterClean(Cleaner $cleaner, array $requestData) ); return $requestData; } - $origData = $requestData; //TODO - remove me, only for debugging purposes + $productIds = $this->getCmpProductIds( + $this->parsePageNumber($requestData), + $this->parseLimit($requestData) + ); + $this->cleanUpCmpSort($requestData, $productIds); + if (empty($productIds)) { + $this->logger->debugWithSource( + 'Nosto did not return products for the request', + $requestData, + $this + ); + return $requestData; + } $this->resetRequestData($requestData); - $this->applyCmpFilter($requestData, $this->getCmpProductIds()); - $this->cleanUpCmpSort($requestData, $this->getCmpProductIds()); + $this->applyCmpFilter( + $requestData, + $productIds + ); } catch (\Exception $e) { $this->logger->debugWithSource( 'Failed to apply CMP - see exception log(s) for datails', @@ -153,7 +180,6 @@ public function afterClean(Cleaner $cleaner, array $requestData) } } - /** * Removes the Nosto sorting key as it's not indexed * @@ -174,7 +200,7 @@ private function cleanUpCmpSort(array &$requestData, $productIds) private function applyCmpFilter(array &$requestData, array $productIds) { $requestData[self::KEY_QUERIES][self::KEY_BIND_TO_QUERY]['queryReference'][] = [ - 'clause' =>'must', + 'clause' => 'must', 'ref' => 'nosto_cmp_id_search' ]; $requestData[self::KEY_QUERIES][self::KEY_CMP] = [ @@ -206,17 +232,40 @@ private function applyCmpFilter(array &$requestData, array $productIds) } /** - * @return int[] + * @param array $requestData + * @return int + */ + private function parsePageNumber(array $requestData) + { + return $requestData[self::KEY_RESULTS_FROM]; + } + + /** + * @param array $requestData + * @return int */ - private function getCmpProductIds() + private function parseLimit(array $requestData) { + return $requestData[self::KEY_RESULT_SIZE]; + } - // TODO - // - inject CMP service - // - build the filters - // - fetch the product ids from Nosto - // - pagination? - return self::$nostoTmpSort; + /** + * @param $pageNum + * @param $limit + * @return int[] + */ + private function getCmpProductIds($pageNum, $limit) + { + try { + $res = $this->categoryService->getPersonalisationResult( + $pageNum, + $limit + ); + return $res ? CategoryMerchandising::parseProductIds($res) : null; + } catch (\Exception $e) { + $this->logger->exception($e); + return null; + } } /** @@ -258,5 +307,4 @@ private function getProductIdField() return self::KEY_ES_PRODUCT_ID; } } - -} \ No newline at end of file +} diff --git a/Utils/CategoryMerchandising.php b/Utils/CategoryMerchandising.php new file mode 100644 index 00000000..0b4ecf7f --- /dev/null +++ b/Utils/CategoryMerchandising.php @@ -0,0 +1,58 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Utils; + + +use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; + +class CategoryMerchandising +{ + /** + * @param CategoryMerchandisingResult $result + * @return array + */ + public static function parseProductIds(CategoryMerchandisingResult $result) + { + $productIds = []; + foreach ($result->getResultSet() as $item) { + if ($item->getProductId() && is_numeric($item->getProductId())) { + $productIds[] = $item->getProductId(); + } + } + return $productIds; + } +} \ No newline at end of file diff --git a/etc/di.xml b/etc/di.xml index 50515ca9..c7f81e86 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -36,6 +36,7 @@ + @@ -51,9 +52,6 @@ - - - From 1ddb88db1472aaf64ca7d88bebae30c5221dbce6 Mon Sep 17 00:00:00 2001 From: Olsi Qose Date: Tue, 8 Sep 2020 17:37:04 +0300 Subject: [PATCH 20/35] Pass closure and name to instrument method --- Plugin/Catalog/Block/Toolbar.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index f47df9bf..ff4934aa 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -201,10 +201,13 @@ public function afterSetCollection( // phpcs:ignore EcgM2.Plugins.Plugin.PluginW private function getCmpResult(Store $store) { return ServerTiming::getInstance()->instrument( - $this->categoryService->getPersonalisationResult( - $this->getCurrentPageNumber() - 1, - $this->getLimit() - ) + function () { + $this->categoryService->getPersonalisationResult( + $this->getCurrentPageNumber() - 1, + $this->getLimit() + ); + }, + self::TIME_PROF_GRAPHQL_QUERY ); } From 99b6783a1ea7f8d31d9d0801eb30d9d2e9f08044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Wed, 9 Sep 2020 12:22:09 +0300 Subject: [PATCH 21/35] Fix the pagination when using ES search engine and make Toolbar also to use the StateAwareCategoryService --- Model/Service/Recommendation/Category.php | 6 +- .../StateAwareCategoryService.php | 51 +++++++++++-- Plugin/Catalog/Block/AbstractBlock.php | 73 ++++++++----------- Plugin/Catalog/Block/Pager.php | 12 ++- Plugin/Catalog/Block/Toolbar.php | 58 +++++---------- .../Search/Request/RequestCleaner.php | 13 +++- Utils/CategoryMerchandising.php | 3 +- composer.json | 2 +- 8 files changed, 119 insertions(+), 99 deletions(-) diff --git a/Model/Service/Recommendation/Category.php b/Model/Service/Recommendation/Category.php index b4d5baa7..1f9d1183 100644 --- a/Model/Service/Recommendation/Category.php +++ b/Model/Service/Recommendation/Category.php @@ -38,6 +38,8 @@ use Nosto\Model\Signup\Account as NostoAccount; use Nosto\Operation\AbstractGraphQLOperation; +use Nosto\Request\Http\Exception\AbstractHttpException; +use Nosto\Request\Http\Exception\HttpResponseException; use Nosto\Service\FeatureAccess; use Nosto\Operation\Recommendation\CategoryMerchandising; use Magento\Framework\Stdlib\CookieManagerInterface; @@ -72,8 +74,8 @@ public function __construct( * @param bool $previewMode * @return CategoryMerchandisingResult * @throws NostoException - * @throws \Nosto\Request\Http\Exception\AbstractHttpException - * @throws \Nosto\Request\Http\Exception\HttpResponseException + * @throws AbstractHttpException + * @throws HttpResponseException */ public function getPersonalisationResult( NostoAccount $nostoAccount, diff --git a/Model/Service/Recommendation/StateAwareCategoryService.php b/Model/Service/Recommendation/StateAwareCategoryService.php index dc52dd88..b03ba4e9 100644 --- a/Model/Service/Recommendation/StateAwareCategoryService.php +++ b/Model/Service/Recommendation/StateAwareCategoryService.php @@ -44,6 +44,7 @@ use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\StoreManagerInterface; use Nosto\Cmp\Model\Filter\FilterBuilder; +use Nosto\Cmp\Utils\Debug\ServerTiming; use Nosto\NostoException; use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; use Nosto\Service\FeatureAccess; @@ -56,6 +57,7 @@ class StateAwareCategoryService implements StateAwareCategoryServiceInterface { const NOSTO_PREVIEW_COOKIE = 'nostopreview'; const MAX_PRODUCT_AMOUNT = 100; + const TIME_PROF_GRAPHQL_QUERY = 'cmp_graphql_query'; /** * @var Category @@ -107,6 +109,16 @@ class StateAwareCategoryService implements StateAwareCategoryServiceInterface */ private $lastResult = null; + /** + * @var int + */ + private $lastUsedLimit; + + /** + * @var int + */ + private $lastUsedPage; + /** * Category constructor. * @param CookieManagerInterface $cookieManager @@ -180,15 +192,22 @@ public function getPersonalisationResult( } $previewMode = (bool)$this->cookieManager->getCookie(self::NOSTO_PREVIEW_COOKIE); - $this->lastResult = $this->categoryService->getPersonalisationResult( - $nostoAccount, - $this->filterBuilder, - $this->cookieManager->getCookie(NostoCustomer::COOKIE_NAME), - $category, - $pageNumber, - $limit, - $previewMode + $this->lastResult = ServerTiming::getInstance()->instrument( + function () use ($nostoAccount, $previewMode, $category, $pageNumber, $limit) { + return $this->categoryService->getPersonalisationResult( + $nostoAccount, + $this->filterBuilder, + $this->cookieManager->getCookie(NostoCustomer::COOKIE_NAME), + $category, + $pageNumber, + $limit, + $previewMode + ); + }, + self::TIME_PROF_GRAPHQL_QUERY ); + $this->lastUsedLimit = $limit; + $this->lastUsedPage = $pageNumber; return $this->lastResult; } @@ -211,4 +230,20 @@ private function getCurrentCategoryString(StoreInterface $store) $category = $this->registry->registry('current_category'); //@phan-suppress-current-line PhanDeprecatedFunction return $this->categoryBuilder->getCategory($category, $store); } + + /** + * @return int + */ + public function getLastUsedLimit(): int + { + return $this->lastUsedLimit; + } + + /** + * @return int + */ + public function getLastUsedPage(): int + { + return $this->lastUsedPage; + } } diff --git a/Plugin/Catalog/Block/AbstractBlock.php b/Plugin/Catalog/Block/AbstractBlock.php index 44205432..175efae0 100644 --- a/Plugin/Catalog/Block/AbstractBlock.php +++ b/Plugin/Catalog/Block/AbstractBlock.php @@ -38,12 +38,14 @@ use Magento\Backend\Block\Template\Context; use Magento\Catalog\Block\Product\ProductList\Toolbar as MagentoToolbar; -use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\View\Element\Template; -use Magento\Theme\Block\Html\Pager as MagentoPager; +use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\Theme\Block\Html\Pager as MagentoPager; use Nosto\Cmp\Helper\CategorySorting as NostoHelperSorting; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; +use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryService; +use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryServiceInterface; use Nosto\Tagging\Helper\Account as NostoHelperAccount; use Nosto\Tagging\Logger\Logger as NostoLogger; @@ -79,12 +81,18 @@ abstract class AbstractBlock extends Template /** @var bool */ public static $catalogTakeover; + /** + * @var StateAwareCategoryService + */ + private $categoryService; + /** * AbstractBlock constructor. * @param Context $context * @param ParameterResolverInterface $parameterResolver * @param NostoCmpHelperData $nostoCmpHelperData * @param NostoHelperAccount $nostoHelperAccount + * @param StateAwareCategoryServiceInterface $categoryService * @param NostoLogger $logger */ public function __construct( @@ -92,8 +100,10 @@ public function __construct( ParameterResolverInterface $parameterResolver, NostoCmpHelperData $nostoCmpHelperData, NostoHelperAccount $nostoHelperAccount, + StateAwareCategoryServiceInterface $categoryService, NostoLogger $logger ) { + $this->categoryService = $categoryService; $this->paramResolver = $parameterResolver; $this->nostoCmpHelperData = $nostoCmpHelperData; $this->nostoHelperAccount = $nostoHelperAccount; @@ -106,16 +116,11 @@ public function __construct( * Checks if current sorting order is Nosto's `Personalized for you` * and category sorting is enabled * + * @param StoreInterface $store * @return bool */ - public function isCmpCurrentSortOrder() + public function isCmpCurrentSortOrder(StoreInterface $store) { - try { - $store = $this->storeManager->getStore(); - } catch (NoSuchEntityException $e) { - $this->logger->info('Cannot get store'); - return false; - } $currentOrder = $this->getCurrentOrder(); if ($currentOrder === null) { return false; @@ -138,23 +143,12 @@ public function isCmpCurrentSortOrder() */ public function isCmpTakingOverCatalog() { - if (self::$catalogTakeover === null) { - self::$catalogTakeover = $this->isCmpResult(); - } - return self::$catalogTakeover; - } - - /** - * @return bool - */ - private function isCmpResult() - { - if (!$this->isCmpCurrentSortOrder() || - (self::$totalProducts === 0 || self::$totalProducts === null) - ) { - return false; + $categoryMerchandisingResult = $this->getCategoryService()->getLastResult(); + if ($categoryMerchandisingResult !== null + && !empty($categoryMerchandisingResult->getTrackingCode()) + ) { + return true; } - return true; } /** @@ -168,20 +162,15 @@ private function getCurrentOrder() return self::$currentOrder; } - /** - * @param int $totalProducts - */ - public function setTotalProducts($totalProducts) - { - self::$totalProducts = $totalProducts; - } - /** * @return int */ public function getTotalProducts() { - return self::$totalProducts; + if ($this->getCategoryService()->getLastResult() !== null) { + return $this->getCategoryService()->getLastResult()->getTotalPrimaryCount(); + } + return null; } /** @@ -253,7 +242,7 @@ public function getLastPageNumber() if ($this->lastPageNumber !== null) { return $this->lastPageNumber; } - $this->lastPageNumber = (int) ceil(self::$totalProducts/self::$limit); + $this->lastPageNumber = (int) ceil($this->getTotalProducts() / $this->getLimit()); return $this->lastPageNumber; } @@ -262,22 +251,22 @@ public function getLastPageNumber() */ public function getLimit() { - return self::$limit; + return $this->getCategoryService()->getLastUsedLimit(); } /** - * @param int $limit + * @return int */ - public function setLimit(int $limit) + public function getCurrentPageNumber() { - self::$limit = $limit; + return $this->paramResolver->getCurrentPage(); } /** - * @return int + * @return StateAwareCategoryService */ - public function getCurrentPageNumber() + public function getCategoryService(): StateAwareCategoryService { - return $this->paramResolver->getCurrentPage(); + return $this->categoryService; } } diff --git a/Plugin/Catalog/Block/Pager.php b/Plugin/Catalog/Block/Pager.php index bee81797..94f681a1 100644 --- a/Plugin/Catalog/Block/Pager.php +++ b/Plugin/Catalog/Block/Pager.php @@ -40,6 +40,7 @@ use Magento\Theme\Block\Html\Pager as MagentoPager; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; +use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryServiceInterface; use Nosto\Tagging\Helper\Account as NostoHelperAccount; use Nosto\Tagging\Logger\Logger as NostoLogger; @@ -51,6 +52,7 @@ class Pager extends AbstractBlock * @param NostoCmpHelperData $nostoCmpHelperData * @param NostoHelperAccount $nostoHelperAccount * @param ParameterResolverInterface $parameterResolver + * @param StateAwareCategoryServiceInterface $categoryService * @param NostoLogger $logger */ public function __construct( @@ -58,9 +60,17 @@ public function __construct( NostoCmpHelperData $nostoCmpHelperData, NostoHelperAccount $nostoHelperAccount, ParameterResolverInterface $parameterResolver, + StateAwareCategoryServiceInterface $categoryService, NostoLogger $logger ) { - parent::__construct($context, $parameterResolver, $nostoCmpHelperData, $nostoHelperAccount, $logger); + parent::__construct( + $context, + $parameterResolver, + $nostoCmpHelperData, + $nostoHelperAccount, + $categoryService, + $logger + ); } /** diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index f47df9bf..21d6d189 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -43,7 +43,6 @@ use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; use Magento\Framework\DB\Select; use Magento\Framework\Exception\NoSuchEntityException; -use Magento\Framework\Exception\LocalizedException; use /** @noinspection PhpDeprecationInspection */ Magento\Framework\Registry; use Magento\Framework\Stdlib\CookieManagerInterface; @@ -51,26 +50,21 @@ use Magento\Store\Model\Store; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; use Nosto\Cmp\Helper\SearchEngine; +use Nosto\Cmp\Model\Filter\FilterBuilder as NostoFilterBuilder; use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryService; -use Nosto\Cmp\Utils\CategoryMerchandising; -use Nosto\Cmp\Utils\CategoryMerchandisingResult as CategoryMerchandisingResultUtil; -use Nosto\Cmp\Utils\Debug\Product as ProductDebug; -use Nosto\Cmp\Utils\Debug\ServerTiming; -use Nosto\Cmp\Model\Service\Recommendation\Category as CategoryRecommendation; use Nosto\Cmp\Plugin\Catalog\Model\Product as NostoProductPlugin; +use Nosto\Cmp\Utils\CategoryMerchandising as CategoryMerchandisingUtil; +use Nosto\Cmp\Utils\Debug\Product as ProductDebug; use Nosto\Helper\ArrayHelper as NostoHelperArray; use Nosto\NostoException; use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; use Nosto\Tagging\Helper\Account as NostoHelperAccount; use Nosto\Tagging\Logger\Logger as NostoLogger; use Nosto\Tagging\Model\Service\Product\Category\DefaultCategoryService as CategoryBuilder; -use Nosto\Tagging\Model\Customer\Customer as NostoCustomer; -use Nosto\Cmp\Model\Filter\FilterBuilder as NostoFilterBuilder; use Zend_Db_Expr; class Toolbar extends AbstractBlock { - const TIME_PROF_GRAPHQL_QUERY = 'cmp_graphql_query'; /** @var CategoryBuilder */ private $categoryBuilder; @@ -84,9 +78,6 @@ class Toolbar extends AbstractBlock /** @var State */ private $state; - /** @var StateAwareCategoryService */ - private $categoryService; - /** @var NostoFilterBuilder */ private $nostoFilterBuilder; @@ -127,12 +118,18 @@ public function __construct( $this->categoryBuilder = $builder; $this->storeManager = $context->getStoreManager(); $this->cookieManager = $cookieManager; - $this->categoryService = $categoryService; $this->nostoFilterBuilder = $nostoFilterBuilder; $this->registry = $registry; $this->state = $state; $this->searchEngineHelper = $searchEngineHelper; - parent::__construct($context, $parameterResolver, $nostoCmpHelperData, $nostoHelperAccount, $logger); + parent::__construct( + $context, + $parameterResolver, + $nostoCmpHelperData, + $nostoHelperAccount, + $categoryService, + $logger + ); } /** @@ -142,7 +139,7 @@ public function __construct( * @return MagentoToolbar * @throws NoSuchEntityException */ - public function afterSetCollection( // phpcs:ignore EcgM2.Plugins.Plugin.PluginWarning + public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWarning MagentoToolbar $subject ) { if (!$this->searchEngineHelper->isMysql()) { @@ -153,7 +150,7 @@ public function afterSetCollection( // phpcs:ignore EcgM2.Plugins.Plugin.PluginW } /* @var Store $store */ $store = $this->storeManager->getStore(); - if ($this->isCmpCurrentSortOrder()) { + if ($this->isCmpCurrentSortOrder($store)) { try { /* @var ProductCollection $subjectCollection */ $subjectCollection = $subject->getCollection(); @@ -162,14 +159,12 @@ public function afterSetCollection( // phpcs:ignore EcgM2.Plugins.Plugin.PluginW "Collection is not instanceof ProductCollection" ); } - $this->setLimit($subjectCollection->getPageSize()); $result = $this->getCmpResult($store); //@phan-suppress-current-line PhanTypeMismatchArgument //Get ids of products to order - $nostoProductIds = $this->parseProductIds($result); + $nostoProductIds = CategoryMerchandisingUtil::parseProductIds($result); if (!empty($nostoProductIds) && NostoHelperArray::onlyScalarValues($nostoProductIds) ) { - $this->setTotalProducts($result->getTotalPrimaryCount()); ProductDebug::getInstance()->setProductIds($nostoProductIds); $nostoProductIds = array_reverse($nostoProductIds); $this->sortByProductIds($subjectCollection, $nostoProductIds); @@ -194,17 +189,14 @@ public function afterSetCollection( // phpcs:ignore EcgM2.Plugins.Plugin.PluginW } /** - * @param Store $store * @return CategoryMerchandisingResult * @throws NostoException */ - private function getCmpResult(Store $store) + private function getCmpResult() { - return ServerTiming::getInstance()->instrument( - $this->categoryService->getPersonalisationResult( - $this->getCurrentPageNumber() - 1, - $this->getLimit() - ) + return $this->getCategoryService()->getPersonalisationResult( + $this->getCurrentPageNumber() - 1, + $this->getLimit() ); } @@ -235,20 +227,6 @@ private function whereInProductIds(ProductCollection $collection, array $nostoPr $select->where($zendExpression); } - /** - * @param CategoryMerchandisingResult $result - * @return array - */ - private function parseProductIds(CategoryMerchandisingResult $result) - { - try { - return CategoryMerchandising::parseProductIds($result); - } catch (Exception $e) { - $this->logger->exception($e); - } - return $productIds; - } - /** * @param ProductCollection $collection * @param array $nostoProductIds diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index 7afeb07b..19524985 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -38,7 +38,6 @@ use Magento\Framework\Search\Request\Cleaner; use Magento\Store\Model\StoreManagerInterface; -use Magento\TestFramework\Store\StoreManager; use Nosto\Cmp\Helper\SearchEngine; use Nosto\Cmp\Model\Filter\FilterBuilder; use Nosto\Cmp\Model\Service\Recommendation\Category; @@ -237,7 +236,11 @@ private function applyCmpFilter(array &$requestData, array $productIds) */ private function parsePageNumber(array $requestData) { - return $requestData[self::KEY_RESULTS_FROM]; + $from = $requestData[self::KEY_RESULTS_FROM]; + if ($from < 1) { + return 0; + } + return (int) ceil($from / $this->parseLimit($requestData)); } /** @@ -246,7 +249,7 @@ private function parsePageNumber(array $requestData) */ private function parseLimit(array $requestData) { - return $requestData[self::KEY_RESULT_SIZE]; + return (int) $requestData[self::KEY_RESULT_SIZE]; } /** @@ -292,6 +295,10 @@ private function resetRequestData(array &$requestData) } } $requestData['filters'] = []; + + // Reset also the start point since Nosto will only use product ids + $requestData[self::KEY_RESULTS_FROM] = 0; + } /** diff --git a/Utils/CategoryMerchandising.php b/Utils/CategoryMerchandising.php index 0b4ecf7f..8d649746 100644 --- a/Utils/CategoryMerchandising.php +++ b/Utils/CategoryMerchandising.php @@ -36,7 +36,6 @@ namespace Nosto\Cmp\Utils; - use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; class CategoryMerchandising @@ -55,4 +54,4 @@ public static function parseProductIds(CategoryMerchandisingResult $result) } return $productIds; } -} \ No newline at end of file +} diff --git a/composer.json b/composer.json index a2126ef8..c5d047e6 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "require": { "nosto/module-nostotagging": "^5.0.3", "nosto/php-sdk": "^5.1.1", - "php": ">=7.0.0" + "php": ">=7.1.0" }, "repositories": [ { From ac7af069d1677657974db78173ccc750f511389e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Wed, 9 Sep 2020 15:38:30 +0300 Subject: [PATCH 22/35] Add CMP parameter to product URLs when using CMP --- Helper/SearchEngine.php | 1 - .../StateAwareCategoryService.php | 2 +- Plugin/Catalog/Block/AbstractBlock.php | 24 ++++-- Plugin/Catalog/Block/ListProduct.php | 81 +++++++++++++++++++ etc/di.xml | 3 + 5 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 Plugin/Catalog/Block/ListProduct.php diff --git a/Helper/SearchEngine.php b/Helper/SearchEngine.php index 6cf81fe7..9fca519e 100644 --- a/Helper/SearchEngine.php +++ b/Helper/SearchEngine.php @@ -36,7 +36,6 @@ namespace Nosto\Cmp\Helper; -use bovigo\vfs\visitor\BaseVisitor; use Magento\Framework\Search\EngineResolverInterface; class SearchEngine diff --git a/Model/Service/Recommendation/StateAwareCategoryService.php b/Model/Service/Recommendation/StateAwareCategoryService.php index b03ba4e9..f368ee1c 100644 --- a/Model/Service/Recommendation/StateAwareCategoryService.php +++ b/Model/Service/Recommendation/StateAwareCategoryService.php @@ -100,7 +100,7 @@ class StateAwareCategoryService implements StateAwareCategoryServiceInterface private $registry; /** - * @var Builder + * @var CategoryBuilder */ private $categoryBuilder; diff --git a/Plugin/Catalog/Block/AbstractBlock.php b/Plugin/Catalog/Block/AbstractBlock.php index 175efae0..2e133cfd 100644 --- a/Plugin/Catalog/Block/AbstractBlock.php +++ b/Plugin/Catalog/Block/AbstractBlock.php @@ -52,10 +52,7 @@ abstract class AbstractBlock extends Template { /** @var int */ - public static $totalProducts; - - /** @var int */ - public static $limit; + private $limit; /** @var int */ private $lastPageNumber; @@ -242,7 +239,7 @@ public function getLastPageNumber() if ($this->lastPageNumber !== null) { return $this->lastPageNumber; } - $this->lastPageNumber = (int) ceil($this->getTotalProducts() / $this->getLimit()); + $this->lastPageNumber = (int) ceil($this->getTotalProducts() / $this->getLastUsedLimit()); return $this->lastPageNumber; } @@ -251,9 +248,16 @@ public function getLastPageNumber() */ public function getLimit() { - return $this->getCategoryService()->getLastUsedLimit(); + return $this->limit; } + /** + * @return int|null + */ + private function getLastUsedLimit() + { + return $this->getCategoryService()->getLastUsedLimit(); + } /** * @return int */ @@ -269,4 +273,12 @@ public function getCategoryService(): StateAwareCategoryService { return $this->categoryService; } + + /** + * @param int $limit + */ + public function setLimit(int $limit): void + { + $this->limit = $limit; + } } diff --git a/Plugin/Catalog/Block/ListProduct.php b/Plugin/Catalog/Block/ListProduct.php new file mode 100644 index 00000000..218dcfa0 --- /dev/null +++ b/Plugin/Catalog/Block/ListProduct.php @@ -0,0 +1,81 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Plugin\Catalog\Block; + +use Magento\Catalog\Block\Product\ListProduct as MagentoListProduct; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryServiceInterface; +use Nosto\Cmp\Plugin\Catalog\Model\Product as NostoProductPlugin; +use Nosto\Cmp\Utils\CategoryMerchandising; + +class ListProduct +{ + /** + * @var StateAwareCategoryServiceInterface + */ + private $categoryService; + + public function __construct( + StateAwareCategoryServiceInterface $categoryService + ) { + $this->categoryService = $categoryService; + } + + /** + * @param MagentoListProduct $listProduct + * @param Collection $collection + * @return Collection + */ + public function afterGetLoadedProductCollection(// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + MagentoListProduct $listProduct, + Collection $collection + ) { + if ($this->categoryService->getLastResult() == null) { + return; + } + $cmpProductIds = CategoryMerchandising::parseProductIds($this->categoryService->getLastResult()); + $collection->each(static function ($product) use ($cmpProductIds) { + /* @var Product $product */ + if (in_array($product->getId(), $cmpProductIds, true)) { + $product->setData(NostoProductPlugin::NOSTO_TRACKING_PARAMETER_NAME, true); + } + }); + + return $collection; + } +} diff --git a/etc/di.xml b/etc/di.xml index c7f81e86..678085b4 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -58,4 +58,7 @@ + + + \ No newline at end of file From 9099cb04dc71fbd1e0c5af03c002d13f25f30890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Wed, 9 Sep 2020 15:50:23 +0300 Subject: [PATCH 23/35] Fix the logic for mysql backed search engine --- Plugin/Catalog/Block/AbstractBlock.php | 21 +++---------------- Plugin/Catalog/Block/Toolbar.php | 28 +++++++++----------------- 2 files changed, 12 insertions(+), 37 deletions(-) diff --git a/Plugin/Catalog/Block/AbstractBlock.php b/Plugin/Catalog/Block/AbstractBlock.php index 2e133cfd..9201d9ae 100644 --- a/Plugin/Catalog/Block/AbstractBlock.php +++ b/Plugin/Catalog/Block/AbstractBlock.php @@ -239,25 +239,18 @@ public function getLastPageNumber() if ($this->lastPageNumber !== null) { return $this->lastPageNumber; } - $this->lastPageNumber = (int) ceil($this->getTotalProducts() / $this->getLastUsedLimit()); + $this->lastPageNumber = (int) ceil($this->getTotalProducts() / $this->getLimit()); return $this->lastPageNumber; } /** * @return int */ - public function getLimit() - { - return $this->limit; - } - - /** - * @return int|null - */ - private function getLastUsedLimit() + private function getLimit() { return $this->getCategoryService()->getLastUsedLimit(); } + /** * @return int */ @@ -273,12 +266,4 @@ public function getCategoryService(): StateAwareCategoryService { return $this->categoryService; } - - /** - * @param int $limit - */ - public function setLimit(int $limit): void - { - $this->limit = $limit; - } } diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index 21d6d189..d3505338 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -159,7 +159,10 @@ public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWa "Collection is not instanceof ProductCollection" ); } - $result = $this->getCmpResult($store); //@phan-suppress-current-line PhanTypeMismatchArgument + $result = $this->getCmpResult( + $this->getCurrentPageNumber()-1, + $subjectCollection->getPageSize() + ); //Get ids of products to order $nostoProductIds = CategoryMerchandisingUtil::parseProductIds($result); if (!empty($nostoProductIds) @@ -173,7 +176,6 @@ public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWa $subjectCollection->getSelectSql()->__toString(), ['nosto' => 'cmp'] ); - $this->addTrackParamToProduct($subjectCollection, $nostoProductIds); } else { $this->logger->info(sprintf( "CMP result is empty for category: %s", @@ -189,14 +191,16 @@ public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWa } /** + * @param int $start starting from 0 + * @param int $limit * @return CategoryMerchandisingResult * @throws NostoException */ - private function getCmpResult() + private function getCmpResult($start, $limit) { return $this->getCategoryService()->getPersonalisationResult( - $this->getCurrentPageNumber() - 1, - $this->getLimit() + $start, + $limit ); } @@ -226,18 +230,4 @@ private function whereInProductIds(ProductCollection $collection, array $nostoPr ); $select->where($zendExpression); } - - /** - * @param ProductCollection $collection - * @param array $nostoProductIds - */ - private function addTrackParamToProduct(ProductCollection $collection, array $nostoProductIds) - { - $collection->each(static function ($product) use ($nostoProductIds) { - /* @var Product $product */ - if (in_array($product->getId(), $nostoProductIds, true)) { - $product->setData(NostoProductPlugin::NOSTO_TRACKING_PARAMETER_NAME, true); - } - }); - } } From 2b060431485ea2032c9eb661ddc33ca9872b9389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Thu, 10 Sep 2020 11:53:23 +0300 Subject: [PATCH 24/35] Remove redundant class vars from Toolbar, move product id debug recording to a service, add more logging --- .../StateAwareCategoryService.php | 6 ++ Plugin/Catalog/Block/AbstractBlock.php | 32 ++++++---- Plugin/Catalog/Block/ListProduct.php | 2 +- Plugin/Catalog/Block/Toolbar.php | 59 ++++--------------- 4 files changed, 39 insertions(+), 60 deletions(-) diff --git a/Model/Service/Recommendation/StateAwareCategoryService.php b/Model/Service/Recommendation/StateAwareCategoryService.php index f368ee1c..6c0670b7 100644 --- a/Model/Service/Recommendation/StateAwareCategoryService.php +++ b/Model/Service/Recommendation/StateAwareCategoryService.php @@ -44,6 +44,8 @@ use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\StoreManagerInterface; use Nosto\Cmp\Model\Filter\FilterBuilder; +use Nosto\Cmp\Utils\CategoryMerchandising; +use Nosto\Cmp\Utils\Debug\Product as ProductDebug; use Nosto\Cmp\Utils\Debug\ServerTiming; use Nosto\NostoException; use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; @@ -208,6 +210,10 @@ function () use ($nostoAccount, $previewMode, $category, $pageNumber, $limit) { ); $this->lastUsedLimit = $limit; $this->lastUsedPage = $pageNumber; + ProductDebug::getInstance()->setProductIds( + CategoryMerchandising::parseProductIds($this->lastResult) + ); + return $this->lastResult; } diff --git a/Plugin/Catalog/Block/AbstractBlock.php b/Plugin/Catalog/Block/AbstractBlock.php index 9201d9ae..d2e4413a 100644 --- a/Plugin/Catalog/Block/AbstractBlock.php +++ b/Plugin/Catalog/Block/AbstractBlock.php @@ -51,33 +51,27 @@ abstract class AbstractBlock extends Template { - /** @var int */ - private $limit; - /** @var int */ private $lastPageNumber; /** @var ParameterResolverInterface */ - public $paramResolver; + private $paramResolver; /** @var StoreManagerInterface */ - public $storeManager; + private $storeManager; /** @var NostoCmpHelperData */ - public $nostoCmpHelperData; + private $nostoCmpHelperData; /** @var NostoHelperAccount */ - public $nostoHelperAccount; + private $nostoHelperAccount; /** @var NostoLogger */ - public $logger; + private $logger; /** @var string */ public static $currentOrder; - /** @var bool */ - public static $catalogTakeover; - /** * @var StateAwareCategoryService */ @@ -266,4 +260,20 @@ public function getCategoryService(): StateAwareCategoryService { return $this->categoryService; } + + /** + * @return StoreManagerInterface + */ + public function getStoreManager(): StoreManagerInterface + { + return $this->storeManager; + } + + /** + * @return NostoLogger + */ + public function getLogger(): NostoLogger + { + return $this->logger; + } } diff --git a/Plugin/Catalog/Block/ListProduct.php b/Plugin/Catalog/Block/ListProduct.php index 218dcfa0..b7655dad 100644 --- a/Plugin/Catalog/Block/ListProduct.php +++ b/Plugin/Catalog/Block/ListProduct.php @@ -66,7 +66,7 @@ public function afterGetLoadedProductCollection(// phpcs:ignore Generic.CodeAnal Collection $collection ) { if ($this->categoryService->getLastResult() == null) { - return; + return $collection; } $cmpProductIds = CategoryMerchandising::parseProductIds($this->categoryService->getLastResult()); $collection->each(static function ($product) use ($cmpProductIds) { diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index d3505338..b321d71a 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -39,48 +39,24 @@ use Exception; use Magento\Backend\Block\Template\Context; use Magento\Catalog\Block\Product\ProductList\Toolbar as MagentoToolbar; -use Magento\Catalog\Model\Product; use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; use Magento\Framework\DB\Select; use Magento\Framework\Exception\NoSuchEntityException; -use /** @noinspection PhpDeprecationInspection */ - Magento\Framework\Registry; -use Magento\Framework\Stdlib\CookieManagerInterface; -use Magento\LayeredNavigation\Block\Navigation\State; use Magento\Store\Model\Store; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; use Nosto\Cmp\Helper\SearchEngine; -use Nosto\Cmp\Model\Filter\FilterBuilder as NostoFilterBuilder; use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryService; -use Nosto\Cmp\Plugin\Catalog\Model\Product as NostoProductPlugin; use Nosto\Cmp\Utils\CategoryMerchandising as CategoryMerchandisingUtil; -use Nosto\Cmp\Utils\Debug\Product as ProductDebug; use Nosto\Helper\ArrayHelper as NostoHelperArray; use Nosto\NostoException; use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; use Nosto\Tagging\Helper\Account as NostoHelperAccount; use Nosto\Tagging\Logger\Logger as NostoLogger; -use Nosto\Tagging\Model\Service\Product\Category\DefaultCategoryService as CategoryBuilder; use Zend_Db_Expr; class Toolbar extends AbstractBlock { - /** @var CategoryBuilder */ - private $categoryBuilder; - - /** @var Registry */ - private $registry; - - /** @var CookieManagerInterface */ - private $cookieManager; - - /** @var State */ - private $state; - - /** @var NostoFilterBuilder */ - private $nostoFilterBuilder; - /** @var SearchEngine */ private $searchEngineHelper; @@ -91,36 +67,20 @@ class Toolbar extends AbstractBlock * @param Context $context * @param NostoCmpHelperData $nostoCmpHelperData * @param NostoHelperAccount $nostoHelperAccount - * @param CategoryBuilder $builder * @param StateAwareCategoryService $categoryService - * @param CookieManagerInterface $cookieManager * @param ParameterResolverInterface $parameterResolver * @param NostoLogger $logger - * @param NostoFilterBuilder $nostoFilterBuilder - * @param Registry $registry - * @param State $state * @param SearchEngine $searchEngineHelper */ public function __construct( Context $context, NostoCmpHelperData $nostoCmpHelperData, NostoHelperAccount $nostoHelperAccount, - CategoryBuilder $builder, StateAwareCategoryService $categoryService, - CookieManagerInterface $cookieManager, ParameterResolverInterface $parameterResolver, NostoLogger $logger, - NostoFilterBuilder $nostoFilterBuilder, - Registry $registry, - State $state, SearchEngine $searchEngineHelper ) { - $this->categoryBuilder = $builder; - $this->storeManager = $context->getStoreManager(); - $this->cookieManager = $cookieManager; - $this->nostoFilterBuilder = $nostoFilterBuilder; - $this->registry = $registry; - $this->state = $state; $this->searchEngineHelper = $searchEngineHelper; parent::__construct( $context, @@ -149,7 +109,7 @@ public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWa return $subject; } /* @var Store $store */ - $store = $this->storeManager->getStore(); + $store = $this->getStoreManager()->getStore(); if ($this->isCmpCurrentSortOrder($store)) { try { /* @var ProductCollection $subjectCollection */ @@ -168,22 +128,25 @@ public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWa if (!empty($nostoProductIds) && NostoHelperArray::onlyScalarValues($nostoProductIds) ) { - ProductDebug::getInstance()->setProductIds($nostoProductIds); $nostoProductIds = array_reverse($nostoProductIds); $this->sortByProductIds($subjectCollection, $nostoProductIds); $this->whereInProductIds($subjectCollection, $nostoProductIds); - $this->logger->debug( + $this->getLogger()->debug( $subjectCollection->getSelectSql()->__toString(), ['nosto' => 'cmp'] ); } else { - $this->logger->info(sprintf( - "CMP result is empty for category: %s", - $this->getCurrentCategoryString($store) //@phan-suppress-current-line PhanTypeMismatchArgument - )); + $this->getLogger()->debug( + sprintf( + 'Got empty CMP result from Nosto for category %s' + . ' - possibly no sequence is configured for this category', + $this->getCurrentCategoryString($store) //@phan-suppress-current-line PhanTypeMismatchArgument + ), + ['nosto' => 'cmp'] + ); } } catch (Exception $e) { - $this->logger->exception($e); + $this->getLogger()->exception($e); } } self::$isProcessed = true; From dbd85235dd25dda1315045c16358277956b10808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Thu, 10 Sep 2020 14:57:04 +0300 Subject: [PATCH 25/35] Add more logging and introduce own logger interface & implementation for the module --- Block/CategoryMapping.php | 11 +++- Logger/Logger.php | 56 ++++++++++++++++++ Logger/LoggerInterface.php | 59 +++++++++++++++++++ Model/Filter/FilterBuilder.php | 8 +-- .../StateAwareCategoryService.php | 42 +++++++------ Plugin/Catalog/Block/AbstractBlock.php | 13 ++-- Plugin/Catalog/Block/Pager.php | 6 +- Plugin/Catalog/Block/Toolbar.php | 27 +++++---- Plugin/Catalog/Model/Config.php | 14 ++--- Plugin/Catalog/Model/Sortby.php | 13 ++-- .../Search/Request/RequestCleaner.php | 36 ++++++----- etc/di.xml | 1 + 12 files changed, 209 insertions(+), 77 deletions(-) create mode 100644 Logger/Logger.php create mode 100644 Logger/LoggerInterface.php diff --git a/Block/CategoryMapping.php b/Block/CategoryMapping.php index 426a93c8..a66a055c 100644 --- a/Block/CategoryMapping.php +++ b/Block/CategoryMapping.php @@ -44,7 +44,7 @@ use Magento\Framework\View\Element\Template\Context; use Magento\Store\Model\Store; use Magento\Store\Model\StoreManagerInterface; -use Nosto\Tagging\Logger\Logger as NostoLogger; +use Nosto\Cmp\Logger\LoggerInterface; use Nosto\Tagging\Model\Service\Product\Category\DefaultCategoryService as CategoryBuilder; class CategoryMapping extends Template @@ -58,18 +58,23 @@ class CategoryMapping extends Template /** @var CategoryBuilder */ private $categoryBuilder; - /** @var NostoLogger */ + /** @var LoggerInterface */ private $logger; /** * CategoryMapping constructor. + * @param StoreManagerInterface $storeManager + * @param CollectionFactory $collectionFactory + * @param CategoryBuilder $categoryBuilder + * @param Context $context + * @param LoggerInterface $logger */ public function __construct( StoreManagerInterface $storeManager, CollectionFactory $collectionFactory, CategoryBuilder $categoryBuilder, Context $context, - NostoLogger $logger + LoggerInterface $logger ) { parent::__construct($context); $this->storeManager = $storeManager; diff --git a/Logger/Logger.php b/Logger/Logger.php new file mode 100644 index 00000000..f032c4d0 --- /dev/null +++ b/Logger/Logger.php @@ -0,0 +1,56 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Logger; + +use Nosto\Tagging\Logger\Logger as NostoLogger; + +class Logger extends NostoLogger implements LoggerInterface +{ + /** + * Logs a debug level message with given source class info + * + * @param $message + * @param object $sourceClass + * @param array $context + * @return bool + */ + public function debugCmp($message, $sourceClass, array $context = []) + { + $mergedContext = array_merge(['nosto' => 'cmp'], $context); + return $this->debugWithSource($message, $mergedContext, $sourceClass); + } +} diff --git a/Logger/LoggerInterface.php b/Logger/LoggerInterface.php new file mode 100644 index 00000000..cf9163d1 --- /dev/null +++ b/Logger/LoggerInterface.php @@ -0,0 +1,59 @@ + + * @copyright 2020 Nosto Solutions Ltd + * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause + * + */ + +namespace Nosto\Cmp\Logger; + +use Throwable; + +interface LoggerInterface +{ + /** + * Logs a debug level message with given source class info + * + * @param $message + * @param object $sourceClass + * @param array $context + * @return bool + */ + public function debugCmp($message, $sourceClass, array $context = []); + + /** + * Logs an exception and sends it to New relic if available + * @param Throwable $exception + * @return bool + */ + public function exception(Throwable $exception); +} diff --git a/Model/Filter/FilterBuilder.php b/Model/Filter/FilterBuilder.php index 9e71d7ad..36642c21 100644 --- a/Model/Filter/FilterBuilder.php +++ b/Model/Filter/FilterBuilder.php @@ -44,7 +44,7 @@ use Nosto\Operation\Recommendation\IncludeFilters; use Nosto\Operation\Recommendation\ExcludeFilters; use Nosto\Tagging\Helper\Data as NostoHelperData; -use Nosto\Tagging\Logger\Logger as NostoLogger; +use Nosto\Cmp\Logger\LoggerInterface; class FilterBuilder { @@ -60,7 +60,7 @@ class FilterBuilder /** @var string */ private $brand; - /** @var NostoLogger */ + /** @var LoggerInterface */ private $logger; /** @@ -68,13 +68,13 @@ class FilterBuilder * @param IncludeFilters $includeFilters * @param ExcludeFilters $excludeFilters * @param NostoHelperData $nostoHelperData - * @param NostoLogger $logger + * @param LoggerInterface $logger */ public function __construct( IncludeFilters $includeFilters, ExcludeFilters $excludeFilters, NostoHelperData $nostoHelperData, - NostoLogger $logger + LoggerInterface $logger ) { $this->includeFilters = $includeFilters; $this->excludeFilters = $excludeFilters; diff --git a/Model/Service/Recommendation/StateAwareCategoryService.php b/Model/Service/Recommendation/StateAwareCategoryService.php index 6c0670b7..0f96a17f 100644 --- a/Model/Service/Recommendation/StateAwareCategoryService.php +++ b/Model/Service/Recommendation/StateAwareCategoryService.php @@ -37,12 +37,12 @@ namespace Nosto\Cmp\Model\Service\Recommendation; use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Registry; use Magento\Framework\Stdlib\CookieManagerInterface; use Magento\LayeredNavigation\Block\Navigation\State; use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\StoreManagerInterface; +use Nosto\Cmp\Logger\LoggerInterface; use Nosto\Cmp\Model\Filter\FilterBuilder; use Nosto\Cmp\Utils\CategoryMerchandising; use Nosto\Cmp\Utils\Debug\Product as ProductDebug; @@ -51,7 +51,6 @@ use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; use Nosto\Service\FeatureAccess; use Nosto\Tagging\Helper\Account; -use Nosto\Tagging\Logger\Logger; use Nosto\Tagging\Model\Customer\Customer as NostoCustomer; use Nosto\Tagging\Model\Service\Product\Category\DefaultCategoryService as CategoryBuilder; @@ -87,7 +86,7 @@ class StateAwareCategoryService implements StateAwareCategoryServiceInterface private $accountHelper; /** - * @var Logger + * @var LoggerInterface */ private $logger; @@ -131,7 +130,7 @@ class StateAwareCategoryService implements StateAwareCategoryServiceInterface * @param StoreManagerInterface $storeManager * @param Registry $registry * @param CategoryBuilder $categoryBuilder - * @param Logger $logger + * @param LoggerInterface $logger */ public function __construct( CookieManagerInterface $cookieManager, @@ -142,7 +141,7 @@ public function __construct( StoreManagerInterface $storeManager, Registry $registry, CategoryBuilder $categoryBuilder, - Logger $logger + LoggerInterface $logger ) { $this->cookieManager = $cookieManager; $this->categoryService = $categoryService; @@ -159,20 +158,13 @@ public function __construct( /** * @inheritDoc * @throws NostoException + * @throws LocalizedException */ public function getPersonalisationResult( $pageNumber, $limit ): ?CategoryMerchandisingResult { - //TODO - add the store as a parameter or get it from the state / store manager - // build filters & call the unredlying layer - // remember to tag this as 3.0.0 - try { - $store = $this->storeManager->getStore(); - } catch (NoSuchEntityException $e) { - $this->logger->exception($e); - return null; - } + $store = $this->storeManager->getStore(); $category = $this->getCurrentCategoryString($store); $nostoAccount = $this->accountHelper->findAccount($store); $featureAccess = new FeatureAccess($nostoAccount); @@ -185,13 +177,9 @@ public function getPersonalisationResult( } // Build filters $this->filterBuilder->init($store); - try { - $this->filterBuilder->buildFromSelectedFilters( - $this->state->getActiveFilters() - ); - } catch (LocalizedException $e) { - $this->logger->exception($e); - } + $this->filterBuilder->buildFromSelectedFilters( + $this->state->getActiveFilters() + ); $previewMode = (bool)$this->cookieManager->getCookie(self::NOSTO_PREVIEW_COOKIE); $this->lastResult = ServerTiming::getInstance()->instrument( @@ -213,7 +201,17 @@ function () use ($nostoAccount, $previewMode, $category, $pageNumber, $limit) { ProductDebug::getInstance()->setProductIds( CategoryMerchandising::parseProductIds($this->lastResult) ); - + $this->logger->debugCmp( + sprintf( + 'Got %d / %d (total) product ids from Nosto CMP for category "%s", using page num: %d, using limit: %d', + $this->lastResult->getResultSet()->count(), + $this->lastResult->getTotalPrimaryCount(), + $category, + $pageNumber, + $limit + ), + $this + ); return $this->lastResult; } diff --git a/Plugin/Catalog/Block/AbstractBlock.php b/Plugin/Catalog/Block/AbstractBlock.php index d2e4413a..9138e72c 100644 --- a/Plugin/Catalog/Block/AbstractBlock.php +++ b/Plugin/Catalog/Block/AbstractBlock.php @@ -47,7 +47,7 @@ use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryService; use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryServiceInterface; use Nosto\Tagging\Helper\Account as NostoHelperAccount; -use Nosto\Tagging\Logger\Logger as NostoLogger; +use Nosto\Cmp\Logger\LoggerInterface; abstract class AbstractBlock extends Template { @@ -66,7 +66,7 @@ abstract class AbstractBlock extends Template /** @var NostoHelperAccount */ private $nostoHelperAccount; - /** @var NostoLogger */ + /** @var LoggerInterface */ private $logger; /** @var string */ @@ -84,7 +84,7 @@ abstract class AbstractBlock extends Template * @param NostoCmpHelperData $nostoCmpHelperData * @param NostoHelperAccount $nostoHelperAccount * @param StateAwareCategoryServiceInterface $categoryService - * @param NostoLogger $logger + * @param LoggerInterface $logger */ public function __construct( Context $context, @@ -92,7 +92,7 @@ public function __construct( NostoCmpHelperData $nostoCmpHelperData, NostoHelperAccount $nostoHelperAccount, StateAwareCategoryServiceInterface $categoryService, - NostoLogger $logger + LoggerInterface $logger ) { $this->categoryService = $categoryService; $this->paramResolver = $parameterResolver; @@ -140,6 +140,7 @@ public function isCmpTakingOverCatalog() ) { return true; } + return false; } /** @@ -270,9 +271,9 @@ public function getStoreManager(): StoreManagerInterface } /** - * @return NostoLogger + * @return LoggerInterface */ - public function getLogger(): NostoLogger + public function getLogger(): LoggerInterface { return $this->logger; } diff --git a/Plugin/Catalog/Block/Pager.php b/Plugin/Catalog/Block/Pager.php index 94f681a1..09f9facc 100644 --- a/Plugin/Catalog/Block/Pager.php +++ b/Plugin/Catalog/Block/Pager.php @@ -42,7 +42,7 @@ use Nosto\Cmp\Helper\Data as NostoCmpHelperData; use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryServiceInterface; use Nosto\Tagging\Helper\Account as NostoHelperAccount; -use Nosto\Tagging\Logger\Logger as NostoLogger; +use Nosto\Cmp\Logger\LoggerInterface; class Pager extends AbstractBlock { @@ -53,7 +53,7 @@ class Pager extends AbstractBlock * @param NostoHelperAccount $nostoHelperAccount * @param ParameterResolverInterface $parameterResolver * @param StateAwareCategoryServiceInterface $categoryService - * @param NostoLogger $logger + * @param LoggerInterface $logger */ public function __construct( Context $context, @@ -61,7 +61,7 @@ public function __construct( NostoHelperAccount $nostoHelperAccount, ParameterResolverInterface $parameterResolver, StateAwareCategoryServiceInterface $categoryService, - NostoLogger $logger + LoggerInterface $logger ) { parent::__construct( $context, diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index b321d71a..6b828843 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -51,7 +51,7 @@ use Nosto\NostoException; use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; use Nosto\Tagging\Helper\Account as NostoHelperAccount; -use Nosto\Tagging\Logger\Logger as NostoLogger; +use Nosto\Cmp\Logger\LoggerInterface; use Zend_Db_Expr; class Toolbar extends AbstractBlock @@ -69,7 +69,7 @@ class Toolbar extends AbstractBlock * @param NostoHelperAccount $nostoHelperAccount * @param StateAwareCategoryService $categoryService * @param ParameterResolverInterface $parameterResolver - * @param NostoLogger $logger + * @param LoggerInterface $logger * @param SearchEngine $searchEngineHelper */ public function __construct( @@ -78,7 +78,7 @@ public function __construct( NostoHelperAccount $nostoHelperAccount, StateAwareCategoryService $categoryService, ParameterResolverInterface $parameterResolver, - NostoLogger $logger, + LoggerInterface $logger, SearchEngine $searchEngineHelper ) { $this->searchEngineHelper = $searchEngineHelper; @@ -102,10 +102,15 @@ public function __construct( public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWarning MagentoToolbar $subject ) { - if (!$this->searchEngineHelper->isMysql()) { - return $subject; - } - if (self::$isProcessed) { + if (self::$isProcessed || !$this->searchEngineHelper->isMysql()) { + $this->getLogger()->debugCmp( + sprintf( + 'Skipping toolbar handling, processed flag is %s, search engine in use "%s"', + self::$isProcessed, + $this->searchEngineHelper->getCurrentEngine() + ), + $this + ); return $subject; } /* @var Store $store */ @@ -131,18 +136,18 @@ public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWa $nostoProductIds = array_reverse($nostoProductIds); $this->sortByProductIds($subjectCollection, $nostoProductIds); $this->whereInProductIds($subjectCollection, $nostoProductIds); - $this->getLogger()->debug( + $this->getLogger()->debugCmp( $subjectCollection->getSelectSql()->__toString(), - ['nosto' => 'cmp'] + $this ); } else { - $this->getLogger()->debug( + $this->getLogger()->debugCmp( sprintf( 'Got empty CMP result from Nosto for category %s' . ' - possibly no sequence is configured for this category', $this->getCurrentCategoryString($store) //@phan-suppress-current-line PhanTypeMismatchArgument ), - ['nosto' => 'cmp'] + $this ); } } catch (Exception $e) { diff --git a/Plugin/Catalog/Model/Config.php b/Plugin/Catalog/Model/Config.php index 80c05576..3cb6e81f 100644 --- a/Plugin/Catalog/Model/Config.php +++ b/Plugin/Catalog/Model/Config.php @@ -36,15 +36,15 @@ namespace Nosto\Cmp\Plugin\Catalog\Model; -use Magento\Catalog\Model\Config as MagentoConfig; -use Nosto\Cmp\Helper\Data as NostoCmpHelperData; -use Nosto\Cmp\Helper\CategorySorting as NostoHelperSorting; -use Nosto\Tagging\Helper\Account as NostoHelperAccount; use Magento\Backend\Block\Template\Context; -use Magento\Store\Model\StoreManagerInterface; -use Magento\Framework\View\Element\Template; +use Magento\Catalog\Model\Config as MagentoConfig; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\View\Element\Template; use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use Nosto\Cmp\Helper\CategorySorting as NostoHelperSorting; +use Nosto\Cmp\Helper\Data as NostoCmpHelperData; +use Nosto\Tagging\Helper\Account as NostoHelperAccount; class Config extends Template { @@ -85,7 +85,7 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @throws NoSuchEntityException */ - public function afterGetAttributeUsedForSortByArray( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + public function afterGetAttributeUsedForSortByArray(// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter MagentoConfig $catalogConfig, $options ) { diff --git a/Plugin/Catalog/Model/Sortby.php b/Plugin/Catalog/Model/Sortby.php index 0094c3b2..316d1718 100644 --- a/Plugin/Catalog/Model/Sortby.php +++ b/Plugin/Catalog/Model/Sortby.php @@ -34,17 +34,16 @@ * */ - namespace Nosto\Cmp\Plugin\Catalog\Model; -use Magento\Catalog\Model\Category\Attribute\Source\Sortby as MagentoSortby; -use Nosto\Cmp\Helper\CategorySorting as NostoHelperSorting; -use Nosto\Cmp\Helper\Data as NostoCmpHelperData; use Magento\Backend\Block\Template\Context; -use Magento\Store\Model\StoreManagerInterface; -use Magento\Framework\View\Element\Template; +use Magento\Catalog\Model\Category\Attribute\Source\Sortby as MagentoSortby; use Magento\Framework\App\Request\Http; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\View\Element\Template; +use Magento\Store\Model\StoreManagerInterface; +use Nosto\Cmp\Helper\CategorySorting as NostoHelperSorting; +use Nosto\Cmp\Helper\Data as NostoCmpHelperData; class Sortby extends Template { @@ -91,7 +90,7 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @suppress PhanTypeMismatchArgument */ - public function afterGetAllOptions( // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + public function afterGetAllOptions(// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter MagentoSortby $sortBy, $options ) { diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index 19524985..21a9692d 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -46,7 +46,7 @@ use Nosto\Cmp\Utils\CategoryMerchandising; use Nosto\Cmp\Utils\Search; use Nosto\Tagging\Helper\Account as NostoHelperAccount; -use Nosto\Tagging\Logger\Logger; +use Nosto\Cmp\Logger\LoggerInterface; class RequestCleaner { @@ -67,7 +67,7 @@ class RequestCleaner private $parameterResolver; /** - * @var Logger + * @var LoggerInterface */ private $logger; @@ -103,7 +103,7 @@ class RequestCleaner * @param NostoHelperAccount $nostoHelperAccount * @param FilterBuilder $filterBuilder * @param StateAwareCategoryServiceInterface $categoryService - * @param Logger $logger + * @param LoggerInterface $logger */ public function __construct( ParameterResolverInterface $parameterResolver, @@ -112,7 +112,7 @@ public function __construct( NostoHelperAccount $nostoHelperAccount, FilterBuilder $filterBuilder, StateAwareCategoryServiceInterface $categoryService, - Logger $logger + LoggerInterface $logger ) { $this->parameterResolver = $parameterResolver; $this->logger = $logger; @@ -133,32 +133,40 @@ public function __construct( public function afterClean(Cleaner $cleaner, array $requestData) { if (!Search::isNostoSorting($requestData)) { + $this->logger->debugCmp('Nosto sorting not used or not found from request data', $this, $requestData); return $requestData; } try { if (!isset($requestData[self::KEY_QUERIES][self::KEY_BIND_TO_QUERY]) || !isset($requestData[self::KEY_QUERIES][self::KEY_BIND_TO_QUERY]['queryReference']) ) { - $this->logger->debugWithSource( + $this->logger->debugCmp( sprintf( 'Could not find %s from ES request data', self::KEY_BIND_TO_QUERY ), - $requestData, - $this + $this, + $requestData ); return $requestData; } + $this->logger->debugCmp( + sprintf( + 'Using %s as search engine', + $this->searchEngineHelper->getCurrentEngine() + ), + $this + ); $productIds = $this->getCmpProductIds( $this->parsePageNumber($requestData), $this->parseLimit($requestData) ); $this->cleanUpCmpSort($requestData, $productIds); if (empty($productIds)) { - $this->logger->debugWithSource( + $this->logger->debugCmp( 'Nosto did not return products for the request', - $requestData, - $this + $this, + $requestData ); return $requestData; } @@ -168,10 +176,10 @@ public function afterClean(Cleaner $cleaner, array $requestData) $productIds ); } catch (\Exception $e) { - $this->logger->debugWithSource( - 'Failed to apply CMP - see exception log(s) for datails', - $requestData, - $this + $this->logger->debugCmp( + 'Failed to apply CMP - see exception log(s) for details', + $this, + $requestData ); $this->logger->exception($e); } finally { diff --git a/etc/di.xml b/etc/di.xml index 678085b4..38b2431b 100644 --- a/etc/di.xml +++ b/etc/di.xml @@ -37,6 +37,7 @@ + From 25224a91628a013b4e81f9edfba7740b66cc5f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Wed, 16 Sep 2020 13:24:10 +0300 Subject: [PATCH 26/35] Code style fixes --- Helper/SearchEngine.php | 1 - .../Service/Recommendation/StateAwareCategoryService.php | 7 +++---- Plugin/Catalog/Block/ParameterResolverInterface.php | 1 - Plugin/Catalog/Block/Toolbar.php | 8 +++----- Plugin/Framework/Search/Request/RequestCleaner.php | 7 +++---- 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/Helper/SearchEngine.php b/Helper/SearchEngine.php index 9fca519e..86b14fa1 100644 --- a/Helper/SearchEngine.php +++ b/Helper/SearchEngine.php @@ -53,7 +53,6 @@ class SearchEngine */ public function __construct( EngineResolverInterface $engineResolver - ) { $this->engineResolver = $engineResolver; } diff --git a/Model/Service/Recommendation/StateAwareCategoryService.php b/Model/Service/Recommendation/StateAwareCategoryService.php index 0f96a17f..89801159 100644 --- a/Model/Service/Recommendation/StateAwareCategoryService.php +++ b/Model/Service/Recommendation/StateAwareCategoryService.php @@ -167,14 +167,13 @@ public function getPersonalisationResult( $store = $this->storeManager->getStore(); $category = $this->getCurrentCategoryString($store); $nostoAccount = $this->accountHelper->findAccount($store); + if ($nostoAccount === null) { + throw new NostoException('Account cannot be null'); + } $featureAccess = new FeatureAccess($nostoAccount); if (!$featureAccess->canUseGraphql()) { throw new NostoException('Missing Nosto API_APPS token'); } - $nostoAccount = $this->accountHelper->findAccount($store); - if ($nostoAccount === null) { - throw new NostoException('Account cannot be null'); - } // Build filters $this->filterBuilder->init($store); $this->filterBuilder->buildFromSelectedFilters( diff --git a/Plugin/Catalog/Block/ParameterResolverInterface.php b/Plugin/Catalog/Block/ParameterResolverInterface.php index f3998e32..1469d28b 100644 --- a/Plugin/Catalog/Block/ParameterResolverInterface.php +++ b/Plugin/Catalog/Block/ParameterResolverInterface.php @@ -36,7 +36,6 @@ namespace Nosto\Cmp\Plugin\Catalog\Block; -//TODO - move under helper or somewhere else. It's not necessarily related to any block. interface ParameterResolverInterface { /** diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index 6b828843..e052966a 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -41,6 +41,7 @@ use Magento\Catalog\Block\Product\ProductList\Toolbar as MagentoToolbar; use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection; use Magento\Framework\DB\Select; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Store\Model\Store; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; @@ -142,11 +143,7 @@ public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWa ); } else { $this->getLogger()->debugCmp( - sprintf( - 'Got empty CMP result from Nosto for category %s' - . ' - possibly no sequence is configured for this category', - $this->getCurrentCategoryString($store) //@phan-suppress-current-line PhanTypeMismatchArgument - ), + 'Got an empty CMP result from Nosto for category', $this ); } @@ -163,6 +160,7 @@ public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWa * @param int $limit * @return CategoryMerchandisingResult * @throws NostoException + * @throws LocalizedException */ private function getCmpResult($start, $limit) { diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index 21a9692d..58c0f9a3 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -129,6 +129,7 @@ public function __construct( * @param Cleaner $cleaner * @param array $requestData * @return array + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterClean(Cleaner $cleaner, array $requestData) { @@ -161,7 +162,7 @@ public function afterClean(Cleaner $cleaner, array $requestData) $this->parsePageNumber($requestData), $this->parseLimit($requestData) ); - $this->cleanUpCmpSort($requestData, $productIds); + $this->cleanUpCmpSort($requestData); if (empty($productIds)) { $this->logger->debugCmp( 'Nosto did not return products for the request', @@ -191,9 +192,8 @@ public function afterClean(Cleaner $cleaner, array $requestData) * Removes the Nosto sorting key as it's not indexed * * @param array $requestData - * @param $productIds */ - private function cleanUpCmpSort(array &$requestData, $productIds) + private function cleanUpCmpSort(array &$requestData) { unset($requestData['sort'][Search::findNostoSortingIndex($requestData)]); } @@ -306,7 +306,6 @@ private function resetRequestData(array &$requestData) // Reset also the start point since Nosto will only use product ids $requestData[self::KEY_RESULTS_FROM] = 0; - } /** From 66ea036f8c561a335f1b20dd84ec6a20a2746d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Wed, 16 Sep 2020 13:35:48 +0300 Subject: [PATCH 27/35] Update phan config to find the Logger directory --- Plugin/Framework/Search/Request/RequestCleaner.php | 3 +-- phan.php | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index 58c0f9a3..8fc820cb 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -129,9 +129,8 @@ public function __construct( * @param Cleaner $cleaner * @param array $requestData * @return array - * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function afterClean(Cleaner $cleaner, array $requestData) + public function afterClean(Cleaner $cleaner, array $requestData) // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter { if (!Search::isNostoSorting($requestData)) { $this->logger->debugCmp('Nosto sorting not used or not found from request data', $this, $requestData); diff --git a/phan.php b/phan.php index 8c4eb677..7e70b060 100644 --- a/phan.php +++ b/phan.php @@ -48,6 +48,7 @@ 'Observer', 'Plugin', 'Utils', + 'Logger', 'vendor/nosto', 'vendor/vlucas', 'vendor/phpseclib', From d37b2bdf03840f77dd2a2115a38e8da04544dcc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Wed, 16 Sep 2020 13:46:58 +0300 Subject: [PATCH 28/35] Code style fixes --- Plugin/Framework/Search/Request/RequestCleaner.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index 8fc820cb..e72a2aa3 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -39,6 +39,7 @@ use Magento\Framework\Search\Request\Cleaner; use Magento\Store\Model\StoreManagerInterface; use Nosto\Cmp\Helper\SearchEngine; +use Nosto\Cmp\Logger\LoggerInterface; use Nosto\Cmp\Model\Filter\FilterBuilder; use Nosto\Cmp\Model\Service\Recommendation\Category; use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryServiceInterface; @@ -46,7 +47,6 @@ use Nosto\Cmp\Utils\CategoryMerchandising; use Nosto\Cmp\Utils\Search; use Nosto\Tagging\Helper\Account as NostoHelperAccount; -use Nosto\Cmp\Logger\LoggerInterface; class RequestCleaner { @@ -130,8 +130,10 @@ public function __construct( * @param array $requestData * @return array */ - public function afterClean(Cleaner $cleaner, array $requestData) // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter - { + public function afterClean( + Cleaner $cleaner, // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + array $requestData + ) { if (!Search::isNostoSorting($requestData)) { $this->logger->debugCmp('Nosto sorting not used or not found from request data', $this, $requestData); return $requestData; From 28dc299f91bb304e35fe3863e4f1502a73529c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Wed, 16 Sep 2020 16:03:25 +0300 Subject: [PATCH 29/35] Code style fixes & doc blocks --- Model/Filter/FilterBuilder.php | 13 ++++++++----- .../StateAwareCategoryService.php | 2 ++ Plugin/Api/Search/SearchResultSorter.php | 2 +- Plugin/Catalog/Block/AbstractBlock.php | 2 +- Plugin/Catalog/Block/ListProduct.php | 5 +++-- Plugin/Catalog/Block/Toolbar.php | 2 +- .../Search/Request/RequestCleaner.php | 18 +++++++++++------- 7 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Model/Filter/FilterBuilder.php b/Model/Filter/FilterBuilder.php index 36642c21..d364466c 100644 --- a/Model/Filter/FilterBuilder.php +++ b/Model/Filter/FilterBuilder.php @@ -142,16 +142,19 @@ public function mapIncludeFilter(Item $item) $value = (bool) $item->getData('value'); break; default: - $this->logger->debug(sprintf( - 'Cannot build include filter for "%s" frontend input type', - $frontendInput - )); + $this->logger->debugCmp( + sprintf( + 'Cannot build include filter for "%s" frontend input type', + $frontendInput + ), + $this + ); return; } try { $this->mapValueToFilter($filterName, $value); } catch (NostoException $e) { - $this->logger->info($e->getMessage()); + $this->logger->exception($e); } } diff --git a/Model/Service/Recommendation/StateAwareCategoryService.php b/Model/Service/Recommendation/StateAwareCategoryService.php index 89801159..62f38e91 100644 --- a/Model/Service/Recommendation/StateAwareCategoryService.php +++ b/Model/Service/Recommendation/StateAwareCategoryService.php @@ -166,6 +166,7 @@ public function getPersonalisationResult( ): ?CategoryMerchandisingResult { $store = $this->storeManager->getStore(); $category = $this->getCurrentCategoryString($store); + //@phan-suppress-next-line PhanTypeMismatchArgument $nostoAccount = $this->accountHelper->findAccount($store); if ($nostoAccount === null) { throw new NostoException('Account cannot be null'); @@ -175,6 +176,7 @@ public function getPersonalisationResult( throw new NostoException('Missing Nosto API_APPS token'); } // Build filters + //@phan-suppress-next-line PhanTypeMismatchArgument $this->filterBuilder->init($store); $this->filterBuilder->buildFromSelectedFilters( $this->state->getActiveFilters() diff --git a/Plugin/Api/Search/SearchResultSorter.php b/Plugin/Api/Search/SearchResultSorter.php index 76246471..64005f3f 100644 --- a/Plugin/Api/Search/SearchResultSorter.php +++ b/Plugin/Api/Search/SearchResultSorter.php @@ -97,7 +97,7 @@ private function findDocumentByProductId(array &$result, $productId) /** * Returns the product ids sorted by Nosto - * @return int[] + * @return int[]|null */ private function getCmpSort() { diff --git a/Plugin/Catalog/Block/AbstractBlock.php b/Plugin/Catalog/Block/AbstractBlock.php index 9138e72c..46c3883f 100644 --- a/Plugin/Catalog/Block/AbstractBlock.php +++ b/Plugin/Catalog/Block/AbstractBlock.php @@ -155,7 +155,7 @@ private function getCurrentOrder() } /** - * @return int + * @return int|null */ public function getTotalProducts() { diff --git a/Plugin/Catalog/Block/ListProduct.php b/Plugin/Catalog/Block/ListProduct.php index b7655dad..7de43459 100644 --- a/Plugin/Catalog/Block/ListProduct.php +++ b/Plugin/Catalog/Block/ListProduct.php @@ -65,10 +65,11 @@ public function afterGetLoadedProductCollection(// phpcs:ignore Generic.CodeAnal MagentoListProduct $listProduct, Collection $collection ) { - if ($this->categoryService->getLastResult() == null) { + $categoryMerchandisingResult = $this->categoryService->getLastResult(); + if ($categoryMerchandisingResult == null) { return $collection; } - $cmpProductIds = CategoryMerchandising::parseProductIds($this->categoryService->getLastResult()); + $cmpProductIds = CategoryMerchandising::parseProductIds($categoryMerchandisingResult); $collection->each(static function ($product) use ($cmpProductIds) { /* @var Product $product */ if (in_array($product->getId(), $cmpProductIds, true)) { diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index e052966a..fea93de2 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -107,7 +107,7 @@ public function afterSetCollection(// phpcs:ignore EcgM2.Plugins.Plugin.PluginWa $this->getLogger()->debugCmp( sprintf( 'Skipping toolbar handling, processed flag is %s, search engine in use "%s"', - self::$isProcessed, + (string) self::$isProcessed, $this->searchEngineHelper->getCurrentEngine() ), $this diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index e72a2aa3..b03c67f5 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -77,7 +77,7 @@ class RequestCleaner private $searchEngineHelper; /** - * @var StoreManager + * @var StoreManagerInterface */ private $storeManager; @@ -92,7 +92,7 @@ class RequestCleaner private $filterBuilder; /** - * @var Category + * @var StateAwareCategoryServiceInterface */ private $categoryService; @@ -130,12 +130,16 @@ public function __construct( * @param array $requestData * @return array */ - public function afterClean( - Cleaner $cleaner, // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + public function afterClean(// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter + Cleaner $cleaner, array $requestData ) { if (!Search::isNostoSorting($requestData)) { - $this->logger->debugCmp('Nosto sorting not used or not found from request data', $this, $requestData); + $this->logger->debugCmp( + 'Nosto sorting not used or not found from request data', + $this, + $requestData + ); return $requestData; } try { @@ -262,8 +266,8 @@ private function parseLimit(array $requestData) } /** - * @param $pageNum - * @param $limit + * @param int $pageNum + * @param int $limit * @return int[] */ private function getCmpProductIds($pageNum, $limit) From c7205c29c39df3064f2742855e6d6565c3dc40d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Wed, 16 Sep 2020 16:11:01 +0300 Subject: [PATCH 30/35] More code style fixes --- .../Recommendation/StateAwareCategoryServiceInterface.php | 2 +- Plugin/Framework/Search/Request/RequestCleaner.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Model/Service/Recommendation/StateAwareCategoryServiceInterface.php b/Model/Service/Recommendation/StateAwareCategoryServiceInterface.php index 7536b469..bfc73b84 100644 --- a/Model/Service/Recommendation/StateAwareCategoryServiceInterface.php +++ b/Model/Service/Recommendation/StateAwareCategoryServiceInterface.php @@ -43,7 +43,7 @@ interface StateAwareCategoryServiceInterface /** * @param int $pageNumber * @param int $limit - * @return CategoryMerchandisingResult + * @return CategoryMerchandisingResult|null */ public function getPersonalisationResult($pageNumber, $limit): ?CategoryMerchandisingResult; diff --git a/Plugin/Framework/Search/Request/RequestCleaner.php b/Plugin/Framework/Search/Request/RequestCleaner.php index b03c67f5..808bef9c 100644 --- a/Plugin/Framework/Search/Request/RequestCleaner.php +++ b/Plugin/Framework/Search/Request/RequestCleaner.php @@ -41,7 +41,6 @@ use Nosto\Cmp\Helper\SearchEngine; use Nosto\Cmp\Logger\LoggerInterface; use Nosto\Cmp\Model\Filter\FilterBuilder; -use Nosto\Cmp\Model\Service\Recommendation\Category; use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryServiceInterface; use Nosto\Cmp\Plugin\Catalog\Block\ParameterResolverInterface; use Nosto\Cmp\Utils\CategoryMerchandising; @@ -268,7 +267,7 @@ private function parseLimit(array $requestData) /** * @param int $pageNum * @param int $limit - * @return int[] + * @return array|null */ private function getCmpProductIds($pageNum, $limit) { From 3fed302a6241a7b68e91ef13f977ed13fb578a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannu=20Po=CC=88lo=CC=88nen?= Date: Thu, 17 Sep 2020 15:31:45 +0300 Subject: [PATCH 31/35] Update change log & bump version --- CHANGELOG.md | 4 ++++ composer.json | 2 +- etc/module.xml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fa4a2a7..e1db992b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning. +### 3.0.0-rc1 +* Add support for using Elasticsearch as a catalog search engine +* Introduce possibility to use all categories (not only the ones in navigation) with Nosto's category merchandising + ### 2.0.1 * Change the script type to `application/json` for category mapping * Add possibility to debug the category query via Magento's debug logging diff --git a/composer.json b/composer.json index c5d047e6..11b3f168 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "nosto/module-nostocmp", "description": "Nosto Category Merchandising extension for Magento 2", "type": "magento2-module", - "version": "2.0.1", + "version": "3.0.0-rc1", "require-dev": { "php": ">=7.1.0", "magento-ecg/coding-standard": "3.*", diff --git a/etc/module.xml b/etc/module.xml index ce536358..b8826949 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -37,7 +37,7 @@ - + From ed966d50f427dfa63404f1c50be8c6e735986fc5 Mon Sep 17 00:00:00 2001 From: olsi-qose Date: Thu, 18 Feb 2021 12:06:59 +0200 Subject: [PATCH 32/35] Bump version and update changelog --- CHANGELOG.md | 2 +- composer.json | 2 +- etc/module.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1db992b..1a48fdca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning. -### 3.0.0-rc1 +### 3.0.0 * Add support for using Elasticsearch as a catalog search engine * Introduce possibility to use all categories (not only the ones in navigation) with Nosto's category merchandising diff --git a/composer.json b/composer.json index 11b3f168..dd6e1980 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "nosto/module-nostocmp", "description": "Nosto Category Merchandising extension for Magento 2", "type": "magento2-module", - "version": "3.0.0-rc1", + "version": "3.0.0", "require-dev": { "php": ">=7.1.0", "magento-ecg/coding-standard": "3.*", diff --git a/etc/module.xml b/etc/module.xml index b8826949..c4ea5ab6 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -37,7 +37,7 @@ - + From 8616fc7a252c26fad624caf68a7adff2aeb1e26c Mon Sep 17 00:00:00 2001 From: olsi-qose Date: Thu, 18 Feb 2021 14:22:51 +0200 Subject: [PATCH 33/35] Gix github actions --- .github/workflows/action.yml | 12 ++++++------ .github/workflows/phan.yml | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index d02aaca7..7babf5a6 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -15,8 +15,8 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: '7.2' - tools: composer, prestissimo - extensions: ast + tools: composer:v1, prestissimo + extensions: ast, bcmath, gd coverage: none #https://github.com/actions/cache/blob/master/examples.md#php---composer @@ -69,8 +69,8 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: '7.2' - tools: composer, prestissimo - extensions: ast + tools: composer:v1, prestissimo + extensions: ast, bcmath, gd coverage: none #https://github.com/actions/cache/blob/master/examples.md#php---composer @@ -120,8 +120,8 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: '7.2' - tools: composer, prestissimo - extensions: ast + tools: composer:v1, prestissimo + extensions: ast, bcmath, gd coverage: none #https://github.com/actions/cache/blob/master/examples.md#php---composer diff --git a/.github/workflows/phan.yml b/.github/workflows/phan.yml index 3e42857b..ab5e7d2f 100644 --- a/.github/workflows/phan.yml +++ b/.github/workflows/phan.yml @@ -16,9 +16,9 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: '7.2' - tools: composer, prestissimo, pecl + tools: composer:v1, prestissimo, pecl + extensions: ast, bcmath, gd, pdo_mysql, soap, zip coverage: none - extensions: ast - name: Cache composer packages id: composer-cache From cd6b7b4b9c6b52065bdac4de9ab59c41dac8913a Mon Sep 17 00:00:00 2001 From: olsi-qose Date: Thu, 18 Feb 2021 14:26:26 +0200 Subject: [PATCH 34/35] Fix CS warning --- Plugin/Catalog/Block/Toolbar.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index 4729fd4e..3776afd4 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -215,5 +215,4 @@ private function whereInProductIds(ProductCollection $collection, array $nostoPr ); $select->where($zendExpression); } - } From 8d9f7fcc79b3b941fc36c3123d640e0cda4631c9 Mon Sep 17 00:00:00 2001 From: olsi-qose Date: Thu, 18 Feb 2021 14:33:56 +0200 Subject: [PATCH 35/35] Remove unused dependencies --- Plugin/Catalog/Block/Toolbar.php | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/Plugin/Catalog/Block/Toolbar.php b/Plugin/Catalog/Block/Toolbar.php index 3776afd4..c958841c 100644 --- a/Plugin/Catalog/Block/Toolbar.php +++ b/Plugin/Catalog/Block/Toolbar.php @@ -43,39 +43,20 @@ use Magento\Framework\DB\Select; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NoSuchEntityException; -use /** @noinspection PhpDeprecationInspection */ - Magento\Framework\Registry; -use Magento\Framework\Stdlib\CookieManagerInterface; -use Magento\LayeredNavigation\Block\Navigation\State; -use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\Store; use Nosto\Cmp\Helper\Data as NostoCmpHelperData; use Nosto\Cmp\Helper\SearchEngine; +use Nosto\Cmp\Logger\LoggerInterface; use Nosto\Cmp\Model\Service\Recommendation\StateAwareCategoryService; use Nosto\Cmp\Utils\CategoryMerchandising as CategoryMerchandisingUtil; -use Nosto\Cmp\Model\Filter\FilterBuilder as NostoFilterBuilder; -use Nosto\Cmp\Model\Service\Recommendation\Category as CategoryRecommendation; -use Nosto\Cmp\Plugin\Catalog\Model\Product as NostoProductPlugin; -use Nosto\Cmp\Utils\Debug\Product as ProductDebug; -use Nosto\Cmp\Utils\Debug\ServerTiming; use Nosto\Helper\ArrayHelper as NostoHelperArray; use Nosto\NostoException; use Nosto\Result\Graphql\Recommendation\CategoryMerchandisingResult; use Nosto\Tagging\Helper\Account as NostoHelperAccount; -use Nosto\Cmp\Logger\LoggerInterface; -use Nosto\Tagging\Logger\Logger as NostoLogger; -use Nosto\Tagging\Model\Customer\Customer as NostoCustomer; -use Nosto\Tagging\Model\Service\Product\Category\DefaultCategoryService as CategoryBuilder; use Zend_Db_Expr; class Toolbar extends AbstractBlock { - const TIME_PROF_GRAPHQL_QUERY = 'cmp_graphql_query'; - const MAX_PRODUCTS = 1000; - - /** @var CategoryBuilder */ - private $categoryBuilder; - /** @var SearchEngine */ private $searchEngineHelper;