├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── documentation-issue.md │ └── feature_request.md ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── action.yml │ ├── ide.yml │ ├── phan.yml │ └── tests.yml ├── .gitignore ├── .idea ├── Magento2.iml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── dictionaries │ └── mridang.xml ├── encodings.xml ├── inspectionProfiles │ ├── CI.xml │ ├── Project_Default.xml │ └── profiles_settings.xml ├── jsLibraryMappings.xml ├── magento2plugin.xml ├── misc.xml ├── modules.xml ├── phing.xml ├── php.xml ├── scopes │ └── Inspection.xml └── vcs.xml ├── Api ├── BaseRepositoryInterface.php ├── CustomerRepositoryInterface.php ├── Data │ ├── CustomerInterface.php │ └── CustomerSearchResultInterface.php └── TaggingDataInterface.php ├── Block ├── Addtocart.php ├── Adminhtml │ ├── Account │ │ ├── Config.php │ │ └── Connection.php │ └── Form │ │ └── Field │ │ └── Tokens.php ├── Category.php ├── Element.php ├── Email │ ├── ImageUrl.php │ └── Visible.php ├── Embed.php ├── Knockout.php ├── Meta.php ├── Order.php ├── PageType.php ├── Product.php ├── Search.php ├── Stub.php ├── TaggingProvider.php ├── TaggingTrait.php └── Variation.php ├── CHANGELOG.md ├── Console └── Command │ ├── NostoAccountConnectCommand.php │ ├── NostoAccountRemoveCommand.php │ ├── NostoClearQueueCommand.php │ └── NostoPopulateCustomerReferenceCommand.php ├── Controller ├── Adminhtml │ └── Account │ │ ├── Base.php │ │ ├── Connect.php │ │ ├── Create.php │ │ ├── Delete.php │ │ ├── Index.php │ │ ├── Open.php │ │ └── Proxy.php ├── Checkout │ └── Cart │ │ └── Add.php ├── Export │ ├── Base.php │ ├── Category.php │ ├── Order.php │ └── Product.php ├── Frontend │ ├── Cart.php │ └── RestoreCart.php └── Oauth │ └── Index.php ├── Cron ├── CurrenciesCron.php └── RatesCron.php ├── CustomerData ├── ActiveVariationTagging.php ├── CartTagging.php ├── CustomerTagging.php └── HashedTagging.php ├── Exception ├── ParentCategoryDisabledException.php └── ParentProductDisabledException.php ├── Helper ├── Account.php ├── Cache.php ├── Currency.php ├── Customer.php ├── Data.php ├── NewRelic.php ├── Price.php ├── Ratings.php ├── RatingsFactory.php ├── Scope.php ├── Url.php └── Variation.php ├── LICENSE.txt ├── Logger ├── DebugHandler.php ├── ExceptionHandler.php ├── Logger.php └── SystemHandler.php ├── Magento2.iml ├── Model ├── Cache │ └── Type │ │ ├── ProductData.php │ │ └── ProductDataInterface.php ├── Cart │ ├── Builder.php │ ├── Item │ │ ├── Builder.php │ │ ├── Bundle.php │ │ ├── Configurable.php │ │ ├── Grouped.php │ │ └── Simple.php │ └── Restore │ │ └── Builder.php ├── Category │ ├── Builder.php │ ├── CollectionBuilder.php │ ├── Repository.php │ └── UrlBuilder.php ├── Config │ ├── Backend │ │ └── MultiCurrency.php │ └── Source │ │ ├── Brand.php │ │ ├── GoogleCategory.php │ │ ├── Gtin.php │ │ ├── Image.php │ │ ├── Margin.php │ │ ├── Memory.php │ │ ├── MultiCurrency.php │ │ ├── Ratings.php │ │ ├── Selector.php │ │ └── Tags.php ├── Customer │ ├── Customer.php │ ├── CustomerSearchResults.php │ └── Repository.php ├── Email │ └── Repository.php ├── Indexer │ ├── AbstractIndexer.php │ ├── CategoryIndexer.php │ ├── Dimensions │ │ ├── AbstractDimensionModeConfiguration.php │ │ ├── Category │ │ │ └── ModeSwitcherConfiguration.php │ │ ├── ModeSwitcher │ │ │ ├── DimensionModeConfiguration.php │ │ │ ├── ModeSwitcher.php │ │ │ ├── ModeSwitcherConfiguration.php │ │ │ └── ModeSwitcherInterface.php │ │ └── StoreDimensionProvider.php │ ├── IndexerUtil.php │ └── ProductIndexer.php ├── Item │ ├── Bundle.php │ ├── Configurable.php │ ├── Downloadable.php │ ├── Giftcard.php │ ├── Grouped.php │ ├── Simple.php │ └── Virtual.php ├── Meta │ ├── Account │ │ ├── Billing │ │ │ └── Builder.php │ │ ├── Builder.php │ │ ├── Connection │ │ │ └── Builder.php │ │ ├── Owner │ │ │ └── Builder.php │ │ ├── Settings │ │ │ ├── Builder.php │ │ │ ├── Currencies │ │ │ │ └── Builder.php │ │ │ └── Service.php │ │ └── Sso │ │ │ └── Builder.php │ └── Oauth │ │ └── Builder.php ├── Mview │ ├── ChangeLog.php │ ├── ChangeLogInterface.php │ ├── Mview.php │ └── MviewInterface.php ├── Order │ ├── Builder.php │ ├── Collection.php │ ├── Item │ │ ├── Builder.php │ │ ├── Bundle.php │ │ ├── Configurable.php │ │ ├── Grouped.php │ │ └── Simple.php │ └── Status │ │ └── Builder.php ├── Person │ ├── Builder.php │ └── Tagging │ │ └── Builder.php ├── Product │ ├── Builder.php │ ├── CollectionBuilder.php │ ├── Ratings.php │ ├── Repository.php │ ├── Sku │ │ ├── Builder.php │ │ └── Collection.php │ ├── Tags │ │ └── LowStock.php │ ├── Url │ │ └── Builder.php │ └── Variation │ │ ├── Builder.php │ │ └── Collection.php ├── Rates │ ├── Builder.php │ └── Service.php ├── Resolver │ └── TaggingDataResolver.php ├── ResourceModel │ ├── Customer.php │ ├── Customer │ │ └── Collection.php │ ├── Magento │ │ ├── Category │ │ │ ├── Collection.php │ │ │ └── CollectionBuilder.php │ │ └── Product │ │ │ ├── Collection.php │ │ │ └── CollectionBuilder.php │ └── Sku.php ├── Service │ ├── AbstractService.php │ ├── Cache │ │ └── CacheService.php │ ├── Indexer │ │ ├── IndexerStatusService.php │ │ └── IndexerStatusServiceInterface.php │ ├── Product │ │ ├── Attribute │ │ │ ├── AbstractAttributeService.php │ │ │ ├── AttributeProviderInterface.php │ │ │ ├── AttributeServiceInterface.php │ │ │ ├── CachingAttributeService.php │ │ │ ├── DefaultAttributeProvider.php │ │ │ └── DefaultAttributeService.php │ │ ├── AvailabilityService.php │ │ ├── CachingProductService.php │ │ ├── Category │ │ │ ├── CachingCategoryService.php │ │ │ ├── CategoryServiceInterface.php │ │ │ └── DefaultCategoryService.php │ │ ├── DefaultProductComparator.php │ │ ├── DefaultProductSerializer.php │ │ ├── DefaultProductService.php │ │ ├── ImageService.php │ │ ├── ProductComparatorInterface.php │ │ ├── ProductSerializerInterface.php │ │ ├── ProductServiceInterface.php │ │ └── SanitizingProductService.php │ ├── Stock │ │ ├── Provider │ │ │ ├── CachingStockProvider.php │ │ │ ├── DefaultStockProvider.php │ │ │ ├── StockProviderInterface.php │ │ │ └── StockRegistryProvider.php │ │ └── StockService.php │ ├── Store │ │ └── MissingStoreException.php │ ├── Sync │ │ ├── AbstractBulkConsumer.php │ │ ├── AbstractBulkPublisher.php │ │ ├── BulkConsumerInterface.php │ │ ├── BulkPublisherInterface.php │ │ ├── Delete │ │ │ ├── AsyncBulkConsumer.php │ │ │ ├── AsyncBulkPublisher.php │ │ │ └── DeleteService.php │ │ └── Upsert │ │ │ ├── Category │ │ │ ├── AsyncBulkConsumer.php │ │ │ ├── AsyncBulkPublisher.php │ │ │ └── SyncService.php │ │ │ └── Product │ │ │ ├── AsyncBulkConsumer.php │ │ │ ├── AsyncBulkPublisher.php │ │ │ └── SyncService.php │ └── Update │ │ ├── CategoryUpdateService.php │ │ └── ProductUpdateService.php ├── System │ └── Message │ │ └── Notification │ │ ├── InvalidAccount.php │ │ └── MissingApiTokens.php ├── TaggingData.php └── User │ └── Builder.php ├── Observer ├── Adminhtml │ └── Config.php ├── Cart │ └── Add.php ├── Category │ └── Update.php ├── Customer │ ├── Save.php │ └── UpdateMarketingPermission.php ├── Order │ └── Save.php ├── Product │ ├── Base.php │ ├── MassProductAttributeUpdate.php │ └── Review.php ├── Rates │ └── Update.php └── Settings │ └── Update.php ├── Plugin ├── CategoryUpdate.php ├── ProductUpdate.php └── Sales │ └── OrderRepository.php ├── README.md ├── Setup └── Patch │ ├── Data │ ├── AddCustomerReference.php │ └── AlterCustomerReferenceNonEditable.php │ └── Schema │ └── MakeCustomerIdNullable.php ├── Test └── Unit │ ├── Helper │ └── AccountTest.php │ └── Util │ └── UrlTest.php ├── Util ├── Benchmark.php ├── Customer.php ├── PagingIterator.php ├── Repository.php ├── StringUtil.php └── Url.php ├── build.xml ├── compile.sh ├── composer.json ├── composer.lock ├── default.conf ├── entrypoint.sh ├── etc ├── acl.xml ├── adminhtml │ ├── di.xml │ ├── events.xml │ ├── menu.xml │ ├── routes.xml │ └── system.xml ├── cache.xml ├── communication.xml ├── config.xml ├── crontab.xml ├── csp_whitelist.xml ├── db_schema.xml ├── db_schema_whitelist.json ├── di.xml ├── events.xml ├── frontend │ ├── di.xml │ ├── routes.xml │ └── sections.xml ├── indexer.xml ├── module.xml ├── mview.xml ├── queue.xml ├── queue_consumer.xml ├── queue_publisher.xml ├── queue_topology.xml ├── schema.graphqls └── webapi.xml ├── inspect.sh ├── phan.php ├── phpunit.xml ├── registration.php ├── ruleset.xml ├── supervisord.conf └── view ├── adminhtml ├── layout │ └── nosto_account_index.xml ├── templates │ ├── config.phtml │ ├── connection.phtml │ └── tokens.phtml └── web │ └── js │ └── nostoRemoveModal.js └── frontend ├── layout ├── catalog_category_view.xml ├── catalog_product_view.xml ├── catalogsearch_result_index.xml ├── checkout_cart_index.xml ├── checkout_index_index.xml ├── checkout_onepage_success.xml ├── cms_index_index.xml ├── cms_noroute_index.xml ├── default.xml ├── hyva_checkout_index_index.xml └── hyva_checkout_onepage.xml ├── requirejs-config.js ├── tailwind └── tailwind.config.js ├── templates ├── addtocart.phtml ├── cart.phtml ├── customer.phtml ├── element.phtml ├── embed.phtml ├── hyva │ ├── cart.phtml │ ├── customer.phtml │ ├── tagging-provider.phtml │ └── variation.phtml ├── js │ ├── nostojs.phtml │ └── tagging-providers-include.phtml ├── jsstub.phtml ├── luma │ ├── cart.phtml │ ├── customer.phtml │ ├── tagging-provider.phtml │ └── variation.phtml ├── meta.phtml ├── tagging-provider.phtml └── variation.phtml └── web └── js ├── nostojs.js ├── recobuy.js ├── tagging-providers.js └── view ├── cart-tagging.js ├── customer-tagging.js └── variation-tagging.js /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report errors and problems 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Magento 2 version(s) used**: x.y.z 11 | **Extension version(s) affected**: x.y.z 12 | 13 | **Description** 14 | 15 | 16 | **How to reproduce** 17 | 18 | 19 | **Magento 2 mode** 20 | - [ ] Developer 21 | - [ ] Production 22 | 23 | **Full page cache** 24 | - [ ] Enabled 25 | - [ ] Disabled 26 | 27 | **Nosto indexer mode** 28 | - [ ] Update On Save 29 | - [ ] Update By Schedule 30 | 31 | **Possible Solution** 32 | 33 | 34 | **Additional context** 35 | 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation-issue.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation Issue 3 | about: Missing, misleading or incomplete documentation issues 4 | title: '' 5 | labels: docs 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Documentation issue** 11 | 12 | 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Ideas for new features and improvements 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | 12 | 13 | **Describe the solution you'd like** 14 | 15 | 16 | **Describe alternatives you've considered** 17 | 18 | 19 | **Additional context** 20 | 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | registries: 3 | adobe: 4 | type: composer-repository 5 | url: https://repo.magento.com 6 | username: ${{ secrets.REPO_USR }} 7 | password: ${{ secrets.REPO_PSW }} 8 | 9 | updates: 10 | - package-ecosystem: composer 11 | directory: "/" 12 | schedule: 13 | interval: weekly 14 | open-pull-requests-limit: 0 15 | registries: 16 | - adobe -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | ## Related Issue 7 | 8 | 9 | 10 | 11 | 12 | ## Motivation and Context 13 | 14 | 15 | ## How Has This Been Tested? 16 | 17 | 18 | 19 | 20 | ## Documentation: 21 | 22 | 23 | ## Checklist: 24 | - [ ] My code follows the code style of this project. 25 | - [ ] I have updated the documentation accordingly. 26 | - [ ] All new and existing tests passed. 27 | - [ ] I have assigned the correct milestone or created one if non-existent. 28 | - [ ] I have correctly labeled this pull request. 29 | - [ ] I have linked the corresponding issue in this description. 30 | - [ ] I have updated the corresponding Jira ticket. 31 | - [ ] I have requested a review from at least 2 reviewers 32 | - [ ] I have checked the base branch of this pull request 33 | - [ ] I have checked my code for any possible security vulnerabilities 34 | -------------------------------------------------------------------------------- /.github/workflows/phan.yml: -------------------------------------------------------------------------------- 1 | name: Phan 2 | 3 | on: [push] 4 | 5 | jobs: 6 | 7 | phan: 8 | name: Phan Analysis 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v4 13 | 14 | ############################################################################ 15 | - name: Set up PHP 16 | uses: shivammathur/setup-php@v2 17 | with: 18 | php-version: '7.4' 19 | tools: composer:v2, pecl 20 | coverage: none 21 | extensions: ast, bcmath, gd, pdo_mysql, zip, soap 22 | 23 | - name: Cache composer packages 24 | id: composer-cache 25 | run: | 26 | composer config cache-files-dir 27 | echo "::set-output name=dir::$(composer config cache-files-dir)" 28 | - uses: actions/cache@v4 29 | with: 30 | path: ${{ steps.composer-cache.outputs.dir }} 31 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 32 | restore-keys: | 33 | ${{ runner.os }}-composer- 34 | 35 | - name: Update project dependencies 36 | env: 37 | REPO_USR: ${{ secrets.REPO_USR }} 38 | REPO_PSW: ${{ secrets.REPO_PSW }} 39 | run: | 40 | composer config repositories.0 composer https://repo.magento.com 41 | composer config http-basic.repo.magento.com "$REPO_USR" "$REPO_PSW" 42 | composer install --prefer-dist --no-progress --no-suggest 43 | ############################################################################ 44 | 45 | - name: Install Magento 46 | id: install-magento 47 | run: | 48 | composer create-project magento/community-edition=2.4.4 magento --no-dev 49 | cd magento 50 | composer config minimum-stability dev 51 | composer config prefer-stable true 52 | composer require --no-update nosto/module-nostotagging:dev-${GITHUB_REF#refs/heads/}#${GITHUB_SHA} 53 | composer update --no-dev 54 | bin/magento module:enable --all 55 | bin/magento setup:di:compile 56 | cd .. 57 | cp -r magento/generated vendor/magento/ 58 | rm -rf magento 59 | env: 60 | GITHUB_BRANCH: ${{ github.base_ref }} 61 | 62 | - name: Run Phan analysis 63 | id: phan-analysis 64 | run: | 65 | ./vendor/bin/phan --config-file=phan.php --output-mode=checkstyle --output=chkphan.xml 66 | continue-on-error: true 67 | 68 | - name: Archive static analysis results 69 | uses: actions/upload-artifact@v4 70 | with: 71 | name: phan-analysis-results 72 | path: chkphan.xml 73 | 74 | - name: Report annotations 75 | id: report-annotations 76 | run: ./vendor/bin/cs2pr chkphan.xml 77 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Unit Tests 2 | 3 | on: [push] 4 | 5 | jobs: 6 | 7 | phpcs: 8 | name: Code Sniffer 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | 13 | ############################################################################ 14 | - name: Set up PHP 15 | uses: shivammathur/setup-php@v2 16 | with: 17 | php-version: '7.4' 18 | tools: composer 19 | extensions: ast, bcmath, gd 20 | coverage: none 21 | 22 | #https://github.com/actions/cache/blob/master/examples.md#php---composer 23 | - name: Cache composer packages 24 | id: composer-cache 25 | run: | 26 | composer config cache-files-dir 27 | echo "::set-output name=dir::$(composer config cache-files-dir)" 28 | - uses: actions/cache@v4 29 | with: 30 | path: ${{ steps.composer-cache.outputs.dir }} 31 | key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} 32 | restore-keys: | 33 | ${{ runner.os }}-composer- 34 | 35 | - name: Update project dependencies 36 | env: 37 | REPO_USR: ${{ secrets.REPO_USR }} 38 | REPO_PSW: ${{ secrets.REPO_PSW }} 39 | run: | 40 | composer config repositories.0 composer https://repo.magento.com 41 | composer config http-basic.repo.magento.com "$REPO_USR" "$REPO_PSW" 42 | composer install --prefer-dist --no-progress --no-suggest 43 | ############################################################################ 44 | 45 | - name: Run unit tests 46 | run: | 47 | ./vendor/bin/phpunit Test 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor 3 | .htaccess* 4 | .env 5 | build 6 | pub 7 | bin 8 | phan.xml 9 | chk*xml 10 | output 11 | .phpunit.cache 12 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 56 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/dictionaries/mridang.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | crontab 5 | frontpage 6 | gitignore 7 | meqp 8 | mview 9 | nosto 10 | percona 11 | phan 12 | phpmd 13 | phpseclib 14 | phtml 15 | signup 16 | skus 17 | squiz 18 | upsert 19 | versioning 20 | yotpo 21 | zendframework 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/jsLibraryMappings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/magento2plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/phing.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $PROJECT_DIR$/vendor/phing/phing/bin/phing 5 | 6 | -------------------------------------------------------------------------------- /.idea/scopes/Inspection.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Api/BaseRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Api; 38 | 39 | use Magento\Framework\Api\SearchCriteriaInterface; 40 | use Magento\Framework\Data\SearchResultInterface; 41 | 42 | interface BaseRepositoryInterface 43 | { 44 | /** 45 | * Get search result 46 | * 47 | * @param SearchCriteriaInterface $searchCriteria 48 | * @return SearchResultInterface 49 | */ 50 | public function search(SearchCriteriaInterface $searchCriteria); 51 | } 52 | -------------------------------------------------------------------------------- /Api/Data/CustomerSearchResultInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Api\Data; 38 | 39 | use Magento\Framework\Data\SearchResultInterface; 40 | 41 | interface CustomerSearchResultInterface extends SearchResultInterface 42 | { 43 | /** 44 | * Get items from search results 45 | * 46 | * @return CustomerInterface[] 47 | */ 48 | public function getItems(); 49 | 50 | /** 51 | * Set items to the search results 52 | * 53 | * @param CustomerInterface[] $items 54 | * @return $this 55 | */ 56 | public function setItems(array $items); 57 | } 58 | -------------------------------------------------------------------------------- /Api/TaggingDataInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | namespace Nosto\Tagging\Api; 37 | 38 | /** 39 | * Interface for tagging data API 40 | * 41 | * @api 42 | */ 43 | interface TaggingDataInterface 44 | { 45 | /** 46 | * Get tagging data for the specified page type 47 | * 48 | * @param string $pageType The page type (product, category, cart, search, frontpage, order, notfound) 49 | * @return array 50 | */ 51 | public function getTaggingData($pageType); 52 | } 53 | -------------------------------------------------------------------------------- /Controller/Adminhtml/Account/Base.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Controller\Adminhtml\Account; 38 | 39 | use Magento\Backend\App\Action; 40 | 41 | abstract class Base extends Action 42 | { 43 | /** 44 | * Is the user allowed to view Nosto account settings 45 | * 46 | * @return bool 47 | */ 48 | public function _isAllowed() 49 | { 50 | return $this->_authorization->isAllowed(self::ADMIN_RESOURCE); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Controller/Frontend/RestoreCart.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Controller\Frontend; 38 | 39 | /** 40 | * Class for backwards compatibility with Nosto Magento 2 extension version 2.1.0 41 | * 42 | * @deprecated 43 | */ 44 | class RestoreCart extends Cart // @codingStandardsIgnoreLine 45 | { 46 | } 47 | -------------------------------------------------------------------------------- /CustomerData/HashedTagging.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\CustomerData; 38 | 39 | abstract class HashedTagging 40 | { 41 | 42 | /** 43 | * @var string the algorithm to use for hashing visitor id. 44 | */ 45 | public const VISITOR_HASH_ALGO = 'sha256'; 46 | 47 | /** 48 | * Return the checksum for for the customer tagging i.e hashed cookie identifier or HCID for 49 | * short. This is used to sign the tagging so that if it is in fact cached, the cookie and 50 | * tagging signature won't match and the data will be discarded 51 | * 52 | * @param string $string 53 | * @return string 54 | */ 55 | public function generateVisitorChecksum(string $string) 56 | { 57 | return hash(self::VISITOR_HASH_ALGO, $string); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Exception/ParentCategoryDisabledException.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Exception; 38 | 39 | use Nosto\NostoException; 40 | use Throwable; 41 | 42 | class ParentCategoryDisabledException extends NostoException 43 | { 44 | public function __construct($categoryId, $code = 0, Throwable $previous = null) 45 | { 46 | $message = "Parent category is disabled for category with id: " . $categoryId; 47 | parent::__construct($message, $code, $previous); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Exception/ParentProductDisabledException.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Exception; 38 | 39 | use Nosto\NostoException; 40 | use Throwable; 41 | 42 | class ParentProductDisabledException extends NostoException 43 | { 44 | public function __construct(int $productId, $code = 0, Throwable $previous = null) 45 | { 46 | $message = "Parent product is disabled for SKU with id: " . $productId; 47 | parent::__construct($message, $code, $previous); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Helper/NewRelic.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Helper; 38 | 39 | use Throwable; 40 | 41 | /** 42 | * New Relic wrapper utility 43 | */ 44 | class NewRelic 45 | { 46 | /** 47 | * Checks if New Relic extension is loaded 48 | * 49 | * @return bool 50 | */ 51 | public function newRelicAvailable() 52 | { 53 | return extension_loaded('newrelic'); 54 | } 55 | 56 | /** 57 | * Reports an exception to new relic 58 | * 59 | * @param Throwable $throwable 60 | */ 61 | public function reportException(Throwable $throwable) 62 | { 63 | if ($this->newRelicAvailable()) { 64 | /** @noinspection PhpComposerExtensionStubsInspection */ 65 | newrelic_notice_error($throwable->getMessage(), $throwable); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Helper/RatingsFactory.php: -------------------------------------------------------------------------------- 1 | 33 | * @copyright 2020 Nosto Solutions Ltd 34 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 35 | * 36 | */ 37 | 38 | namespace Nosto\Tagging\Helper; 39 | 40 | use Magento\Framework\ObjectManagerInterface; 41 | use Yotpo\Reviews\Model\Sync\RichSnippets; 42 | 43 | class RatingsFactory 44 | { 45 | /** 46 | * @var ObjectManagerInterface 47 | */ 48 | private ObjectManagerInterface $objectManager; 49 | 50 | /** 51 | * @param ObjectManagerInterface $objectManager 52 | */ 53 | public function __construct(ObjectManagerInterface $objectManager) 54 | { 55 | $this->objectManager = $objectManager; 56 | } 57 | 58 | /** 59 | * @return RichSnippets 60 | * @suppress PhanUndeclaredTypeReturnType 61 | */ 62 | public function create() 63 | { 64 | /** @phan-suppress-next-line PhanUndeclaredTypeReturnType */ 65 | return $this->objectManager->create('Yotpo\Reviews\Model\Sync\RichSnippets'); // @codingStandardsIgnoreLine 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Logger/DebugHandler.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Logger; 38 | 39 | use Magento\Framework\Logger\Handler\Base; 40 | use Monolog\Logger; 41 | 42 | class DebugHandler extends Base 43 | { 44 | protected $fileName = '/var/log/nosto-debug.log'; 45 | protected $loggerType = Logger::DEBUG; 46 | } 47 | -------------------------------------------------------------------------------- /Logger/ExceptionHandler.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Logger; 38 | 39 | use Magento\Framework\Logger\Handler\Base; 40 | use Monolog\Logger; 41 | 42 | class ExceptionHandler extends Base 43 | { 44 | protected $fileName = '/var/log/nosto-exception.log'; 45 | protected $loggerType = Logger::INFO; 46 | } 47 | -------------------------------------------------------------------------------- /Logger/SystemHandler.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Logger; 38 | 39 | use Magento\Framework\Logger\Handler\Base; 40 | use Monolog\Logger; 41 | 42 | class SystemHandler extends Base 43 | { 44 | protected $fileName = '/var/log/nosto-system.log'; 45 | protected $loggerType = Logger::INFO; 46 | } 47 | -------------------------------------------------------------------------------- /Magento2.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Model/Cache/Type/ProductData.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Cache\Type; 38 | 39 | use Magento\Framework\App\Cache\Type\FrontendPool; 40 | use Magento\Framework\Cache\Frontend\Decorator\TagScope; 41 | 42 | class ProductData extends TagScope implements ProductDataInterface 43 | { 44 | /** 45 | * Cache type code unique among all cache types 46 | */ 47 | public const TYPE_IDENTIFIER = 'nosto_product_cache'; 48 | 49 | /** 50 | * The tag name that limits the cache cleaning scope within a particular tag 51 | */ 52 | public const CACHE_TAG = 'NOSTO_PRODUCT'; 53 | 54 | /** 55 | * @param FrontendPool $cacheFrontendPool 56 | */ 57 | public function __construct(FrontendPool $cacheFrontendPool) 58 | { 59 | parent::__construct( 60 | $cacheFrontendPool->get(self::TYPE_IDENTIFIER), 61 | self::CACHE_TAG 62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Model/Cache/Type/ProductDataInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Cache\Type; 38 | 39 | use Magento\Framework\Cache\FrontendInterface; 40 | 41 | interface ProductDataInterface extends FrontendInterface 42 | { 43 | public function getTag(); 44 | } 45 | -------------------------------------------------------------------------------- /Model/Cart/Item/Simple.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Cart\Item; 38 | 39 | use Magento\Quote\Model\Quote\Item; 40 | use Nosto\Tagging\Model\Item\Simple as SimpleItem; 41 | 42 | class Simple extends SimpleItem 43 | { 44 | /** 45 | * Returns the name of the product. Simple products will have their own name 46 | * 47 | * @param Item $item the ordered item 48 | * @return string the name of the product 49 | */ 50 | public function buildItemName(Item $item): string 51 | { 52 | $type = $item->getProduct()->getTypeInstance(); 53 | $parentIds = $type->getParentIdsByChild($item->getItemId()); 54 | return $this->buildName($item, $parentIds); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Model/Config/Source/GoogleCategory.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Config\Source; 38 | 39 | use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection; 40 | 41 | /** 42 | * Option array class to generate a list of selectable options that allows the merchant to choose 43 | * any attribute for his google category tag. 44 | */ 45 | class GoogleCategory extends Selector 46 | { 47 | /** 48 | * @param Collection $collection 49 | */ 50 | public function filterCollection(Collection $collection) 51 | { 52 | /** 53 | * Argument is of type array but string is expected 54 | */ 55 | /** @phan-suppress-next-next-line PhanTypeMismatchArgumentProbablyReal */ 56 | /** @noinspection PhpParamsInspection */ 57 | $collection->setFrontendInputTypeFilter(['text', 'textarea']); 58 | } 59 | 60 | public function isNullable() 61 | { 62 | return true; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Model/Config/Source/Gtin.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Config\Source; 38 | 39 | use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection; 40 | 41 | /** 42 | * Option array class to generate a list of selectable options that allows the merchant to choose 43 | * any attribute for his GTIN tag. 44 | */ 45 | class Gtin extends Selector 46 | { 47 | /** 48 | * @param Collection $collection 49 | */ 50 | public function filterCollection(Collection $collection) 51 | { 52 | /** 53 | * Argument is of type array but string is expected 54 | */ 55 | /** @phan-suppress-next-next-line PhanTypeMismatchArgumentProbablyReal */ 56 | /** @noinspection PhpParamsInspection */ 57 | $collection->setFrontendInputTypeFilter(['text', 'textarea']); 58 | } 59 | 60 | public function isNullable() 61 | { 62 | return true; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Model/Config/Source/Image.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Config\Source; 38 | 39 | use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection; 40 | 41 | /** 42 | * Option array class to generate a list of selectable options that allows the merchant to choose 43 | * any image attribute for his image tag. 44 | */ 45 | class Image extends Selector 46 | { 47 | public function filterCollection(Collection $collection) 48 | { 49 | $collection->setFrontendInputTypeFilter('media_image'); 50 | } 51 | 52 | public function isNullable() 53 | { 54 | return false; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Model/Config/Source/Margin.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Config\Source; 38 | 39 | use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection; 40 | 41 | /** 42 | * Option array class to generate a list of selectable options that allows the merchant to choose 43 | * any price attribute for his supplier-cost tag. 44 | */ 45 | class Margin extends Selector 46 | { 47 | public function filterCollection(Collection $collection) 48 | { 49 | $collection->setFrontendInputTypeFilter('price'); 50 | } 51 | 52 | public function isNullable() 53 | { 54 | return true; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Model/Config/Source/Memory.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Config\Source; 38 | 39 | use Magento\Framework\Data\OptionSourceInterface; 40 | use Magento\Framework\Phrase; 41 | 42 | class Memory implements OptionSourceInterface 43 | { 44 | /** 45 | * Options getter 46 | * 47 | * @return array 48 | */ 49 | public function toOptionArray() 50 | { 51 | $options = []; 52 | for ($i = 10; $i <= 100; $i += 10) { 53 | $options[] = ['value' => $i, 'label' => new Phrase($i . '%')]; 54 | } 55 | return $options; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Model/Config/Source/MultiCurrency.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Config\Source; 38 | 39 | use Magento\Framework\Data\OptionSourceInterface; 40 | use Magento\Framework\Phrase; 41 | use Nosto\Tagging\Helper\Data; 42 | 43 | /** 44 | * Option array class to generate a list of selectable options that allows the merchant to choose 45 | * any image attribute for his image tag. 46 | */ 47 | class MultiCurrency implements OptionSourceInterface 48 | { 49 | /** 50 | * Options getter 51 | * 52 | * @return array 53 | */ 54 | public function toOptionArray() 55 | { 56 | return [ 57 | ['value' => Data::SETTING_VALUE_MC_EXCHANGE_RATE, 'label' => new Phrase('Exchange rates')], 58 | ['value' => Data::SETTING_VALUE_MC_SINGLE, 'label' => new Phrase('Single currency')], 59 | ['value' => Data::SETTING_VALUE_MC_DISABLED, 'label' => new Phrase('Disabled')] 60 | ]; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Model/Config/Source/Tags.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Config\Source; 38 | 39 | use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection; 40 | 41 | /** 42 | * Option array class to generate a list of selectable options that allows the merchant to choose 43 | * any attribute for his brand tag. 44 | */ 45 | class Tags extends Selector 46 | { 47 | // @codingStandardsIgnoreLine 48 | public function filterCollection(Collection $collection) 49 | { 50 | } 51 | 52 | public function isNullable() 53 | { 54 | return true; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Model/Customer/CustomerSearchResults.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Customer; 38 | 39 | use Magento\Framework\Api\Search\SearchResult; 40 | use Nosto\Tagging\Api\Data\CustomerSearchResultInterface; 41 | 42 | class CustomerSearchResults extends SearchResult implements CustomerSearchResultInterface // @codingStandardsIgnoreLine 43 | { 44 | } 45 | -------------------------------------------------------------------------------- /Model/Indexer/Dimensions/ModeSwitcher/ModeSwitcherInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Indexer\Dimensions\ModeSwitcher; 38 | 39 | use Magento\Indexer\Model\ModeSwitcherInterface as MagentoModeSwitcherInterface; 40 | 41 | interface ModeSwitcherInterface extends MagentoModeSwitcherInterface 42 | { 43 | /** 44 | * @return string 45 | */ 46 | public function getMode(): string; 47 | } 48 | -------------------------------------------------------------------------------- /Model/Item/Bundle.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Item; 38 | 39 | use Magento\Catalog\Model\Product\Type; 40 | 41 | class Bundle 42 | { 43 | /** Product type for bundled item */ 44 | public const TYPE = Type::TYPE_BUNDLE; 45 | } 46 | -------------------------------------------------------------------------------- /Model/Item/Configurable.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Item; 38 | 39 | use Magento\ConfigurableProduct\Model\Product\Type\Configurable as Type; 40 | 41 | class Configurable 42 | { 43 | /** Product type for configurable item */ 44 | public const TYPE = Type::TYPE_CODE; 45 | } 46 | -------------------------------------------------------------------------------- /Model/Item/Downloadable.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Item; 38 | 39 | use Magento\Downloadable\Model\Product\Type; 40 | 41 | class Downloadable 42 | { 43 | /** Product type for downloadable item */ 44 | public const TYPE = Type::TYPE_DOWNLOADABLE; 45 | } 46 | -------------------------------------------------------------------------------- /Model/Item/Giftcard.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Item; 38 | 39 | class Giftcard 40 | { 41 | /** Product type for gift card item */ 42 | public const TYPE = 'giftcard'; 43 | } 44 | -------------------------------------------------------------------------------- /Model/Item/Grouped.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Item; 38 | 39 | use Magento\GroupedProduct\Model\Product\Type\Grouped as Type; 40 | 41 | class Grouped 42 | { 43 | /** Product type for grouped item */ 44 | public const TYPE = Type::TYPE_CODE; 45 | } 46 | -------------------------------------------------------------------------------- /Model/Item/Virtual.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Item; 38 | 39 | use Magento\Catalog\Model\Product\Type; 40 | 41 | class Virtual 42 | { 43 | /** Product type for configurable item */ 44 | public const TYPE = Type::TYPE_VIRTUAL; 45 | } 46 | -------------------------------------------------------------------------------- /Model/Mview/ChangeLog.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Mview; 38 | 39 | use Exception; 40 | use Magento\Framework\Mview\View\Changelog as MagentoChangelog; 41 | 42 | class ChangeLog extends MagentoChangelog implements ChangeLogInterface 43 | { 44 | /** 45 | * @inheritDoc 46 | * @throws Exception 47 | */ 48 | public function getTotalRows() 49 | { 50 | $changelogTableName = $this->resource->getTableName($this->getName()); 51 | if ($this->connection->isTableExists($changelogTableName)) { 52 | $select = $this->connection->select() // @codingStandardsIgnoreLine 53 | ->from( // @codingStandardsIgnoreLine 54 | $changelogTableName, 55 | 'COUNT(*)' 56 | ); 57 | 58 | return (int)$this->connection->fetchOne($select); 59 | } 60 | return 0; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Model/Mview/ChangeLogInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Mview; 38 | 39 | use Magento\Framework\Mview\View\ChangelogInterface as MagentoChangelogInterface; 40 | 41 | interface ChangeLogInterface extends MagentoChangelogInterface 42 | { 43 | /** 44 | * Get total rows in changelog table 45 | * @return int 46 | */ 47 | public function getTotalRows(); 48 | } 49 | -------------------------------------------------------------------------------- /Model/Mview/Mview.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Mview; 38 | 39 | use Magento\Framework\Mview\View; 40 | 41 | /** 42 | * Class Mview 43 | * This dummy class is needed because Magento's ViewInterface is missing setId method 44 | * but it exists in the implementation class 45 | */ 46 | // @codingStandardsIgnoreFile 47 | class Mview extends View implements MviewInterface 48 | { 49 | } 50 | -------------------------------------------------------------------------------- /Model/Mview/MviewInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Mview; 38 | 39 | use Magento\Framework\Mview\ViewInterface; 40 | 41 | interface MviewInterface extends ViewInterface 42 | { 43 | /** 44 | * Set view id 45 | * @param string|int $id 46 | * @return $this 47 | */ 48 | public function setId($id); 49 | } 50 | -------------------------------------------------------------------------------- /Model/Order/Item/Simple.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Order\Item; 38 | 39 | use Magento\Sales\Model\Order\Item; 40 | use Nosto\Tagging\Model\Item\Simple as SimpleItem; 41 | 42 | class Simple extends SimpleItem 43 | { 44 | /** 45 | * Returns the name of the product. Simple products will have their own name 46 | * 47 | * @param Item $item the ordered item 48 | * @return string the name of the product 49 | */ 50 | public function buildItemName(Item $item): string 51 | { 52 | if ($item->getProduct()) { 53 | $type = $item->getProduct()->getTypeInstance(); 54 | $parentIds = $type->getParentIdsByChild($item->getProductId()); 55 | } else { 56 | $parentIds = 0; 57 | } 58 | return $this->buildName($item, $parentIds); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Model/Product/Ratings.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Product; 38 | 39 | class Ratings 40 | { 41 | /** @var int */ 42 | private int $reviewCount; 43 | 44 | /** @var float */ 45 | private float $rating; 46 | 47 | /** 48 | * @return int $reviewCount 49 | */ 50 | public function getReviewCount() 51 | { 52 | return $this->reviewCount; 53 | } 54 | 55 | /** 56 | * @param int $reviewCount 57 | */ 58 | public function setReviewCount(int $reviewCount) 59 | { 60 | $this->reviewCount = (int)$reviewCount; 61 | } 62 | 63 | public function getRating() 64 | { 65 | return $this->rating; 66 | } 67 | 68 | /** 69 | * @param float $rating 70 | */ 71 | public function setRating(float $rating) 72 | { 73 | $this->rating = (float)$rating; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Model/ResourceModel/Customer.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\ResourceModel; 38 | 39 | use Magento\Framework\Model\ResourceModel\Db\AbstractDb; 40 | use Nosto\Tagging\Api\Data\CustomerInterface; 41 | 42 | class Customer extends AbstractDb 43 | { 44 | public const TABLE_NAME = 'nosto_tagging_customer'; 45 | 46 | /** 47 | * Initialize resource model 48 | * 49 | * @return void 50 | */ 51 | public function _construct() 52 | { 53 | $this->_init(self::TABLE_NAME, CustomerInterface::ID); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Model/ResourceModel/Customer/Collection.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\ResourceModel\Customer; 38 | 39 | use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection; 40 | use Nosto\Tagging\Model\Customer\Customer; 41 | use Nosto\Tagging\Model\ResourceModel\Customer as ResourceModelCustomer; 42 | 43 | class Collection extends AbstractCollection 44 | { 45 | /** 46 | * Define resource model 47 | * 48 | * @return void 49 | */ 50 | public function _construct() 51 | { 52 | $this->_init( 53 | Customer::class, 54 | ResourceModelCustomer::class 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Model/ResourceModel/Magento/Category/Collection.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\ResourceModel\Magento\Category; 38 | 39 | use Magento\Catalog\Model\ResourceModel\Category\Collection as MagentoCategoryCollection; 40 | use Magento\Framework\Exception\LocalizedException; 41 | 42 | class Collection extends MagentoCategoryCollection 43 | { 44 | /** 45 | * @return Collection 46 | * @throws LocalizedException 47 | */ 48 | public function addActiveFilter(): Collection 49 | { 50 | return $this->addAttributeToFilter('status', ['eq' => 1]); 51 | } 52 | 53 | /** 54 | * @param array $ids 55 | * @return Collection 56 | * @throws LocalizedException 57 | */ 58 | public function addIdsToFilter(array $ids): Collection 59 | { 60 | return $this->addAttributeToFilter($this->getIdFieldName(), ['in' => $ids]); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Model/Service/Indexer/IndexerStatusServiceInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Indexer; 38 | 39 | interface IndexerStatusServiceInterface 40 | { 41 | /** 42 | * @param $indexerId 43 | * @return void 44 | */ 45 | public function clearProcessedChangelog($indexerId); 46 | 47 | /** 48 | * @param $indexerId 49 | * @return int 50 | */ 51 | public function getTotalChangelogCount($indexerId); 52 | 53 | /** 54 | * @param $indexerId 55 | * @return int 56 | */ 57 | public function getCurrentWatermark($indexerId); 58 | } 59 | -------------------------------------------------------------------------------- /Model/Service/Product/Attribute/AttributeProviderInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Product\Attribute; 38 | 39 | use Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection as AttributeCollection; 40 | 41 | interface AttributeProviderInterface 42 | { 43 | /** 44 | * Returns a collection of attributes that are possible to be added either 45 | * into the custom fields or tags in Nosto product. 46 | * 47 | * @return AttributeCollection|null 48 | */ 49 | public function getSelectableAttributesForNosto(); 50 | 51 | /** 52 | * Returns a collection of attributes filtered by the give attribute codes. 53 | * 54 | * @param array $attributeCodes a list of attribute codes 55 | * @return AttributeCollection|null 56 | */ 57 | public function getAttributesByAttributeCodes(array $attributeCodes); 58 | } 59 | -------------------------------------------------------------------------------- /Model/Service/Product/Category/CategoryServiceInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Product\Category; 38 | 39 | use Magento\Catalog\Model\Category; 40 | use Magento\Catalog\Model\Product; 41 | use Magento\Store\Api\Data\StoreInterface; 42 | 43 | interface CategoryServiceInterface 44 | { 45 | /** 46 | * @param Category $category 47 | * @param StoreInterface $store 48 | * @return null|string 49 | */ 50 | public function getCategory(Category $category, StoreInterface $store); 51 | 52 | /** 53 | * @param Product $product 54 | * @param StoreInterface $store 55 | * @return array 56 | */ 57 | public function getCategories(Product $product, StoreInterface $store); 58 | 59 | /** 60 | * @param Product $product 61 | * @param StoreInterface $store 62 | * @return array 63 | */ 64 | public function getCategoryParentIds(Product $product, StoreInterface $store); 65 | } 66 | -------------------------------------------------------------------------------- /Model/Service/Product/DefaultProductComparator.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Product; 38 | 39 | use Nosto\Helper\SerializationHelper; 40 | use Nosto\Tagging\Util\StringUtil; 41 | use Nosto\Types\Product\ProductInterface; 42 | 43 | class DefaultProductComparator implements ProductComparatorInterface 44 | { 45 | /** 46 | * @inheritDoc 47 | */ 48 | public function isEqual(ProductInterface $product1, ProductInterface $product2) 49 | { 50 | $stringUtil = new StringUtil(); 51 | $product1string = $stringUtil->stripWhitespaceAndLinebreaks(SerializationHelper::serialize($product1)); 52 | $product2string = $stringUtil->stripWhitespaceAndLinebreaks(SerializationHelper::serialize($product2)); 53 | 54 | return $product1string === $product2string; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Model/Service/Product/DefaultProductSerializer.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Product; 38 | 39 | use Nosto\Model\Product\Product; 40 | use Nosto\Types\Product\ProductInterface; 41 | use Nosto\Util\Base64Serialize; 42 | 43 | /** 44 | * Default class for serializing and deserializing objects 45 | */ 46 | class DefaultProductSerializer implements ProductSerializerInterface 47 | { 48 | /** 49 | * @inheritDoc 50 | */ 51 | public function fromString(string $data) 52 | { 53 | return Base64Serialize::fromString($data, [Product::class]); 54 | } 55 | 56 | /** 57 | * @inheritDoc 58 | */ 59 | public function toString(ProductInterface $product) 60 | { 61 | return Base64Serialize::toString($product); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Model/Service/Product/ProductComparatorInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Product; 38 | 39 | use Nosto\Types\Product\ProductInterface; 40 | 41 | interface ProductComparatorInterface 42 | { 43 | /** 44 | * @param ProductInterface $product1 45 | * @param ProductInterface $product2 46 | * @return boolean 47 | */ 48 | public function isEqual(ProductInterface $product1, ProductInterface $product2); 49 | } 50 | -------------------------------------------------------------------------------- /Model/Service/Product/ProductSerializerInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Product; 38 | 39 | use Nosto\Model\Product\Product; 40 | use Nosto\Types\Product\ProductInterface; 41 | 42 | interface ProductSerializerInterface 43 | { 44 | /** 45 | * @param ProductInterface $product 46 | * @return string 47 | */ 48 | public function toString(ProductInterface $product); 49 | 50 | /** 51 | * @param string $data 52 | * @return Product|null 53 | */ 54 | public function fromString(string $data); 55 | } 56 | -------------------------------------------------------------------------------- /Model/Service/Product/ProductServiceInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Product; 38 | 39 | use Magento\Catalog\Api\Data\ProductInterface; 40 | use Magento\Store\Api\Data\StoreInterface; 41 | use Nosto\Model\Product\Product as NostoProduct; 42 | 43 | interface ProductServiceInterface 44 | { 45 | /** 46 | * @param ProductInterface $product 47 | * @param StoreInterface $store 48 | * @return NostoProduct|null 49 | */ 50 | public function getProduct(ProductInterface $product, StoreInterface $store); 51 | } 52 | -------------------------------------------------------------------------------- /Model/Service/Store/MissingStoreException.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Store; 38 | 39 | use RuntimeException; 40 | 41 | class MissingStoreException extends RuntimeException // @codingStandardsIgnoreLine 42 | { 43 | } 44 | -------------------------------------------------------------------------------- /Model/Service/Sync/BulkConsumerInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Sync; 38 | 39 | use Exception; 40 | use Magento\AsynchronousOperations\Api\Data\OperationInterface; 41 | 42 | interface BulkConsumerInterface 43 | { 44 | /** 45 | * Processing operation for data sync 46 | * 47 | * @param OperationInterface $operation 48 | * @return void 49 | * @throws Exception 50 | */ 51 | public function processOperation(OperationInterface $operation); 52 | } 53 | -------------------------------------------------------------------------------- /Model/Service/Sync/BulkPublisherInterface.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Model\Service\Sync; 38 | 39 | interface BulkPublisherInterface 40 | { 41 | /** 42 | * @param int $storeId 43 | * @param array $entityIds 44 | * @return void 45 | */ 46 | public function execute(int $storeId, array $entityIds = []); 47 | } 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nosto module for Magento 2 2 | 3 | Increase your conversion rate and average order value by delivering your 4 | customers personalized product recommendations throughout their shopping 5 | journey. 6 | 7 | Nosto allows you to deliver every customer a personalized shopping experience 8 | through recommendations based on their unique user behavior - increasing 9 | conversion, average order value and customer retention as a result. 10 | 11 | [http://nosto.com](http://nosto.com/) 12 | 13 | ## Installing 14 | 15 | The preferred way of installing the extension is via [Composer](https://getcomposer.org/). If you don't have composer installed yet you can get it by following [these instructions](https://getcomposer.org/doc/00-intro.md). It's recommended to install composer globally. You will also need public key and private key from Magento Marketplace or Magento Connect in order to install packages to Magento 2 via Composer. Please follow these instructions to get public key and private key http://devdocs.magento.com/guides/v2.1/install-gde/prereq/connect-auth.html. Once you have composer installed you can install Nosto extension (nosto/module-nostotagging). 16 | 17 | For complete installation instructions please see our [Wiki](https://github.com/Nosto/nosto-magento2/wiki) 18 | 19 | ## License 20 | 21 | Open Software License ("OSL") v3.0 -------------------------------------------------------------------------------- /Test/Unit/Util/UrlTest.php: -------------------------------------------------------------------------------- 1 | 33 | * @copyright 2020 Nosto Solutions Ltd 34 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 35 | * 36 | */ 37 | 38 | declare(strict_types=1); 39 | 40 | namespace Nosto\Tagging\Test\Unit\Util; 41 | 42 | use Nosto\Tagging\Util\Url; 43 | use PHPUnit\Framework\TestCase; 44 | 45 | class UrlTest extends TestCase 46 | { 47 | private Url $url; 48 | 49 | public function setUp(): void 50 | { 51 | $this->url = new Url(); 52 | } 53 | 54 | /** 55 | * @covers Url::removePubFromUrl() 56 | * @return void 57 | */ 58 | public function testRemovePubFromUrl() 59 | { 60 | $urlToRemovePub = 'https://magento2.dev.nos.to/media/pub/18263871.jpg'; 61 | $result = $this->url->removePubFromUrl($urlToRemovePub); 62 | $this->assertEquals('https://magento2.dev.nos.to/media/18263871.jpg', $result); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Util/Customer.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Util; 38 | 39 | use Magento\Customer\Api\Data\CustomerInterface; 40 | use Magento\Customer\Model\Backend\Customer\Interceptor as CustomerInterceptor; 41 | 42 | class Customer 43 | { 44 | public const CUSTOMER_REFERENCE_HASH_ALGO = 'sha256'; 45 | 46 | /** 47 | * @param CustomerInterface|CustomerInterceptor $customer 48 | * @return string 49 | */ 50 | public function generateCustomerReference($customer) 51 | { 52 | return hash( 53 | self::CUSTOMER_REFERENCE_HASH_ALGO, 54 | $customer->getId() . $customer->getEmail() 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Util/StringUtil.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Util; 38 | 39 | class StringUtil 40 | { 41 | /** 42 | * Strips out all whitespace and line breaks from a given string 43 | * 44 | * @param string $string 45 | * @return string 46 | */ 47 | public function stripWhitespaceAndLinebreaks(string $string): string 48 | { 49 | return preg_replace( 50 | '/[ \t]+/', 51 | ' ', 52 | preg_replace( 53 | '/[\r\n]+/', 54 | "\n", 55 | $string 56 | ) 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Util/Url.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | namespace Nosto\Tagging\Util; 38 | 39 | class Url 40 | { 41 | /** 42 | * Remove the first "/pub/" from a URL 43 | * 44 | * @param string $url 45 | * @return mixed 46 | */ 47 | public function removePubFromUrl(string $url) 48 | { 49 | $path = '/pub/'; 50 | $pos = strpos($url, $path); 51 | if ($pos !== false) { 52 | return substr_replace($url, '/', $pos, strlen($path)); 53 | } 54 | 55 | return $url; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | BRANCH_NAME=$(git branch --show-current) 3 | PROJECT_NAME=$(cat composer.json| jq --raw-output .name) 4 | APP_DIR=$(pwd) 5 | TMP_DIR=$(mktemp -d -t ci-XXXXXXXXXX) 6 | cd $TMP_DIR || exit 0 7 | composer create-project magento/community-edition=2.4.4 . 8 | composer config minimum-stability dev 9 | composer config prefer-stable true 10 | composer require --no-update ${PROJECT_NAME}:dev-${BRANCH_NAME} 11 | composer require --no-update magento/module-asynchronous-operations:@stable 12 | composer update --no-dev 13 | bin/magento module:enable --all 14 | bin/magento setup:di:compile 15 | mv -f generated $APP_DIR/vendor/magento/generated 16 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nosto/module-nostotagging", 3 | "description": "Increase your conversion rate and average order value by delivering your customers personalized product recommendations throughout their shopping journey.", 4 | "type": "magento2-module", 5 | "version": "8.0.6", 6 | "require-dev": { 7 | "phpmd/phpmd": "^2.5", 8 | "sebastian/phpcpd": "*", 9 | "phing/phing": "2.*", 10 | "magento-ecg/coding-standard": "4.5.*", 11 | "magento/module-catalog": "104.0.2", 12 | "magento/module-sales": "103.0.3", 13 | "magento/module-sales-inventory": "100.4.0.*", 14 | "magento/module-sales-rule": "101.2.3", 15 | "magento/module-store": "101.1.3", 16 | "magento/module-configurable-product": "100.4.3", 17 | "magento/module-directory": "100.4.3", 18 | "magento/module-bundle": "101.0.3", 19 | "magento/module-search": "101.1.3", 20 | "magento/module-catalog-search": "102.0.3", 21 | "magento/module-quote": "101.2.3", 22 | "magento/module-review": "100.4.3", 23 | "magento/module-grouped-product": "100.4.3", 24 | "mridang/pmd-annotations": "^0.0.2", 25 | "staabm/annotate-pull-request-from-checkstyle": "^1.1", 26 | "magento/magento-coding-standard": "^5.0", 27 | "magento/module-asynchronous-operations": "100.4.3", 28 | "phan/phan": "5.3.0", 29 | "drenso/phan-extensions": "3.5.1", 30 | "yotpo/module-yotpo-combined": "^4.1", 31 | "phpunit/phpunit": "~9.5.18" 32 | }, 33 | "suggest": { 34 | "magento/product-community-edition": "2.*", 35 | "yotpo/module-yotpo-combined": "^4.1" 36 | }, 37 | "license": [ 38 | "OSL-3.0" 39 | ], 40 | "require": { 41 | "php": ">=7.4.0", 42 | "magento/framework": ">=101.0.6|~104.0", 43 | "ext-json": "*", 44 | "nosto/php-sdk": "^7.6.4", 45 | "laminas/laminas-uri": "*" 46 | }, 47 | "repositories": [ 48 | { 49 | "type": "composer", 50 | "url": "https://repo.magento.com/" 51 | } 52 | ], 53 | "autoload": { 54 | "psr-4": { 55 | "Nosto\\Tagging\\": "" 56 | }, 57 | "files": [ 58 | "registration.php" 59 | ] 60 | }, 61 | "archive": { 62 | "exclude": [ 63 | "!composer.*", 64 | "Jenkinsfile", 65 | "default.conf", 66 | "Dockerfile", 67 | ".DS_STORE", 68 | ".idea", 69 | ".phan", 70 | ".docker", 71 | "ruleset.xml", 72 | "phan.*", 73 | ".gitignore", 74 | "build.xml", 75 | ".github", 76 | "supervisord.conf", 77 | "entrypoint.sh", 78 | "/magento" 79 | ] 80 | }, 81 | "config": { 82 | "process-timeout":3600 83 | }, 84 | "scripts": { 85 | "di:compile": "./compile.sh", 86 | "ci:inspect": "./inspect.sh" 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /default.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerAdmin mage-admin@localhost 3 | DocumentRoot /var/www/html 4 | DirectoryIndex index.php index.html index.htm 5 | 6 | Require all granted 7 | Options FollowSymLinks MultiViews 8 | AllowOverride FileInfo AuthConfig Limit Indexes Options=All,MultiViews 9 | 10 | AddDefaultCharset UTF-8 11 | SetOutputFilter DEFLATE 12 | ErrorLog /var/log/apache2/error.log 13 | CustomLog /var/log/apache2/access.log combined 14 | 15 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [ "$1" != "" ]; then 5 | exec "$@" 6 | else 7 | exec supervisord -c /etc/supervisord.conf 8 | fi 9 | -------------------------------------------------------------------------------- /etc/adminhtml/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 39 | 40 | 41 | Nosto\Tagging\Model\System\Message\Notification\InvalidAccount 42 | Nosto\Tagging\Model\System\Message\Notification\MissingApiTokens 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /etc/adminhtml/events.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 40 | 41 | 43 | 45 | 46 | 47 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /etc/adminhtml/menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 40 | 41 | 43 | 47 | 48 | -------------------------------------------------------------------------------- /etc/adminhtml/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /etc/cache.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 39 | 40 | Cache for Nosto product data 41 | 42 | -------------------------------------------------------------------------------- /etc/crontab.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 40 | 41 | 42 | 4 * * * * 43 | 44 | 45 | 0 1 * * * 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /etc/csp_whitelist.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | *.nosto.com 7 | *.nos.to 8 | 9 | 10 | 11 | 12 | *.nosto.com 13 | *.nos.to 14 | 15 | 16 | 17 | 18 | *.nosto.com 19 | *.nos.to 20 | 21 | 22 | 23 | 24 | *.nosto.com 25 | *.nos.to 26 | 27 | 28 | 29 | 30 | *.nosto.com 31 | *.nos.to 32 | 33 | 34 | 35 | 36 | *.nosto.com 37 | *.nos.to 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /etc/db_schema.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /etc/db_schema_whitelist.json: -------------------------------------------------------------------------------- 1 | { 2 | "nosto_tagging_customer": { 3 | "column": { 4 | "id": true, 5 | "customer_id": true, 6 | "quote_id": true, 7 | "nosto_id": true, 8 | "created_at": true, 9 | "updated_at": true, 10 | "restore_cart_hash": true 11 | }, 12 | "index": { 13 | "NOSTO_TAGGING_CUSTOMER_QUOTE_ID": true 14 | }, 15 | "constraint": { 16 | "PRIMARY": true 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /etc/frontend/routes.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /etc/indexer.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | Nosto Product Indexer 39 | Populates message queue with product ids to be sent to Nosto 40 | 41 | 42 | Nosto Category Indexer 43 | Populates message queue with category ids to be sent to Nosto 44 | Category 45 | 46 | 47 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /etc/queue_publisher.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /etc/queue_topology.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /etc/schema.graphqls: -------------------------------------------------------------------------------- 1 | type Query { 2 | nostoTaggingData( 3 | pageType: String! 4 | ): NostoTaggingData @resolver(class: "Nosto\\Tagging\\Model\\Resolver\\TaggingDataResolver") 5 | } 6 | 7 | type NostoTaggingData { 8 | pageType: String 9 | products: [NostoProduct] 10 | cart: NostoCart 11 | customer: NostoCustomer 12 | categories: [String] 13 | variation: String 14 | searchTerm: String 15 | } 16 | 17 | type NostoProduct { 18 | productId: String 19 | name: String 20 | url: String 21 | imageUrl: String 22 | priceCurrencyCode: String 23 | price: Float 24 | listPrice: Float 25 | price_currency_code: String 26 | availability: String 27 | categories: [String] 28 | description: String 29 | brand: String 30 | variation_id: String 31 | google_category: String 32 | gender: String 33 | age_group: String 34 | custom_fields: NostoCustomFields 35 | gtin: String 36 | rating_value: Float 37 | skus: [NostoSku] 38 | alternate_image_urls: [String] 39 | tags: [String] 40 | } 41 | 42 | type NostoSku { 43 | id: String 44 | name: String 45 | price: Float 46 | listPrice: Float 47 | url: String 48 | imageUrl: String 49 | availability: String 50 | gtin: String 51 | custom_fields: NostoCustomFields 52 | } 53 | 54 | type NostoCart { 55 | hcid: String 56 | restore_cart_url: String 57 | items: [NostoCartItem] 58 | } 59 | 60 | type NostoCartItem { 61 | product_id: String 62 | sku_id: String 63 | name: String 64 | unit_price: Float 65 | price_currency_code: String 66 | quantity: Int 67 | } 68 | 69 | type NostoCustomer { 70 | first_name: String 71 | last_name: String 72 | email: String 73 | hcid: String 74 | customer_reference: String 75 | customer_group: String 76 | gender: String 77 | date_of_birth: String 78 | marketing_permission: Boolean 79 | } 80 | 81 | type NostoCustomFields { 82 | additionalProp: String 83 | } 84 | -------------------------------------------------------------------------------- /etc/webapi.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /inspect.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker run --env GITHUB_WORKSPACE=/app --volume="$(pwd)"/.:/app docker.pkg.github.com/mridang/action-phpstorm/stormy:latest /app /app/.idea/inspectionProfiles/CI.xml /tmp v2 Inspection 4 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | Test/Unit 18 | 19 | 20 | 21 | 23 | 24 | Api 25 | Block 26 | Console 27 | Controller 28 | Cron 29 | CustomerData 30 | Exception 31 | Helper 32 | Logger 33 | Model 34 | Observer 35 | Plugin 36 | Util 37 | Setup 38 | view 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | use Dotenv\Dotenv; 38 | use Magento\Framework\Component\ComponentRegistrar; 39 | 40 | ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Nosto_Tagging', __DIR__); 41 | 42 | if (file_exists(dirname(__FILE__) . DIRECTORY_SEPARATOR . '.env')) { 43 | /** @noinspection PhpParamsInspection */ 44 | $dotenv = new Dotenv(dirname(__FILE__)); // @codingStandardsIgnoreLine 45 | $dotenv->overload(); 46 | } 47 | -------------------------------------------------------------------------------- /supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | 4 | [program:mysql] 5 | command =/usr/sbin/mysqld 6 | autorestart=true 7 | 8 | 9 | [program:apache2] 10 | command=apachectl -D "FOREGROUND" -k start 11 | redirect_stderr=true 12 | autostart=true 13 | autorestart=false 14 | -------------------------------------------------------------------------------- /view/adminhtml/layout/nosto_account_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 36 | 37 | 38 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /view/adminhtml/templates/config.phtml: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | use Nosto\Tagging\Block\Adminhtml\Account\Config; 38 | 39 | /** 40 | * @var Config $block 41 | */ 42 | ?> 43 | 44 | 49 | -------------------------------------------------------------------------------- /view/frontend/requirejs-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Nosto Solutions Ltd 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of the copyright holder nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | * @author Nosto Solutions Ltd 31 | * @copyright 2020 Nosto Solutions Ltd 32 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 33 | * 34 | */ 35 | 36 | var config = { 37 | map: { 38 | '*': { 39 | nostojs: 'Nosto_Tagging/js/nostojs', 40 | recobuy: 'Nosto_Tagging/js/recobuy' 41 | } 42 | }, 43 | paths: { 44 | 'Nosto_Tagging/js/nostojs': 'Nosto_Tagging/js/nostojs', 45 | 'Nosto_Tagging/js/tagging-providers': 'Nosto_Tagging/js/tagging-providers' 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /view/frontend/tailwind/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020, Nosto Solutions Ltd 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 15 | * 3. Neither the name of the copyright holder nor the names of its contributors 16 | * may be used to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | * 30 | * @author Nosto Solutions Ltd 31 | * @copyright 2020 Nosto Solutions Ltd 32 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 33 | * 34 | */ 35 | module.exports = { 36 | content: [ 37 | '../templates/**/*.phtml', 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /view/frontend/templates/cart.phtml: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | /** 38 | * @var \Nosto\Tagging\Block\Knockout $block 39 | */ 40 | 41 | $isHyva = $block->isHyva(); 42 | 43 | if ($isHyva) { 44 | echo $block->getLayout() 45 | ->createBlock(\Nosto\Tagging\Block\Knockout::class) 46 | ->setTemplate('Nosto_Tagging::hyva/cart.phtml') 47 | ->setData($block->getData()) 48 | ->toHtml(); 49 | } else { 50 | echo $block->getLayout() 51 | ->createBlock(\Nosto\Tagging\Block\Knockout::class) 52 | ->setTemplate('Nosto_Tagging::luma/cart.phtml') 53 | ->setData($block->getData()) 54 | ->toHtml(); 55 | } 56 | -------------------------------------------------------------------------------- /view/frontend/templates/customer.phtml: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | /** 38 | * @var \Nosto\Tagging\Block\Knockout $block 39 | */ 40 | 41 | $isHyva = $block->isHyva(); 42 | 43 | if ($isHyva) { 44 | echo $block->getLayout() 45 | ->createBlock(\Nosto\Tagging\Block\Knockout::class) 46 | ->setTemplate('Nosto_Tagging::hyva/customer.phtml') 47 | ->setData($block->getData()) 48 | ->toHtml(); 49 | } else { 50 | echo $block->getLayout() 51 | ->createBlock(\Nosto\Tagging\Block\Knockout::class) 52 | ->setTemplate('Nosto_Tagging::luma/customer.phtml') 53 | ->setData($block->getData()) 54 | ->toHtml(); 55 | } 56 | -------------------------------------------------------------------------------- /view/frontend/templates/hyva/tagging-provider.phtml: -------------------------------------------------------------------------------- 1 | 32 | * @copyright 2020 Nosto Solutions Ltd 33 | * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause 34 | * 35 | */ 36 | 37 | /** 38 | * @var \Nosto\Tagging\Block\TaggingProvider $block 39 | * @var Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer 40 | */ 41 | $taggingConfig = $block->getTaggingConfig(); 42 | ?> 43 | 44 | 45 | isNostoEnabled()): 46 | 47 | $script = <<