From 80d8de9dc363aec878b5efa45504c6687b908181 Mon Sep 17 00:00:00 2001 From: Svyatoslav Varpikhovsky Date: Tue, 18 Jun 2024 12:53:39 +0300 Subject: [PATCH] FRW-7443 Implemented Store Context functionality. (#10950) FRW-7443 Implemented Store Context functionality. --- .coveralls.yml | 3 + .editorconfig | 14 ++ .gitattributes | 36 +++ .github/workflows/ci.yml | 52 ++++ .gitignore | 22 ++ CHANGELOG.md | 3 + LICENSE | 40 +++ README.md | 15 ++ architecture-baseline.json | 1 + codeception.yml | 14 ++ composer.json | 48 ++++ data/translation/Zed/de_DE.csv | 8 + data/translation/Zed/en_US.csv | 8 + dependency.json | 5 + phpstan.neon | 3 + psalm-report.json | 5 + .../Transfer/store_context.transfer.xml | 60 +++++ .../Business/Creator/StoreContextCreator.php | 55 +++++ .../Creator/StoreContextCreatorInterface.php | 21 ++ .../Business/Expander/StoreExpander.php | 45 ++++ .../Expander/StoreExpanderInterface.php | 20 ++ .../Business/Reader/StoreContextReader.php | 69 ++++++ .../Reader/StoreContextReaderInterface.php | 28 +++ .../Business/Reader/TimezoneReader.php | 19 ++ .../Reader/TimezoneReaderInterface.php | 16 ++ .../Business/StoreContextBusinessFactory.php | 212 ++++++++++++++++ .../Business/StoreContextFacade.php | 115 +++++++++ .../Business/StoreContextFacadeInterface.php | 92 +++++++ .../Business/Updater/StoreContextUpdater.php | 55 +++++ .../Updater/StoreContextUpdaterInterface.php | 21 ++ .../Validator/Rule/ApplicationRule.php | 69 ++++++ .../Rule/ContextAlreadyExistRule.php | 61 +++++ .../Validator/Rule/ContextNotFoundRule.php | 61 +++++ .../Rule/DefaultContextExistRule.php | 56 +++++ .../Rule/OneContextPerApplicationRule.php | 98 ++++++++ .../StoreContextValidatorRuleInterface.php | 20 ++ .../Business/Validator/Rule/TimezoneRule.php | 65 +++++ .../Validator/StoreContextValidator.php | 113 +++++++++ .../StoreContextValidatorInterface.php | 23 ++ .../Business/Writer/StoreContextWriter.php | 122 ++++++++++ .../Writer/StoreContextWriterInterface.php | 32 +++ .../Mapper/StoreContextMapper.php | 110 +++++++++ .../Mapper/StoreContextMapperInterface.php | 47 ++++ .../ContextStoreCollectionExpanderPlugin.php | 42 ++++ .../Store/ContextStorePostCreatePlugin.php | 40 +++ .../Store/ContextStorePostUpdatePlugin.php | 40 +++ .../ContextStorePreCreateValidationPlugin.php | 40 +++ .../ContextStorePreUpdateValidationPlugin.php | 40 +++ .../StoreContextCommunicationFactory.php | 29 +++ ...toreContextToUtilEncodingServiceBridge.php | 54 +++++ ...eContextToUtilEncodingServiceInterface.php | 30 +++ .../Propel/AbstractSpyStoreContext.php | 23 ++ .../Propel/AbstractSpyStoreContextQuery.php | 23 ++ .../Propel/Mapper/StoreContextMapper.php | 91 +++++++ .../Schema/spy_store_context.schema.xml | 15 ++ .../Persistence/StoreContextEntityManager.php | 65 +++++ .../StoreContextEntityManagerInterface.php | 27 +++ .../StoreContextPersistenceFactory.php | 46 ++++ .../Persistence/StoreContextRepository.php | 89 +++++++ .../StoreContextRepositoryInterface.php | 27 +++ .../Zed/StoreContext/StoreContextConfig.php | 33 +++ .../StoreContextDependencyProvider.php | 67 +++++ .../Business/StoreContextFacadeTest.php | 229 ++++++++++++++++++ .../Validator/Rule/ApplicationRuleTest.php | 106 ++++++++ .../Rule/ContextAlreadyExistRuleTest.php | 113 +++++++++ .../Rule/ContextNotFoundRuleTest.php | 101 ++++++++ .../Rule/DefaultContextExistRuleTest.php | 99 ++++++++ .../Rule/OneContextPerApplicationRuleTest.php | 113 +++++++++ .../Validator/Rule/TimezoneRuleTest.php | 100 ++++++++ ...ntextStoreCollectionExpanderPluginTest.php | 100 ++++++++ .../ContextStorePostCreatePluginTest.php | 83 +++++++ .../ContextStorePostUpdatePluginTest.php | 83 +++++++ ...textStorePreCreateValidationPluginTest.php | 83 +++++++ ...textStorePreUpdateValidationPluginTest.php | 83 +++++++ .../_support/StoreContextBusinessTester.php | 172 +++++++++++++ .../StoreContextCommunicationTester.php | 35 +++ .../Zed/StoreContext/codeception.yml | 49 ++++ tooling.yml | 5 + 78 files changed, 4357 insertions(+) create mode 100644 .coveralls.yml create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 architecture-baseline.json create mode 100644 codeception.yml create mode 100644 composer.json create mode 100644 data/translation/Zed/de_DE.csv create mode 100644 data/translation/Zed/en_US.csv create mode 100644 dependency.json create mode 100644 phpstan.neon create mode 100644 psalm-report.json create mode 100644 src/Spryker/Shared/StoreContext/Transfer/store_context.transfer.xml create mode 100644 src/Spryker/Zed/StoreContext/Business/Creator/StoreContextCreator.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Creator/StoreContextCreatorInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Expander/StoreExpander.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Expander/StoreExpanderInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Reader/StoreContextReader.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Reader/StoreContextReaderInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Reader/TimezoneReader.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Reader/TimezoneReaderInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Business/StoreContextBusinessFactory.php create mode 100644 src/Spryker/Zed/StoreContext/Business/StoreContextFacade.php create mode 100644 src/Spryker/Zed/StoreContext/Business/StoreContextFacadeInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Updater/StoreContextUpdater.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Updater/StoreContextUpdaterInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Validator/Rule/ApplicationRule.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Validator/Rule/ContextAlreadyExistRule.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Validator/Rule/ContextNotFoundRule.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Validator/Rule/DefaultContextExistRule.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Validator/Rule/OneContextPerApplicationRule.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Validator/Rule/StoreContextValidatorRuleInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Validator/Rule/TimezoneRule.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Validator/StoreContextValidator.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Validator/StoreContextValidatorInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Writer/StoreContextWriter.php create mode 100644 src/Spryker/Zed/StoreContext/Business/Writer/StoreContextWriterInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Communication/Mapper/StoreContextMapper.php create mode 100644 src/Spryker/Zed/StoreContext/Communication/Mapper/StoreContextMapperInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStoreCollectionExpanderPlugin.php create mode 100644 src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostCreatePlugin.php create mode 100644 src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostUpdatePlugin.php create mode 100644 src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreCreateValidationPlugin.php create mode 100644 src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreUpdateValidationPlugin.php create mode 100644 src/Spryker/Zed/StoreContext/Communication/StoreContextCommunicationFactory.php create mode 100644 src/Spryker/Zed/StoreContext/Dependency/Service/StoreContextToUtilEncodingServiceBridge.php create mode 100644 src/Spryker/Zed/StoreContext/Dependency/Service/StoreContextToUtilEncodingServiceInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Persistence/Propel/AbstractSpyStoreContext.php create mode 100644 src/Spryker/Zed/StoreContext/Persistence/Propel/AbstractSpyStoreContextQuery.php create mode 100644 src/Spryker/Zed/StoreContext/Persistence/Propel/Mapper/StoreContextMapper.php create mode 100644 src/Spryker/Zed/StoreContext/Persistence/Propel/Schema/spy_store_context.schema.xml create mode 100644 src/Spryker/Zed/StoreContext/Persistence/StoreContextEntityManager.php create mode 100644 src/Spryker/Zed/StoreContext/Persistence/StoreContextEntityManagerInterface.php create mode 100644 src/Spryker/Zed/StoreContext/Persistence/StoreContextPersistenceFactory.php create mode 100644 src/Spryker/Zed/StoreContext/Persistence/StoreContextRepository.php create mode 100644 src/Spryker/Zed/StoreContext/Persistence/StoreContextRepositoryInterface.php create mode 100644 src/Spryker/Zed/StoreContext/StoreContextConfig.php create mode 100644 src/Spryker/Zed/StoreContext/StoreContextDependencyProvider.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Business/StoreContextFacadeTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ApplicationRuleTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ContextAlreadyExistRuleTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ContextNotFoundRuleTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/DefaultContextExistRuleTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/OneContextPerApplicationRuleTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/TimezoneRuleTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStoreCollectionExpanderPluginTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostCreatePluginTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostUpdatePluginTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreCreateValidationPluginTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreUpdateValidationPluginTest.php create mode 100644 tests/SprykerTest/Zed/StoreContext/_support/StoreContextBusinessTester.php create mode 100644 tests/SprykerTest/Zed/StoreContext/_support/StoreContextCommunicationTester.php create mode 100644 tests/SprykerTest/Zed/StoreContext/codeception.yml create mode 100644 tooling.yml diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 0000000..be4561e --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,3 @@ +coverage_clover: tests/_output/coverage.xml +json_path: tests/_output/coveralls-upload.json +service_name: travis-ci diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3191e88 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at https://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.bat] +end_of_line = crlf + diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..51f3ea4 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,36 @@ +# Define the line ending behavior of the different file extensions +# Set the default behavior, in case people don't have core.autocrlf set. +* text text=auto eol=lf + +*.php diff=php + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary +*.gif binary +*.jpeg binary +*.zip binary +*.phar binary +*.ttf binary +*.woff binary +*.woff2 binary +*.eot binary +*.ico binary +*.mo binary +*.pdf binary +*.xsd binary +*.exe binary + +# Remove files for archives generated using `git archive` +dependency.json export-ignore +phpstan.json export-ignore +phpstan.neon export-ignore +psalm-report.json export-ignore linguist-generated=true +tooling.yml export-ignore +.coveralls.yml export-ignore +.travis.yml export-ignore +.editorconfig export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.github/ export-ignore +architecture-baseline.json export-ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e851193 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +name: CI + +on: + push: + branches: + - 'master' + pull_request: + workflow_dispatch: + +jobs: + validation: + name: Validation + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + extensions: mbstring, intl, bcmath + coverage: none + + - name: Composer Install + run: composer install --prefer-dist --no-interaction --profile + + - name: Run validation + run: composer validate + + - name: Syntax check + run: find ./src -path src -prune -o -type f -name '*.php' -print0 | xargs -0 -n1 -P4 php -l -n | (! grep -v "No syntax errors detected" ) + + lowest: + name: Prefer Lowest + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + extensions: mbstring, intl, bcmath + coverage: none + + - name: Composer Install + run: composer install --prefer-dist --no-interaction --profile + + - name: Composer Update + run: composer update --prefer-lowest --prefer-dist --no-interaction --profile -vvv diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..97f5d1d --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# IDEs +/.idea +/.project +/nbproject +/.buildpath +/.settings +*.sublime-* +*.AppleDouble +*.AppleDB +*.AppleDesktop + +# OS +.DS_Store + +/vendor +composer.lock +.phpunit.result.cache + +# tests +tests/**/_generated/ +tests/_output/* +!tests/_output/.gitkeep diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9257d14 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# StoreContext Changelog + +[Release Changelog](https://github.com/spryker/store-context/releases) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..36237b3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,40 @@ +SPRYKER SYSTEMS GMBH EVALUATION LICENSE AGREEMENT + +SPRYKER SYSTEMS GMBH, REGISTERED WITH THE COMMERCIAL REGISTER OF THE LOWER COURT OF HAMBURG UNDER HRB 134310 +("WE" OR "SPRYKER")GRANTS YOU (THE "LICENSEE") THE RIGHT TO USE THE SOFTWARE (AS DEFINED BELOW) +UNDER THE PROVISIONS OF THIS EVALUATION LICENSE AGREEMENT (THE "AGREEMENT"). + +The "Software" includes any software owned and distributed by Spryker under this Agreement. The Software +contains elements of open source components, to which different license terms apply respectively. +These open source components are needed to be installed separately. + +Spryker grants to Licensee, during the 45-calendar-day period (the "Evaluation Period") following the download of the Software, +the nontransferable, nonexclusive limited, free of charge license to permit Licensee's employees to internally use the Software +to test and evaluate the Software in connection with potentially purchasing non-evaluation licenses to the Software. + +Licensee shall not (i) use the Software to set up a productive live system, for development purposes or any other purposes apart +from evaluating the Software; (ii) copy any part of the Software except to make one copy for back-up purposes; (iii) distribute, +disclose, market, rent, lease, or transfer the Software or act as a service bureau with respect to the Software; (iv) export the +Software or install it in multiple locations; (v) disclose any confidential information provided by Spryker; (vi) modify or make +derivative works of the Software; or (vii) allow others to make or obtain copies of the Software. + +THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND. SPRYKER DISCLAIMS ALL WARRANTIES, EXPRESSED OR IMPLIED, INCLUDING +BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, TITLE, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. SPRYKER WILL NOT +BE LIABLE FOR ANY DAMAGES ASSOCIATED WITH THE SOFTWARE, INCLUDING WITHOUT LIMITATION ORDINARY, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL +DAMAGES OF ANY KIND, INCLUDING BUT NOT LIMITED TO DAMAGES RELATING TO LOST DATA OR LOST PROFITS, EVEN IF SPRYKER HAS BEEN ADVISED OF +THE POSSIBILITY OF SUCH DAMAGES. + +Licensee's license to use the Software shall terminate on the earlier of (i) the expiration of the Evaluation Period, or (ii) the date +both parties enter into a definitive agreement for the provision by Spryker to Licensee of a non-evaluation license to the Software. +Upon termination of the license as provided above, Licensee shall promptly destroy the Software and any back-up copy of the Software +made during the Evaluation Period if Spryker and the Licensee have not agreed a non-evaluation license to the Software. + +This Agreement shall be governed by the laws of Germany to the exclusion of IPR (International Law) and the United Nations Convention +on Contracts for the International Sale of Goods (CISG). The parties consent to the jurisdiction of the courts in Berlin (Germany). + +This Agreement is not assignable or transferable by Licensee and any attempt to do so is null and void. + +This Agreement constitutes the entire agreement between the parties concerning Licensee's use of the Software. This Agreement supersedes +any prior verbal understanding between the parties and any Licensee purchase order or other ordering document, regardless of whether such +document is received by Spryker before or after execution of this Agreement. This Agreement may be amended only in a writing signed by +an authorized officer of Spryker. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7f87d0d --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# StoreContext Module +[![Latest Stable Version](https://poser.pugx.org/spryker/store-context/v/stable.svg)](https://packagist.org/packages/spryker/store-context) +[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%208.1-8892BF.svg)](https://php.net/) + +Module provides store context functionality. + +## Installation + +``` +composer require spryker/store-context +``` + +## Documentation + +[Spryker Documentation](https://docs.spryker.com) diff --git a/architecture-baseline.json b/architecture-baseline.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/architecture-baseline.json @@ -0,0 +1 @@ +[] diff --git a/codeception.yml b/codeception.yml new file mode 100644 index 0000000..10d4bd6 --- /dev/null +++ b/codeception.yml @@ -0,0 +1,14 @@ +namespace: StoreContext +include: + - tests/SprykerTest/Zed/StoreContext +paths: + tests: tests + output: tests/_output + data: tests/_data + support: tests/_support + envs: tests/_envs +settings: + suite_class: \PHPUnit\Framework\TestSuite + colors: true + memory_limit: 1024M + log: true diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..be92602 --- /dev/null +++ b/composer.json @@ -0,0 +1,48 @@ +{ + "name": "spryker/store-context", + "type": "library", + "description": "StoreContext module", + "license": "proprietary", + "require": { + "php": ">=8.1", + "spryker/kernel": "^3.30.0", + "spryker/store": "^1.25.0", + "spryker/store-extension": "^1.0.0", + "spryker/transfer": "^3.27.0", + "spryker/util-encoding": "^2.0.0" + }, + "require-dev": { + "spryker/application": "*", + "spryker/code-sniffer": "*", + "spryker/container": "*", + "spryker/propel": "*", + "spryker/testify": "*" + }, + "autoload": { + "psr-4": { + "Spryker\\": "src/Spryker/" + } + }, + "autoload-dev": { + "psr-4": { + "SprykerTest\\": "tests/SprykerTest/" + } + }, + "minimum-stability": "dev", + "prefer-stable": true, + "scripts": { + "cs-check": "phpcs -p -s --standard=vendor/spryker/code-sniffer/SprykerStrict/ruleset.xml src/ tests/", + "cs-fix": "phpcbf -p --standard=vendor/spryker/code-sniffer/SprykerStrict/ruleset.xml src/ tests/" + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "config": { + "sort-packages": true, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + } +} diff --git a/data/translation/Zed/de_DE.csv b/data/translation/Zed/de_DE.csv new file mode 100644 index 0000000..082b711 --- /dev/null +++ b/data/translation/Zed/de_DE.csv @@ -0,0 +1,8 @@ +"Application %application% is not valid.","Anwendung %application% ist ungültig." +"Default store context do not exist in the store context collection.","Standardeinstellungen sind in der Store-Einstellungen Collection nicht vorhanden." +"Application %application% is used more than once.","Anwendung %application% wird mehr als einmal verwendet." +"Timezone %timezone% is not valid.","Zeitzone %timezone% ist ungültig." +"Store context already exist for id: %id%.","Speichereinstellungen existieren bereits für ID: %id%." +"Store context not found for store id: %id%.","Speichereinstellungen für Store-ID: %id% nicht gefunden." +"Store context collection is missing.","Die Sammlung der Speichereinstellungen fehlt." +"Store is missing in store context.","Der Store fehlt im Store-Kontext." diff --git a/data/translation/Zed/en_US.csv b/data/translation/Zed/en_US.csv new file mode 100644 index 0000000..09e3274 --- /dev/null +++ b/data/translation/Zed/en_US.csv @@ -0,0 +1,8 @@ +"Application %application% is not valid.","Application %application% is not valid." +"Default store context do not exist in the store context collection.","Default settings do not exist in the store settings collection." +"Application %application% is used more than once.","Application %application% is used more than once." +"Timezone %timezone% is not valid.","Timezone %timezone% is not valid." +"Store context already exist for id: %id%.","Store settings already exist for id: %id%." +"Store context not found for store id: %id%.","Store settings not found for store id: %id%." +"Store context collection is missing.","Store settings collection is missing." +"Store is missing in store context.","Store is missing in store context." diff --git a/dependency.json b/dependency.json new file mode 100644 index 0000000..1932e90 --- /dev/null +++ b/dependency.json @@ -0,0 +1,5 @@ +{ + "include": { + "spryker/transfer": "Provides transfer objects definition with strict types." + } +} diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..e435fc2 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,3 @@ +parameters: + level: 8 + checkGenericClassInNonGenericObjectType: false diff --git a/psalm-report.json b/psalm-report.json new file mode 100644 index 0000000..a6ed8da --- /dev/null +++ b/psalm-report.json @@ -0,0 +1,5 @@ +{ + "error": [], + "warning": [], + "deprecation": [] +} diff --git a/src/Spryker/Shared/StoreContext/Transfer/store_context.transfer.xml b/src/Spryker/Shared/StoreContext/Transfer/store_context.transfer.xml new file mode 100644 index 0000000..704cf6a --- /dev/null +++ b/src/Spryker/Shared/StoreContext/Transfer/store_context.transfer.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Spryker/Zed/StoreContext/Business/Creator/StoreContextCreator.php b/src/Spryker/Zed/StoreContext/Business/Creator/StoreContextCreator.php new file mode 100644 index 0000000..4bbf0ee --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Creator/StoreContextCreator.php @@ -0,0 +1,55 @@ +storeContextWriter = $storeContextWriter; + $this->storeContextValidator = $storeContextValidator; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + public function createStoreContextCollection( + StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + ): StoreContextCollectionResponseTransfer { + $storeContextCollectionResponseTransfer = $this->storeContextValidator->validateStoreContextCollection($storeContextCollectionRequestTransfer); + + if (count($storeContextCollectionResponseTransfer->getErrors()) > 0) { + return $storeContextCollectionResponseTransfer; + } + + return $this->storeContextWriter->createStoreContextCollection($storeContextCollectionRequestTransfer); + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Creator/StoreContextCreatorInterface.php b/src/Spryker/Zed/StoreContext/Business/Creator/StoreContextCreatorInterface.php new file mode 100644 index 0000000..a6436c3 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Creator/StoreContextCreatorInterface.php @@ -0,0 +1,21 @@ +storeContextReader = $storeContextReader; + } + + /** + * @param \Generated\Shared\Transfer\StoreCollectionTransfer $storeCollectionTransfer + * + * @return \Generated\Shared\Transfer\StoreCollectionTransfer + */ + public function expandStoreCollectionTransferWithStoreContext(StoreCollectionTransfer $storeCollectionTransfer): StoreCollectionTransfer + { + $indexedStoreApplicationContextCollectionTransfer = $this->storeContextReader->getStoreApplicationContextCollectionsIndexedByIdStore($storeCollectionTransfer); + + /** @var \Generated\Shared\Transfer\StoreTransfer $storeTransfer */ + foreach ($storeCollectionTransfer->getStores() as $storeTransfer) { + $storeTransfer->setApplicationContextCollection($indexedStoreApplicationContextCollectionTransfer[$storeTransfer->getIdStoreOrFail()] ?? null); + } + + return $storeCollectionTransfer; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Expander/StoreExpanderInterface.php b/src/Spryker/Zed/StoreContext/Business/Expander/StoreExpanderInterface.php new file mode 100644 index 0000000..4c81ba7 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Expander/StoreExpanderInterface.php @@ -0,0 +1,20 @@ +storeContextRepository = $storeContextRepository; + } + + /** + * @param int $idStore + * + * @return \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer + */ + public function getStoreApplicationContextCollectionByIdStore(int $idStore): StoreApplicationContextCollectionTransfer + { + return $this->storeContextRepository->findStoreApplicationContextCollectionByIdStore($idStore) ?? new StoreApplicationContextCollectionTransfer(); + } + + /** + * @param \Generated\Shared\Transfer\StoreCollectionTransfer $storeCollectionTransfer + * + * @return array + */ + public function getStoreApplicationContextCollectionsIndexedByIdStore(StoreCollectionTransfer $storeCollectionTransfer): array + { + return $this->storeContextRepository->getStoreApplicationContextCollectionsIndexedByIdStore( + $this->extractStoreIdsFromStoreCollectionTransfer($storeCollectionTransfer), + ); + } + + /** + * @param \Generated\Shared\Transfer\StoreCollectionTransfer $storeCollectionTransfer + * + * @return array + */ + protected function extractStoreIdsFromStoreCollectionTransfer(StoreCollectionTransfer $storeCollectionTransfer): array + { + $storeIds = []; + + /** + * @var \Generated\Shared\Transfer\StoreTransfer $storeTransfer + */ + foreach ($storeCollectionTransfer->getStores() as $storeTransfer) { + $storeIds[] = $storeTransfer->getIdStoreOrFail(); + } + + return $storeIds; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Reader/StoreContextReaderInterface.php b/src/Spryker/Zed/StoreContext/Business/Reader/StoreContextReaderInterface.php new file mode 100644 index 0000000..e83b25a --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Reader/StoreContextReaderInterface.php @@ -0,0 +1,28 @@ + + */ + public function getStoreApplicationContextCollectionsIndexedByIdStore(StoreCollectionTransfer $storeCollectionTransfer): array; + + /** + * @param int $idStore + * + * @return \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer + */ + public function getStoreApplicationContextCollectionByIdStore(int $idStore): StoreApplicationContextCollectionTransfer; +} diff --git a/src/Spryker/Zed/StoreContext/Business/Reader/TimezoneReader.php b/src/Spryker/Zed/StoreContext/Business/Reader/TimezoneReader.php new file mode 100644 index 0000000..34d7832 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Reader/TimezoneReader.php @@ -0,0 +1,19 @@ + + */ + public function getAvailableTimezones(): array + { + return timezone_identifiers_list(); + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Reader/TimezoneReaderInterface.php b/src/Spryker/Zed/StoreContext/Business/Reader/TimezoneReaderInterface.php new file mode 100644 index 0000000..4c68632 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Reader/TimezoneReaderInterface.php @@ -0,0 +1,16 @@ + + */ + public function getAvailableTimezones(): array; +} diff --git a/src/Spryker/Zed/StoreContext/Business/StoreContextBusinessFactory.php b/src/Spryker/Zed/StoreContext/Business/StoreContextBusinessFactory.php new file mode 100644 index 0000000..103b905 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/StoreContextBusinessFactory.php @@ -0,0 +1,212 @@ +createStoreContextReader(), + ); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Writer\StoreContextWriterInterface + */ + public function createStoreContextWriter(): StoreContextWriterInterface + { + return new StoreContextWriter($this->getEntityManager()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Reader\StoreContextReaderInterface + */ + public function createStoreContextReader(): StoreContextReaderInterface + { + return new StoreContextReader($this->getRepository()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Creator\StoreContextCreatorInterface + */ + public function createStoreContextCreator(): StoreContextCreatorInterface + { + return new StoreContextCreator( + $this->createStoreContextWriter(), + $this->createStoreContextCreateValidator(), + ); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Updater\StoreContextUpdaterInterface + */ + public function createStoreContextUpdater(): StoreContextUpdaterInterface + { + return new StoreContextUpdater( + $this->createStoreContextWriter(), + $this->createStoreContextUpdateValidator(), + ); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\StoreContextValidatorInterface + */ + public function createStoreContextCreateValidator(): StoreContextValidatorInterface + { + return new StoreContextValidator($this->getCreateValidatorRules()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\StoreContextValidatorInterface + */ + public function createStoreContextUpdateValidator(): StoreContextValidatorInterface + { + return new StoreContextValidator($this->getUpdateValidatorRules()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\StoreContextValidatorInterface + */ + public function createStoreContextValidator(): StoreContextValidatorInterface + { + return new StoreContextValidator($this->getDefaultValidatorRules()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Reader\TimezoneReaderInterface + */ + public function createTimezoneReader(): TimezoneReaderInterface + { + return new TimezoneReader(); + } + + /** + * @return array<\Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface> + */ + public function getDefaultValidatorRules(): array + { + return [ + $this->createApplicationRule(), + $this->createDefaultConfigurationRule(), + $this->createOneContextPerApplicationRule(), + $this->createTimezoneRule(), + ]; + } + + /** + * @return array<\Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface> + */ + public function getCreateValidatorRules(): array + { + return [ + $this->createContextAlreadyExistRule(), + $this->createApplicationRule(), + $this->createDefaultConfigurationRule(), + $this->createOneContextPerApplicationRule(), + $this->createTimezoneRule(), + ]; + } + + /** + * @return array<\Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface> + */ + public function getUpdateValidatorRules(): array + { + return [ + $this->createContextNotFoundRule(), + $this->createApplicationRule(), + $this->createDefaultConfigurationRule(), + $this->createOneContextPerApplicationRule(), + $this->createTimezoneRule(), + ]; + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + public function createTimezoneRule(): StoreContextValidatorRuleInterface + { + return new TimezoneRule($this->createTimezoneReader()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + public function createOneContextPerApplicationRule(): StoreContextValidatorRuleInterface + { + return new OneContextPerApplicationRule($this->getConfig()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + public function createDefaultConfigurationRule(): StoreContextValidatorRuleInterface + { + return new DefaultContextExistRule(); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + public function createApplicationRule(): StoreContextValidatorRuleInterface + { + return new ApplicationRule($this->getConfig()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + public function createContextAlreadyExistRule(): StoreContextValidatorRuleInterface + { + return new ContextAlreadyExistRule( + $this->createStoreContextReader(), + ); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + public function createContextNotFoundRule(): StoreContextValidatorRuleInterface + { + return new ContextNotFoundRule( + $this->createStoreContextReader(), + ); + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/StoreContextFacade.php b/src/Spryker/Zed/StoreContext/Business/StoreContextFacade.php new file mode 100644 index 0000000..b1704c5 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/StoreContextFacade.php @@ -0,0 +1,115 @@ +getFactory() + ->createStoreExpander() + ->expandStoreCollectionTransferWithStoreContext($storeCollectionTransfer); + } + + /** + * {@inheritDoc} + * + * @api + * + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + public function validateStoreContextCollection( + StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + ): StoreContextCollectionResponseTransfer { + return $this->getFactory() + ->createStoreContextValidator() + ->validateStoreContextCollection($storeContextCollectionRequestTransfer); + } + + /** + * {@inheritDoc} + * + * @api + * + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + public function createStoreContextCollection( + StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + ): StoreContextCollectionResponseTransfer { + return $this->getFactory() + ->createStoreContextCreator() + ->createStoreContextCollection($storeContextCollectionRequestTransfer); + } + + /** + * {@inheritDoc} + * + * @api + * + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + public function updateStoreContextCollection(StoreContextCollectionRequestTransfer $storeCollectionRequestTransfer): StoreContextCollectionResponseTransfer + { + return $this->getFactory() + ->createStoreContextUpdater() + ->updateStoreContextCollection($storeCollectionRequestTransfer); + } + + /** + * {@inheritDoc} + * + * @api + * + * @return array + */ + public function getAvilableTimeZones(): array + { + return $this->getFactory() + ->createTimezoneReader() + ->getAvailableTimezones(); + } + + /** + * {@inheritDoc} + * + * @api + * + * @return array + */ + public function getAvilableApplications(): array + { + return $this->getFactory() + ->getConfig() + ->getStoreContextApplications(); + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/StoreContextFacadeInterface.php b/src/Spryker/Zed/StoreContext/Business/StoreContextFacadeInterface.php new file mode 100644 index 0000000..9a23dc9 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/StoreContextFacadeInterface.php @@ -0,0 +1,92 @@ + + */ + public function getAvilableTimeZones(): array; + + /** + * Specification: + * - Gets available application names. + * + * @api + * + * @return array + */ + public function getAvilableApplications(): array; +} diff --git a/src/Spryker/Zed/StoreContext/Business/Updater/StoreContextUpdater.php b/src/Spryker/Zed/StoreContext/Business/Updater/StoreContextUpdater.php new file mode 100644 index 0000000..cfbb85a --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Updater/StoreContextUpdater.php @@ -0,0 +1,55 @@ +storeContextWriter = $storeContextWriter; + $this->storeContextValidator = $storeContextValidator; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + public function updateStoreContextCollection( + StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + ): StoreContextCollectionResponseTransfer { + $storeContextCollectionResponseTransfer = $this->storeContextValidator->validateStoreContextCollection($storeContextCollectionRequestTransfer); + + if (count($storeContextCollectionResponseTransfer->getErrors()) > 0) { + return $storeContextCollectionResponseTransfer; + } + + return $this->storeContextWriter->updateStoreContextCollection($storeContextCollectionRequestTransfer); + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Updater/StoreContextUpdaterInterface.php b/src/Spryker/Zed/StoreContext/Business/Updater/StoreContextUpdaterInterface.php new file mode 100644 index 0000000..4c742d7 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Updater/StoreContextUpdaterInterface.php @@ -0,0 +1,21 @@ +storeContextConfig = $storeContextConfig; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + * + * @return array<\Generated\Shared\Transfer\ErrorTransfer> + */ + public function validateStoreContext(StoreContextTransfer $storeContextTransfer): array + { + $errorTransfers = []; + $storeContextApplications = $this->storeContextConfig->getStoreContextApplications(); + $storeApplicationContextTransfers = $storeContextTransfer->getApplicationContextCollectionOrFail()->getApplicationContexts(); + + foreach ($storeApplicationContextTransfers as $storeApplicationContextTransfer) { + $storeContextApplication = $storeApplicationContextTransfer->getApplication(); + + if ($storeContextApplication === null) { + continue; + } + + if (!in_array($storeContextApplication, $storeContextApplications)) { + $errorTransfers[] = (new ErrorTransfer()) + ->setMessage(static::ERROR_MESSAGE) + ->setEntityIdentifier($storeContextApplication) + ->setParameters([ + static::APPLICATION => $storeContextApplication, + ]); + } + } + + return $errorTransfers; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Validator/Rule/ContextAlreadyExistRule.php b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/ContextAlreadyExistRule.php new file mode 100644 index 0000000..fbb4fb4 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/ContextAlreadyExistRule.php @@ -0,0 +1,61 @@ +storeContextReader = $storeContextReader; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + * + * @return array<\Generated\Shared\Transfer\ErrorTransfer> + */ + public function validateStoreContext(StoreContextTransfer $storeContextTransfer): array + { + $storeId = $storeContextTransfer->getStoreOrFail()->getIdStoreOrFail(); + $storeContextCollectionTransfer = $this->storeContextReader->getStoreApplicationContextCollectionByIdStore($storeId); + + if ($storeContextCollectionTransfer->getApplicationContexts()->count() > 0) { + return [ + (new ErrorTransfer()) + ->setMessage(static::ERROR_MESSAGE_STORE_CONTEXT_EXISTS) + ->setParameters([ + static::PLACEHOLDER_ID => $storeId, + ]), + ]; + } + + return []; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Validator/Rule/ContextNotFoundRule.php b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/ContextNotFoundRule.php new file mode 100644 index 0000000..f03f1b7 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/ContextNotFoundRule.php @@ -0,0 +1,61 @@ +storeContextReader = $storeContextReader; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + * + * @return array<\Generated\Shared\Transfer\ErrorTransfer> + */ + public function validateStoreContext(StoreContextTransfer $storeContextTransfer): array + { + $storeId = $storeContextTransfer->getStoreOrFail()->getIdStoreOrFail(); + $storeContextCollectionTransfer = $this->storeContextReader->getStoreApplicationContextCollectionByIdStore($storeId); + + if ($storeContextCollectionTransfer->getApplicationContexts()->count() === 0) { + return [ + (new ErrorTransfer()) + ->setMessage(static::ERROR_MESSAGE_STORE_CONTEXT_NOT_FOUND) + ->setParameters([ + static::PLACEHOLDER_ID => $storeId, + ]), + ]; + } + + return []; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Validator/Rule/DefaultContextExistRule.php b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/DefaultContextExistRule.php new file mode 100644 index 0000000..372c702 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/DefaultContextExistRule.php @@ -0,0 +1,56 @@ + + */ + public function validateStoreContext(StoreContextTransfer $storeContextTransfer): array + { + $errorTransfers = []; + $defaultContextExists = false; + + /** + * @var \Generated\Shared\Transfer\StoreApplicationContextTransfer $storeApplicationContextTransfer + */ + foreach ($storeContextTransfer->getApplicationContextCollectionOrFail()->getApplicationContexts() as $storeApplicationContextTransfer) { + $storeContextApplication = $storeApplicationContextTransfer->getApplication(); + + if ($storeContextApplication === null) { + $defaultContextExists = true; + + break; + } + } + + if ($defaultContextExists === false) { + $errorTransfers[] = (new ErrorTransfer()) + ->setMessage(static::ERROR_MESSAGE) + ->setEntityIdentifier(static::APPLICATION); + } + + return $errorTransfers; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Validator/Rule/OneContextPerApplicationRule.php b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/OneContextPerApplicationRule.php new file mode 100644 index 0000000..b5b3f2e --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/OneContextPerApplicationRule.php @@ -0,0 +1,98 @@ +storeContextConfig = $storeContextConfig; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + * + * @return array<\Generated\Shared\Transfer\ErrorTransfer> + */ + public function validateStoreContext(StoreContextTransfer $storeContextTransfer): array + { + $errorTransfers = []; + foreach ($this->countStoreContextsPerApplications($storeContextTransfer->getApplicationContextCollectionOrFail()) as $storeContextApplication => $count) { + if ($count > 1) { + $errorTransfers[] = $this->createErrorTransfer($storeContextApplication); + } + } + + return $errorTransfers; + } + + /** + * @param string $storeContextApplication + * + * @return \Generated\Shared\Transfer\ErrorTransfer + */ + protected function createErrorTransfer(string $storeContextApplication): ErrorTransfer + { + return (new ErrorTransfer()) + ->setEntityIdentifier($storeContextApplication) + ->setMessage(static::ERROR_MESSAGE) + ->setParameters([ + static::APPLICATION => $storeContextApplication, + ]); + } + + /** + * @param \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer $storeApplicationContextCollectionTransfer + * + * @return array + */ + protected function countStoreContextsPerApplications(StoreApplicationContextCollectionTransfer $storeApplicationContextCollectionTransfer): array + { + $storeContextApplications = $this->storeContextConfig->getStoreContextApplications(); + + $storeContextApplicationsCount = []; + + /** + * @var \Generated\Shared\Transfer\StoreApplicationContextTransfer $storeApplicationContextTransfer + */ + foreach ($storeApplicationContextCollectionTransfer->getApplicationContexts() as $storeApplicationContextTransfer) { + $storeContextApplication = $storeApplicationContextTransfer->getApplication(); + + if (!isset($storeContextApplicationsCount[$storeContextApplication])) { + $storeContextApplicationsCount[$storeContextApplication] = 0; + } + + $storeContextApplicationsCount[$storeContextApplication]++; + } + + return $storeContextApplicationsCount; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Validator/Rule/StoreContextValidatorRuleInterface.php b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/StoreContextValidatorRuleInterface.php new file mode 100644 index 0000000..9a9da36 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/StoreContextValidatorRuleInterface.php @@ -0,0 +1,20 @@ + + */ + public function validateStoreContext(StoreContextTransfer $storeContextTransfer): array; +} diff --git a/src/Spryker/Zed/StoreContext/Business/Validator/Rule/TimezoneRule.php b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/TimezoneRule.php new file mode 100644 index 0000000..0f7b36f --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Validator/Rule/TimezoneRule.php @@ -0,0 +1,65 @@ +timezoneReader = $timezoneReader; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + * + * @return array<\Generated\Shared\Transfer\ErrorTransfer> + */ + public function validateStoreContext(StoreContextTransfer $storeContextTransfer): array + { + $errorTransfers = []; + /** + * @var \Generated\Shared\Transfer\StoreApplicationContextTransfer $storeApplicationContextTransfer + */ + foreach ($storeContextTransfer->getApplicationContextCollectionOrFail()->getApplicationContexts() as $storeApplicationContextTransfer) { + $storeApplicationContextTimezone = $storeApplicationContextTransfer->getTimezone(); + + if (!in_array($storeApplicationContextTimezone, $this->timezoneReader->getAvailableTimezones())) { + $errorTransfers[] = (new ErrorTransfer()) + ->setMessage(static::ERROR_MESSAGE) + ->setEntityIdentifier($storeApplicationContextTimezone) + ->setParameters([ + static::TIMEZONE => $storeApplicationContextTimezone, + ]); + } + } + + return $errorTransfers; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Validator/StoreContextValidator.php b/src/Spryker/Zed/StoreContext/Business/Validator/StoreContextValidator.php new file mode 100644 index 0000000..7baec67 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Validator/StoreContextValidator.php @@ -0,0 +1,113 @@ + + */ + protected array $validatorRules = []; + + /** + * @param array<\Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface> $validatorRules + */ + public function __construct(array $validatorRules) + { + $this->validatorRules = $validatorRules; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + public function validateStoreContextCollection( + StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + ): StoreContextCollectionResponseTransfer { + $storeContextCollectionResponseTransfer = new StoreContextCollectionResponseTransfer(); + + foreach ($storeContextCollectionRequestTransfer->getContexts() as $storeContextTransfer) { + $errorTransfers = $this->validateStoreContext($storeContextTransfer); + + if (count($errorTransfers) === 0) { + $storeContextCollectionResponseTransfer->addContext($storeContextTransfer); + + continue; + } + + $storeContextCollectionResponseTransfer = $this->addErrorsToResponse($storeContextCollectionResponseTransfer, $errorTransfers); + } + + return $storeContextCollectionResponseTransfer; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer $storeContextCollectionResponseTransfer + * @param array<\Generated\Shared\Transfer\ErrorTransfer> $errorTransfers + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + protected function addErrorsToResponse( + StoreContextCollectionResponseTransfer $storeContextCollectionResponseTransfer, + array $errorTransfers + ): StoreContextCollectionResponseTransfer { + /** @var \Generated\Shared\Transfer\ErrorTransfer $errorTransfer */ + foreach ($errorTransfers as $errorTransfer) { + $storeContextCollectionResponseTransfer->addError($errorTransfer); + } + + return $storeContextCollectionResponseTransfer; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + * + * @return array<\Generated\Shared\Transfer\ErrorTransfer> + */ + protected function validateStoreContext(StoreContextTransfer $storeContextTransfer): array + { + $errorTransfers = []; + + if ($storeContextTransfer->getStore() === null) { + $errorTransfers[] = (new ErrorTransfer())->setMessage(static::ERROR_MESSAGE_STORE_MISSING); + } + + if ($storeContextTransfer->getApplicationContextCollection() === null) { + $errorTransfers[] = + (new ErrorTransfer()) + ->setMessage(static::ERROR_MESSAGE_STORE_CONTEXT_COLLECTION_MISSING) + ->setEntityIdentifier($storeContextTransfer->getStoreOrFail()->getName()); + } + + if (count($errorTransfers) > 0) { + return $errorTransfers; + } + + foreach ($this->validatorRules as $validatorRule) { + $errorTransfers = array_merge($errorTransfers, $validatorRule->validateStoreContext($storeContextTransfer)); + } + + return $errorTransfers; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Validator/StoreContextValidatorInterface.php b/src/Spryker/Zed/StoreContext/Business/Validator/StoreContextValidatorInterface.php new file mode 100644 index 0000000..5fb3db8 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Validator/StoreContextValidatorInterface.php @@ -0,0 +1,23 @@ +storeContextEntityManager = $storeContextEntityManager; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + public function createStoreContextCollection( + StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + ): StoreContextCollectionResponseTransfer { + return $this->getTransactionHandler()->handleTransaction(function () use ($storeContextCollectionRequestTransfer) { + return $this->executeCreateStoreContextCollectionTransaction($storeContextCollectionRequestTransfer); + }); + } + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + protected function executeCreateStoreContextCollectionTransaction( + StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + ): StoreContextCollectionResponseTransfer { + $storeContextCollectionResponseTransfer = new StoreContextCollectionResponseTransfer(); + + /** + * @var \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + */ + foreach ($storeContextCollectionRequestTransfer->getContexts() as $storeContextTransfer) { + $storeContextTransfer = $this->storeContextEntityManager->createStoreContext($storeContextTransfer); + $storeContextCollectionResponseTransfer->addContext($storeContextTransfer); + } + + return $storeContextCollectionResponseTransfer; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + public function updateStoreContextCollection( + StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + ): StoreContextCollectionResponseTransfer { + return $this->getTransactionHandler()->handleTransaction(function () use ($storeContextCollectionRequestTransfer) { + return $this->executeUpdateStoreContextCollectionTransaction($storeContextCollectionRequestTransfer); + }); + } + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer + */ + protected function executeUpdateStoreContextCollectionTransaction( + StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + ): StoreContextCollectionResponseTransfer { + $storeContextCollectionResponseTransfer = new StoreContextCollectionResponseTransfer(); + + foreach ($storeContextCollectionRequestTransfer->getContexts() as $storeContextTransfer) { + $storeContextTransfer = $this->storeContextEntityManager->updateStoreContext($storeContextTransfer); + if ($storeContextTransfer->getApplicationContextCollection() !== null) { + $storeContextCollectionResponseTransfer->addContext($storeContextTransfer); + + continue; + } + + $storeContextCollectionResponseTransfer->addError( + (new ErrorTransfer()) + ->setMessage(static::ERROR_MESSAGE_FAILED_TO_UPDATE_STORE_CONTEXT) + ->setEntityIdentifier((string)$storeContextTransfer->getStoreOrFail()->getIdStore()) + ->setParameters( + [ + static::ERROR_MESSAGE_STORE_PLACEHOLDER => $storeContextTransfer->getStoreOrFail()->getNameOrFail(), + ], + ), + ); + } + + return $storeContextCollectionResponseTransfer; + } +} diff --git a/src/Spryker/Zed/StoreContext/Business/Writer/StoreContextWriterInterface.php b/src/Spryker/Zed/StoreContext/Business/Writer/StoreContextWriterInterface.php new file mode 100644 index 0000000..822d60f --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Business/Writer/StoreContextWriterInterface.php @@ -0,0 +1,32 @@ + $storeTransfers + * + * @return \Generated\Shared\Transfer\StoreCollectionTransfer + */ + public function mapStoreTransfersToStoreCollectionTransfer(array $storeTransfers): StoreCollectionTransfer + { + $storeCollectionTransfer = new StoreCollectionTransfer(); + + foreach ($storeTransfers as $storeTransfer) { + $storeCollectionTransfer->addStore($storeTransfer); + } + + return $storeCollectionTransfer; + } + + /** + * @param \Generated\Shared\Transfer\StoreCollectionTransfer $storeCollectionTransfer + * + * @return array<\Generated\Shared\Transfer\StoreTransfer> + */ + public function mapStoreCollectionTransferToStoreTransfers(StoreCollectionTransfer $storeCollectionTransfer): array + { + $storeTransfers = []; + foreach ($storeCollectionTransfer->getStores() as $storeTransfer) { + $storeTransfers[] = $storeTransfer; + } + + return $storeTransfers; + } + + /** + * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer + */ + public function mapStoreTranferToStoreContextCollectionRequestTransfer(StoreTransfer $storeTransfer): StoreContextCollectionRequestTransfer + { + $storeContextCollectionRequestTransfer = new StoreContextCollectionRequestTransfer(); + + $storeContextCollectionRequestTransfer->addContext( + (new StoreContextTransfer())->setStore($storeTransfer)->setApplicationContextCollection( + $storeTransfer->getapplicationContextCollection(), + ), + ); + + return $storeContextCollectionRequestTransfer; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer $storeContextCollectionResponseTransfer + * + * @return \Generated\Shared\Transfer\StoreResponseTransfer + */ + public function mapStoreContextCollectionResponseTranferToStoreResponseTransfer( + StoreContextCollectionResponseTransfer $storeContextCollectionResponseTransfer + ): StoreResponseTransfer { + $storeResponseTransfer = new StoreResponseTransfer(); + + $storeResponseTransfer->setIsSuccessful(count($storeContextCollectionResponseTransfer->getErrors()) === 0); + if (count($storeContextCollectionResponseTransfer->getContexts()) > 0) { + $storeResponseTransfer->setStore($storeContextCollectionResponseTransfer->getContexts()[0]->getStore()); + } + + $storeResponseTransfer->setMessages($this->mapErrorTransfersToMessageTransfers($storeContextCollectionResponseTransfer->getErrors())); + + return $storeResponseTransfer; + } + + /** + * @param \ArrayObject $errorTransfers + * + * @return \ArrayObject<\Generated\Shared\Transfer\MessageTransfer> + */ + protected function mapErrorTransfersToMessageTransfers(ArrayObject $errorTransfers): ArrayObject + { + $messageTransfers = []; + + /** + * @var \Generated\Shared\Transfer\ErrorTransfer $errorTransfer + */ + foreach ($errorTransfers as $errorTransfer) { + $messageTransfers[] = (new MessageTransfer()) + ->setParameters($errorTransfer->getParameters()) + ->setValue($errorTransfer->getMessage()); + } + + return new ArrayObject($messageTransfers); + } +} diff --git a/src/Spryker/Zed/StoreContext/Communication/Mapper/StoreContextMapperInterface.php b/src/Spryker/Zed/StoreContext/Communication/Mapper/StoreContextMapperInterface.php new file mode 100644 index 0000000..669ab9e --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Communication/Mapper/StoreContextMapperInterface.php @@ -0,0 +1,47 @@ + $storeTransfers + * + * @return \Generated\Shared\Transfer\StoreCollectionTransfer + */ + public function mapStoreTransfersToStoreCollectionTransfer(array $storeTransfers): StoreCollectionTransfer; + + /** + * @param \Generated\Shared\Transfer\StoreCollectionTransfer $storeCollectionTransfer + * + * @return array<\Generated\Shared\Transfer\StoreTransfer> + */ + public function mapStoreCollectionTransferToStoreTransfers(StoreCollectionTransfer $storeCollectionTransfer): array; + + /** + * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer + * + * @return \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer + */ + public function mapStoreTranferToStoreContextCollectionRequestTransfer(StoreTransfer $storeTransfer): StoreContextCollectionRequestTransfer; + + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionResponseTransfer $storeContextCollectionResponseTransfer + * + * @return \Generated\Shared\Transfer\StoreResponseTransfer + */ + public function mapStoreContextCollectionResponseTranferToStoreResponseTransfer( + StoreContextCollectionResponseTransfer $storeContextCollectionResponseTransfer + ): StoreResponseTransfer; +} diff --git a/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStoreCollectionExpanderPlugin.php b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStoreCollectionExpanderPlugin.php new file mode 100644 index 0000000..db3c2bc --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStoreCollectionExpanderPlugin.php @@ -0,0 +1,42 @@ + $storeTransfers + * + * @return array<\Generated\Shared\Transfer\StoreTransfer> + */ + public function expand(array $storeTransfers): array + { + $storeCollectionTransfer = $this->getFactory() + ->createStoreContextMapper() + ->mapStoreTransfersToStoreCollectionTransfer($storeTransfers); + + return $this->getFactory() + ->createStoreContextMapper() + ->mapStoreCollectionTransferToStoreTransfers( + $this->getFacade()->expandStoreCollection($storeCollectionTransfer), + ); + } +} diff --git a/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostCreatePlugin.php b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostCreatePlugin.php new file mode 100644 index 0000000..179d491 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostCreatePlugin.php @@ -0,0 +1,40 @@ +getFactory()->createStoreContextMapper()->mapStoreContextCollectionResponseTranferToStoreResponseTransfer( + $this->getFacade()->createStoreContextCollection( + $this->getFactory()->createStoreContextMapper()->mapStoreTranferToStoreContextCollectionRequestTransfer($storeTransfer), + ), + ); + } +} diff --git a/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostUpdatePlugin.php b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostUpdatePlugin.php new file mode 100644 index 0000000..562c743 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostUpdatePlugin.php @@ -0,0 +1,40 @@ +getFactory()->createStoreContextMapper()->mapStoreContextCollectionResponseTranferToStoreResponseTransfer( + $this->getFacade()->updateStoreContextCollection( + $this->getFactory()->createStoreContextMapper()->mapStoreTranferToStoreContextCollectionRequestTransfer($storeTransfer), + ), + ); + } +} diff --git a/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreCreateValidationPlugin.php b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreCreateValidationPlugin.php new file mode 100644 index 0000000..70f967e --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreCreateValidationPlugin.php @@ -0,0 +1,40 @@ +getFactory()->createStoreContextMapper()->mapStoreContextCollectionResponseTranferToStoreResponseTransfer( + $this->getFacade()->validateStoreContextCollection( + $this->getFactory()->createStoreContextMapper()->mapStoreTranferToStoreContextCollectionRequestTransfer($storeTransfer), + ), + ); + } +} diff --git a/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreUpdateValidationPlugin.php b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreUpdateValidationPlugin.php new file mode 100644 index 0000000..a3f7696 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreUpdateValidationPlugin.php @@ -0,0 +1,40 @@ +getFactory()->createStoreContextMapper()->mapStoreContextCollectionResponseTranferToStoreResponseTransfer( + $this->getFacade()->validateStoreContextCollection( + $this->getFactory()->createStoreContextMapper()->mapStoreTranferToStoreContextCollectionRequestTransfer($storeTransfer), + ), + ); + } +} diff --git a/src/Spryker/Zed/StoreContext/Communication/StoreContextCommunicationFactory.php b/src/Spryker/Zed/StoreContext/Communication/StoreContextCommunicationFactory.php new file mode 100644 index 0000000..6655f42 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Communication/StoreContextCommunicationFactory.php @@ -0,0 +1,29 @@ +utilEncodingService = $utilEncodingService; + } + + /** + * @param array $value + * @param int|null $options + * @param int|null $depth + * + * @return string|null + */ + public function encodeJson(array $value, ?int $options = null, ?int $depth = null): ?string + { + return $this->utilEncodingService->encodeJson($value, $options, $depth); + } + + /** + * @param string $jsonValue + * @param bool $assoc Deprecated: `false` is deprecated, always use `true` for array return. + * @param int|null $depth + * @param int|null $options + * + * @return object|array|null + */ + public function decodeJson(string $jsonValue, bool $assoc = false, ?int $depth = null, ?int $options = null) + { + if ($assoc === false) { + trigger_error('Param #2 `$assoc` must be `true` as return of type `object` is not accepted.', E_USER_DEPRECATED); + } + + /** @phpstan-var array|null */ + return $this->utilEncodingService->decodeJson($jsonValue, $assoc, $depth, $options); + } +} diff --git a/src/Spryker/Zed/StoreContext/Dependency/Service/StoreContextToUtilEncodingServiceInterface.php b/src/Spryker/Zed/StoreContext/Dependency/Service/StoreContextToUtilEncodingServiceInterface.php new file mode 100644 index 0000000..e3d10fe --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Dependency/Service/StoreContextToUtilEncodingServiceInterface.php @@ -0,0 +1,30 @@ + $value + * @param int|null $options + * @param int|null $depth + * + * @return string|null + */ + public function encodeJson(array $value, ?int $options = null, ?int $depth = null): ?string; + + /** + * @param string $jsonValue + * @param bool $assoc Deprecated: `false` is deprecated, always use `true` for array return. + * @param int|null $depth + * @param int|null $options + * + * @return object|array|null + */ + public function decodeJson(string $jsonValue, bool $assoc = false, ?int $depth = null, ?int $options = null); +} diff --git a/src/Spryker/Zed/StoreContext/Persistence/Propel/AbstractSpyStoreContext.php b/src/Spryker/Zed/StoreContext/Persistence/Propel/AbstractSpyStoreContext.php new file mode 100644 index 0000000..c4cadf0 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Persistence/Propel/AbstractSpyStoreContext.php @@ -0,0 +1,23 @@ +utilEncodingService = $utilEncodingService; + } + + /** + * @param \Orm\Zed\StoreContext\Persistence\SpyStoreContext $storeContextEntity + * @param \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer $storeApplicationContextCollectionTransfer + * + * @return \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer + */ + public function mapStoreContextEntityToStoreApplicationContextCollectionTransfer( + SpyStoreContext $storeContextEntity, + StoreApplicationContextCollectionTransfer $storeApplicationContextCollectionTransfer + ): StoreApplicationContextCollectionTransfer { + $storeApplicationContextCollectionData = $this->utilEncodingService->decodeJson($storeContextEntity->getApplicationContextCollection(), true); + + if ($storeApplicationContextCollectionData === null || !is_array($storeApplicationContextCollectionData)) { + return $storeApplicationContextCollectionTransfer; + } + + $storeApplicationContextCollectionTransfer->fromArray($storeApplicationContextCollectionData); + + return $storeApplicationContextCollectionTransfer; + } + + /** + * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + * @param \Orm\Zed\StoreContext\Persistence\SpyStoreContext $storeContextEntity + * + * @return \Orm\Zed\StoreContext\Persistence\SpyStoreContext + */ + public function mapStoreContextTransferToStoreContextEntity( + StoreContextTransfer $storeContextTransfer, + SpyStoreContext $storeContextEntity + ): SpyStoreContext { + $storeContextEntity->setFkStore($storeContextTransfer->getStoreOrFail()->getIdStoreOrFail()); + $storeContextEntity->setApplicationContextCollection( + $this->utilEncodingService->encodeJson($storeContextTransfer->getApplicationContextCollectionOrFail()->toArray()) ?? '{}', + ); + + return $storeContextEntity; + } + + /** + * @param \Orm\Zed\StoreContext\Persistence\SpyStoreContext $storeContextEntity + * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + * + * @return \Generated\Shared\Transfer\StoreContextTransfer + */ + public function mapStoreContextEntityToStoreContextTransfer( + SpyStoreContext $storeContextEntity, + StoreContextTransfer $storeContextTransfer + ): StoreContextTransfer { + $applicationContextCollection = $this->utilEncodingService->decodeJson($storeContextEntity->getApplicationContextCollection(), true); + + if (!is_array($applicationContextCollection)) { + return $storeContextTransfer; + } + + $storeContextTransfer->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer())->fromArray($applicationContextCollection), + ); + + return $storeContextTransfer; + } +} diff --git a/src/Spryker/Zed/StoreContext/Persistence/Propel/Schema/spy_store_context.schema.xml b/src/Spryker/Zed/StoreContext/Persistence/Propel/Schema/spy_store_context.schema.xml new file mode 100644 index 0000000..9cf49d6 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Persistence/Propel/Schema/spy_store_context.schema.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + +
+
diff --git a/src/Spryker/Zed/StoreContext/Persistence/StoreContextEntityManager.php b/src/Spryker/Zed/StoreContext/Persistence/StoreContextEntityManager.php new file mode 100644 index 0000000..580cf3d --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Persistence/StoreContextEntityManager.php @@ -0,0 +1,65 @@ +getFactory() + ->createStoreContextMapper() + ->mapStoreContextTransferToStoreContextEntity($storeContextTransfer, new SpyStoreContext()); + + $storeContextEntity->save(); + + return $this->getFactory()->createStoreContextMapper() + ->mapStoreContextEntityToStoreContextTransfer( + $storeContextEntity, + $storeContextTransfer, + ); + } + + /** + * @param \Generated\Shared\Transfer\StoreContextTransfer $storeContextTransfer + * + * @return \Generated\Shared\Transfer\StoreContextTransfer + */ + public function updateStoreContext(StoreContextTransfer $storeContextTransfer): StoreContextTransfer + { + $storeContextEntity = $this->getFactory() + ->createStoreContextQuery() + ->filterByFkStore($storeContextTransfer->getStoreOrFail()->getIdStoreOrFail()) + ->findOne(); + + if (!$storeContextEntity) { + return $storeContextTransfer; + } + + $storeContextEntity = $this->getFactory() + ->createStoreContextMapper() + ->mapStoreContextTransferToStoreContextEntity($storeContextTransfer, $storeContextEntity); + + $storeContextEntity->save(); + + return $this->getFactory() + ->createStoreContextMapper() + ->mapStoreContextEntityToStoreContextTransfer($storeContextEntity, $storeContextTransfer); + } +} diff --git a/src/Spryker/Zed/StoreContext/Persistence/StoreContextEntityManagerInterface.php b/src/Spryker/Zed/StoreContext/Persistence/StoreContextEntityManagerInterface.php new file mode 100644 index 0000000..fe9df8c --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Persistence/StoreContextEntityManagerInterface.php @@ -0,0 +1,27 @@ +getServiceUtilEncoding()); + } + + /** + * @return \Spryker\Zed\StoreContext\Dependency\Service\StoreContextToUtilEncodingServiceInterface + */ + public function getServiceUtilEncoding(): StoreContextToUtilEncodingServiceInterface + { + return $this->getProvidedDependency(StoreContextDependencyProvider::SERVICE_UTIL_ENCODING); + } +} diff --git a/src/Spryker/Zed/StoreContext/Persistence/StoreContextRepository.php b/src/Spryker/Zed/StoreContext/Persistence/StoreContextRepository.php new file mode 100644 index 0000000..9f692e6 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Persistence/StoreContextRepository.php @@ -0,0 +1,89 @@ +getFactory() + ->createStoreContextQuery() + ->filterByFkStore($idStore) + ->findOne(); + + if (!$storeContextEntity) { + return null; + } + + return $this->getFactory() + ->createStoreContextMapper() + ->mapStoreContextEntityToStoreApplicationContextCollectionTransfer( + $storeContextEntity, + new StoreApplicationContextCollectionTransfer(), + ); + } + + /** + * Result format: + * [ + * $idStore => StoreContextCollectionTransfer, + * ... + * ] + * + * @param array $storeIds + * + * @return array + */ + public function getStoreApplicationContextCollectionsIndexedByIdStore(array $storeIds): array + { + $storeContextEntityCollection = $this->getFactory() + ->createStoreContextQuery() + ->filterByFkStore_In($storeIds) + ->find(); + + if ($storeContextEntityCollection->count() === 0) { + return []; + } + + return $this->indexStoreApplicationContextCollectionTransfer($storeContextEntityCollection->getData()); + } + + /** + * @param array<\Orm\Zed\StoreContext\Persistence\SpyStoreContext> $storeContextEntities + * + * @return array<\Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer> + */ + protected function indexStoreApplicationContextCollectionTransfer(array $storeContextEntities): array + { + $storeApplicationContextCollectionTransfers = []; + + foreach ($storeContextEntities as $storeContextEntity) { + $storeContextCollectionTransfer = $this->getFactory() + ->createStoreContextMapper() + ->mapStoreContextEntityToStoreApplicationContextCollectionTransfer( + $storeContextEntity, + new StoreApplicationContextCollectionTransfer(), + ); + + $storeApplicationContextCollectionTransfers[$storeContextEntity->getFkStore()] = $storeContextCollectionTransfer; + } + + return $storeApplicationContextCollectionTransfers; + } +} diff --git a/src/Spryker/Zed/StoreContext/Persistence/StoreContextRepositoryInterface.php b/src/Spryker/Zed/StoreContext/Persistence/StoreContextRepositoryInterface.php new file mode 100644 index 0000000..556b8c1 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/Persistence/StoreContextRepositoryInterface.php @@ -0,0 +1,27 @@ + $storeIds + * + * @return array + */ + public function getStoreApplicationContextCollectionsIndexedByIdStore(array $storeIds): array; +} diff --git a/src/Spryker/Zed/StoreContext/StoreContextConfig.php b/src/Spryker/Zed/StoreContext/StoreContextConfig.php new file mode 100644 index 0000000..4c76421 --- /dev/null +++ b/src/Spryker/Zed/StoreContext/StoreContextConfig.php @@ -0,0 +1,33 @@ + + */ + public function getStoreContextApplications(): array + { + return [ + 'ZED', + 'YVES', + 'MERCHANT_PORTAL', + 'GLUE', + 'GLUE_STOREFRONT', + 'GLUE_BACKEND', + ]; + } +} diff --git a/src/Spryker/Zed/StoreContext/StoreContextDependencyProvider.php b/src/Spryker/Zed/StoreContext/StoreContextDependencyProvider.php new file mode 100644 index 0000000..6b4b77c --- /dev/null +++ b/src/Spryker/Zed/StoreContext/StoreContextDependencyProvider.php @@ -0,0 +1,67 @@ +addUtilEncodingService($container); + + return $container; + } + + /** + * @param \Spryker\Zed\Kernel\Container $container + * + * @return \Spryker\Zed\Kernel\Container + */ + public function providePersistenceLayerDependencies(Container $container): Container + { + $container = parent::providePersistenceLayerDependencies($container); + + $container = $this->addUtilEncodingService($container); + + return $container; + } + + /** + * @param \Spryker\Zed\Kernel\Container $container + * + * @return \Spryker\Zed\Kernel\Container + */ + protected function addUtilEncodingService(Container $container): Container + { + $container->set(static::SERVICE_UTIL_ENCODING, function (Container $container) { + return new StoreContextToUtilEncodingServiceBridge( + $container->getLocator()->utilEncoding()->service(), + ); + }); + + return $container; + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Business/StoreContextFacadeTest.php b/tests/SprykerTest/Zed/StoreContext/Business/StoreContextFacadeTest.php new file mode 100644 index 0000000..66b2e26 --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Business/StoreContextFacadeTest.php @@ -0,0 +1,229 @@ +tester->haveStore([$this->tester::FIELD_STORE_NAME => $this->tester::STORE_NAME_XX]); + $storeCollectionTransfer = (new StoreCollectionTransfer())->addStore($storeTransfer); + $storeContextTransfer = $this->tester->haveStoreContext($storeTransfer->getIdStore()); + + // Act + $storeCollectionTransfer = $this->tester->createStoreContextFacade()->expandStoreCollection($storeCollectionTransfer); + + // Assert + /** + * @var \Generated\Shared\Transfer\StoreTransfer $extendedStoreTransfer + */ + $extendedStoreTransfer = $storeCollectionTransfer->getStores()[0]; + $this->assertCount(1, $storeCollectionTransfer->getStores()); + $this->assertSame($storeTransfer->getIdStore(), $storeCollectionTransfer->getStores()[0]->getIdStore()); + $this->assertCount(count($storeContextTransfer->getApplicationContextCollection()->getApplicationContexts()), $extendedStoreTransfer->getApplicationContextCollection()->getApplicationContexts()); + $this->assertSame($this->tester::TIMEZONE_DEFAULT, $extendedStoreTransfer->getApplicationContextCollection()->getApplicationContexts()[0]->getTimezone()); + } + + /** + * @return void + */ + public function testExpandStoreCollectionIfStoreContextNotExistSuccessful(): void + { + // Arrange + $storeTransfer = $this->tester->haveStore([$this->tester::FIELD_STORE_NAME => $this->tester::STORE_NAME_XX]); + $storeCollectionTranfer = (new StoreCollectionTransfer())->addStore($storeTransfer); + + // Act + $storeCollectionTranfer = $this->tester->createStoreContextFacade()->expandStoreCollection($storeCollectionTranfer); + + // Assert + $this->assertCount(1, $storeCollectionTranfer->getStores()); + $this->assertNull($storeCollectionTranfer->getStores()[0]->getApplicationContextCollection()); + } + + /** + * @return void + */ + public function testValidateStoreContextCollectionSuccessful(): void + { + // Arrange + $storeTransfer = $this->tester->haveStore([$this->tester::FIELD_STORE_NAME => $this->tester::STORE_NAME_XX]); + $storeContextTransfer = $this->tester->haveStoreContext($storeTransfer->getIdStore()); + $storeContextCollectionRequestTransfer = (new StoreContextCollectionRequestTransfer())->addContext( + (new StoreContextTransfer())->setStore($storeTransfer)->setApplicationContextCollection( + $storeContextTransfer->getApplicationContextCollection(), + ), + ); + // Act + $storeContextCollectionResponseTransfer = $this->tester->createStoreContextFacade()->validateStoreContextCollection($storeContextCollectionRequestTransfer); + + // Assert + $this->assertCount(0, $storeContextCollectionResponseTransfer->getErrors()); + } + + /** + * @return void + */ + public function testCreateStoreContextCollectionReturnsResponseWithoutErrors(): void + { + // Arrange + $storeTransfer = $this->tester->haveStore([$this->tester::FIELD_STORE_NAME => $this->tester::STORE_NAME_XX]); + $storeContextCollectionRequestTransfer = (new StoreContextCollectionRequestTransfer())->addContext( + (new StoreContextTransfer())->setStore($storeTransfer) + ->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone($this->tester::TIMEZONE_DEFAULT), + )->addApplicationContext( + (new StoreApplicationContextTransfer()) + ->setTimezone($this->tester::TIMEZONE_DEFAULT) + ->setApplication($this->tester::APP_NAME), + ), + ), + ); + + // Act + $storeContextCollectionResponseTransfer = $this->tester->createStoreContextFacade()->createStoreContextCollection($storeContextCollectionRequestTransfer); + + // Assert + $this->assertCount(0, $storeContextCollectionResponseTransfer->getErrors()); + $this->assertCount(1, $storeContextCollectionResponseTransfer->getContexts()); + } + + /** + * @return void + */ + public function testCreateStoreContextCollectionReturnsErrorStoreContextAlreadyExists(): void + { + // Arrange + $storeTransfer = $this->tester->haveStore([$this->tester::FIELD_STORE_NAME => $this->tester::STORE_NAME_XX]); + $storeContextCollectionRequestTransfer = (new StoreContextCollectionRequestTransfer())->addContext( + (new StoreContextTransfer())->setStore($storeTransfer) + ->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone($this->tester::TIMEZONE_DEFAULT), + )->addApplicationContext( + (new StoreApplicationContextTransfer()) + ->setTimezone($this->tester::TIMEZONE_DEFAULT) + ->setApplication($this->tester::APP_NAME), + ), + ), + ); + $this->tester->createStoreContextFacade()->createStoreContextCollection($storeContextCollectionRequestTransfer); + + // Act + $storeContextCollectionResponseTransfer = $this->tester->createStoreContextFacade()->createStoreContextCollection($storeContextCollectionRequestTransfer); + + // Assert + $this->assertCount(1, $storeContextCollectionResponseTransfer->getErrors()); + $this->assertSame($this->tester::MESSAGE_STORE_CONTEXT_EXISTS, $storeContextCollectionResponseTransfer->getErrors()[0]->getMessage()); + } + + /** + * @return void + */ + public function testCreateStoreContextReturnErrorMessageStoreContextCollectionEmpty(): void + { + // Arrange + $storeTransfer = $this->tester->haveStore([$this->tester::FIELD_STORE_NAME => $this->tester::STORE_NAME_XX]); + $storeContextCollectionRequestTransfer = (new StoreContextCollectionRequestTransfer())->addContext( + (new StoreContextTransfer())->setStore($storeTransfer), + ); + + // Act + $storeContextCollectionResponseTransfer = $this->tester->createStoreContextFacade()->createStoreContextCollection($storeContextCollectionRequestTransfer); + + // Assert + $this->assertCount(1, $storeContextCollectionResponseTransfer->getErrors()); + $this->assertSame($this->tester::MESSAGE_STORE_CONTEXT_MISSING, $storeContextCollectionResponseTransfer->getErrors()[0]->getMessage()); + } + + /** + * @return void + */ + public function testUpdateStoreContextSuccessfull(): void + { + // Arrange + $storeTransfer = $this->tester->haveStore([$this->tester::FIELD_STORE_NAME => $this->tester::STORE_NAME_XX]); + $storeContextCollectionRequestTransfer = (new StoreContextCollectionRequestTransfer())->addContext( + (new StoreContextTransfer())->setStore($storeTransfer) + ->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone($this->tester::TIMEZONE_DEFAULT), + )->addApplicationContext( + (new StoreApplicationContextTransfer()) + ->setTimezone($this->tester::TIMEZONE_DEFAULT) + ->setApplication($this->tester::APP_NAME), + ), + ), + ); + $this->tester->createStoreContextFacade()->createStoreContextCollection($storeContextCollectionRequestTransfer); + + // Act + $storeContextCollectionResponseTransfer = $this->tester->createStoreContextFacade()->updateStoreContextCollection($storeContextCollectionRequestTransfer); + + // Assert + $this->assertCount(0, $storeContextCollectionResponseTransfer->getErrors()); + $this->assertCount(1, $storeContextCollectionResponseTransfer->getContexts()); + } + + /** + * @return void + */ + public function testUpdateStoreContextReturnErrorMessageStoreContextCollectionEmpty(): void + { + // Arrange + $storeTransfer = $this->tester->haveStore([$this->tester::FIELD_STORE_NAME => $this->tester::STORE_NAME_XX]); + $storeContextCollectionRequestTransfer = (new StoreContextCollectionRequestTransfer())->addContext( + (new StoreContextTransfer())->setStore($storeTransfer) + ->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone($this->tester::TIMEZONE_DEFAULT), + )->addApplicationContext( + (new StoreApplicationContextTransfer()) + ->setTimezone($this->tester::TIMEZONE_DEFAULT) + ->setApplication($this->tester::APP_NAME), + ), + ), + ); + + // Act + $storeContextCollectionResponseTransfer = $this->tester->createStoreContextFacade()->updateStoreContextCollection($storeContextCollectionRequestTransfer); + + // Assert + $this->assertCount(1, $storeContextCollectionResponseTransfer->getErrors()); + $this->assertSame($this->tester::MESSAGE_STORE_CONTEXT_DOESNT_EXIST, $storeContextCollectionResponseTransfer->getErrors()[0]->getMessage()); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ApplicationRuleTest.php b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ApplicationRuleTest.php new file mode 100644 index 0000000..1e15b75 --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ApplicationRuleTest.php @@ -0,0 +1,106 @@ +createApplicationRule(); + // Act + $errorTransfers = $rule->validateStoreContext($this->createStoreContextTransfer()); + + // Assert + $this->assertEmpty($errorTransfers); + } + + /** + * @return void + */ + public function testValidateStoreContextReturnsErrorMessageApplicationNotValid(): void + { + // Arrange + $rule = $this->createApplicationRule(); + + $storeContextTransfer = $this->createStoreContextTransfer(); + $storeContextTransfer->getApplicationContextCollection()->getApplicationContexts()[0]->setApplication('wrong'); + + // Act + $errorMessages = $rule->validateStoreContext($storeContextTransfer); + + // Assert + $this->assertCount(1, $errorMessages); + $this->assertSame($this->tester::MESSAGE_APP_NOT_VALID, $errorMessages[0]->getMessage()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + protected function createApplicationRule(): StoreContextValidatorRuleInterface + { + $mockStoreContextConfig = $this->createMock(StoreContextConfig::class); + $mockStoreContextConfig->method('getStoreContextApplications')->willReturn([$this->tester::APP_NAME, $this->tester::APP_NAME_YVES]); + + return new ApplicationRule($mockStoreContextConfig); + } + + /** + * @return \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer + */ + protected function createStoreApplicationContextCollectionTransfer(): StoreApplicationContextCollectionTransfer + { + return (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone($this->tester::TIMEZONE_DEFAULT), + )->addApplicationContext( + (new StoreApplicationContextTransfer())->setApplication($this->tester::APP_NAME)->setTimezone($this->tester::TIMEZONE_DEFAULT), + )->addApplicationContext( + (new StoreApplicationContextTransfer())->setApplication($this->tester::APP_NAME_YVES)->setTimezone($this->tester::TIMEZONE_ZED), + ); + } + + /** + * @return \Generated\Shared\Transfer\StoreContextTransfer + */ + protected function createStoreContextTransfer(): StoreContextTransfer + { + return (new StoreContextTransfer())->setApplicationContextCollection( + $this->createStoreApplicationContextCollectionTransfer(), + )->setStore((new StoreTransfer())->setIdStore(999)); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ContextAlreadyExistRuleTest.php b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ContextAlreadyExistRuleTest.php new file mode 100644 index 0000000..d6be90b --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ContextAlreadyExistRuleTest.php @@ -0,0 +1,113 @@ +createMock(StoreContextReaderInterface::class); + $readerMock->method('getStoreApplicationContextCollectionByIdStore') + ->willReturn((new StoreApplicationContextCollectionTransfer())); + + $rule = new ContextAlreadyExistRule($readerMock); + + // Act + $errorTransfers = $rule->validateStoreContext($this->createStoreContextTransfer()); + + // Assert + $this->assertEmpty($errorTransfers); + } + + /** + * @return void + */ + public function testValidateStoreContextReturnsErrorMessageStoreContextAlreadyExist(): void + { + // Arrange + $rule = $this->createApplicationRule(); + + $storeContextTransfer = $this->createStoreContextTransfer(); + + // Act + $errorMessages = $rule->validateStoreContext($storeContextTransfer); + + // Assert + $this->assertCount(1, $errorMessages); + $this->assertSame('Store context already exist for id: %id%.', $errorMessages[0]->getMessage()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + protected function createApplicationRule(): StoreContextValidatorRuleInterface + { + $readerMock = $this->createMock(StoreContextReaderInterface::class); + $readerMock->method('getStoreApplicationContextCollectionByIdStore') + ->willReturn((new StoreApplicationContextCollectionTransfer())->addApplicationContext( + new StoreApplicationContextTransfer(), + )); + + return new ContextAlreadyExistRule($readerMock); + } + + /** + * @return \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer + */ + protected function createStoreApplicationContextCollectionTransfer(): StoreApplicationContextCollectionTransfer + { + return (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone($this->tester::TIMEZONE_DEFAULT), + )->addApplicationContext( + (new StoreApplicationContextTransfer())->setApplication($this->tester::APP_NAME)->setTimezone($this->tester::TIMEZONE_DEFAULT), + )->addApplicationContext( + (new StoreApplicationContextTransfer())->setApplication($this->tester::APP_NAME_YVES)->setTimezone($this->tester::TIMEZONE_ZED), + ); + } + + /** + * @return \Generated\Shared\Transfer\StoreContextTransfer + */ + protected function createStoreContextTransfer(): StoreContextTransfer + { + return (new StoreContextTransfer())->setApplicationContextCollection( + $this->createStoreApplicationContextCollectionTransfer(), + )->setStore((new StoreTransfer())->setIdStore(999)); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ContextNotFoundRuleTest.php b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ContextNotFoundRuleTest.php new file mode 100644 index 0000000..3c21f99 --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/ContextNotFoundRuleTest.php @@ -0,0 +1,101 @@ +createMock(StoreContextReaderInterface::class); + $readerMock->method('getStoreApplicationContextCollectionByIdStore') + ->willReturn((new StoreApplicationContextCollectionTransfer())->addApplicationContext( + new StoreApplicationContextTransfer(), + )); + + $rule = new ContextNotFoundRule($readerMock); + + // Act + $errorTransfers = $rule->validateStoreContext($this->createStoreContextTransfer()); + + // Assert + $this->assertEmpty($errorTransfers); + } + + /** + * @return void + */ + public function testValidateStoreContextReturnsErrorMessageStoreContextNotFound(): void + { + // Arrange + $readerMock = $this->createMock(StoreContextReaderInterface::class); + $readerMock->method('getStoreApplicationContextCollectionByIdStore') + ->willReturn((new StoreApplicationContextCollectionTransfer())); + + $rule = new ContextNotFoundRule($readerMock); + + // Act + $errorMessages = $rule->validateStoreContext($this->createStoreContextTransfer()); + + // Assert + $this->assertCount(1, $errorMessages); + $this->assertSame('Store context not found for store id: %id%.', $errorMessages[0]->getMessage()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + protected function createApplicationRule(): StoreContextValidatorRuleInterface + { + $readerMock = $this->createMock(StoreContextReaderInterface::class); + $readerMock->method('getStoreApplicationContextCollectionByIdStore') + ->willReturn((new StoreApplicationContextCollectionTransfer())->addApplicationContext( + new StoreApplicationContextTransfer(), + )); + + return new ContextNotFoundRule($readerMock); + } + + /** + * @return \Generated\Shared\Transfer\StoreContextTransfer + */ + protected function createStoreContextTransfer(): StoreContextTransfer + { + return (new StoreContextTransfer())->setStore((new StoreTransfer())->setIdStore(999)); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/DefaultContextExistRuleTest.php b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/DefaultContextExistRuleTest.php new file mode 100644 index 0000000..e1f9238 --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/DefaultContextExistRuleTest.php @@ -0,0 +1,99 @@ +createDefaultConfigurationExistRule(); + + // Act + $messages = $rule->validateStoreContext($this->createStoreContextTransfer()); + + // Assert + $this->assertEmpty($messages); + } + + /** + * @return void + */ + public function testValidateStoreContextnReturnsErrorMessageDefaultContextNotExist(): void + { + // Arrange + $rule = $this->createDefaultConfigurationExistRule(); + + $storeContextTransfer = $this->createStoreContextTransfer(); + $storeContextTransfer->getApplicationContextCollection()->getApplicationContexts()[0]->setApplication($this->tester::APP_NAME_YVES); + + // Act + $messages = $rule->validateStoreContext($storeContextTransfer); + + // Assert + $this->assertCount(1, $messages); + $this->assertSame($this->tester::MESSAGE_DEFAULT_CONTEXT_NOT_EXIST, $messages[0]->getMessage()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + protected function createDefaultConfigurationExistRule(): StoreContextValidatorRuleInterface + { + return new DefaultContextExistRule(); + } + + /** + * @return \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer + */ + protected function createStoreApplicationContextCollectionTransfer(): StoreApplicationContextCollectionTransfer + { + return (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone($this->tester::TIMEZONE_DEFAULT), + ); + } + + /** + * @return \Generated\Shared\Transfer\StoreContextTransfer + */ + protected function createStoreContextTransfer(): StoreContextTransfer + { + return (new StoreContextTransfer())->setApplicationContextCollection( + $this->createStoreApplicationContextCollectionTransfer(), + )->setStore((new StoreTransfer())->setIdStore(999)); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/OneContextPerApplicationRuleTest.php b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/OneContextPerApplicationRuleTest.php new file mode 100644 index 0000000..e5b151d --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/OneContextPerApplicationRuleTest.php @@ -0,0 +1,113 @@ +createOneContextPerApplicationRule(); + + // Act + $messages = $rule->validateStoreContext($this->createStoreContextTransfer()); + + // Assert + $this->assertEmpty($messages); + } + + /** + * @return void + */ + public function testValidateStoreContextReturnsErrorMessageApplicationUsedMoreThenOnce(): void + { + // Arrange + $rule = $this->createOneContextPerApplicationRule(); + $storeContextTransfer = $this->createStoreContextTransfer(); + $storeContextTransfer->getApplicationContextCollection()->addApplicationContext( + (new StoreApplicationContextTransfer())->setApplication($this->tester::APP_NAME)->setTimezone($this->tester::TIMEZONE_DEFAULT), + ); + + // Act + $messages = $rule->validateStoreContext($storeContextTransfer); + + // Assert + $this->assertNotEmpty($messages); + $this->assertInstanceOf(ErrorTransfer::class, $messages[0]); + $this->assertSame(static::MESSAGE_APPLICATION_USED_MORE_THAN_ONCE, $messages[0]->getMessage()); + } + + /** + * @return \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer + */ + protected function createStoreApplicationContextCollectionTransfer(): StoreApplicationContextCollectionTransfer + { + return (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone($this->tester::TIMEZONE_DEFAULT), + )->addApplicationContext( + (new StoreApplicationContextTransfer())->setApplication($this->tester::APP_NAME)->setTimezone($this->tester::TIMEZONE_DEFAULT), + ); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + protected function createOneContextPerApplicationRule(): StoreContextValidatorRuleInterface + { + $mockStoreContextConfig = $this->createMock(StoreContextConfig::class); + $mockStoreContextConfig->method('getStoreContextApplications')->willReturn([$this->tester::APP_NAME, $this->tester::APP_NAME_YVES]); + + return new OneContextPerApplicationRule($mockStoreContextConfig); + } + + /** + * @return \Generated\Shared\Transfer\StoreContextTransfer + */ + protected function createStoreContextTransfer(): StoreContextTransfer + { + return (new StoreContextTransfer())->setApplicationContextCollection( + $this->createStoreApplicationContextCollectionTransfer(), + )->setStore((new StoreTransfer())->setIdStore(999)); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/TimezoneRuleTest.php b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/TimezoneRuleTest.php new file mode 100644 index 0000000..192c8d2 --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Business/Validator/Rule/TimezoneRuleTest.php @@ -0,0 +1,100 @@ +createTimezoneRule(); + $storeContextTransfer = (new StoreContextTransfer())->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone($this->tester::TIMEZONE_DEFAULT), + ), + )->setStore((new StoreTransfer())->setIdStore(999)); + + // Act + $messages = $rule->validateStoreContext($storeContextTransfer); + + // Assert + $this->assertEmpty($messages); + } + + /** + * @return void + */ + public function testValidateStoreContextReturnsErrorMessage(): void + { + // Arrange + $rule = $this->createTimezoneRule(); + $storeContextTransfer = (new StoreContextTransfer())->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone('invalid-timezone'), + ), + ) + ->setStore((new StoreTransfer())->setIdStore(999)); + + // Act + $messages = $rule->validateStoreContext($storeContextTransfer); + + // Assert + $this->assertNotEmpty($messages); + $this->assertSame('Timezone %timezone% is not valid.', $messages[0]->getMessage()); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\Validator\Rule\StoreContextValidatorRuleInterface + */ + protected function createTimezoneRule(): StoreContextValidatorRuleInterface + { + return new TimezoneRule( + new TimezoneReader(), + ); + } + + /** + * @return \Generated\Shared\Transfer\StoreContextTransfer + */ + protected function createStoreContextTransfer(): StoreContextTransfer + { + return (new StoreContextTransfer())->setApplicationContextCollection( + $this->createStoreApplicationContextCollectionTransfer(), + )->setStore((new StoreTransfer())->setIdStore(999)); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStoreCollectionExpanderPluginTest.php b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStoreCollectionExpanderPluginTest.php new file mode 100644 index 0000000..d1b1d84 --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStoreCollectionExpanderPluginTest.php @@ -0,0 +1,100 @@ +setIdStore(static::FIRST_STORE_ID), + (new StoreTransfer())->setIdStore(static::SECOND_STORE_ID), + ]; + $mockFacade = $this->createPartialMock(StoreContextFacade::class, ['expandStoreCollection']); + $mockFacade->method('expandStoreCollection') + ->with( + $this->callback( + /** + * @param \Generated\Shared\Transfer\StoreCollectionTransfer $storeCollectionTransfer + * + * @return bool + */ + function ($storeCollectionTransfer) { + return $storeCollectionTransfer->getStores()[0]->getIdStore() === static::FIRST_STORE_ID && + $storeCollectionTransfer->getStores()[1]->getIdStore() === static::SECOND_STORE_ID; + }, + ), + )->willReturn( + (new StoreCollectionTransfer()) + ->addStore( + (new StoreTransfer())->setIdStore(static::FIRST_STORE_ID), + )->addStore( + (new StoreTransfer())->setIdStore(static::SECOND_STORE_ID)->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer())->addApplicationContext( + (new StoreApplicationContextTransfer())->setTimezone('Europe/Berlin'), + ), + ), + ), + ); + $plugin->setFacade($mockFacade); + + // Act + $storeTransfersResult = $plugin->expand($storeTransfers); + + // Assert + $this->assertIsArray($storeTransfersResult); + $this->assertCount(2, $storeTransfersResult); + $this->assertInstanceOf(StoreTransfer::class, $storeTransfersResult[0]); + $this->assertInstanceOf(StoreTransfer::class, $storeTransfersResult[1]); + $this->assertEquals(100, $storeTransfersResult[0]->getIdStore()); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostCreatePluginTest.php b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostCreatePluginTest.php new file mode 100644 index 0000000..1fc1e92 --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostCreatePluginTest.php @@ -0,0 +1,83 @@ +setIdStore(static::DEFAULT_STORE_ID); + $mockFacade = $this->createPartialMock(StoreContextFacade::class, ['createStoreContextCollection']); + $mockFacade->method('createStoreContextCollection') + ->with( + $this->callback( + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return bool + */ + function ($storeContextCollectionRequestTransfer) { + return $storeContextCollectionRequestTransfer->getContexts()[0]->getStore()->getIdStore() === static::DEFAULT_STORE_ID; + }, + ), + )->willReturn( + (new StoreContextCollectionResponseTransfer()) + ->addContext( + (new StoreContextTransfer())->setStore( + (new StoreTransfer())->setIdStore(static::DEFAULT_STORE_ID), + )->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer()), + ), + ), + ); + + $plugin = new ContextStorePostCreatePlugin(); + $plugin->setFacade($mockFacade); + + // Act + $storeResponseTransfer = $plugin->execute($storeTransfer); + + // Assert + $this->assertEquals(static::DEFAULT_STORE_ID, $storeResponseTransfer->getStore()->getIdStore()); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostUpdatePluginTest.php b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostUpdatePluginTest.php new file mode 100644 index 0000000..e3c40aa --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePostUpdatePluginTest.php @@ -0,0 +1,83 @@ +setIdStore(static::DEFAULT_STORE_ID); + $mockFacade = $this->createPartialMock(StoreContextFacade::class, ['updateStoreContextCollection']); + $mockFacade->method('updateStoreContextCollection') + ->with( + $this->callback( + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return bool + */ + function ($storeContextCollectionRequestTransfer) { + return count($storeContextCollectionRequestTransfer->getContexts()) === 1 && $storeContextCollectionRequestTransfer->getContexts()[0]->getStore()->getIdStore() === static::DEFAULT_STORE_ID; + }, + ), + )->willReturn( + (new StoreContextCollectionResponseTransfer()) + ->addContext( + (new StoreContextTransfer())->setStore( + (new StoreTransfer())->setIdStore(static::DEFAULT_STORE_ID), + )->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer()), + ), + ), + ); + + $plugin = new ContextStorePostUpdatePlugin(); + $plugin->setFacade($mockFacade); + + // Act + $storeResponseTransfer = $plugin->execute($storeTransfer); + + // Assert + $this->assertEquals(static::DEFAULT_STORE_ID, $storeResponseTransfer->getStore()->getIdStore()); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreCreateValidationPluginTest.php b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreCreateValidationPluginTest.php new file mode 100644 index 0000000..d78bb93 --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreCreateValidationPluginTest.php @@ -0,0 +1,83 @@ +setIdStore(static::DEFAULT_STORE_ID); + $mockFacade = $this->createPartialMock(StoreContextFacade::class, ['validateStoreContextCollection']); + $mockFacade->method('validateStoreContextCollection') + ->with( + $this->callback( + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return bool + */ + function ($storeContextCollectionRequestTransfer) { + return count($storeContextCollectionRequestTransfer->getContexts()) === 1 && $storeContextCollectionRequestTransfer->getContexts()[0]->getStore()->getIdStore() === static::DEFAULT_STORE_ID; + }, + ), + )->willReturn( + (new StoreContextCollectionResponseTransfer()) + ->addContext( + (new StoreContextTransfer())->setStore( + (new StoreTransfer())->setIdStore(static::DEFAULT_STORE_ID), + )->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer()), + ), + ), + ); + + $plugin = new ContextStorePreCreateValidationPlugin(); + $plugin->setFacade($mockFacade); + + // Act + $storeResponseTransfer = $plugin->validate($storeTransfer); + + // Assert + $this->assertEquals(static::DEFAULT_STORE_ID, $storeResponseTransfer->getStore()->getIdStore()); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreUpdateValidationPluginTest.php b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreUpdateValidationPluginTest.php new file mode 100644 index 0000000..31135d0 --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/Communication/Plugin/Store/ContextStorePreUpdateValidationPluginTest.php @@ -0,0 +1,83 @@ +setIdStore(static::DEFAULT_STORE_ID); + $mockFacade = $this->createPartialMock(StoreContextFacade::class, ['validateStoreContextCollection']); + $mockFacade->method('validateStoreContextCollection') + ->with( + $this->callback( + /** + * @param \Generated\Shared\Transfer\StoreContextCollectionRequestTransfer $storeContextCollectionRequestTransfer + * + * @return bool + */ + function ($storeContextCollectionRequestTransfer) { + return count($storeContextCollectionRequestTransfer->getContexts()) === 1 && $storeContextCollectionRequestTransfer->getContexts()[0]->getStore()->getIdStore() === static::DEFAULT_STORE_ID; + }, + ), + )->willReturn( + (new StoreContextCollectionResponseTransfer()) + ->addContext( + (new StoreContextTransfer())->setStore( + (new StoreTransfer())->setIdStore(static::DEFAULT_STORE_ID), + )->setApplicationContextCollection( + (new StoreApplicationContextCollectionTransfer()), + ), + ), + ); + + $plugin = new ContextStorePreUpdateValidationPlugin(); + $plugin->setFacade($mockFacade); + + // Act + $storeResponseTransfer = $plugin->validate($storeTransfer); + + // Assert + $this->assertEquals(static::DEFAULT_STORE_ID, $storeResponseTransfer->getStore()->getIdStore()); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/_support/StoreContextBusinessTester.php b/tests/SprykerTest/Zed/StoreContext/_support/StoreContextBusinessTester.php new file mode 100644 index 0000000..25d1abd --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/_support/StoreContextBusinessTester.php @@ -0,0 +1,172 @@ +addContext( + (new StoreContextTransfer()) + ->setStore((new StoreTransfer())->setIdStore($idStore)) + ->setApplicationContextCollection($this->createDefaultStoreApplicationContextCollectionTransfer()), + ); + + $storeContextCollectionResponseTransfer = $this->getStoreContextFacade()->createStoreContextCollection( + $storeContextCollectionRequestTransfer, + ); + + return $storeContextCollectionResponseTransfer->getContexts()->offsetGet(0); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\StoreContextFacadeInterface + */ + public function createStoreContextFacade(): StoreContextFacadeInterface + { + return new StoreContextFacade(); + } + + /** + * @return \Generated\Shared\Transfer\StoreContextCollectionTransfer + */ + public function createStoreContextCollectionTransfer(): StoreContextCollectionTransfer + { + return new StoreContextCollectionTransfer(); + } + + /** + * @return \Spryker\Zed\StoreContext\Business\StoreContextFacadeInterface + */ + protected function getStoreContextFacade(): StoreContextFacadeInterface + { + return $this->getLocator()->storeContext()->facade(); + } + + /** + * @return \Generated\Shared\Transfer\StoreApplicationContextCollectionTransfer + */ + protected function createDefaultStoreApplicationContextCollectionTransfer(): StoreApplicationContextCollectionTransfer + { + return (new StoreApplicationContextCollectionTransfer()) + ->addApplicationContext( + (new StoreApplicationContextTransfer()) + ->setTimezone(static::TIMEZONE_BERLIN), + )->addApplicationContext( + (new StoreApplicationContextTransfer()) + ->setTimezone(static::TIMEZONE_LONDON) + ->setApplication(static::APPLICATION_ZED), + ); + } +} diff --git a/tests/SprykerTest/Zed/StoreContext/_support/StoreContextCommunicationTester.php b/tests/SprykerTest/Zed/StoreContext/_support/StoreContextCommunicationTester.php new file mode 100644 index 0000000..a40f7ef --- /dev/null +++ b/tests/SprykerTest/Zed/StoreContext/_support/StoreContextCommunicationTester.php @@ -0,0 +1,35 @@ +