From 05291a7c3f9577697e7db805c90ca6dd960917c2 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:30:03 +0200 Subject: [PATCH 01/60] Upgrade composer.json to Sylius 2 / PHP 8.2 / Symfony 7.4 - sylius/sylius ^2.0 replaces the individual sylius/* 1.x packages - symfony/* bumped to ^6.4||^7.4, doctrine/orm ^2.18||^3.3, doctrine/collections ^2.2 - adds sylius/test-application, drops jms/serializer-bundle - phpunit/behat bootstrap updated to the new test-application kernel --- .gitignore | 1 + behat.yml.dist | 36 ++---- composer.json | 122 ++++++++---------- phpunit.xml.dist | 4 +- tests/Application/.env | 47 ------- tests/Application/.env.test | 3 - tests/Application/.eslintrc.js | 20 --- tests/Application/.gitignore | 23 ---- .../Doctrine/ORM/CustomerRepository.php | 14 -- .../Doctrine/ORM/OrderRepository.php | 14 -- tests/Application/Kernel.php | 88 ------------- tests/Application/Model/Order.php | 29 ----- tests/Application/Model/OrderItem.php | 22 ---- tests/Application/Model/OrderItemUnit.php | 20 --- tests/Application/Model/Product.php | 20 --- tests/Application/assets/admin/entry.js | 1 - tests/Application/assets/shop/entry.js | 1 - tests/Application/bin/console | 38 ------ tests/Application/composer.json | 5 - .../config/api_platform/.gitignore | 0 tests/Application/config/bootstrap.php | 23 ---- tests/Application/config/bundles.php | 67 ---------- tests/Application/config/jwt/private.pem | 54 -------- tests/Application/config/jwt/public.pem | 14 -- .../Application/config/packages/_sylius.yaml | 40 ------ .../config/packages/api_platform.yaml | 9 -- tests/Application/config/packages/assets.yaml | 7 - .../config/packages/dev/debug.yaml | 4 - .../config/packages/dev/framework.yaml | 2 - .../config/packages/dev/jms_serializer.yaml | 12 -- .../config/packages/dev/monolog.yaml | 9 -- .../config/packages/dev/routing.yaml | 3 - .../config/packages/dev/web_profiler.yaml | 3 - .../Application/config/packages/doctrine.yaml | 25 ---- .../config/packages/doctrine_migrations.yaml | 4 - .../Application/config/packages/fos_rest.yaml | 11 -- .../config/packages/framework.yaml | 9 -- .../config/packages/jms_serializer.yaml | 4 - .../packages/lexik_jwt_authentication.yaml | 4 - .../config/packages/liip_imagine.yaml | 6 - tests/Application/config/packages/mailer.yaml | 3 - .../config/packages/prod/doctrine.yaml | 31 ----- .../config/packages/prod/jms_serializer.yaml | 10 -- .../config/packages/prod/monolog.yaml | 10 -- .../Application/config/packages/routing.yaml | 3 - .../Application/config/packages/security.yaml | 122 ------------------ .../packages/setono_sylius_gift_card.yaml | 3 - .../packages/stof_doctrine_extensions.yaml | 4 - .../config/packages/sylius_api.yaml | 2 - .../config/packages/test/framework.yaml | 4 - .../config/packages/test/mailer.yaml | 7 - .../config/packages/test/monolog.yaml | 6 - .../config/packages/test/security.yaml | 6 - .../test/setono_sylius_gift_card.yaml | 9 -- .../config/packages/test/sylius_theme.yaml | 3 - .../config/packages/test/web_profiler.yaml | 6 - .../config/packages/translation.yaml | 8 -- tests/Application/config/packages/twig.yaml | 12 -- .../config/packages/twig_extensions.yaml | 11 -- .../config/packages/validator.yaml | 3 - .../config/packages/webpack_encore.yaml | 5 - tests/Application/config/routes.yaml | 2 - .../config/routes/dev/web_profiler.yaml | 7 - .../config/routes/liip_imagine.yaml | 2 - .../config/routes/sylius_admin.yaml | 3 - .../Application/config/routes/sylius_api.yaml | 3 - .../config/routes/sylius_shop.yaml | 23 ---- .../Application/config/secrets/dev/.gitignore | 0 .../config/secrets/prod/.gitignore | 0 .../config/secrets/test/.gitignore | 0 .../config/secrets/test_cached/.gitignore | 0 .../config/serialization/.gitignore | 0 tests/Application/config/services.yaml | 4 - tests/Application/config/services_test.yaml | 3 - tests/Application/docker-compose.yaml | 8 -- tests/Application/package.json | 30 ----- tests/Application/public/.htaccess | 25 ---- tests/Application/public/favicon.ico | Bin 32038 -> 0 bytes tests/Application/public/index.php | 29 ----- .../Application/public/media/image/.gitignore | 0 tests/Application/public/robots.txt | 4 - tests/Application/templates/.gitignore | 0 .../Form/imagesTheme.html.twig | 17 --- .../Order/Show/Summary/_item.html.twig | 58 --------- .../Order/Show/Summary/_totals.html.twig | 67 ---------- .../Product/Tab/_details.html.twig | 70 ---------- .../bundles/SyliusAdminBundle/_logo.html.twig | 5 - .../SyliusAdminBundle/_scripts.html.twig | 1 - .../SyliusAdminBundle/_styles.html.twig | 1 - .../Cart/Summary/_items.html.twig | 36 ------ .../Cart/Summary/_totals.html.twig | 67 ---------- .../SyliusShopBundle/Cart/summary.html.twig | 31 ----- .../Checkout/_summary.html.twig | 89 ------------- .../Common/Order/Table/_totals.html.twig | 64 --------- .../Homepage/_banner.html.twig | 2 - .../Layout/Footer/Grid/_plus.html.twig | 9 -- .../Layout/Header/_logo.html.twig | 5 - .../Taxon/_horizontalMenu.html.twig | 25 ---- .../SyliusShopBundle/_scripts.html.twig | 1 - .../SyliusShopBundle/_styles.html.twig | 1 - .../bundles/SyliusShopBundle/layout.html.twig | 18 --- tests/Application/translations/.gitignore | 0 tests/Application/var/.gitignore | 0 tests/Application/webpack.config.js | 47 ------- 104 files changed, 73 insertions(+), 1770 deletions(-) delete mode 100644 tests/Application/.env delete mode 100644 tests/Application/.env.test delete mode 100644 tests/Application/.eslintrc.js delete mode 100644 tests/Application/.gitignore delete mode 100644 tests/Application/Doctrine/ORM/CustomerRepository.php delete mode 100644 tests/Application/Doctrine/ORM/OrderRepository.php delete mode 100644 tests/Application/Kernel.php delete mode 100644 tests/Application/Model/Order.php delete mode 100644 tests/Application/Model/OrderItem.php delete mode 100644 tests/Application/Model/OrderItemUnit.php delete mode 100644 tests/Application/Model/Product.php delete mode 100644 tests/Application/assets/admin/entry.js delete mode 100644 tests/Application/assets/shop/entry.js delete mode 100755 tests/Application/bin/console delete mode 100644 tests/Application/composer.json delete mode 100644 tests/Application/config/api_platform/.gitignore delete mode 100644 tests/Application/config/bootstrap.php delete mode 100644 tests/Application/config/bundles.php delete mode 100644 tests/Application/config/jwt/private.pem delete mode 100644 tests/Application/config/jwt/public.pem delete mode 100644 tests/Application/config/packages/_sylius.yaml delete mode 100644 tests/Application/config/packages/api_platform.yaml delete mode 100644 tests/Application/config/packages/assets.yaml delete mode 100644 tests/Application/config/packages/dev/debug.yaml delete mode 100644 tests/Application/config/packages/dev/framework.yaml delete mode 100644 tests/Application/config/packages/dev/jms_serializer.yaml delete mode 100644 tests/Application/config/packages/dev/monolog.yaml delete mode 100644 tests/Application/config/packages/dev/routing.yaml delete mode 100644 tests/Application/config/packages/dev/web_profiler.yaml delete mode 100644 tests/Application/config/packages/doctrine.yaml delete mode 100644 tests/Application/config/packages/doctrine_migrations.yaml delete mode 100644 tests/Application/config/packages/fos_rest.yaml delete mode 100644 tests/Application/config/packages/framework.yaml delete mode 100644 tests/Application/config/packages/jms_serializer.yaml delete mode 100644 tests/Application/config/packages/lexik_jwt_authentication.yaml delete mode 100644 tests/Application/config/packages/liip_imagine.yaml delete mode 100644 tests/Application/config/packages/mailer.yaml delete mode 100644 tests/Application/config/packages/prod/doctrine.yaml delete mode 100644 tests/Application/config/packages/prod/jms_serializer.yaml delete mode 100644 tests/Application/config/packages/prod/monolog.yaml delete mode 100644 tests/Application/config/packages/routing.yaml delete mode 100644 tests/Application/config/packages/security.yaml delete mode 100644 tests/Application/config/packages/setono_sylius_gift_card.yaml delete mode 100644 tests/Application/config/packages/stof_doctrine_extensions.yaml delete mode 100644 tests/Application/config/packages/sylius_api.yaml delete mode 100644 tests/Application/config/packages/test/framework.yaml delete mode 100644 tests/Application/config/packages/test/mailer.yaml delete mode 100644 tests/Application/config/packages/test/monolog.yaml delete mode 100644 tests/Application/config/packages/test/security.yaml delete mode 100644 tests/Application/config/packages/test/setono_sylius_gift_card.yaml delete mode 100644 tests/Application/config/packages/test/sylius_theme.yaml delete mode 100644 tests/Application/config/packages/test/web_profiler.yaml delete mode 100644 tests/Application/config/packages/translation.yaml delete mode 100644 tests/Application/config/packages/twig.yaml delete mode 100644 tests/Application/config/packages/twig_extensions.yaml delete mode 100644 tests/Application/config/packages/validator.yaml delete mode 100644 tests/Application/config/packages/webpack_encore.yaml delete mode 100644 tests/Application/config/routes.yaml delete mode 100644 tests/Application/config/routes/dev/web_profiler.yaml delete mode 100644 tests/Application/config/routes/liip_imagine.yaml delete mode 100644 tests/Application/config/routes/sylius_admin.yaml delete mode 100644 tests/Application/config/routes/sylius_api.yaml delete mode 100644 tests/Application/config/routes/sylius_shop.yaml delete mode 100644 tests/Application/config/secrets/dev/.gitignore delete mode 100644 tests/Application/config/secrets/prod/.gitignore delete mode 100644 tests/Application/config/secrets/test/.gitignore delete mode 100644 tests/Application/config/secrets/test_cached/.gitignore delete mode 100644 tests/Application/config/serialization/.gitignore delete mode 100644 tests/Application/config/services.yaml delete mode 100644 tests/Application/config/services_test.yaml delete mode 100644 tests/Application/docker-compose.yaml delete mode 100644 tests/Application/package.json delete mode 100644 tests/Application/public/.htaccess delete mode 100644 tests/Application/public/favicon.ico delete mode 100644 tests/Application/public/index.php delete mode 100644 tests/Application/public/media/image/.gitignore delete mode 100644 tests/Application/public/robots.txt delete mode 100644 tests/Application/templates/.gitignore delete mode 100644 tests/Application/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_item.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusAdminBundle/Product/Tab/_details.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusAdminBundle/_logo.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusAdminBundle/_scripts.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusAdminBundle/_styles.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/Cart/summary.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/_scripts.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/_styles.html.twig delete mode 100644 tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig delete mode 100644 tests/Application/translations/.gitignore delete mode 100644 tests/Application/var/.gitignore delete mode 100644 tests/Application/webpack.config.js diff --git a/.gitignore b/.gitignore index 82b272e5..1b2c7949 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /vendor/ /node_modules/ /composer.lock +/var/ /etc/build/* !/etc/build/.gitignore diff --git a/behat.yml.dist b/behat.yml.dist index 3bfa4adf..75635d8b 100644 --- a/behat.yml.dist +++ b/behat.yml.dist @@ -4,6 +4,8 @@ imports: default: extensions: + DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension: ~ + FriendsOfBehat\MinkDebugExtension: directory: etc/build clean_start: false @@ -11,39 +13,27 @@ default: Behat\MinkExtension: files_path: "%paths.base%/vendor/sylius/sylius/src/Sylius/Behat/Resources/fixtures/" - base_url: "http://localhost:8080/" + base_url: "%env(BEHAT_BASE_URL)%" default_session: symfony - javascript_session: chrome + javascript_session: chromedriver sessions: symfony: symfony: ~ - chrome: - selenium2: - browser: chrome - capabilities: - browserName: chrome - browser: chrome - version: "" - marionette: null # https://github.com/Behat/MinkExtension/pull/311 - chrome: - switches: - - "start-fullscreen" - - "start-maximized" - - "no-sandbox" - extra_capabilities: - unexpectedAlertBehaviour: accept - firefox: - selenium2: - browser: firefox - show_auto: false + chromedriver: + chrome: + api_url: "%env(BEHAT_CHROME_URL)%" + validate_certificate: false FriendsOfBehat\SymfonyExtension: - bootstrap: tests/Application/config/bootstrap.php + bootstrap: vendor/sylius/test-application/config/bootstrap.php kernel: - class: Setono\SyliusGiftCardPlugin\Tests\Application\Kernel + class: Sylius\TestApplication\Kernel + environment: test FriendsOfBehat\VariadicExtension: ~ FriendsOfBehat\SuiteSettingsExtension: paths: - "features" + + SyliusLabs\SuiteTagsExtension: ~ diff --git a/composer.json b/composer.json index af86ad3c..231d788a 100644 --- a/composer.json +++ b/composer.json @@ -4,67 +4,50 @@ "license": "MIT", "type": "sylius-plugin", "require": { - "php": ">=8.1", + "php": "^8.2", "ext-filter": "*", "ext-mbstring": "*", - "api-platform/core": "^2.6", - "doctrine/collections": "^1.8", - "doctrine/dbal": "^2.13 || ^3.0", - "doctrine/orm": "^2.7", - "doctrine/persistence": "^1.3 || ^2.5 || ^3.0", - "fakerphp/faker": "^1.21", - "knplabs/knp-menu": "^3.3", + "doctrine/collections": "^2.2", + "doctrine/dbal": "^3.0", + "doctrine/orm": "^2.18 || ^3.3", + "doctrine/persistence": "^3.3", + "fakerphp/faker": "^1.23", + "knplabs/knp-menu": "^3.5", "knplabs/knp-snappy": "^1.4", "knplabs/knp-snappy-bundle": "^1.9", "setono/doctrine-object-manager-trait": "^1.1", - "sylius/api-bundle": "^1.11", - "sylius/channel": "^1.0", - "sylius/channel-bundle": "^1.0", - "sylius/core": "^1.0", - "sylius/core-bundle": "^1.0", - "sylius/currency": "^1.0", - "sylius/customer": "^1.0", - "sylius/grid-bundle": "^1.0", - "sylius/locale": "^1.0", - "sylius/locale-bundle": "^1.0", - "sylius/mailer-bundle": "^1.6 || ^2.0", - "sylius/money-bundle": "^1.0", - "sylius/order": "^1.10", - "sylius/order-bundle": "^1.0", - "sylius/product": "^1.0", - "sylius/product-bundle": "^1.0", - "sylius/promotion": "^1.0", - "sylius/resource-bundle": "^1.8", - "sylius/shipping-bundle": "^1.0", - "sylius/ui-bundle": "^1.0", - "sylius/user": "^1.0", - "symfony/config": "^5.4 || ^6.4", - "symfony/dependency-injection": "^5.4 || ^6.4", - "symfony/event-dispatcher": "^5.4 || ^6.4", - "symfony/form": "^5.4 || ^6.4", - "symfony/http-foundation": "^5.4 || ^6.4", - "symfony/http-kernel": "^5.4 || ^6.4", - "symfony/messenger": "^5.4 || ^6.4", - "symfony/options-resolver": "^5.4 || ^6.4", - "symfony/property-access": "^5.4 || ^6.4", - "symfony/routing": "^5.4 || ^6.4", - "symfony/security-core": "^5.4 || ^6.4", - "symfony/serializer": "^5.4 || ^6.4", - "symfony/translation-contracts": "^2.4", - "symfony/validator": "^5.4 || ^6.4", - "twig/twig": "^2.15 || ^3.5", + "sylius/grid-bundle": "^1.16", + "sylius/mailer-bundle": "^2.0", + "sylius/resource-bundle": "^1.14", + "sylius/sylius": "^2.0", + "symfony/config": "^6.4 || ^7.4", + "symfony/dependency-injection": "^6.4 || ^7.4", + "symfony/event-dispatcher": "^6.4 || ^7.4", + "symfony/form": "^6.4 || ^7.4", + "symfony/http-foundation": "^6.4 || ^7.4", + "symfony/http-kernel": "^6.4 || ^7.4", + "symfony/messenger": "^6.4 || ^7.4", + "symfony/options-resolver": "^6.4 || ^7.4", + "symfony/property-access": "^6.4 || ^7.4", + "symfony/routing": "^6.4 || ^7.4", + "symfony/security-core": "^6.4 || ^7.4", + "symfony/serializer": "^6.4 || ^7.4", + "symfony/translation-contracts": "^3.5", + "symfony/validator": "^6.4 || ^7.4", + "twig/twig": "^3.5", "webimpress/safe-writer": "^2.2", "webmozart/assert": "^1.11" }, "require-dev": { - "babdev/pagerfanta-bundle": "^3.8", - "behat/behat": "^3.14", - "doctrine/doctrine-bundle": "^2.7", + "babdev/pagerfanta-bundle": "^4.4", + "behat/behat": "^3.16", + "dmore/behat-chrome-extension": "^1.4", + "dmore/chrome-mink-driver": "^2.9", + "doctrine/doctrine-bundle": "^2.13", "infection/infection": "^0.27.10", - "jms/serializer-bundle": "^4.2", - "lexik/jwt-authentication-bundle": "^2.17", - "matthiasnoback/symfony-config-test": "^4.3 || ^5.1", - "matthiasnoback/symfony-dependency-injection-test": "^4.3 || ^5.1", + "lexik/jwt-authentication-bundle": "^3.1", + "matthiasnoback/symfony-config-test": "^5.1", + "matthiasnoback/symfony-dependency-injection-test": "^5.1", "php-http/message-factory": "^1.1", "phpspec/phpspec": "^7.4", "phpspec/prophecy-phpunit": "^2.0.2", @@ -74,15 +57,15 @@ "psalm/plugin-symfony": "^5.0", "setono/code-quality-pack": "^2.7", "setono/sylius-behat-pack": "^0.2.2", - "sylius/sylius": "~1.12.13", - "symfony/debug-bundle": "^5.4 || ^6.4", - "symfony/dotenv": "^5.4 || ^6.4", - "symfony/intl": "^5.4 || ^6.4", - "symfony/property-info": "^5.4 || ^6.4", - "symfony/web-profiler-bundle": "^5.4 || ^6.4", - "symfony/webpack-encore-bundle": "^1.17.2", - "weirdan/doctrine-psalm-plugin": "^2.9", - "willdurand/negotiation": "^3.1" + "sylius-labs/suite-tags-extension": "~0.2", + "sylius/test-application": "^2.0.0@alpha", + "symfony/debug-bundle": "^6.4 || ^7.4", + "symfony/dotenv": "^6.4 || ^7.4", + "symfony/intl": "^6.4 || ^7.4", + "symfony/property-info": "^6.4 || ^7.4", + "symfony/web-profiler-bundle": "^6.4 || ^7.4", + "symfony/webpack-encore-bundle": "^2.2", + "weirdan/doctrine-psalm-plugin": "^2.9" }, "prefer-stable": true, "autoload": { @@ -93,20 +76,29 @@ "autoload-dev": { "psr-4": { "Setono\\SyliusGiftCardPlugin\\Tests\\": "tests/" - }, - "classmap": [ - "tests/Application/Kernel.php" - ] + } }, "config": { "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": false, "ergebnis/composer-normalize": true, "infection/extension-installer": true, - "symfony/thanks": false + "php-http/discovery": false, + "symfony/thanks": false, + "symfony/runtime": true, + "symfony/flex": true }, "sort-packages": true }, + "extra": { + "branch-alias": { + "dev-sylius-2": "2.0-dev" + }, + "symfony": { + "require": "^7.4" + }, + "public-dir": "vendor/sylius/test-application/public" + }, "scripts": { "analyse": "psalm", "check-style": "ecs check", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 33c5b231..ecbf8bb5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -3,7 +3,7 @@ + bootstrap="vendor/sylius/test-application/config/bootstrap.php"> src/ @@ -15,7 +15,7 @@ - + diff --git a/tests/Application/.env b/tests/Application/.env deleted file mode 100644 index b877f52b..00000000 --- a/tests/Application/.env +++ /dev/null @@ -1,47 +0,0 @@ -# In all environments, the following files are loaded if they exist, -# the later taking precedence over the former: -# -# * .env contains default values for the environment variables needed by the app -# * .env.local uncommitted file with local overrides -# * .env.$APP_ENV committed environment-specific defaults -# * .env.$APP_ENV.local uncommitted environment-specific overrides -# -# Real environment variables win over .env files. -# -# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. -# -# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). -# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration - -###> symfony/framework-bundle ### -APP_ENV=dev -APP_DEBUG=1 -APP_SECRET=EDITME -###< symfony/framework-bundle ### - -###> doctrine/doctrine-bundle ### -# Format described at https://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url -# For a sqlite database, use: "sqlite:///%kernel.project_dir%/var/data.db" -# Set "serverVersion" to your server version to avoid edge-case exceptions and extra database calls -DATABASE_URL=mysql://root@127.0.0.1/setono_sylius_gift_card_%kernel.environment%?serverVersion=5.7 -###< doctrine/doctrine-bundle ### - -###> lexik/jwt-authentication-bundle ### -JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem -JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem -JWT_PASSPHRASE=acme_plugin_development -###< lexik/jwt-authentication-bundle ### - -###> symfony/messenger ### -# Choose one of the transports below -# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages -MESSENGER_TRANSPORT_DSN=doctrine://default -# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages -###< symfony/messenger ### - -###> symfony/swiftmailer-bundle ### -# For Gmail as a transport, use: "gmail://username:password@localhost" -# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode=" -# Delivery is disabled by default via "null://localhost" -MAILER_DSN=null://localhost -###< symfony/swiftmailer-bundle ### diff --git a/tests/Application/.env.test b/tests/Application/.env.test deleted file mode 100644 index 85259611..00000000 --- a/tests/Application/.env.test +++ /dev/null @@ -1,3 +0,0 @@ -APP_SECRET='ch4mb3r0f5ecr3ts' - -KERNEL_CLASS='Setono\SyliusGiftCardPlugin\Tests\Application\Kernel' diff --git a/tests/Application/.eslintrc.js b/tests/Application/.eslintrc.js deleted file mode 100644 index dfddb254..00000000 --- a/tests/Application/.eslintrc.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - extends: 'airbnb-base', - env: { - node: true, - }, - rules: { - 'object-shorthand': ['error', 'always', { - avoidQuotes: true, - avoidExplicitReturnArrows: true, - }], - 'function-paren-newline': ['error', 'consistent'], - 'max-len': ['warn', 120, 2, { - ignoreUrls: true, - ignoreComments: false, - ignoreRegExpLiterals: true, - ignoreStrings: true, - ignoreTemplateLiterals: true, - }], - }, -}; diff --git a/tests/Application/.gitignore b/tests/Application/.gitignore deleted file mode 100644 index bc600a8c..00000000 --- a/tests/Application/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -/public/assets -/public/build -/public/css -/public/js -/public/media/* -!/public/media/image/ -/public/media/image/* -!/public/media/image/.gitignore - -/node_modules - -###> symfony/framework-bundle ### -/.env.*.local -/.env.local -/.env.local.php -/public/bundles -/var/ -/vendor/ -###< symfony/framework-bundle ### - -###> symfony/web-server-bundle ### -/.web-server-pid -###< symfony/web-server-bundle ### diff --git a/tests/Application/Doctrine/ORM/CustomerRepository.php b/tests/Application/Doctrine/ORM/CustomerRepository.php deleted file mode 100644 index e5dcf397..00000000 --- a/tests/Application/Doctrine/ORM/CustomerRepository.php +++ /dev/null @@ -1,14 +0,0 @@ -getProjectDir() . '/var/cache/' . $this->environment; - } - - public function getLogDir(): string - { - return $this->getProjectDir() . '/var/log'; - } - - public function registerBundles(): iterable - { - foreach ($this->getConfigurationDirectories() as $confDir) { - $bundlesFile = $confDir . '/bundles.php'; - if (false === is_file($bundlesFile)) { - continue; - } - yield from $this->registerBundlesFromFile($bundlesFile); - } - } - - protected function configureRoutes(RoutingConfigurator $routes): void - { - foreach ($this->getConfigurationDirectories() as $confDir) { - $this->loadRoutesConfiguration($routes, $confDir); - } - } - - protected function getContainerBaseClass(): string - { - if ($this->isTestEnvironment()) { - return MockerContainer::class; - } - - return parent::getContainerBaseClass(); - } - - private function loadRoutesConfiguration(RoutingConfigurator $routes, string $confDir): void - { - $routes->import($confDir . '/{routes}/*' . self::CONFIG_EXTS); - $routes->import($confDir . '/{routes}/' . $this->environment . '/**/*' . self::CONFIG_EXTS); - $routes->import($confDir . '/{routes}' . self::CONFIG_EXTS); - } - - /** - * @return BundleInterface[] - */ - private function registerBundlesFromFile(string $bundlesFile): iterable - { - $contents = require $bundlesFile; - foreach ($contents as $class => $envs) { - if (isset($envs['all']) || isset($envs[$this->environment])) { - yield new $class(); - } - } - } - - /** - * @return string[] - */ - private function getConfigurationDirectories(): iterable - { - yield $this->getProjectDir() . '/config'; - } - - private function isTestEnvironment(): bool - { - return str_starts_with($this->getEnvironment(), 'test'); - } -} diff --git a/tests/Application/Model/Order.php b/tests/Application/Model/Order.php deleted file mode 100644 index 3a482a03..00000000 --- a/tests/Application/Model/Order.php +++ /dev/null @@ -1,29 +0,0 @@ -__SetonoSyliusGiftCardOrderTraitConstruct(); - - parent::__construct(); - } -} diff --git a/tests/Application/Model/OrderItem.php b/tests/Application/Model/OrderItem.php deleted file mode 100644 index 6c27b5d4..00000000 --- a/tests/Application/Model/OrderItem.php +++ /dev/null @@ -1,22 +0,0 @@ -getParameterOption(['--env', '-e'], null, true)) { - putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env); -} - -if ($input->hasParameterOption('--no-debug', true)) { - putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0'); -} - -require dirname(__DIR__).'/config/bootstrap.php'; - -if ($_SERVER['APP_DEBUG']) { - umask(0000); - - if (class_exists(Debug::class)) { - Debug::enable(); - } -} - -$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); -$application = new Application($kernel); -$application->run($input); diff --git a/tests/Application/composer.json b/tests/Application/composer.json deleted file mode 100644 index 326735f5..00000000 --- a/tests/Application/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "sylius/plugin-skeleton-test-application", - "description": "Sylius application for plugin testing purposes (composer.json needed for project dir resolving)", - "license": "MIT" -} diff --git a/tests/Application/config/api_platform/.gitignore b/tests/Application/config/api_platform/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/config/bootstrap.php b/tests/Application/config/bootstrap.php deleted file mode 100644 index 2291ab42..00000000 --- a/tests/Application/config/bootstrap.php +++ /dev/null @@ -1,23 +0,0 @@ -=1.2) -if (is_array($env = @include dirname(__DIR__) . '/.env.local.php')) { - $_SERVER += $env; - $_ENV += $env; -} elseif (!class_exists(Dotenv::class)) { - throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); -} else { - // load all the .env files - (new Dotenv())->loadEnv(dirname(__DIR__) . '/.env'); -} - -$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; -$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; -$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], \FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; diff --git a/tests/Application/config/bundles.php b/tests/Application/config/bundles.php deleted file mode 100644 index fdf32a28..00000000 --- a/tests/Application/config/bundles.php +++ /dev/null @@ -1,67 +0,0 @@ - ['all' => true], - Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], - Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], - Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], - Sylius\Bundle\OrderBundle\SyliusOrderBundle::class => ['all' => true], - Sylius\Bundle\MoneyBundle\SyliusMoneyBundle::class => ['all' => true], - Sylius\Bundle\CurrencyBundle\SyliusCurrencyBundle::class => ['all' => true], - Sylius\Bundle\LocaleBundle\SyliusLocaleBundle::class => ['all' => true], - Sylius\Bundle\ProductBundle\SyliusProductBundle::class => ['all' => true], - Sylius\Bundle\ChannelBundle\SyliusChannelBundle::class => ['all' => true], - Sylius\Bundle\AttributeBundle\SyliusAttributeBundle::class => ['all' => true], - Sylius\Bundle\TaxationBundle\SyliusTaxationBundle::class => ['all' => true], - Sylius\Bundle\ShippingBundle\SyliusShippingBundle::class => ['all' => true], - Sylius\Bundle\PaymentBundle\SyliusPaymentBundle::class => ['all' => true], - Sylius\Bundle\MailerBundle\SyliusMailerBundle::class => ['all' => true], - Sylius\Bundle\PromotionBundle\SyliusPromotionBundle::class => ['all' => true], - Sylius\Bundle\AddressingBundle\SyliusAddressingBundle::class => ['all' => true], - Sylius\Bundle\InventoryBundle\SyliusInventoryBundle::class => ['all' => true], - Sylius\Bundle\TaxonomyBundle\SyliusTaxonomyBundle::class => ['all' => true], - Sylius\Bundle\UserBundle\SyliusUserBundle::class => ['all' => true], - Sylius\Bundle\CustomerBundle\SyliusCustomerBundle::class => ['all' => true], - Sylius\Bundle\UiBundle\SyliusUiBundle::class => ['all' => true], - Sylius\Bundle\ReviewBundle\SyliusReviewBundle::class => ['all' => true], - Sylius\Bundle\CoreBundle\SyliusCoreBundle::class => ['all' => true], - Sylius\Bundle\ResourceBundle\SyliusResourceBundle::class => ['all' => true], - - // Begin: In test app, those 3 needs to be loaded before our plugin or the Api Resource override won't work - Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], - ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], - Sylius\Bundle\ApiBundle\SyliusApiBundle::class => ['all' => true], - // End: In test app, those 3 needs to be loaded before our plugin or the Api Resource override won't work - - Setono\SyliusGiftCardPlugin\SetonoSyliusGiftCardPlugin::class => ['all' => true], - Sylius\Bundle\GridBundle\SyliusGridBundle::class => ['all' => true], - winzou\Bundle\StateMachineBundle\winzouStateMachineBundle::class => ['all' => true], - Sonata\BlockBundle\SonataBlockBundle::class => ['all' => true], - Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle::class => ['all' => true], - JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true], - FOS\RestBundle\FOSRestBundle::class => ['all' => true], - Knp\Bundle\GaufretteBundle\KnpGaufretteBundle::class => ['all' => true], - Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true], - League\FlysystemBundle\FlysystemBundle::class => ['all' => true], - Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true], - Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true], - Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], - Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], - Sylius\Bundle\FixturesBundle\SyliusFixturesBundle::class => ['all' => true], - Sylius\Bundle\PayumBundle\SyliusPayumBundle::class => ['all' => true], - Sylius\Bundle\ThemeBundle\SyliusThemeBundle::class => ['all' => true], - Sylius\Bundle\AdminBundle\SyliusAdminBundle::class => ['all' => true], - Sylius\Bundle\ShopBundle\SyliusShopBundle::class => ['all' => true], - Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true], - Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], - FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true], - Knp\Bundle\SnappyBundle\KnpSnappyBundle::class => ['all' => true], - SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true], - BabDev\PagerfantaBundle\BabDevPagerfantaBundle::class => ['all' => true], - SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], - Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], - Sylius\Calendar\SyliusCalendarBundle::class => ['all' => true], -]; diff --git a/tests/Application/config/jwt/private.pem b/tests/Application/config/jwt/private.pem deleted file mode 100644 index 2bcf0230..00000000 --- a/tests/Application/config/jwt/private.pem +++ /dev/null @@ -1,54 +0,0 @@ ------BEGIN ENCRYPTED PRIVATE KEY----- -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 ------END ENCRYPTED PRIVATE KEY----- diff --git a/tests/Application/config/jwt/public.pem b/tests/Application/config/jwt/public.pem deleted file mode 100644 index cb4e13da..00000000 --- a/tests/Application/config/jwt/public.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN PUBLIC KEY----- -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6QkmF/Xi5nAYb8Kzr7qC -d63V2K+d/nCXbpDUKKDPJAqOtTlMoQSuJRLNnhhp7z1i/Cp4Bhifr20Pu2dq8JYg -6pRT4ctqvYb/MXxAaPZc3EcBC0S6AhgKO/fDvR3LcqYqGJmQQOXZvxTsgqongdvV -4XbqFBMMgngyayoBk0VKTaI/s+LQhIce+1QaxbAI0+/zbR0hZ1hWT73orJi3do+1 -TBzQol+V7WGa8LlJfmgM56qO3BmVkeTDMBc27pGp6g3+Oufk/l29jEGJlUT9yu7Q -BRhaQTWNVASa2aD+AKjVBzJh53O2zD8slAbjF1M9U7bbWN28Sv+xC/dUz0q9HnPu -RsY2tnwryqTyYn/Hf2xyP3/KvjJ6oslAwemu5JirdJkO7KVQAthWG42gLuhZg3ks -cSZhCLZH7nO2UDsf+2ZZgdbhpYZwR4gDRfNt7GKWXnWZOz9Uw1yVCPgylyZRZwg8 -l0y9aABdj3379I22icrwpMZbAgkyxNSV6UNJuxZksLUoP3i9OvXYgPYU9E4tU/Ul -Dm/T1rGSReGoPkU1YQnI50bq7p1byIoUu2scTflvpTVI5a7zULkS1tg60xk7vBRC -aBc7nr4UEtA235N6uLtcGxH11WBMwsKX69sSU0sQdC4Sk25zXM2gc8R1XV9K3qz2 -wQorQRlCwrkG44VRDgbFH+8CAwEAAQ== ------END PUBLIC KEY----- diff --git a/tests/Application/config/packages/_sylius.yaml b/tests/Application/config/packages/_sylius.yaml deleted file mode 100644 index 872717f0..00000000 --- a/tests/Application/config/packages/_sylius.yaml +++ /dev/null @@ -1,40 +0,0 @@ -imports: - - { resource: "@SyliusCoreBundle/Resources/config/app/config.yml" } - - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" } - - { resource: "@SyliusShopBundle/Resources/config/app/config.yml" } - - { resource: "@SyliusApiBundle/Resources/config/app/config.yaml" } - -parameters: - sylius_core.public_dir: '%kernel.project_dir%/public' - -sylius_shop: - product_grid: - include_all_descendants: true - -sylius_api: - enabled: true - -sylius_customer: - resources: - customer: - classes: - repository: Setono\SyliusGiftCardPlugin\Tests\Application\Doctrine\ORM\CustomerRepository - -sylius_order: - resources: - order: - classes: - model: Setono\SyliusGiftCardPlugin\Tests\Application\Model\Order - repository: Setono\SyliusGiftCardPlugin\Tests\Application\Doctrine\ORM\OrderRepository - order_item: - classes: - model: Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItem - order_item_unit: - classes: - model: Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItemUnit - -sylius_product: - resources: - product: - classes: - model: Setono\SyliusGiftCardPlugin\Tests\Application\Model\Product diff --git a/tests/Application/config/packages/api_platform.yaml b/tests/Application/config/packages/api_platform.yaml deleted file mode 100644 index 26def491..00000000 --- a/tests/Application/config/packages/api_platform.yaml +++ /dev/null @@ -1,9 +0,0 @@ -api_platform: - mapping: - paths: - - '%kernel.project_dir%/../../vendor/sylius/sylius/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources' - - '%kernel.project_dir%/config/api_platform' - patch_formats: - json: ['application/merge-patch+json'] - swagger: - versions: [3] diff --git a/tests/Application/config/packages/assets.yaml b/tests/Application/config/packages/assets.yaml deleted file mode 100644 index 24689011..00000000 --- a/tests/Application/config/packages/assets.yaml +++ /dev/null @@ -1,7 +0,0 @@ -framework: - assets: - packages: - shop: - json_manifest_path: '%kernel.project_dir%/public/build/shop/manifest.json' - admin: - json_manifest_path: '%kernel.project_dir%/public/build/admin/manifest.json' diff --git a/tests/Application/config/packages/dev/debug.yaml b/tests/Application/config/packages/dev/debug.yaml deleted file mode 100644 index 26d4e53d..00000000 --- a/tests/Application/config/packages/dev/debug.yaml +++ /dev/null @@ -1,4 +0,0 @@ -debug: - # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser. - # See the "server:dump" command to start a new server. - dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%" diff --git a/tests/Application/config/packages/dev/framework.yaml b/tests/Application/config/packages/dev/framework.yaml deleted file mode 100644 index 4b116def..00000000 --- a/tests/Application/config/packages/dev/framework.yaml +++ /dev/null @@ -1,2 +0,0 @@ -framework: - profiler: { only_exceptions: false } diff --git a/tests/Application/config/packages/dev/jms_serializer.yaml b/tests/Application/config/packages/dev/jms_serializer.yaml deleted file mode 100644 index 2f32a9b1..00000000 --- a/tests/Application/config/packages/dev/jms_serializer.yaml +++ /dev/null @@ -1,12 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/packages/dev/monolog.yaml b/tests/Application/config/packages/dev/monolog.yaml deleted file mode 100644 index da2b092d..00000000 --- a/tests/Application/config/packages/dev/monolog.yaml +++ /dev/null @@ -1,9 +0,0 @@ -monolog: - handlers: - main: - type: stream - path: "%kernel.logs_dir%/%kernel.environment%.log" - level: debug - firephp: - type: firephp - level: info diff --git a/tests/Application/config/packages/dev/routing.yaml b/tests/Application/config/packages/dev/routing.yaml deleted file mode 100644 index 4116679a..00000000 --- a/tests/Application/config/packages/dev/routing.yaml +++ /dev/null @@ -1,3 +0,0 @@ -framework: - router: - strict_requirements: true diff --git a/tests/Application/config/packages/dev/web_profiler.yaml b/tests/Application/config/packages/dev/web_profiler.yaml deleted file mode 100644 index 1f1cb2bb..00000000 --- a/tests/Application/config/packages/dev/web_profiler.yaml +++ /dev/null @@ -1,3 +0,0 @@ -web_profiler: - toolbar: true - intercept_redirects: false diff --git a/tests/Application/config/packages/doctrine.yaml b/tests/Application/config/packages/doctrine.yaml deleted file mode 100644 index dc76b940..00000000 --- a/tests/Application/config/packages/doctrine.yaml +++ /dev/null @@ -1,25 +0,0 @@ -parameters: - # Adds a fallback DATABASE_URL if the env var is not set. - # This allows you to run cache:warmup even if your - # environment variables are not available yet. - # You should not need to change this value. - env(DATABASE_URL): '' - -doctrine: - dbal: - driver: 'pdo_mysql' - server_version: '5.7' - charset: UTF8 - - url: '%env(resolve:DATABASE_URL)%' - - orm: - auto_generate_proxy_classes: '%kernel.debug%' - auto_mapping: true - mappings: - App: - is_bundle: false - type: annotation - dir: '%kernel.project_dir%/Model' - prefix: 'Setono\SyliusGiftCardPlugin\Tests\Application\Model' - alias: App diff --git a/tests/Application/config/packages/doctrine_migrations.yaml b/tests/Application/config/packages/doctrine_migrations.yaml deleted file mode 100644 index cdbc01ae..00000000 --- a/tests/Application/config/packages/doctrine_migrations.yaml +++ /dev/null @@ -1,4 +0,0 @@ -doctrine_migrations: - storage: - table_storage: - table_name: sylius_migrations diff --git a/tests/Application/config/packages/fos_rest.yaml b/tests/Application/config/packages/fos_rest.yaml deleted file mode 100644 index eaebb277..00000000 --- a/tests/Application/config/packages/fos_rest.yaml +++ /dev/null @@ -1,11 +0,0 @@ -fos_rest: - exception: true - view: - formats: - json: true - xml: true - empty_content: 204 - format_listener: - rules: - - { path: '^/api/v1/.*', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: true } - - { path: '^/', stop: true } diff --git a/tests/Application/config/packages/framework.yaml b/tests/Application/config/packages/framework.yaml deleted file mode 100644 index 3df2c0ad..00000000 --- a/tests/Application/config/packages/framework.yaml +++ /dev/null @@ -1,9 +0,0 @@ -framework: - secret: '%env(APP_SECRET)%' - ide: phpstorm - form: - enabled: true - legacy_error_messages: false - csrf_protection: true - session: - handler_id: ~ diff --git a/tests/Application/config/packages/jms_serializer.yaml b/tests/Application/config/packages/jms_serializer.yaml deleted file mode 100644 index ed7bc613..00000000 --- a/tests/Application/config/packages/jms_serializer.yaml +++ /dev/null @@ -1,4 +0,0 @@ -jms_serializer: - visitors: - xml_serialization: - format_output: '%kernel.debug%' diff --git a/tests/Application/config/packages/lexik_jwt_authentication.yaml b/tests/Application/config/packages/lexik_jwt_authentication.yaml deleted file mode 100644 index edfb69dc..00000000 --- a/tests/Application/config/packages/lexik_jwt_authentication.yaml +++ /dev/null @@ -1,4 +0,0 @@ -lexik_jwt_authentication: - secret_key: '%env(resolve:JWT_SECRET_KEY)%' - public_key: '%env(resolve:JWT_PUBLIC_KEY)%' - pass_phrase: '%env(JWT_PASSPHRASE)%' diff --git a/tests/Application/config/packages/liip_imagine.yaml b/tests/Application/config/packages/liip_imagine.yaml deleted file mode 100644 index bb2e7ceb..00000000 --- a/tests/Application/config/packages/liip_imagine.yaml +++ /dev/null @@ -1,6 +0,0 @@ -liip_imagine: - resolvers: - default: - web_path: - web_root: "%kernel.project_dir%/public" - cache_prefix: "media/cache" diff --git a/tests/Application/config/packages/mailer.yaml b/tests/Application/config/packages/mailer.yaml deleted file mode 100644 index 56a650d8..00000000 --- a/tests/Application/config/packages/mailer.yaml +++ /dev/null @@ -1,3 +0,0 @@ -framework: - mailer: - dsn: '%env(MAILER_DSN)%' diff --git a/tests/Application/config/packages/prod/doctrine.yaml b/tests/Application/config/packages/prod/doctrine.yaml deleted file mode 100644 index 2f16f0fd..00000000 --- a/tests/Application/config/packages/prod/doctrine.yaml +++ /dev/null @@ -1,31 +0,0 @@ -doctrine: - orm: - metadata_cache_driver: - type: service - id: doctrine.system_cache_provider - query_cache_driver: - type: service - id: doctrine.system_cache_provider - result_cache_driver: - type: service - id: doctrine.result_cache_provider - -services: - doctrine.result_cache_provider: - class: Symfony\Component\Cache\DoctrineProvider - public: false - arguments: - - '@doctrine.result_cache_pool' - doctrine.system_cache_provider: - class: Symfony\Component\Cache\DoctrineProvider - public: false - arguments: - - '@doctrine.system_cache_pool' - -framework: - cache: - pools: - doctrine.result_cache_pool: - adapter: cache.app - doctrine.system_cache_pool: - adapter: cache.system diff --git a/tests/Application/config/packages/prod/jms_serializer.yaml b/tests/Application/config/packages/prod/jms_serializer.yaml deleted file mode 100644 index c2881820..00000000 --- a/tests/Application/config/packages/prod/jms_serializer.yaml +++ /dev/null @@ -1,10 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/packages/prod/monolog.yaml b/tests/Application/config/packages/prod/monolog.yaml deleted file mode 100644 index 64612114..00000000 --- a/tests/Application/config/packages/prod/monolog.yaml +++ /dev/null @@ -1,10 +0,0 @@ -monolog: - handlers: - main: - type: fingers_crossed - action_level: error - handler: nested - nested: - type: stream - path: "%kernel.logs_dir%/%kernel.environment%.log" - level: debug diff --git a/tests/Application/config/packages/routing.yaml b/tests/Application/config/packages/routing.yaml deleted file mode 100644 index 368bc7f4..00000000 --- a/tests/Application/config/packages/routing.yaml +++ /dev/null @@ -1,3 +0,0 @@ -framework: - router: - strict_requirements: ~ diff --git a/tests/Application/config/packages/security.yaml b/tests/Application/config/packages/security.yaml deleted file mode 100644 index 2f5c6875..00000000 --- a/tests/Application/config/packages/security.yaml +++ /dev/null @@ -1,122 +0,0 @@ -security: - enable_authenticator_manager: true - providers: - sylius_admin_user_provider: - id: sylius.admin_user_provider.email_or_name_based - sylius_api_admin_user_provider: - id: sylius.admin_user_provider.email_or_name_based - sylius_shop_user_provider: - id: sylius.shop_user_provider.email_or_name_based - sylius_api_shop_user_provider: - id: sylius.shop_user_provider.email_or_name_based - - password_hashers: - Sylius\Component\User\Model\UserInterface: argon2i - firewalls: - admin: - switch_user: true - context: admin - pattern: "%sylius.security.admin_regex%" - provider: sylius_admin_user_provider - form_login: - provider: sylius_admin_user_provider - login_path: sylius_admin_login - check_path: sylius_admin_login_check - failure_path: sylius_admin_login - default_target_path: sylius_admin_dashboard - use_forward: false - use_referer: true - enable_csrf: true - csrf_parameter: _csrf_admin_security_token - csrf_token_id: admin_authenticate - remember_me: - secret: "%env(APP_SECRET)%" - path: "/%sylius_admin.path_name%" - name: APP_ADMIN_REMEMBER_ME - lifetime: 31536000 - remember_me_parameter: _remember_me - logout: - path: sylius_admin_logout - target: sylius_admin_login - - new_api_admin_user: - pattern: "%sylius.security.new_api_admin_regex%/.*" - provider: sylius_api_admin_user_provider - stateless: true - entry_point: jwt - json_login: - check_path: "%sylius.security.new_api_admin_route%/authentication-token" - username_path: email - password_path: password - success_handler: lexik_jwt_authentication.handler.authentication_success - failure_handler: lexik_jwt_authentication.handler.authentication_failure - jwt: true - - new_api_shop_user: - pattern: "%sylius.security.new_api_shop_regex%/.*" - provider: sylius_api_shop_user_provider - stateless: true - entry_point: jwt - json_login: - check_path: "%sylius.security.new_api_shop_route%/authentication-token" - username_path: email - password_path: password - success_handler: lexik_jwt_authentication.handler.authentication_success - failure_handler: lexik_jwt_authentication.handler.authentication_failure - jwt: true - - shop: - switch_user: { role: ROLE_ALLOWED_TO_SWITCH } - context: shop - pattern: "%sylius.security.shop_regex%" - provider: sylius_shop_user_provider - form_login: - success_handler: sylius.authentication.success_handler - failure_handler: sylius.authentication.failure_handler - provider: sylius_shop_user_provider - login_path: sylius_shop_login - check_path: sylius_shop_login_check - failure_path: sylius_shop_login - default_target_path: sylius_shop_homepage - use_forward: false - use_referer: true - enable_csrf: true - csrf_parameter: _csrf_shop_security_token - csrf_token_id: shop_authenticate - remember_me: - secret: "%env(APP_SECRET)%" - name: APP_SHOP_REMEMBER_ME - lifetime: 31536000 - remember_me_parameter: _remember_me - logout: - path: sylius_shop_logout - target: sylius_shop_homepage - invalidate_session: false - - dev: - pattern: ^/(_(profiler|wdt)|css|images|js)/ - security: false - - access_control: - - { path: "%sylius.security.admin_regex%/_partial", role: PUBLIC_ACCESS, ips: [127.0.0.1, ::1] } - - { path: "%sylius.security.admin_regex%/_partial", role: ROLE_NO_ACCESS } - - { path: "%sylius.security.shop_regex%/_partial", role: PUBLIC_ACCESS, ips: [127.0.0.1, ::1] } - - { path: "%sylius.security.shop_regex%/_partial", role: ROLE_NO_ACCESS } - - - { path: "%sylius.security.admin_regex%/forgotten-password", role: PUBLIC_ACCESS } - - - { path: "%sylius.security.admin_regex%/login", role: PUBLIC_ACCESS } - - { path: "%sylius.security.shop_regex%/login", role: PUBLIC_ACCESS } - - - { path: "%sylius.security.shop_regex%/register", role: PUBLIC_ACCESS } - - { path: "%sylius.security.shop_regex%/verify", role: PUBLIC_ACCESS } - - - { path: "%sylius.security.admin_regex%", role: ROLE_ADMINISTRATION_ACCESS } - - { path: "%sylius.security.shop_regex%/account", role: ROLE_USER } - - - { path: "%sylius.security.new_api_admin_route%/reset-password-requests", role: PUBLIC_ACCESS } - - { path: "%sylius.security.new_api_admin_regex%/.*", role: ROLE_API_ACCESS } - - { path: "%sylius.security.new_api_admin_route%/authentication-token", role: PUBLIC_ACCESS } - - { path: "%sylius.security.new_api_user_account_regex%/.*", role: ROLE_USER } - - { path: "%sylius.security.new_api_shop_route%/authentication-token", role: PUBLIC_ACCESS } - - { path: "%sylius.security.new_api_shop_regex%/.*", role: PUBLIC_ACCESS } diff --git a/tests/Application/config/packages/setono_sylius_gift_card.yaml b/tests/Application/config/packages/setono_sylius_gift_card.yaml deleted file mode 100644 index ccb4949d..00000000 --- a/tests/Application/config/packages/setono_sylius_gift_card.yaml +++ /dev/null @@ -1,3 +0,0 @@ -imports: - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/config.yaml" } - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/fixtures.yaml" } diff --git a/tests/Application/config/packages/stof_doctrine_extensions.yaml b/tests/Application/config/packages/stof_doctrine_extensions.yaml deleted file mode 100644 index 7770f74e..00000000 --- a/tests/Application/config/packages/stof_doctrine_extensions.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html -# See the official DoctrineExtensions documentation for more details: https://github.com/Atlantic18/DoctrineExtensions/tree/master/doc/ -stof_doctrine_extensions: - default_locale: '%locale%' diff --git a/tests/Application/config/packages/sylius_api.yaml b/tests/Application/config/packages/sylius_api.yaml deleted file mode 100644 index cd01aaf7..00000000 --- a/tests/Application/config/packages/sylius_api.yaml +++ /dev/null @@ -1,2 +0,0 @@ -sylius_api: - enabled: true diff --git a/tests/Application/config/packages/test/framework.yaml b/tests/Application/config/packages/test/framework.yaml deleted file mode 100644 index fc1d3c13..00000000 --- a/tests/Application/config/packages/test/framework.yaml +++ /dev/null @@ -1,4 +0,0 @@ -framework: - test: ~ - session: - storage_factory_id: session.storage.factory.mock_file diff --git a/tests/Application/config/packages/test/mailer.yaml b/tests/Application/config/packages/test/mailer.yaml deleted file mode 100644 index 092eb288..00000000 --- a/tests/Application/config/packages/test/mailer.yaml +++ /dev/null @@ -1,7 +0,0 @@ -framework: - mailer: - dsn: 'null://null' - cache: - pools: - test.mailer_pool: - adapter: cache.adapter.filesystem diff --git a/tests/Application/config/packages/test/monolog.yaml b/tests/Application/config/packages/test/monolog.yaml deleted file mode 100644 index 7e2b9e3a..00000000 --- a/tests/Application/config/packages/test/monolog.yaml +++ /dev/null @@ -1,6 +0,0 @@ -monolog: - handlers: - main: - type: stream - path: "%kernel.logs_dir%/%kernel.environment%.log" - level: error diff --git a/tests/Application/config/packages/test/security.yaml b/tests/Application/config/packages/test/security.yaml deleted file mode 100644 index 4071d319..00000000 --- a/tests/Application/config/packages/test/security.yaml +++ /dev/null @@ -1,6 +0,0 @@ -security: - password_hashers: - Sylius\Component\User\Model\UserInterface: - algorithm: argon2i - time_cost: 3 - memory_cost: 10 diff --git a/tests/Application/config/packages/test/setono_sylius_gift_card.yaml b/tests/Application/config/packages/test/setono_sylius_gift_card.yaml deleted file mode 100644 index 9a091d6c..00000000 --- a/tests/Application/config/packages/test/setono_sylius_gift_card.yaml +++ /dev/null @@ -1,9 +0,0 @@ -setono_sylius_gift_card: - pdf_rendering: - default_orientation: 'Landscape' - available_orientations: - - Landscape - default_page_size: 'B0' - available_page_sizes: - - A5 - - B0 diff --git a/tests/Application/config/packages/test/sylius_theme.yaml b/tests/Application/config/packages/test/sylius_theme.yaml deleted file mode 100644 index 4d34199f..00000000 --- a/tests/Application/config/packages/test/sylius_theme.yaml +++ /dev/null @@ -1,3 +0,0 @@ -sylius_theme: - sources: - test: ~ diff --git a/tests/Application/config/packages/test/web_profiler.yaml b/tests/Application/config/packages/test/web_profiler.yaml deleted file mode 100644 index 03752de2..00000000 --- a/tests/Application/config/packages/test/web_profiler.yaml +++ /dev/null @@ -1,6 +0,0 @@ -web_profiler: - toolbar: false - intercept_redirects: false - -framework: - profiler: { collect: false } diff --git a/tests/Application/config/packages/translation.yaml b/tests/Application/config/packages/translation.yaml deleted file mode 100644 index 1f4f9664..00000000 --- a/tests/Application/config/packages/translation.yaml +++ /dev/null @@ -1,8 +0,0 @@ -framework: - default_locale: '%locale%' - translator: - paths: - - '%kernel.project_dir%/translations' - fallbacks: - - '%locale%' - - 'en' diff --git a/tests/Application/config/packages/twig.yaml b/tests/Application/config/packages/twig.yaml deleted file mode 100644 index 8545473d..00000000 --- a/tests/Application/config/packages/twig.yaml +++ /dev/null @@ -1,12 +0,0 @@ -twig: - paths: ['%kernel.project_dir%/templates'] - debug: '%kernel.debug%' - strict_variables: '%kernel.debug%' - -services: - _defaults: - public: false - autowire: true - autoconfigure: true - - Twig\Extra\Intl\IntlExtension: ~ diff --git a/tests/Application/config/packages/twig_extensions.yaml b/tests/Application/config/packages/twig_extensions.yaml deleted file mode 100644 index 0881cc95..00000000 --- a/tests/Application/config/packages/twig_extensions.yaml +++ /dev/null @@ -1,11 +0,0 @@ -services: - _defaults: - public: false - autowire: true - autoconfigure: true - - # Uncomment any lines below to activate that Twig extension - #Twig\Extensions\ArrayExtension: ~ - #Twig\Extensions\DateExtension: ~ - #Twig\Extensions\IntlExtension: ~ - #Twig\Extensions\TextExtension: ~ diff --git a/tests/Application/config/packages/validator.yaml b/tests/Application/config/packages/validator.yaml deleted file mode 100644 index 61807db6..00000000 --- a/tests/Application/config/packages/validator.yaml +++ /dev/null @@ -1,3 +0,0 @@ -framework: - validation: - enable_annotations: true diff --git a/tests/Application/config/packages/webpack_encore.yaml b/tests/Application/config/packages/webpack_encore.yaml deleted file mode 100644 index 9bee2488..00000000 --- a/tests/Application/config/packages/webpack_encore.yaml +++ /dev/null @@ -1,5 +0,0 @@ -webpack_encore: - output_path: '%kernel.project_dir%/public/build/default' - builds: - shop: '%kernel.project_dir%/public/build/shop' - admin: '%kernel.project_dir%/public/build/admin' diff --git a/tests/Application/config/routes.yaml b/tests/Application/config/routes.yaml deleted file mode 100644 index c1e265d0..00000000 --- a/tests/Application/config/routes.yaml +++ /dev/null @@ -1,2 +0,0 @@ -setono_sylius_gift_card: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes.yaml" diff --git a/tests/Application/config/routes/dev/web_profiler.yaml b/tests/Application/config/routes/dev/web_profiler.yaml deleted file mode 100644 index 3e79dc21..00000000 --- a/tests/Application/config/routes/dev/web_profiler.yaml +++ /dev/null @@ -1,7 +0,0 @@ -_wdt: - resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" - prefix: /_wdt - -_profiler: - resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" - prefix: /_profiler diff --git a/tests/Application/config/routes/liip_imagine.yaml b/tests/Application/config/routes/liip_imagine.yaml deleted file mode 100644 index 201cbd5d..00000000 --- a/tests/Application/config/routes/liip_imagine.yaml +++ /dev/null @@ -1,2 +0,0 @@ -_liip_imagine: - resource: "@LiipImagineBundle/Resources/config/routing.yaml" diff --git a/tests/Application/config/routes/sylius_admin.yaml b/tests/Application/config/routes/sylius_admin.yaml deleted file mode 100644 index b9c12c22..00000000 --- a/tests/Application/config/routes/sylius_admin.yaml +++ /dev/null @@ -1,3 +0,0 @@ -sylius_admin: - resource: "@SyliusAdminBundle/Resources/config/routing.yml" - prefix: '/%sylius_admin.path_name%' diff --git a/tests/Application/config/routes/sylius_api.yaml b/tests/Application/config/routes/sylius_api.yaml deleted file mode 100644 index ae01ffce..00000000 --- a/tests/Application/config/routes/sylius_api.yaml +++ /dev/null @@ -1,3 +0,0 @@ -sylius_api: - resource: "@SyliusApiBundle/Resources/config/routing.yml" - prefix: "%sylius.security.new_api_route%" diff --git a/tests/Application/config/routes/sylius_shop.yaml b/tests/Application/config/routes/sylius_shop.yaml deleted file mode 100644 index 22e7a4a9..00000000 --- a/tests/Application/config/routes/sylius_shop.yaml +++ /dev/null @@ -1,23 +0,0 @@ -sylius_shop: - resource: "@SyliusShopBundle/Resources/config/routing.yml" - prefix: /{_locale} - requirements: - _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ - -sylius_shop_payum: - resource: "@SyliusShopBundle/Resources/config/routing/payum.yml" - -sylius_shop_default_locale: - path: / - methods: [GET] - defaults: - _controller: sylius.controller.shop.locale_switch::switchAction - -# see https://web.dev/change-password-url/ -sylius_shop_request_password_reset_token_redirect: - path: /.well-known/change-password - methods: [GET] - controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction - defaults: - route: sylius_shop_request_password_reset_token - permanent: false diff --git a/tests/Application/config/secrets/dev/.gitignore b/tests/Application/config/secrets/dev/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/config/secrets/prod/.gitignore b/tests/Application/config/secrets/prod/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/config/secrets/test/.gitignore b/tests/Application/config/secrets/test/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/config/secrets/test_cached/.gitignore b/tests/Application/config/secrets/test_cached/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/config/serialization/.gitignore b/tests/Application/config/serialization/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/config/services.yaml b/tests/Application/config/services.yaml deleted file mode 100644 index 615506eb..00000000 --- a/tests/Application/config/services.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# Put parameters here that don't need to change on each machine where the app is deployed -# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration -parameters: - locale: en_US diff --git a/tests/Application/config/services_test.yaml b/tests/Application/config/services_test.yaml deleted file mode 100644 index d9b02e3d..00000000 --- a/tests/Application/config/services_test.yaml +++ /dev/null @@ -1,3 +0,0 @@ -imports: - - { resource: "../../Behat/Resources/services.xml" } - - { resource: "../../../vendor/sylius/sylius/src/Sylius/Behat/Resources/config/services.xml" } diff --git a/tests/Application/docker-compose.yaml b/tests/Application/docker-compose.yaml deleted file mode 100644 index b547ffa7..00000000 --- a/tests/Application/docker-compose.yaml +++ /dev/null @@ -1,8 +0,0 @@ -version: '3.7' - -services: - mailer: - image: "schickling/mailcatcher:latest" - ports: - - "1080" - - "1025" diff --git a/tests/Application/package.json b/tests/Application/package.json deleted file mode 100644 index 8f62c4c7..00000000 --- a/tests/Application/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "dependencies": { - "chart.js": "^3.9", - "jquery": "^3.6", - "jquery.dirtyforms": "^2.0", - "lightbox2": "^2.9", - "semantic-ui-css": "^2.2", - "slick-carousel": "^1.8" - }, - "devDependencies": { - "@symfony/webpack-encore": "^1.8", - "eslint": "^8.18", - "eslint-config-airbnb-base": "^15.0", - "eslint-import-resolver-babel-module": "^5.3", - "eslint-plugin-import": "^2.26", - "node-sass": "^7.0", - "sass-loader": "^12.0" - }, - "scripts": { - "dev": "encore dev", - "build": "encore production", - "watch": "encore dev --watch" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Sylius/Sylius.git" - }, - "author": "Paweł Jędrzejewski", - "license": "MIT" -} diff --git a/tests/Application/public/.htaccess b/tests/Application/public/.htaccess deleted file mode 100644 index 99ed00df..00000000 --- a/tests/Application/public/.htaccess +++ /dev/null @@ -1,25 +0,0 @@ -DirectoryIndex app.php - - - RewriteEngine On - - RewriteCond %{HTTP:Authorization} ^(.*) - RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] - - RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ - RewriteRule ^(.*) - [E=BASE:%1] - - RewriteCond %{ENV:REDIRECT_STATUS} ^$ - RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L] - - RewriteCond %{REQUEST_FILENAME} -f - RewriteRule .? - [L] - - RewriteRule .? %{ENV:BASE}/index.php [L] - - - - - RedirectMatch 302 ^/$ /index.php/ - - diff --git a/tests/Application/public/favicon.ico b/tests/Application/public/favicon.ico deleted file mode 100644 index 592f7a8e45d5ef6fe2a3c0426b5276e463480ba5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32038 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 diff --git a/tests/Application/public/index.php b/tests/Application/public/index.php deleted file mode 100644 index b550b6a8..00000000 --- a/tests/Application/public/index.php +++ /dev/null @@ -1,29 +0,0 @@ -handle($request); -$response->send(); -$kernel->terminate($request, $response); diff --git a/tests/Application/public/media/image/.gitignore b/tests/Application/public/media/image/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/public/robots.txt b/tests/Application/public/robots.txt deleted file mode 100644 index 214e4119..00000000 --- a/tests/Application/public/robots.txt +++ /dev/null @@ -1,4 +0,0 @@ -# www.robotstxt.org/ -# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 - -User-agent: * diff --git a/tests/Application/templates/.gitignore b/tests/Application/templates/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig deleted file mode 100644 index 39599d88..00000000 --- a/tests/Application/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig +++ /dev/null @@ -1,17 +0,0 @@ -{% extends '@!SyliusAdmin/Form/imagesTheme.html.twig' %} - -{% block setono_sylius_gift_card_gift_card_configuration_image_widget %} - {%- if form.type is defined -%} - {{- form_row(form.type) -}} - {%- endif -%} - - {%- if form.vars.value.path|default(null) is not null -%} - {{ form.vars.value.type }} - {%- endif -%} - -
- {{- form_errors(form.file) -}} -
-{% endblock %} diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_item.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_item.html.twig deleted file mode 100644 index 878d5b9f..00000000 --- a/tests/Application/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_item.html.twig +++ /dev/null @@ -1,58 +0,0 @@ -{# @var \Sylius\Component\Core\Model\OrderItemInterface item #} -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} - -{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} -{% set unitPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT') %} -{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} -{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} - -{% set variant = item.variant %} -{% set product = variant.product %} - -{% set aggregatedUnitPromotionAdjustments = item.getAdjustmentsTotalRecursively(unitPromotionAdjustment) + item.getAdjustmentsTotalRecursively(orderPromotionAdjustment) %} -{% set subtotal = (item.unitPrice * item.quantity) + aggregatedUnitPromotionAdjustments %} - -{% set taxIncluded = sylius_admin_order_unit_tax_included(item) %} -{% set taxExcluded = sylius_admin_order_unit_tax_excluded(item) %} - - - - {% include '@SyliusAdmin/Product/_info.html.twig' %} - {# @var \Setono\SyliusGiftCardPlugin\Model\OrderItemUnitInterface itemUnit #} - {% for itemUnit in item.units %} - {% set giftCard = itemUnit.giftCard %} - {% if giftCard is not null %} - {{ giftCard.code }} - {% endif %} - {% endfor %} - - - {{ money.format(item.unitPrice, order.currencyCode) }} - - - {{ money.format(item.units.first.adjustmentsTotal(unitPromotionAdjustment), order.currencyCode) }} - - - ~ {{ money.format(item.units.first.adjustmentsTotal(orderPromotionAdjustment), order.currencyCode) }} - - - {{ money.format(item.fullDiscountedUnitPrice, order.currencyCode) }} - - - {{ item.quantity }} - - - {{ money.format(subtotal, order.currencyCode) }} - - -
{{ money.format(taxExcluded, order.currencyCode) }}
-
-
{{ money.format(taxIncluded, order.currencyCode) }} -
- ({{ 'sylius.ui.included_in_price'|trans }}) -
- - - {{ money.format(item.total, order.currencyCode) }} - - diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig deleted file mode 100644 index d7c5fe17..00000000 --- a/tests/Application/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig +++ /dev/null @@ -1,67 +0,0 @@ -{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} - -{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} -{% set orderShippingPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_SHIPPING_PROMOTION_ADJUSTMENT') %} -{% set itemPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_ITEM_PROMOTION_ADJUSTMENT') %} -{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} -{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} - -{% set orderShippingPromotions = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(orderShippingPromotionAdjustment)) %} - - - - - {{ 'sylius.ui.tax_total'|trans }}: - {{ money.format(order.taxTotal, order.currencyCode) }} - - - {{ 'sylius.ui.items_total'|trans }}: - {{ money.format(order.itemsTotal, order.currencyCode) }} - - - - - {% if not order.adjustments(shippingAdjustment).isEmpty() %} -
-
{{ 'sylius.ui.shipping'|trans }}:
- {% for adjustment in order.adjustments(shippingAdjustment) %} -
-
{{ money.format(adjustment.amount, order.currencyCode) }}
-
-
- {{ adjustment.label }}: -
-
-
- {% endfor %} -
- {% else %} -

{{ 'sylius.ui.no_shipping_charges'|trans }}

- {% endif %} - - {% if not orderShippingPromotions is empty %} - -
-
{{ 'sylius.ui.shipping_discount'|trans }}:
- {% for label, amount in orderShippingPromotions %} -
-
- {{ money.format(amount, order.currencyCode) }} -
-
- {% endfor %} -
- - {% endif %} - - {{ 'sylius.ui.shipping_total'|trans }}: - {{ money.format(order.shippingTotal, order.currencyCode) }} - - -{% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig' %} - - - {{ 'sylius.ui.order_total'|trans }}: - {{ money.format(order.total, order.currencyCode) }} - - diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/Product/Tab/_details.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/Product/Tab/_details.html.twig deleted file mode 100644 index d386b12b..00000000 --- a/tests/Application/templates/bundles/SyliusAdminBundle/Product/Tab/_details.html.twig +++ /dev/null @@ -1,70 +0,0 @@ -{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationFormWithSlug %} - -
-

{{ 'sylius.ui.details'|trans }}

- -
- {{ form_errors(form) }} - -
-
-
- {{ form_row(form.code) }} - {{ form_row(form.enabled) }} - {{ form_row(form.giftCard) }} - {{ form_row(form.giftCardAmountConfigurable) }} - {% if product.simple %} - {{ form_row(form.variant.shippingRequired) }} - {% else %} - {{ form_row(form.options) }} - {{ form_row(form.variantSelectionMethod) }} - {% endif %} - - {# Nothing to see here. #} - -
-
-
- {{ form_row(form.channels) }} -
-
- {% if product.simple %} -
-
-

{{ 'sylius.ui.pricing'|trans }}

- {% include "@SyliusAdmin/Product/_channel_pricing.html.twig" with { product: product, variantForm: form.variant } only %} -
-
- {% endif %} - - {{ translationFormWithSlug(form.translations, '@SyliusAdmin/Product/_slugField.html.twig', product) }} - {% if product.simple %} - -
-
-

{{ 'sylius.ui.shipping'|trans }}

-
- {{ form_row(form.variant.shippingCategory) }} - {{ form_row(form.variant.width) }} - {{ form_row(form.variant.height) }} - {{ form_row(form.variant.depth) }} - {{ form_row(form.variant.weight) }} -
-
-
-

{{ 'sylius.ui.taxes'|trans }}

-
- {{ form_row(form.variant.taxCategory) }} -
-
-
- {% endif %} - - {{ sylius_template_event(['sylius.admin.product.' ~ action ~ '.tab_details', 'sylius.admin.product.tab_details'], {'form': form}) }} -
-
diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/_logo.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/_logo.html.twig deleted file mode 100644 index 1b65d7f2..00000000 --- a/tests/Application/templates/bundles/SyliusAdminBundle/_logo.html.twig +++ /dev/null @@ -1,5 +0,0 @@ - -
- Sylius -
-
diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/_scripts.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/_scripts.html.twig deleted file mode 100644 index f5f98358..00000000 --- a/tests/Application/templates/bundles/SyliusAdminBundle/_scripts.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ encore_entry_script_tags('admin-entry', null, 'admin') }} diff --git a/tests/Application/templates/bundles/SyliusAdminBundle/_styles.html.twig b/tests/Application/templates/bundles/SyliusAdminBundle/_styles.html.twig deleted file mode 100644 index a96144cd..00000000 --- a/tests/Application/templates/bundles/SyliusAdminBundle/_styles.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ encore_entry_link_tags('admin-entry', null, 'admin') }} diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig deleted file mode 100644 index c3aff79c..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig +++ /dev/null @@ -1,36 +0,0 @@ -
- {{ form_start(form, {'action': path('sylius_shop_cart_save'), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} - {{ form_errors(form) }} - - {{ form_row(form._token) }} - {{ form_end(form, {'render_rest': false}) }} - - {{ sylius_template_event('sylius.shop.cart.summary.items', {'cart': cart, 'form': form}) }} - - - - - - - - - - - - - {% for key, item in cart.items %} - {% include '@SyliusShop/Cart/Summary/_item.html.twig' with {'item': item, 'form': form.items[key], 'main_form': form.vars.id, 'loop_index': loop.index} %} - {% endfor %} - -
{{ 'sylius.ui.item'|trans }}{{ 'sylius.ui.unit_price'|trans }}{{ 'sylius.ui.qty'|trans }}{{ 'sylius.ui.total'|trans }}
- {% if form.promotionCoupon is defined %} - - - {{ sylius_template_event('sylius.shop.cart.coupon', {'cart': cart, 'form': form, 'main_form': form.vars.id}) }} - - {% endif %} - - {% include '@SetonoSyliusGiftCardPlugin/Cart/_giftCard.html.twig' with {'order': cart} %} - - {% include '@SyliusShop/Cart/Summary/_update.html.twig' with {'main_form': form.vars.id} %} -
diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig deleted file mode 100644 index 2f1d93ad..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig +++ /dev/null @@ -1,67 +0,0 @@ -{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} - -{% set itemsSubtotal = sylius_order_items_subtotal(cart) %} -{% set taxIncluded = sylius_order_tax_included(cart) %} -{% set taxExcluded = sylius_order_tax_excluded(cart) %} - -
-

{{ 'sylius.ui.summary'|trans }}

- - {{ sylius_template_event('sylius.shop.cart.summary.totals', {'cart': cart}) }} - - - - - - - - {% if cart.orderPromotionTotal %} - - - - - {% endif %} - {% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig' %} - {% if cart.shipments is not empty %} - - - - - {% endif %} - - - - - - - - - {% if cart.currencyCode is not same as(sylius.currencyCode) %} - - - - - {% endif %} - -
{{ 'sylius.ui.items_total'|trans }}:{{ money.convertAndFormat(itemsSubtotal) }}
{{ 'sylius.ui.discount'|trans }}:{{ money.convertAndFormat(cart.orderPromotionTotal) }}
{{ 'sylius.ui.shipping_estimated_cost'|trans }}: - {% if cart.getAdjustmentsTotal('shipping') > cart.shippingTotal %} - {{ money.convertAndFormat(cart.getAdjustmentsTotal('shipping')) }} - {% endif %} - {{ money.convertAndFormat(cart.shippingTotal) }} -
{{ 'sylius.ui.taxes_total'|trans }}: - {% if not taxIncluded and not taxExcluded %} -
{{ money.convertAndFormat(0) }}
- {% endif %} - {% if taxExcluded %} -
{{ money.convertAndFormat(taxExcluded) }}
- {% endif %} - {% if taxIncluded %} -
- ({{ 'sylius.ui.included_in_price'|trans }}) - {{ money.convertAndFormat(taxIncluded) }} -
- {% endif %} -
{{ 'sylius.ui.order_total'|trans }}:{{ money.convertAndFormat(cart.total) }}
{{ 'sylius.ui.base_currency_order_total'|trans }}:{{ money.format(cart.total, cart.currencyCode) }}
-
- -{% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusShopBundle/Cart/summary.html.twig' %} diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Cart/summary.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Cart/summary.html.twig deleted file mode 100644 index bb44ee4e..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/Cart/summary.html.twig +++ /dev/null @@ -1,31 +0,0 @@ -{# @see https://symfony.com/blog/new-in-symfony-3-4-improved-the-overriding-of-templates#overriding-and-extending-templates #} -{% extends '@!SyliusShop/Cart/summary.html.twig' %} -{% import '@SyliusUi/Macro/messages.html.twig' as messages %} - -{% block content %} - {% if not cart.empty %} - {{ sylius_template_event('sylius.shop.cart.header', {'header': header, 'cart': cart}) }} -
-
- {{ sylius_template_event('sylius.shop.cart.items', {'cart': cart, 'form': form}) }} -
-
- {{ sylius_template_event('sylius.shop.cart.summary', {'cart': cart}) }} -
-
- {{ sylius_template_event('sylius.shop.cart.suggestions', {'cart': cart}) }} - {% else %} - {{ messages.info('sylius.ui.your_cart_is_empty') }} - {% endif %} -{% endblock %} - -{% block javascripts %} - {{ parent() }} - - - -{% endblock %} diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig deleted file mode 100644 index 4e544208..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig +++ /dev/null @@ -1,89 +0,0 @@ -{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} - -{% set itemsSubtotal = sylius_order_items_subtotal(order) %} -{% set taxIncluded = sylius_order_tax_included(order) %} -{% set taxExcluded = sylius_order_tax_excluded(order) %} - -
- - - - - - - - - - {% for item in order.items %} - - - - - - {% endfor %} - - - - - - - - - - - {% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig' %} - - - - - {% if order.shipments is not empty %} - - - - - {% endif %} - - - - - -
{{ 'sylius.ui.item'|trans }}{{ 'sylius.ui.qty'|trans }}{{ 'sylius.ui.subtotal'|trans }}
{{ item.getVariant.product.name }} - {{ item.quantity }} - - {{ money.convertAndFormat(item.subtotal) }} -
- {{ 'sylius.ui.items_total'|trans }}: - - {{ money.convertAndFormat(itemsSubtotal) }} -
- {{ 'sylius.ui.taxes_total'|trans }}: - - {% if not taxIncluded and not taxExcluded %} -
{{ money.convertAndFormat(0) }}
- {% endif %} - {% if taxExcluded %} -
{{ money.convertAndFormat(taxExcluded) }}
- {% endif %} - {% if taxIncluded %} -
- {{ money.convertAndFormat(taxIncluded) }} -
({{ 'sylius.ui.included_in_price'|trans }})
-
- {% endif %} -
- {{ 'sylius.ui.discount'|trans }}: - - {{ money.convertAndFormat(order.orderPromotionTotal) }} -
- {{ 'sylius.ui.shipping_estimated_cost'|trans }}: - - {% if order.getAdjustmentsTotal('shipping') > order.shippingTotal %} -
{{ money.convertAndFormat(order.getAdjustmentsTotal('shipping')) }}
- {% endif %} - {{ money.convertAndFormat(order.shippingTotal) }} -
- {{ 'sylius.ui.order_total'|trans }}: - - {{ money.convertAndFormat(order.total) }} -
-
diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig deleted file mode 100644 index 07a23642..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig +++ /dev/null @@ -1,64 +0,0 @@ -{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} - -{% set itemsSubtotal = sylius_order_items_subtotal(order) %} -{% set taxIncluded = sylius_order_tax_included(order) %} -{% set taxExcluded = sylius_order_tax_excluded(order) %} - -{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} -{% set orderPromotions = sylius_aggregate_adjustments(order.adjustmentsRecursively(orderPromotionAdjustment)) %} - - - - {{ 'sylius.ui.items_total'|trans }}: {{ money.convertAndFormat(itemsSubtotal) }} - - - - -
-
{{ 'sylius.ui.taxes_total'|trans }}: 
-
- {% if not taxIncluded and not taxExcluded %} -
{{ money.convertAndFormat(0) }}
- {% endif %} - {% if taxExcluded %} -
{{ money.convertAndFormat(taxExcluded) }}
- {% endif %} - {% if taxIncluded %} -
- ({{ 'sylius.ui.included_in_price'|trans }}) - {{ money.convertAndFormat(taxIncluded) }} -
- {% endif %} -
-
- - - - - {{ 'sylius.ui.discount'|trans }}: {{ money.convertAndFormat(order.orderPromotionTotal) }} - {% if order.orderPromotionTotal != 0 %} - - - {% endif %} - - -{% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig' %} - - {% include '@SyliusShop/Common/Order/Table/_shipping.html.twig' with {'order': order} %} - - - - {{ 'sylius.ui.total'|trans }}: {{ money.convertAndFormat(order.total) }} - - -{% if order.currencyCode is not same as(sylius.currencyCode) %} - - - {{ 'sylius.ui.total_in_base_currency'|trans }}: {{ money.format(order.total, order.currencyCode) }} - - -{% endif %} diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig deleted file mode 100644 index bb594f7a..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig +++ /dev/null @@ -1,2 +0,0 @@ -Sylius - diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig deleted file mode 100644 index 0bf5a064..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig deleted file mode 100644 index 39110d6d..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/tests/Application/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig deleted file mode 100644 index 6df10378..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig +++ /dev/null @@ -1,25 +0,0 @@ -{% macro item(taxon) %} - {% import _self as macros %} - - {% if taxon.children|length > 0 %} - - {% else %} - {{ taxon.name }} - {% endif %} -{% endmacro %} - -{% import _self as macros %} - -{% if taxons|length > 0 %} - {% for taxon in taxons %} - {{ macros.item(taxon) }} - {% endfor %} -{% endif %} diff --git a/tests/Application/templates/bundles/SyliusShopBundle/_scripts.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/_scripts.html.twig deleted file mode 100644 index d1655bb9..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/_scripts.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ encore_entry_script_tags('shop-entry', null, 'shop') }} diff --git a/tests/Application/templates/bundles/SyliusShopBundle/_styles.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/_styles.html.twig deleted file mode 100644 index fd2c7cb4..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/_styles.html.twig +++ /dev/null @@ -1 +0,0 @@ -{{ encore_entry_link_tags('shop-entry', null, 'shop') }} diff --git a/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig b/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig deleted file mode 100644 index 637479d9..00000000 --- a/tests/Application/templates/bundles/SyliusShopBundle/layout.html.twig +++ /dev/null @@ -1,18 +0,0 @@ -{# @see https://symfony.com/blog/new-in-symfony-3-4-improved-the-overriding-of-templates#overriding-and-extending-templates #} -{% extends '@!SyliusShop/layout.html.twig' %} - -{% block header %} -
- {% include '@SyliusShop/_header.html.twig' %} - - {{ sylius_template_event('sylius.shop.layout.after_header') }} - - -
-{% endblock %} diff --git a/tests/Application/translations/.gitignore b/tests/Application/translations/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/var/.gitignore b/tests/Application/var/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Application/webpack.config.js b/tests/Application/webpack.config.js deleted file mode 100644 index fae14296..00000000 --- a/tests/Application/webpack.config.js +++ /dev/null @@ -1,47 +0,0 @@ -const path = require('path'); -const Encore = require('@symfony/webpack-encore'); - -const syliusBundles = path.resolve(__dirname, '../../vendor/sylius/sylius/src/Sylius/Bundle/'); -const uiBundleScripts = path.resolve(syliusBundles, 'UiBundle/Resources/private/js/'); -const uiBundleResources = path.resolve(syliusBundles, 'UiBundle/Resources/private/'); - -// Shop config -Encore - .setOutputPath('public/build/shop/') - .setPublicPath('/build/shop') - .addEntry('shop-entry', './assets/shop/entry.js') - .disableSingleRuntimeChunk() - .cleanupOutputBeforeBuild() - .enableSourceMaps(!Encore.isProduction()) - .enableVersioning(Encore.isProduction()) - .enableSassLoader(); - -const shopConfig = Encore.getWebpackConfig(); - -shopConfig.resolve.alias['sylius/ui'] = uiBundleScripts; -shopConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources; -shopConfig.resolve.alias['sylius/bundle'] = syliusBundles; -shopConfig.name = 'shop'; - -Encore.reset(); - -// Admin config -Encore - .setOutputPath('public/build/admin/') - .setPublicPath('/build/admin') - .addEntry('admin-entry', './assets/admin/entry.js') - .disableSingleRuntimeChunk() - .cleanupOutputBeforeBuild() - .enableSourceMaps(!Encore.isProduction()) - .enableVersioning(Encore.isProduction()) - .enableSassLoader(); - -const adminConfig = Encore.getWebpackConfig(); - -adminConfig.resolve.alias['sylius/ui'] = uiBundleScripts; -adminConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources; -adminConfig.resolve.alias['sylius/bundle'] = syliusBundles; -adminConfig.externals = Object.assign({}, adminConfig.externals, { window: 'window', document: 'document' }); -adminConfig.name = 'admin'; - -module.exports = [shopConfig, adminConfig]; From 6695362094b0525e308206e6a6b3c98f0eabccac Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:30:18 +0200 Subject: [PATCH 02/60] Replace custom tests/Application with sylius/test-application Plugin-specific overrides (entity models, repositories, config, template overrides) now live under tests/TestApplication/, wired via the SYLIUS_TEST_APP_BUNDLES_REPLACE_PATH/CONFIGS_TO_IMPORT/ROUTES_TO_IMPORT env vars read by Sylius\TestApplication\Kernel. The plugin bundle must still be registered before SyliusGridBundle, so bundles.php is a full replacement list (not the additive BUNDLES_PATH mechanism) to preserve that order. --- tests/TestApplication/.env | 8 ++ tests/TestApplication/Entity/Order.php | 26 ++++++ tests/TestApplication/Entity/OrderItem.php | 20 +++++ .../TestApplication/Entity/OrderItemUnit.php | 17 ++++ tests/TestApplication/Entity/Product.php | 17 ++++ .../Repository/CustomerRepository.php | 14 +++ .../Repository/OrderRepository.php | 14 +++ tests/TestApplication/config/bundles.php | 75 ++++++++++++++++ tests/TestApplication/config/config.yaml | 63 +++++++++++++ tests/TestApplication/config/routes.yaml | 2 + .../TestApplication/config/services_test.php | 11 +++ .../Form/imagesTheme.html.twig | 17 ++++ .../Order/Show/Summary/_item.html.twig | 58 ++++++++++++ .../Order/Show/Summary/_totals.html.twig | 67 ++++++++++++++ .../Product/Tab/_details.html.twig | 70 +++++++++++++++ .../bundles/SyliusAdminBundle/_logo.html.twig | 5 ++ .../SyliusAdminBundle/_scripts.html.twig | 1 + .../SyliusAdminBundle/_styles.html.twig | 1 + .../Cart/Summary/_items.html.twig | 36 ++++++++ .../Cart/Summary/_totals.html.twig | 67 ++++++++++++++ .../Checkout/_summary.html.twig | 89 +++++++++++++++++++ .../Common/Order/Table/_totals.html.twig | 64 +++++++++++++ .../Homepage/_banner.html.twig | 2 + .../Layout/Footer/Grid/_plus.html.twig | 9 ++ .../Layout/Header/_logo.html.twig | 5 ++ .../Taxon/_horizontalMenu.html.twig | 25 ++++++ .../SyliusShopBundle/_scripts.html.twig | 1 + .../SyliusShopBundle/_styles.html.twig | 1 + .../bundles/SyliusShopBundle/layout.html.twig | 18 ++++ 29 files changed, 803 insertions(+) create mode 100644 tests/TestApplication/.env create mode 100644 tests/TestApplication/Entity/Order.php create mode 100644 tests/TestApplication/Entity/OrderItem.php create mode 100644 tests/TestApplication/Entity/OrderItemUnit.php create mode 100644 tests/TestApplication/Entity/Product.php create mode 100644 tests/TestApplication/Repository/CustomerRepository.php create mode 100644 tests/TestApplication/Repository/OrderRepository.php create mode 100644 tests/TestApplication/config/bundles.php create mode 100644 tests/TestApplication/config/config.yaml create mode 100644 tests/TestApplication/config/routes.yaml create mode 100644 tests/TestApplication/config/services_test.php create mode 100644 tests/TestApplication/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_item.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusAdminBundle/Product/Tab/_details.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusAdminBundle/_logo.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusAdminBundle/_scripts.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusAdminBundle/_styles.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/_scripts.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/_styles.html.twig create mode 100644 tests/TestApplication/templates/bundles/SyliusShopBundle/layout.html.twig diff --git a/tests/TestApplication/.env b/tests/TestApplication/.env new file mode 100644 index 00000000..89f38992 --- /dev/null +++ b/tests/TestApplication/.env @@ -0,0 +1,8 @@ +DATABASE_URL=mysql://root@127.0.0.1/setono_sylius_gift_card_plugin_%kernel.environment% + +BEHAT_BASE_URL="https://127.0.0.1:8080/" +BEHAT_CHROME_URL="http://127.0.0.1:9222" + +SYLIUS_TEST_APP_BUNDLES_REPLACE_PATH="tests/TestApplication/config/bundles.php" +SYLIUS_TEST_APP_CONFIGS_TO_IMPORT="../../../../tests/TestApplication/config/config.yaml" +SYLIUS_TEST_APP_ROUTES_TO_IMPORT="../../../../tests/TestApplication/config/routes.yaml" diff --git a/tests/TestApplication/Entity/Order.php b/tests/TestApplication/Entity/Order.php new file mode 100644 index 00000000..26ef4c9d --- /dev/null +++ b/tests/TestApplication/Entity/Order.php @@ -0,0 +1,26 @@ +__SetonoSyliusGiftCardOrderTraitConstruct(); + + parent::__construct(); + } +} diff --git a/tests/TestApplication/Entity/OrderItem.php b/tests/TestApplication/Entity/OrderItem.php new file mode 100644 index 00000000..b322c197 --- /dev/null +++ b/tests/TestApplication/Entity/OrderItem.php @@ -0,0 +1,20 @@ + ['all' => true], + Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], + Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], + Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], + Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + Sylius\Bundle\OrderBundle\SyliusOrderBundle::class => ['all' => true], + Sylius\Bundle\MoneyBundle\SyliusMoneyBundle::class => ['all' => true], + Sylius\Bundle\CurrencyBundle\SyliusCurrencyBundle::class => ['all' => true], + Sylius\Bundle\LocaleBundle\SyliusLocaleBundle::class => ['all' => true], + Sylius\Bundle\ProductBundle\SyliusProductBundle::class => ['all' => true], + Sylius\Bundle\ChannelBundle\SyliusChannelBundle::class => ['all' => true], + Sylius\Bundle\AttributeBundle\SyliusAttributeBundle::class => ['all' => true], + Sylius\Bundle\TaxationBundle\SyliusTaxationBundle::class => ['all' => true], + Sylius\Bundle\ShippingBundle\SyliusShippingBundle::class => ['all' => true], + Sylius\Bundle\PaymentBundle\SyliusPaymentBundle::class => ['all' => true], + Sylius\Bundle\MailerBundle\SyliusMailerBundle::class => ['all' => true], + Sylius\Bundle\PromotionBundle\SyliusPromotionBundle::class => ['all' => true], + Sylius\Bundle\AddressingBundle\SyliusAddressingBundle::class => ['all' => true], + Sylius\Bundle\InventoryBundle\SyliusInventoryBundle::class => ['all' => true], + Sylius\Bundle\TaxonomyBundle\SyliusTaxonomyBundle::class => ['all' => true], + Sylius\Bundle\UserBundle\SyliusUserBundle::class => ['all' => true], + Sylius\Bundle\CustomerBundle\SyliusCustomerBundle::class => ['all' => true], + Sylius\Bundle\UiBundle\SyliusUiBundle::class => ['all' => true], + Sylius\Bundle\ReviewBundle\SyliusReviewBundle::class => ['all' => true], + Sylius\Bundle\CoreBundle\SyliusCoreBundle::class => ['all' => true], + Sylius\Bundle\ResourceBundle\SyliusResourceBundle::class => ['all' => true], + + // The plugin must be registered before SyliusGridBundle, see README + Setono\SyliusGiftCardPlugin\SetonoSyliusGiftCardPlugin::class => ['all' => true], + + Sylius\Bundle\GridBundle\SyliusGridBundle::class => ['all' => true], + Knp\Bundle\GaufretteBundle\KnpGaufretteBundle::class => ['all' => true], + Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true], + Knp\Bundle\SnappyBundle\KnpSnappyBundle::class => ['all' => true], + Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true], + Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true], + Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], + Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], + Sylius\Bundle\FixturesBundle\SyliusFixturesBundle::class => ['all' => true], + Sylius\Bundle\PayumBundle\SyliusPayumBundle::class => ['all' => true], + Sylius\Bundle\ThemeBundle\SyliusThemeBundle::class => ['all' => true], + Sylius\Bundle\AdminBundle\SyliusAdminBundle::class => ['all' => true], + Sylius\Bundle\ShopBundle\SyliusShopBundle::class => ['all' => true], + Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true], + Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true], + ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], + Sylius\Bundle\ApiBundle\SyliusApiBundle::class => ['all' => true], + Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], + SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true], + BabDev\PagerfantaBundle\BabDevPagerfantaBundle::class => ['all' => true], + Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], + League\FlysystemBundle\FlysystemBundle::class => ['all' => true], + Sylius\TwigExtra\Symfony\SyliusTwigExtraBundle::class => ['all' => true], + Sylius\TwigHooks\SyliusTwigHooksBundle::class => ['all' => true], + Symfony\UX\Icons\UXIconsBundle::class => ['all' => true], + Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], + Symfony\UX\LiveComponent\LiveComponentBundle::class => ['all' => true], + Symfony\UX\Autocomplete\AutocompleteBundle::class => ['all' => true], + Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], + Sylius\Abstraction\StateMachine\SyliusStateMachineAbstractionBundle::class => ['all' => true], + Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true], + Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle::class => ['dev' => true, 'test' => true], + Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle::class => ['dev' => true, 'test' => true], +]; + +if (class_exists('FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle')) { + $bundles[FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class] = ['test' => true, 'test_cached' => true]; +} + +return $bundles; diff --git a/tests/TestApplication/config/config.yaml b/tests/TestApplication/config/config.yaml new file mode 100644 index 00000000..beb6606e --- /dev/null +++ b/tests/TestApplication/config/config.yaml @@ -0,0 +1,63 @@ +imports: + - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/config.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/fixtures.yaml" } + - { resource: "services_test.php" } + +twig: + paths: + '%kernel.project_dir%/../../../tests/TestApplication/templates': ~ + +sylius_api: + enabled: true + +sylius_customer: + resources: + customer: + classes: + repository: Setono\SyliusGiftCardPlugin\Tests\TestApplication\Repository\CustomerRepository + +sylius_order: + resources: + order: + classes: + model: Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Order + repository: Setono\SyliusGiftCardPlugin\Tests\TestApplication\Repository\OrderRepository + order_item: + classes: + model: Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem + order_item_unit: + classes: + model: Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItemUnit + +sylius_product: + resources: + product: + classes: + model: Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Product + +when@test: + setono_sylius_gift_card: + pdf_rendering: + default_orientation: 'Landscape' + available_orientations: + - Landscape + default_page_size: 'B0' + available_page_sizes: + - A5 + - B0 + + sylius_theme: + sources: + test: ~ + +# Remove if you do not need to extend entities +doctrine: + orm: + entity_managers: + default: + mappings: + TestApplication: + is_bundle: false + type: attribute + dir: '%kernel.project_dir%/../../../tests/TestApplication/Entity' + prefix: Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity diff --git a/tests/TestApplication/config/routes.yaml b/tests/TestApplication/config/routes.yaml new file mode 100644 index 00000000..c1e265d0 --- /dev/null +++ b/tests/TestApplication/config/routes.yaml @@ -0,0 +1,2 @@ +setono_sylius_gift_card: + resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes.yaml" diff --git a/tests/TestApplication/config/services_test.php b/tests/TestApplication/config/services_test.php new file mode 100644 index 00000000..17e708dc --- /dev/null +++ b/tests/TestApplication/config/services_test.php @@ -0,0 +1,11 @@ +env(), 'test')) { + $container->import('../../../vendor/sylius/sylius/src/Sylius/Behat/Resources/config/services.xml'); + } +}; diff --git a/tests/TestApplication/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig b/tests/TestApplication/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig new file mode 100644 index 00000000..39599d88 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig @@ -0,0 +1,17 @@ +{% extends '@!SyliusAdmin/Form/imagesTheme.html.twig' %} + +{% block setono_sylius_gift_card_gift_card_configuration_image_widget %} + {%- if form.type is defined -%} + {{- form_row(form.type) -}} + {%- endif -%} + + {%- if form.vars.value.path|default(null) is not null -%} + {{ form.vars.value.type }} + {%- endif -%} + +
+ {{- form_errors(form.file) -}} +
+{% endblock %} diff --git a/tests/TestApplication/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_item.html.twig b/tests/TestApplication/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_item.html.twig new file mode 100644 index 00000000..878d5b9f --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_item.html.twig @@ -0,0 +1,58 @@ +{# @var \Sylius\Component\Core\Model\OrderItemInterface item #} +{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} + +{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} +{% set unitPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT') %} +{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} +{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} + +{% set variant = item.variant %} +{% set product = variant.product %} + +{% set aggregatedUnitPromotionAdjustments = item.getAdjustmentsTotalRecursively(unitPromotionAdjustment) + item.getAdjustmentsTotalRecursively(orderPromotionAdjustment) %} +{% set subtotal = (item.unitPrice * item.quantity) + aggregatedUnitPromotionAdjustments %} + +{% set taxIncluded = sylius_admin_order_unit_tax_included(item) %} +{% set taxExcluded = sylius_admin_order_unit_tax_excluded(item) %} + + + + {% include '@SyliusAdmin/Product/_info.html.twig' %} + {# @var \Setono\SyliusGiftCardPlugin\Model\OrderItemUnitInterface itemUnit #} + {% for itemUnit in item.units %} + {% set giftCard = itemUnit.giftCard %} + {% if giftCard is not null %} + {{ giftCard.code }} + {% endif %} + {% endfor %} + + + {{ money.format(item.unitPrice, order.currencyCode) }} + + + {{ money.format(item.units.first.adjustmentsTotal(unitPromotionAdjustment), order.currencyCode) }} + + + ~ {{ money.format(item.units.first.adjustmentsTotal(orderPromotionAdjustment), order.currencyCode) }} + + + {{ money.format(item.fullDiscountedUnitPrice, order.currencyCode) }} + + + {{ item.quantity }} + + + {{ money.format(subtotal, order.currencyCode) }} + + +
{{ money.format(taxExcluded, order.currencyCode) }}
+
+
{{ money.format(taxIncluded, order.currencyCode) }} +
+ ({{ 'sylius.ui.included_in_price'|trans }}) +
+ + + {{ money.format(item.total, order.currencyCode) }} + + diff --git a/tests/TestApplication/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig b/tests/TestApplication/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig new file mode 100644 index 00000000..d7c5fe17 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig @@ -0,0 +1,67 @@ +{% import "@SyliusAdmin/Common/Macro/money.html.twig" as money %} + +{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} +{% set orderShippingPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_SHIPPING_PROMOTION_ADJUSTMENT') %} +{% set itemPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_ITEM_PROMOTION_ADJUSTMENT') %} +{% set shippingAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::SHIPPING_ADJUSTMENT') %} +{% set taxAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::TAX_ADJUSTMENT') %} + +{% set orderShippingPromotions = sylius_aggregate_adjustments(order.getAdjustmentsRecursively(orderShippingPromotionAdjustment)) %} + + + + + {{ 'sylius.ui.tax_total'|trans }}: + {{ money.format(order.taxTotal, order.currencyCode) }} + + + {{ 'sylius.ui.items_total'|trans }}: + {{ money.format(order.itemsTotal, order.currencyCode) }} + + + + + {% if not order.adjustments(shippingAdjustment).isEmpty() %} +
+
{{ 'sylius.ui.shipping'|trans }}:
+ {% for adjustment in order.adjustments(shippingAdjustment) %} +
+
{{ money.format(adjustment.amount, order.currencyCode) }}
+
+
+ {{ adjustment.label }}: +
+
+
+ {% endfor %} +
+ {% else %} +

{{ 'sylius.ui.no_shipping_charges'|trans }}

+ {% endif %} + + {% if not orderShippingPromotions is empty %} + +
+
{{ 'sylius.ui.shipping_discount'|trans }}:
+ {% for label, amount in orderShippingPromotions %} +
+
+ {{ money.format(amount, order.currencyCode) }} +
+
+ {% endfor %} +
+ + {% endif %} + + {{ 'sylius.ui.shipping_total'|trans }}: + {{ money.format(order.shippingTotal, order.currencyCode) }} + + +{% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig' %} + + + {{ 'sylius.ui.order_total'|trans }}: + {{ money.format(order.total, order.currencyCode) }} + + diff --git a/tests/TestApplication/templates/bundles/SyliusAdminBundle/Product/Tab/_details.html.twig b/tests/TestApplication/templates/bundles/SyliusAdminBundle/Product/Tab/_details.html.twig new file mode 100644 index 00000000..d386b12b --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusAdminBundle/Product/Tab/_details.html.twig @@ -0,0 +1,70 @@ +{% from '@SyliusAdmin/Macro/translationForm.html.twig' import translationFormWithSlug %} + +
+

{{ 'sylius.ui.details'|trans }}

+ +
+ {{ form_errors(form) }} + +
+
+
+ {{ form_row(form.code) }} + {{ form_row(form.enabled) }} + {{ form_row(form.giftCard) }} + {{ form_row(form.giftCardAmountConfigurable) }} + {% if product.simple %} + {{ form_row(form.variant.shippingRequired) }} + {% else %} + {{ form_row(form.options) }} + {{ form_row(form.variantSelectionMethod) }} + {% endif %} + + {# Nothing to see here. #} + +
+
+
+ {{ form_row(form.channels) }} +
+
+ {% if product.simple %} +
+
+

{{ 'sylius.ui.pricing'|trans }}

+ {% include "@SyliusAdmin/Product/_channel_pricing.html.twig" with { product: product, variantForm: form.variant } only %} +
+
+ {% endif %} + + {{ translationFormWithSlug(form.translations, '@SyliusAdmin/Product/_slugField.html.twig', product) }} + {% if product.simple %} + +
+
+

{{ 'sylius.ui.shipping'|trans }}

+
+ {{ form_row(form.variant.shippingCategory) }} + {{ form_row(form.variant.width) }} + {{ form_row(form.variant.height) }} + {{ form_row(form.variant.depth) }} + {{ form_row(form.variant.weight) }} +
+
+
+

{{ 'sylius.ui.taxes'|trans }}

+
+ {{ form_row(form.variant.taxCategory) }} +
+
+
+ {% endif %} + + {{ sylius_template_event(['sylius.admin.product.' ~ action ~ '.tab_details', 'sylius.admin.product.tab_details'], {'form': form}) }} +
+
diff --git a/tests/TestApplication/templates/bundles/SyliusAdminBundle/_logo.html.twig b/tests/TestApplication/templates/bundles/SyliusAdminBundle/_logo.html.twig new file mode 100644 index 00000000..1b65d7f2 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusAdminBundle/_logo.html.twig @@ -0,0 +1,5 @@ + +
+ Sylius +
+
diff --git a/tests/TestApplication/templates/bundles/SyliusAdminBundle/_scripts.html.twig b/tests/TestApplication/templates/bundles/SyliusAdminBundle/_scripts.html.twig new file mode 100644 index 00000000..f5f98358 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusAdminBundle/_scripts.html.twig @@ -0,0 +1 @@ +{{ encore_entry_script_tags('admin-entry', null, 'admin') }} diff --git a/tests/TestApplication/templates/bundles/SyliusAdminBundle/_styles.html.twig b/tests/TestApplication/templates/bundles/SyliusAdminBundle/_styles.html.twig new file mode 100644 index 00000000..a96144cd --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusAdminBundle/_styles.html.twig @@ -0,0 +1 @@ +{{ encore_entry_link_tags('admin-entry', null, 'admin') }} diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig new file mode 100644 index 00000000..c3aff79c --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/Cart/Summary/_items.html.twig @@ -0,0 +1,36 @@ +
+ {{ form_start(form, {'action': path('sylius_shop_cart_save'), 'attr': {'class': 'ui loadable form', 'novalidate': 'novalidate', 'id': form.vars.id}}) }} + {{ form_errors(form) }} + + {{ form_row(form._token) }} + {{ form_end(form, {'render_rest': false}) }} + + {{ sylius_template_event('sylius.shop.cart.summary.items', {'cart': cart, 'form': form}) }} + + + + + + + + + + + + + {% for key, item in cart.items %} + {% include '@SyliusShop/Cart/Summary/_item.html.twig' with {'item': item, 'form': form.items[key], 'main_form': form.vars.id, 'loop_index': loop.index} %} + {% endfor %} + +
{{ 'sylius.ui.item'|trans }}{{ 'sylius.ui.unit_price'|trans }}{{ 'sylius.ui.qty'|trans }}{{ 'sylius.ui.total'|trans }}
+ {% if form.promotionCoupon is defined %} + + + {{ sylius_template_event('sylius.shop.cart.coupon', {'cart': cart, 'form': form, 'main_form': form.vars.id}) }} + + {% endif %} + + {% include '@SetonoSyliusGiftCardPlugin/Cart/_giftCard.html.twig' with {'order': cart} %} + + {% include '@SyliusShop/Cart/Summary/_update.html.twig' with {'main_form': form.vars.id} %} +
diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig new file mode 100644 index 00000000..2f1d93ad --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig @@ -0,0 +1,67 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +{% set itemsSubtotal = sylius_order_items_subtotal(cart) %} +{% set taxIncluded = sylius_order_tax_included(cart) %} +{% set taxExcluded = sylius_order_tax_excluded(cart) %} + +
+

{{ 'sylius.ui.summary'|trans }}

+ + {{ sylius_template_event('sylius.shop.cart.summary.totals', {'cart': cart}) }} + + + + + + + + {% if cart.orderPromotionTotal %} + + + + + {% endif %} + {% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig' %} + {% if cart.shipments is not empty %} + + + + + {% endif %} + + + + + + + + + {% if cart.currencyCode is not same as(sylius.currencyCode) %} + + + + + {% endif %} + +
{{ 'sylius.ui.items_total'|trans }}:{{ money.convertAndFormat(itemsSubtotal) }}
{{ 'sylius.ui.discount'|trans }}:{{ money.convertAndFormat(cart.orderPromotionTotal) }}
{{ 'sylius.ui.shipping_estimated_cost'|trans }}: + {% if cart.getAdjustmentsTotal('shipping') > cart.shippingTotal %} + {{ money.convertAndFormat(cart.getAdjustmentsTotal('shipping')) }} + {% endif %} + {{ money.convertAndFormat(cart.shippingTotal) }} +
{{ 'sylius.ui.taxes_total'|trans }}: + {% if not taxIncluded and not taxExcluded %} +
{{ money.convertAndFormat(0) }}
+ {% endif %} + {% if taxExcluded %} +
{{ money.convertAndFormat(taxExcluded) }}
+ {% endif %} + {% if taxIncluded %} +
+ ({{ 'sylius.ui.included_in_price'|trans }}) + {{ money.convertAndFormat(taxIncluded) }} +
+ {% endif %} +
{{ 'sylius.ui.order_total'|trans }}:{{ money.convertAndFormat(cart.total) }}
{{ 'sylius.ui.base_currency_order_total'|trans }}:{{ money.format(cart.total, cart.currencyCode) }}
+
+ +{% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusShopBundle/Cart/summary.html.twig' %} diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig new file mode 100644 index 00000000..4e544208 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig @@ -0,0 +1,89 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +{% set itemsSubtotal = sylius_order_items_subtotal(order) %} +{% set taxIncluded = sylius_order_tax_included(order) %} +{% set taxExcluded = sylius_order_tax_excluded(order) %} + +
+ + + + + + + + + + {% for item in order.items %} + + + + + + {% endfor %} + + + + + + + + + + + {% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig' %} + + + + + {% if order.shipments is not empty %} + + + + + {% endif %} + + + + + +
{{ 'sylius.ui.item'|trans }}{{ 'sylius.ui.qty'|trans }}{{ 'sylius.ui.subtotal'|trans }}
{{ item.getVariant.product.name }} + {{ item.quantity }} + + {{ money.convertAndFormat(item.subtotal) }} +
+ {{ 'sylius.ui.items_total'|trans }}: + + {{ money.convertAndFormat(itemsSubtotal) }} +
+ {{ 'sylius.ui.taxes_total'|trans }}: + + {% if not taxIncluded and not taxExcluded %} +
{{ money.convertAndFormat(0) }}
+ {% endif %} + {% if taxExcluded %} +
{{ money.convertAndFormat(taxExcluded) }}
+ {% endif %} + {% if taxIncluded %} +
+ {{ money.convertAndFormat(taxIncluded) }} +
({{ 'sylius.ui.included_in_price'|trans }})
+
+ {% endif %} +
+ {{ 'sylius.ui.discount'|trans }}: + + {{ money.convertAndFormat(order.orderPromotionTotal) }} +
+ {{ 'sylius.ui.shipping_estimated_cost'|trans }}: + + {% if order.getAdjustmentsTotal('shipping') > order.shippingTotal %} +
{{ money.convertAndFormat(order.getAdjustmentsTotal('shipping')) }}
+ {% endif %} + {{ money.convertAndFormat(order.shippingTotal) }} +
+ {{ 'sylius.ui.order_total'|trans }}: + + {{ money.convertAndFormat(order.total) }} +
+
diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig new file mode 100644 index 00000000..07a23642 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig @@ -0,0 +1,64 @@ +{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} + +{% set itemsSubtotal = sylius_order_items_subtotal(order) %} +{% set taxIncluded = sylius_order_tax_included(order) %} +{% set taxExcluded = sylius_order_tax_excluded(order) %} + +{% set orderPromotionAdjustment = constant('Sylius\\Component\\Core\\Model\\AdjustmentInterface::ORDER_PROMOTION_ADJUSTMENT') %} +{% set orderPromotions = sylius_aggregate_adjustments(order.adjustmentsRecursively(orderPromotionAdjustment)) %} + + + + {{ 'sylius.ui.items_total'|trans }}: {{ money.convertAndFormat(itemsSubtotal) }} + + + + +
+
{{ 'sylius.ui.taxes_total'|trans }}: 
+
+ {% if not taxIncluded and not taxExcluded %} +
{{ money.convertAndFormat(0) }}
+ {% endif %} + {% if taxExcluded %} +
{{ money.convertAndFormat(taxExcluded) }}
+ {% endif %} + {% if taxIncluded %} +
+ ({{ 'sylius.ui.included_in_price'|trans }}) + {{ money.convertAndFormat(taxIncluded) }} +
+ {% endif %} +
+
+ + + + + {{ 'sylius.ui.discount'|trans }}: {{ money.convertAndFormat(order.orderPromotionTotal) }} + {% if order.orderPromotionTotal != 0 %} + + + {% endif %} + + +{% include '@SetonoSyliusGiftCardPlugin/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig' %} + + {% include '@SyliusShop/Common/Order/Table/_shipping.html.twig' with {'order': order} %} + + + + {{ 'sylius.ui.total'|trans }}: {{ money.convertAndFormat(order.total) }} + + +{% if order.currencyCode is not same as(sylius.currencyCode) %} + + + {{ 'sylius.ui.total_in_base_currency'|trans }}: {{ money.format(order.total, order.currencyCode) }} + + +{% endif %} diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig new file mode 100644 index 00000000..bb594f7a --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/Homepage/_banner.html.twig @@ -0,0 +1,2 @@ +Sylius + diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig new file mode 100644 index 00000000..0bf5a064 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/Layout/Footer/Grid/_plus.html.twig @@ -0,0 +1,9 @@ + diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig new file mode 100644 index 00000000..39110d6d --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/Layout/Header/_logo.html.twig @@ -0,0 +1,5 @@ + diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig new file mode 100644 index 00000000..6df10378 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/Taxon/_horizontalMenu.html.twig @@ -0,0 +1,25 @@ +{% macro item(taxon) %} + {% import _self as macros %} + + {% if taxon.children|length > 0 %} + + {% else %} + {{ taxon.name }} + {% endif %} +{% endmacro %} + +{% import _self as macros %} + +{% if taxons|length > 0 %} + {% for taxon in taxons %} + {{ macros.item(taxon) }} + {% endfor %} +{% endif %} diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/_scripts.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/_scripts.html.twig new file mode 100644 index 00000000..d1655bb9 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/_scripts.html.twig @@ -0,0 +1 @@ +{{ encore_entry_script_tags('shop-entry', null, 'shop') }} diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/_styles.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/_styles.html.twig new file mode 100644 index 00000000..fd2c7cb4 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/_styles.html.twig @@ -0,0 +1 @@ +{{ encore_entry_link_tags('shop-entry', null, 'shop') }} diff --git a/tests/TestApplication/templates/bundles/SyliusShopBundle/layout.html.twig b/tests/TestApplication/templates/bundles/SyliusShopBundle/layout.html.twig new file mode 100644 index 00000000..637479d9 --- /dev/null +++ b/tests/TestApplication/templates/bundles/SyliusShopBundle/layout.html.twig @@ -0,0 +1,18 @@ +{# @see https://symfony.com/blog/new-in-symfony-3-4-improved-the-overriding-of-templates#overriding-and-extending-templates #} +{% extends '@!SyliusShop/layout.html.twig' %} + +{% block header %} +
+ {% include '@SyliusShop/_header.html.twig' %} + + {{ sylius_template_event('sylius.shop.layout.after_header') }} + + +
+{% endblock %} From cf00f5d0846a6e1a7ba98008b28cc941c0b5d511 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:30:49 +0200 Subject: [PATCH 03/60] Migrate order state machine callbacks to Symfony Workflow listeners Sylius 2 defaults to the symfony_workflow state machine adapter; the winzou_state_machine config this plugin relied on is no longer loaded. Replaced the 3 winzou callback yaml files with 4 kernel.event_listener services on workflow..completed. events, following Sylius core's own EventListener\Workflow pattern. Added send() to OrderGiftCardOperatorInterface since the listener needs it. --- .../AssociateGiftCardToCustomerListener.php | 25 ++++++++ .../Workflow/CancelOrderGiftCardListener.php | 29 +++++++++ .../DecrementGiftCardAmountListener.php | 25 ++++++++ .../EnableAndSendGiftCardListener.php | 26 ++++++++ .../OrderGiftCardOperatorInterface.php | 2 + src/Resources/config/app/config.yaml | 60 +------------------ .../config/services/event_listener.xml | 31 +++++++++- 7 files changed, 140 insertions(+), 58 deletions(-) create mode 100644 src/EventListener/Workflow/AssociateGiftCardToCustomerListener.php create mode 100644 src/EventListener/Workflow/CancelOrderGiftCardListener.php create mode 100644 src/EventListener/Workflow/DecrementGiftCardAmountListener.php create mode 100644 src/EventListener/Workflow/EnableAndSendGiftCardListener.php diff --git a/src/EventListener/Workflow/AssociateGiftCardToCustomerListener.php b/src/EventListener/Workflow/AssociateGiftCardToCustomerListener.php new file mode 100644 index 00000000..ef7c51fb --- /dev/null +++ b/src/EventListener/Workflow/AssociateGiftCardToCustomerListener.php @@ -0,0 +1,25 @@ +getSubject(); + Assert::isInstanceOf($order, OrderInterface::class); + + $this->orderGiftCardOperator->associateToCustomer($order); + } +} diff --git a/src/EventListener/Workflow/CancelOrderGiftCardListener.php b/src/EventListener/Workflow/CancelOrderGiftCardListener.php new file mode 100644 index 00000000..8e1bdd2d --- /dev/null +++ b/src/EventListener/Workflow/CancelOrderGiftCardListener.php @@ -0,0 +1,29 @@ +getSubject(); + Assert::isInstanceOf($order, OrderInterface::class); + + $this->orderGiftCardAmountModifier->increment($order); + $this->orderGiftCardOperator->disable($order); + } +} diff --git a/src/EventListener/Workflow/DecrementGiftCardAmountListener.php b/src/EventListener/Workflow/DecrementGiftCardAmountListener.php new file mode 100644 index 00000000..79d4c966 --- /dev/null +++ b/src/EventListener/Workflow/DecrementGiftCardAmountListener.php @@ -0,0 +1,25 @@ +getSubject(); + Assert::isInstanceOf($order, OrderInterface::class); + + $this->orderGiftCardAmountModifier->decrement($order); + } +} diff --git a/src/EventListener/Workflow/EnableAndSendGiftCardListener.php b/src/EventListener/Workflow/EnableAndSendGiftCardListener.php new file mode 100644 index 00000000..277c55a5 --- /dev/null +++ b/src/EventListener/Workflow/EnableAndSendGiftCardListener.php @@ -0,0 +1,26 @@ +getSubject(); + Assert::isInstanceOf($order, OrderInterface::class); + + $this->orderGiftCardOperator->enable($order); + $this->orderGiftCardOperator->send($order); + } +} diff --git a/src/Operator/OrderGiftCardOperatorInterface.php b/src/Operator/OrderGiftCardOperatorInterface.php index 0107d64d..fb9aed9b 100644 --- a/src/Operator/OrderGiftCardOperatorInterface.php +++ b/src/Operator/OrderGiftCardOperatorInterface.php @@ -16,4 +16,6 @@ public function associateToCustomer(OrderInterface $order): void; public function enable(OrderInterface $order): void; public function disable(OrderInterface $order): void; + + public function send(OrderInterface $order): void; } diff --git a/src/Resources/config/app/config.yaml b/src/Resources/config/app/config.yaml index 91154c3e..6159de34 100644 --- a/src/Resources/config/app/config.yaml +++ b/src/Resources/config/app/config.yaml @@ -2,10 +2,6 @@ imports: - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/grids.yaml" } - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/sylius_ui.yaml" } - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/state_machine/sylius_order.yaml" } - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/state_machine/sylius_order_checkout.yaml" } - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/state_machine/sylius_order_payment.yaml" } - sylius_mailer: emails: gift_card_customer: @@ -15,62 +11,12 @@ sylius_mailer: subject: setono_sylius_gift_card.email.your_gift_cards_you_bought_in_the_order template: "@SetonoSyliusGiftCardPlugin/Email/giftCardsFromOrder.html.twig" -jms_serializer: - metadata: - directories: - setono-sylius-gift-card-sylius: - namespace_prefix: "Setono\\SyliusGiftCardPlugin\\Model" - path: "@SetonoSyliusGiftCardPlugin/Resources/config/serializer" - liip_imagine: filter_sets: setono_sylius_gift_card_background: filters: thumbnail: { size: [1200], mode: inset } -sylius_ui: - events: - setono_sylius_gift_card.admin.gift_card_configuration.create.javascripts: - blocks: - preview_uploaded_image: '@SetonoSyliusGiftCardPlugin/Admin/GiftCardConfiguration/_javascripts.html.twig' - - setono_sylius_gift_card.admin.gift_card_configuration.update.javascripts: - blocks: - preview_uploaded_image: '@SetonoSyliusGiftCardPlugin/Admin/GiftCardConfiguration/_javascripts.html.twig' - live_pdf_rendering_js: '@SetonoSyliusGiftCardPlugin/Admin/GiftCardConfiguration/Update/_javascripts.html.twig' - - setono_sylius_gift_card.admin.gift_card.create.javascripts: - blocks: - send_customer_email_js: '@SetonoSyliusGiftCardPlugin/Admin/GiftCard/Create/_javascripts.html.twig' - - setono_sylius_gift_card.shop.account.gift_card.index.after_content_header: - blocks: - after_content_header_legacy: - template: "@SyliusUi/Block/_legacySonataEvent.html.twig" - priority: 50 - context: - event: setono_sylius_gift_card.shop.account.gift_card.index.after_content_header - - setono_sylius_gift_card.shop.account.gift_card.index.after_grid: - blocks: - after_content_header_legacy: - template: "@SyliusUi/Block/_legacySonataEvent.html.twig" - priority: 50 - context: - event: setono_sylius_gift_card.shop.account.gift_card.index.after_grid - - setono_sylius_gift_card.shop.account.gift_card.index.header: - blocks: - after_content_header_legacy: - template: "@SyliusUi/Block/_legacySonataEvent.html.twig" - priority: 50 - context: - event: setono_sylius_gift_card.shop.account.gift_card.index.header - - setono_sylius_gift_card.shop.cart.summary.applied_gift_cards: - blocks: - after_content_header_legacy: - template: "@SyliusUi/Block/_legacySonataEvent.html.twig" - priority: 50 - context: - event: setono_sylius_gift_card.shop.cart.summary.applied_gift_cards +# TODO the admin CRUD javascripts (image preview, live PDF rendering, send-customer-email +# checkbox) and the shop account gift card index hooks used the removed sylius_ui "events" +# block system (SonataBlock-style). They still need to be ported to sylius/twig-hooks. diff --git a/src/Resources/config/services/event_listener.xml b/src/Resources/config/services/event_listener.xml index 1eb03eed..7a20a579 100644 --- a/src/Resources/config/services/event_listener.xml +++ b/src/Resources/config/services/event_listener.xml @@ -25,12 +25,41 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + From b01c0a30c663c61e2494de2ecbdff02faf105bb4 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:31:09 +0200 Subject: [PATCH 04/60] Drop the ApiPlatform-based API layer Per decision: this plugin does not need to migrate/expose its own ApiPlatform API in Sylius 2 (ApiPlatform 2.x -> 4 would have required a full rewrite of DataPersister/DataTransformer/api_resources XML). Removed src/Api/**, api_resources config, the api-specific DI services, dead serialization/validation config for the deleted commands, and the corresponding Unit/Behat API test suites. GiftCardContext (Behat setup step) now calls GiftCardApplicatorInterface directly instead of dispatching the removed AddGiftCardToOrder command, since the shop UI "apply gift card" flow never went through that command in the first place. --- src/Api/Command/AddGiftCardToOrder.php | 27 -- src/Api/Command/AddItemToCart.php | 32 -- .../AssociateConfigurationToChannel.php | 30 -- .../ConfigurationCodeAwareInterface.php | 14 - .../Command/CreateGiftCardConfiguration.php | 40 -- .../Command/GiftCardCodeAwareInterface.php | 14 - src/Api/Command/RemoveGiftCardFromOrder.php | 27 -- .../AddGiftCardToOrderHandler.php | 49 -- .../CommandHandler/AddItemToCartHandler.php | 101 ----- ...AssociateConfigurationToChannelHandler.php | 77 ---- .../CreateGiftCardConfigurationHandler.php | 50 --- .../RemoveGiftCardFromOrderHandler.php | 49 -- .../Action/DownloadGiftCardPdfAction.php | 37 -- .../Action/GiftCardBalanceAction.php | 25 -- .../Action/ResendGiftCardEmailAction.php | 33 -- ...UploadGiftCardConfigurationImageAction.php | 93 ---- .../DataPersister/GiftCardDataPersister.php | 51 --- ...rdCodeAwareInputCommandDataTransformer.php | 33 -- ...onCodeAwareInputCommandDataTransformer.php | 33 -- .../GiftCardsByLoggedInUserExtension.php | 59 --- .../config/api_resources/GiftCard.xml | 160 ------- .../api_resources/GiftCardConfiguration.xml | 78 ---- .../GiftCardConfigurationImage.xml | 64 --- src/Resources/config/api_resources/Order.xml | 419 ------------------ src/Resources/config/routes.yaml | 4 - src/Resources/config/routes/admin_api.yaml | 7 - .../Command/AddGiftCardToOrder.xml | 12 - .../Command/AddItemToCartCommand.xml | 21 - .../AssociateConfigurationToChannel.xml | 16 - .../Command/CreateGiftCardConfiguration.xml | 30 -- .../Command/RemoveGiftCardFromOrder.xml | 12 - src/Resources/config/services.xml | 1 - src/Resources/config/services/api.xml | 12 - .../config/services/api/command_handler.xml | 61 --- .../config/services/api/controller.xml | 40 -- .../config/services/api/data_persister.xml | 14 - .../config/services/api/data_transformer.xml | 18 - .../config/services/api/doctrine.xml | 15 - .../CreateGiftCardConfiguration.xml | 33 -- .../ManagingGiftCardConfigurationsContext.php | 238 ---------- .../Admin/ManagingGiftCardsBalanceContext.php | 53 --- .../Api/Admin/ManagingGiftCardsContext.php | 244 ---------- tests/Behat/Context/Api/Shop/CartContext.php | 73 --- .../Api/Shop/ManagingGiftCardsContext.php | 159 ------- tests/Behat/Context/Setup/GiftCardContext.php | 25 +- tests/Behat/Resources/api/clients.xml | 32 -- tests/Behat/Resources/context/api.xml | 46 -- tests/Behat/Resources/context/setup.xml | 3 +- tests/Behat/Resources/contexts.xml | 1 - tests/Behat/Resources/suites.yml | 7 - .../suites/api/applying_gift_card.yml | 39 -- .../Resources/suites/api/buying_gift_card.yml | 24 - .../api/managing_gift_card_configurations.yml | 25 -- .../suites/api/managing_gift_cards.yml | 23 - .../api/managing_gift_cards_balance.yml | 21 - .../suites/api/managing_shop_gift_cards.yml | 24 - .../Api/Command/AddGiftCardToOrderTest.php | 34 -- tests/Unit/Api/Command/AddItemToCartTest.php | 54 --- .../AssociateConfigurationToChannelTest.php | 34 -- .../CreateGiftCardConfigurationTest.php | 57 --- .../Command/RemoveGiftCardFromOrderTest.php | 34 -- .../AddGiftCardToOrderHandlerTest.php | 117 ----- .../AddItemToCartHandlerTest.php | 236 ---------- ...ciateConfigurationToChannelHandlerTest.php | 250 ----------- ...CreateGiftCardConfigurationHandlerTest.php | 86 ---- .../RemoveGiftCardFromOrderHandlerTest.php | 117 ----- .../Action/DownloadGiftCardPdfActionTest.php | 46 -- .../Action/GiftCardBalanceActionTest.php | 56 --- .../Action/ResendGiftCardEmailActionTest.php | 82 ---- ...adGiftCardConfigurationImageActionTest.php | 214 --------- tests/Unit/Api/Controller/Action/file.jpg | Bin 82565 -> 0 bytes .../GiftCardDataPersisterTest.php | 60 --- ...deAwareInputCommandDataTransformerTest.php | 44 -- .../GiftCardsByLoggedInUserExtensionTest.php | 146 ------ 74 files changed, 19 insertions(+), 4576 deletions(-) delete mode 100644 src/Api/Command/AddGiftCardToOrder.php delete mode 100644 src/Api/Command/AddItemToCart.php delete mode 100644 src/Api/Command/AssociateConfigurationToChannel.php delete mode 100644 src/Api/Command/ConfigurationCodeAwareInterface.php delete mode 100644 src/Api/Command/CreateGiftCardConfiguration.php delete mode 100644 src/Api/Command/GiftCardCodeAwareInterface.php delete mode 100644 src/Api/Command/RemoveGiftCardFromOrder.php delete mode 100644 src/Api/CommandHandler/AddGiftCardToOrderHandler.php delete mode 100644 src/Api/CommandHandler/AddItemToCartHandler.php delete mode 100644 src/Api/CommandHandler/AssociateConfigurationToChannelHandler.php delete mode 100644 src/Api/CommandHandler/CreateGiftCardConfigurationHandler.php delete mode 100644 src/Api/CommandHandler/RemoveGiftCardFromOrderHandler.php delete mode 100644 src/Api/Controller/Action/DownloadGiftCardPdfAction.php delete mode 100644 src/Api/Controller/Action/GiftCardBalanceAction.php delete mode 100644 src/Api/Controller/Action/ResendGiftCardEmailAction.php delete mode 100644 src/Api/Controller/Action/UploadGiftCardConfigurationImageAction.php delete mode 100644 src/Api/DataPersister/GiftCardDataPersister.php delete mode 100644 src/Api/DataTransformer/GiftCardCodeAwareInputCommandDataTransformer.php delete mode 100644 src/Api/DataTransformer/GiftCardConfigurationCodeAwareInputCommandDataTransformer.php delete mode 100644 src/Api/Doctrine/QueryCollectionExtension/GiftCardsByLoggedInUserExtension.php delete mode 100644 src/Resources/config/api_resources/GiftCard.xml delete mode 100644 src/Resources/config/api_resources/GiftCardConfiguration.xml delete mode 100644 src/Resources/config/api_resources/GiftCardConfigurationImage.xml delete mode 100644 src/Resources/config/api_resources/Order.xml delete mode 100644 src/Resources/config/routes/admin_api.yaml delete mode 100644 src/Resources/config/serialization/Command/AddGiftCardToOrder.xml delete mode 100644 src/Resources/config/serialization/Command/AddItemToCartCommand.xml delete mode 100644 src/Resources/config/serialization/Command/AssociateConfigurationToChannel.xml delete mode 100644 src/Resources/config/serialization/Command/CreateGiftCardConfiguration.xml delete mode 100644 src/Resources/config/serialization/Command/RemoveGiftCardFromOrder.xml delete mode 100644 src/Resources/config/services/api.xml delete mode 100644 src/Resources/config/services/api/command_handler.xml delete mode 100644 src/Resources/config/services/api/controller.xml delete mode 100644 src/Resources/config/services/api/data_persister.xml delete mode 100644 src/Resources/config/services/api/data_transformer.xml delete mode 100644 src/Resources/config/services/api/doctrine.xml delete mode 100644 src/Resources/config/validation/CreateGiftCardConfiguration.xml delete mode 100644 tests/Behat/Context/Api/Admin/ManagingGiftCardConfigurationsContext.php delete mode 100644 tests/Behat/Context/Api/Admin/ManagingGiftCardsBalanceContext.php delete mode 100644 tests/Behat/Context/Api/Admin/ManagingGiftCardsContext.php delete mode 100644 tests/Behat/Context/Api/Shop/CartContext.php delete mode 100644 tests/Behat/Context/Api/Shop/ManagingGiftCardsContext.php delete mode 100644 tests/Behat/Resources/api/clients.xml delete mode 100644 tests/Behat/Resources/context/api.xml delete mode 100644 tests/Behat/Resources/suites/api/applying_gift_card.yml delete mode 100644 tests/Behat/Resources/suites/api/buying_gift_card.yml delete mode 100644 tests/Behat/Resources/suites/api/managing_gift_card_configurations.yml delete mode 100644 tests/Behat/Resources/suites/api/managing_gift_cards.yml delete mode 100644 tests/Behat/Resources/suites/api/managing_gift_cards_balance.yml delete mode 100644 tests/Behat/Resources/suites/api/managing_shop_gift_cards.yml delete mode 100644 tests/Unit/Api/Command/AddGiftCardToOrderTest.php delete mode 100644 tests/Unit/Api/Command/AddItemToCartTest.php delete mode 100644 tests/Unit/Api/Command/AssociateConfigurationToChannelTest.php delete mode 100644 tests/Unit/Api/Command/CreateGiftCardConfigurationTest.php delete mode 100644 tests/Unit/Api/Command/RemoveGiftCardFromOrderTest.php delete mode 100644 tests/Unit/Api/CommandHandler/AddGiftCardToOrderHandlerTest.php delete mode 100644 tests/Unit/Api/CommandHandler/AddItemToCartHandlerTest.php delete mode 100644 tests/Unit/Api/CommandHandler/AssociateConfigurationToChannelHandlerTest.php delete mode 100644 tests/Unit/Api/CommandHandler/CreateGiftCardConfigurationHandlerTest.php delete mode 100644 tests/Unit/Api/CommandHandler/RemoveGiftCardFromOrderHandlerTest.php delete mode 100644 tests/Unit/Api/Controller/Action/DownloadGiftCardPdfActionTest.php delete mode 100644 tests/Unit/Api/Controller/Action/GiftCardBalanceActionTest.php delete mode 100644 tests/Unit/Api/Controller/Action/ResendGiftCardEmailActionTest.php delete mode 100644 tests/Unit/Api/Controller/Action/UploadGiftCardConfigurationImageActionTest.php delete mode 100644 tests/Unit/Api/Controller/Action/file.jpg delete mode 100644 tests/Unit/Api/DataPersister/GiftCardDataPersisterTest.php delete mode 100644 tests/Unit/Api/DataTransformer/GiftCardCodeAwareInputCommandDataTransformerTest.php delete mode 100644 tests/Unit/Api/Doctrine/QueryCollectionExtension/GiftCardsByLoggedInUserExtensionTest.php diff --git a/src/Api/Command/AddGiftCardToOrder.php b/src/Api/Command/AddGiftCardToOrder.php deleted file mode 100644 index 43dd5a29..00000000 --- a/src/Api/Command/AddGiftCardToOrder.php +++ /dev/null @@ -1,27 +0,0 @@ -orderTokenValue = $orderTokenValue; - } - - public function getGiftCardCode(): ?string - { - return $this->giftCardCode; - } - - public function setGiftCardCode(?string $giftCardCode): void - { - $this->giftCardCode = $giftCardCode; - } -} diff --git a/src/Api/Command/AddItemToCart.php b/src/Api/Command/AddItemToCart.php deleted file mode 100644 index fdf8735e..00000000 --- a/src/Api/Command/AddItemToCart.php +++ /dev/null @@ -1,32 +0,0 @@ -amount = $amount; - $this->customMessage = $customMessage; - } - - public function getAmount(): ?int - { - return $this->amount; - } - - public function getCustomMessage(): ?string - { - return $this->customMessage; - } -} diff --git a/src/Api/Command/AssociateConfigurationToChannel.php b/src/Api/Command/AssociateConfigurationToChannel.php deleted file mode 100644 index 92032cde..00000000 --- a/src/Api/Command/AssociateConfigurationToChannel.php +++ /dev/null @@ -1,30 +0,0 @@ -localeCode = $localeCode; - $this->channelCode = $channelCode; - } - - public function getConfigurationCode(): ?string - { - return $this->configurationCode; - } - - public function setConfigurationCode(?string $configurationCode): void - { - $this->configurationCode = $configurationCode; - } -} diff --git a/src/Api/Command/ConfigurationCodeAwareInterface.php b/src/Api/Command/ConfigurationCodeAwareInterface.php deleted file mode 100644 index 945d1757..00000000 --- a/src/Api/Command/ConfigurationCodeAwareInterface.php +++ /dev/null @@ -1,14 +0,0 @@ -code = $code; - $this->default = $default; - $this->enabled = $enabled; - $this->defaultValidityPeriod = $defaultValidityPeriod; - $this->pageSize = $pageSize; - $this->orientation = $orientation; - $this->template = $template; - } -} diff --git a/src/Api/Command/GiftCardCodeAwareInterface.php b/src/Api/Command/GiftCardCodeAwareInterface.php deleted file mode 100644 index 82189996..00000000 --- a/src/Api/Command/GiftCardCodeAwareInterface.php +++ /dev/null @@ -1,14 +0,0 @@ -orderTokenValue = $orderTokenValue; - } - - public function getGiftCardCode(): ?string - { - return $this->giftCardCode; - } - - public function setGiftCardCode(?string $giftCardCode): void - { - $this->giftCardCode = $giftCardCode; - } -} diff --git a/src/Api/CommandHandler/AddGiftCardToOrderHandler.php b/src/Api/CommandHandler/AddGiftCardToOrderHandler.php deleted file mode 100644 index 6fca53ef..00000000 --- a/src/Api/CommandHandler/AddGiftCardToOrderHandler.php +++ /dev/null @@ -1,49 +0,0 @@ -giftCardRepository = $giftCardRepository; - $this->orderRepository = $orderRepository; - $this->giftCardApplicator = $giftCardApplicator; - } - - public function __invoke(AddGiftCardToOrder $command): GiftCardInterface - { - $giftCardCode = $command->getGiftCardCode(); - Assert::notNull($giftCardCode); - - $giftCard = $this->giftCardRepository->findOneByCode($giftCardCode); - Assert::notNull($giftCard); - - /** @var OrderInterface|null $order */ - $order = $this->orderRepository->findOneBy(['tokenValue' => $command->orderTokenValue]); - Assert::notNull($order); - - $this->giftCardApplicator->apply($order, $giftCard); - - return $giftCard; - } -} diff --git a/src/Api/CommandHandler/AddItemToCartHandler.php b/src/Api/CommandHandler/AddItemToCartHandler.php deleted file mode 100644 index 54535be5..00000000 --- a/src/Api/CommandHandler/AddItemToCartHandler.php +++ /dev/null @@ -1,101 +0,0 @@ -orderRepository = $orderRepository; - $this->productVariantRepository = $productVariantRepository; - $this->orderModifier = $orderModifier; - $this->cartItemFactory = $cartItemFactory; - $this->orderItemQuantityModifier = $orderItemQuantityModifier; - $this->giftCardFactory = $giftCardFactory; - $this->giftCardManager = $giftCardManager; - } - - public function __invoke(SyliusAddItemToCart $addItemToCart): OrderInterface - { - /** @var ProductVariantInterface|null $productVariant */ - $productVariant = $this->productVariantRepository->findOneBy(['code' => $addItemToCart->productVariantCode]); - - Assert::notNull($productVariant); - Assert::notNull($addItemToCart->orderTokenValue); - - /** @var OrderInterface|null $cart */ - $cart = $this->orderRepository->findCartByTokenValue($addItemToCart->orderTokenValue); - - Assert::notNull($cart); - - /** @var OrderItemInterface $cartItem */ - $cartItem = $this->cartItemFactory->createNew(); - $cartItem->setVariant($productVariant); - - if ($addItemToCart instanceof SetonoSyliusGiftCardAddItemToCart) { - /** @var ProductInterface $product */ - $product = $productVariant->getProduct(); - if ($product->isGiftCardAmountConfigurable()) { - $giftCardAmount = $addItemToCart->getAmount(); - Assert::notNull($giftCardAmount); - $cartItem->setUnitPrice($giftCardAmount); - $cartItem->setImmutable(true); - } - } - - $this->orderItemQuantityModifier->modify($cartItem, $addItemToCart->quantity); - $this->orderModifier->addToOrder($cart, $cartItem); - - if ($addItemToCart instanceof SetonoSyliusGiftCardAddItemToCart) { - /** @var OrderItemUnitInterface $unit */ - foreach ($cartItem->getUnits() as $unit) { - $giftCard = $this->giftCardFactory->createFromOrderItemUnitAndCart($unit, $cart); - $giftCard->setCustomMessage($addItemToCart->getCustomMessage()); - - // As the common flow for any add to cart action will flush later. Do not flush here. - $this->giftCardManager->persist($giftCard); - } - } - - return $cart; - } -} diff --git a/src/Api/CommandHandler/AssociateConfigurationToChannelHandler.php b/src/Api/CommandHandler/AssociateConfigurationToChannelHandler.php deleted file mode 100644 index f8418c22..00000000 --- a/src/Api/CommandHandler/AssociateConfigurationToChannelHandler.php +++ /dev/null @@ -1,77 +0,0 @@ -giftCardConfigurationRepository = $giftCardConfigurationRepository; - $this->channelRepository = $channelRepository; - $this->localeRepository = $localeRepository; - $this->giftCardChannelConfigurationRepository = $giftCardChannelConfigurationRepository; - $this->giftCardChannelConfigurationFactory = $giftCardChannelConfigurationFactory; - } - - public function __invoke(AssociateConfigurationToChannel $command): GiftCardConfigurationInterface - { - Assert::notNull($command->getConfigurationCode(), 'GiftCardConfiguration code can not be null'); - - /** @var GiftCardConfigurationInterface|null $configuration */ - $configuration = $this->giftCardConfigurationRepository->findOneBy(['code' => $command->getConfigurationCode()]); - Assert::notNull($configuration, 'GiftCardConfiguration can not be null'); - - $channel = $this->channelRepository->findOneByCode($command->channelCode); - Assert::notNull($channel, 'Channel can not be null'); - - /** @var LocaleInterface|null $locale */ - $locale = $this->localeRepository->findOneBy(['code' => $command->localeCode]); - Assert::notNull($locale, 'Locale can not be null'); - - /** @var GiftCardChannelConfigurationInterface|null $existingChannelConfiguration */ - $existingChannelConfiguration = $this->giftCardChannelConfigurationRepository->findOneBy([ - 'configuration' => $configuration, - 'channel' => $channel, - 'locale' => $locale, - ]); - if (null !== $existingChannelConfiguration) { - return $configuration; - } - - /** @var GiftCardChannelConfigurationInterface $channelConfiguration */ - $channelConfiguration = $this->giftCardChannelConfigurationFactory->createNew(); - $channelConfiguration->setConfiguration($configuration); - $channelConfiguration->setChannel($channel); - $channelConfiguration->setLocale($locale); - - $configuration->addChannelConfiguration($channelConfiguration); - - return $configuration; - } -} diff --git a/src/Api/CommandHandler/CreateGiftCardConfigurationHandler.php b/src/Api/CommandHandler/CreateGiftCardConfigurationHandler.php deleted file mode 100644 index 47fb3e63..00000000 --- a/src/Api/CommandHandler/CreateGiftCardConfigurationHandler.php +++ /dev/null @@ -1,50 +0,0 @@ -giftCardConfigurationFactory = $giftCardConfigurationFactory; - $this->giftCardConfigurationManager = $giftCardConfigurationManager; - } - - public function __invoke(CreateGiftCardConfiguration $command): GiftCardConfigurationInterface - { - $giftCardConfiguration = $this->giftCardConfigurationFactory->createNew(); - - $giftCardConfiguration->setCode($command->code); - $giftCardConfiguration->setEnabled($command->enabled); - $giftCardConfiguration->setDefault($command->default); - if (null !== $command->defaultValidityPeriod) { - $giftCardConfiguration->setDefaultValidityPeriod($command->defaultValidityPeriod); - } - if (null !== $command->pageSize) { - $giftCardConfiguration->setPageSize($command->pageSize); - } - if (null !== $command->orientation) { - $giftCardConfiguration->setOrientation($command->orientation); - } - if (null !== $command->template) { - $giftCardConfiguration->setTemplate($command->template); - } - - $this->giftCardConfigurationManager->persist($giftCardConfiguration); - - return $giftCardConfiguration; - } -} diff --git a/src/Api/CommandHandler/RemoveGiftCardFromOrderHandler.php b/src/Api/CommandHandler/RemoveGiftCardFromOrderHandler.php deleted file mode 100644 index 8487fa23..00000000 --- a/src/Api/CommandHandler/RemoveGiftCardFromOrderHandler.php +++ /dev/null @@ -1,49 +0,0 @@ -giftCardRepository = $giftCardRepository; - $this->orderRepository = $orderRepository; - $this->giftCardApplicator = $giftCardApplicator; - } - - public function __invoke(RemoveGiftCardFromOrder $command): GiftCardInterface - { - $giftCardCode = $command->getGiftCardCode(); - Assert::notNull($giftCardCode); - - $giftCard = $this->giftCardRepository->findOneByCode($giftCardCode); - Assert::notNull($giftCard); - - /** @var OrderInterface|null $order */ - $order = $this->orderRepository->findOneBy(['tokenValue' => $command->orderTokenValue]); - Assert::notNull($order); - - $this->giftCardApplicator->remove($order, $giftCard); - - return $giftCard; - } -} diff --git a/src/Api/Controller/Action/DownloadGiftCardPdfAction.php b/src/Api/Controller/Action/DownloadGiftCardPdfAction.php deleted file mode 100644 index 8f7ced89..00000000 --- a/src/Api/Controller/Action/DownloadGiftCardPdfAction.php +++ /dev/null @@ -1,37 +0,0 @@ -configurationProvider = $configurationProvider; - $this->pdfRenderer = $giftCardPDFRenderer; - } - - public function __invoke(GiftCardInterface $data): Response - { - $configuration = $this->configurationProvider->getConfigurationForGiftCard($data); - if (!$configuration instanceof GiftCardConfigurationInterface) { - throw new NotFoundHttpException('No configuration found for this GiftCard'); - } - - return $this->pdfRenderer->render($data, $configuration); - } -} diff --git a/src/Api/Controller/Action/GiftCardBalanceAction.php b/src/Api/Controller/Action/GiftCardBalanceAction.php deleted file mode 100644 index 7b89460c..00000000 --- a/src/Api/Controller/Action/GiftCardBalanceAction.php +++ /dev/null @@ -1,25 +0,0 @@ -giftCardRepository = $giftCardRepository; - } - - public function __invoke(): GiftCardBalanceCollection - { - return GiftCardBalanceCollection::createFromGiftCards( - $this->giftCardRepository->findEnabled(), - ); - } -} diff --git a/src/Api/Controller/Action/ResendGiftCardEmailAction.php b/src/Api/Controller/Action/ResendGiftCardEmailAction.php deleted file mode 100644 index fbbc7643..00000000 --- a/src/Api/Controller/Action/ResendGiftCardEmailAction.php +++ /dev/null @@ -1,33 +0,0 @@ -giftCardEmailManager = $giftCardEmailManager; - } - - public function __invoke(GiftCardInterface $data): Response - { - if (($order = $data->getOrder()) !== null) { - $this->giftCardEmailManager->sendEmailWithGiftCardsFromOrder($order, [$data]); - } elseif (($customer = $data->getCustomer()) !== null) { - $this->giftCardEmailManager->sendEmailToCustomerWithGiftCard($customer, $data); - } else { - throw new BadRequestHttpException(); - } - - return new Response(null, Response::HTTP_NO_CONTENT); - } -} diff --git a/src/Api/Controller/Action/UploadGiftCardConfigurationImageAction.php b/src/Api/Controller/Action/UploadGiftCardConfigurationImageAction.php deleted file mode 100644 index 79c47634..00000000 --- a/src/Api/Controller/Action/UploadGiftCardConfigurationImageAction.php +++ /dev/null @@ -1,93 +0,0 @@ -giftCardConfigurationImageFactory = $giftCardConfigurationImageFactory; - $this->giftCardConfigurationImageRepository = $giftCardConfigurationImageRepository; - $this->imageUploader = $imageUploader; - $this->iriConverter = $iriConverter; - } - - public function __invoke(Request $request): GiftCardConfigurationImageInterface - { - /** @var UploadedFile $file */ - $file = $request->files->get('file'); - - /** @var GiftCardConfigurationImageInterface $image */ - $image = $this->giftCardConfigurationImageFactory->createNew(); - $image->setFile($file); - - /** @var string $imageType */ - $imageType = $request->request->get('type') ?? $request->query->get('type'); - Assert::notEmpty($imageType); - - $image->setType($imageType); - - $ownerIri = $request->request->get('owner') ?? $request->query->get('type'); - Assert::stringNotEmpty($ownerIri); - - $owner = $this->getOwner($ownerIri); - - $oldImages = $owner->getImagesByType($imageType); - foreach ($oldImages as $oldImage) { - $owner->removeImage($oldImage); - $this->giftCardConfigurationImageRepository->remove($oldImage); - } - $owner->addImage($image); - - $this->imageUploader->upload($image); - - return $image; - } - - private function getOwner(string $ownerIri): GiftCardConfigurationInterface - { - if ($this->iriConverter instanceof LegacyIriConverterInterface) { - $owner = $this->iriConverter->getItemFromIri($ownerIri); - } else { - /** - * @psalm-suppress UndefinedDocblockClass - * - * @var mixed $owner - */ - $owner = $this->iriConverter->getResourceFromIri($ownerIri); - } - - Assert::isInstanceOf($owner, GiftCardConfigurationInterface::class); - - return $owner; - } -} diff --git a/src/Api/DataPersister/GiftCardDataPersister.php b/src/Api/DataPersister/GiftCardDataPersister.php deleted file mode 100644 index 1512447e..00000000 --- a/src/Api/DataPersister/GiftCardDataPersister.php +++ /dev/null @@ -1,51 +0,0 @@ -decoratedDataPersister = $decoratedDataPersister; - } - - /** - * @param mixed $data - */ - public function supports($data, array $context = []): bool - { - return $data instanceof GiftCardInterface; - } - - /** - * @param GiftCardInterface|mixed $data - * - * @return object|void - */ - public function persist($data, array $context = []) - { - Assert::isInstanceOf($data, GiftCardInterface::class); - - $data->setOrigin(GiftCardInterface::ORIGIN_API); - - return $this->decoratedDataPersister->persist($data, $context); - } - - /** - * @param GiftCardInterface|mixed $data - * - * @return mixed - */ - public function remove($data, array $context = []) - { - return $this->decoratedDataPersister->remove($data, $context); - } -} diff --git a/src/Api/DataTransformer/GiftCardCodeAwareInputCommandDataTransformer.php b/src/Api/DataTransformer/GiftCardCodeAwareInputCommandDataTransformer.php deleted file mode 100644 index 2ebe8a46..00000000 --- a/src/Api/DataTransformer/GiftCardCodeAwareInputCommandDataTransformer.php +++ /dev/null @@ -1,33 +0,0 @@ -setGiftCardCode($giftCard->getCode()); - - return $object; - } - - /** - * @param object $object - */ - public function supportsTransformation($object): bool - { - return $object instanceof GiftCardCodeAwareInterface; - } -} diff --git a/src/Api/DataTransformer/GiftCardConfigurationCodeAwareInputCommandDataTransformer.php b/src/Api/DataTransformer/GiftCardConfigurationCodeAwareInputCommandDataTransformer.php deleted file mode 100644 index d2d49c0b..00000000 --- a/src/Api/DataTransformer/GiftCardConfigurationCodeAwareInputCommandDataTransformer.php +++ /dev/null @@ -1,33 +0,0 @@ -setConfigurationCode($giftCardConfiguration->getCode()); - - return $object; - } - - /** - * @param object $object - */ - public function supportsTransformation($object): bool - { - return $object instanceof ConfigurationCodeAwareInterface; - } -} diff --git a/src/Api/Doctrine/QueryCollectionExtension/GiftCardsByLoggedInUserExtension.php b/src/Api/Doctrine/QueryCollectionExtension/GiftCardsByLoggedInUserExtension.php deleted file mode 100644 index 41b62e32..00000000 --- a/src/Api/Doctrine/QueryCollectionExtension/GiftCardsByLoggedInUserExtension.php +++ /dev/null @@ -1,59 +0,0 @@ -userContext = $userContext; - } - - public function applyToCollection( - QueryBuilder $queryBuilder, - QueryNameGeneratorInterface $queryNameGenerator, - string $resourceClass, - string $operationName = null, - array $context = [], - ): void { - if (!is_a($resourceClass, GiftCardInterface::class, true)) { - return; - } - - $user = $this->userContext->getUser(); - - if ($user instanceof AdminUserInterface) { - return; - } - - if (!$user instanceof ShopUserInterface) { - throw new AccessDeniedException(); - } - - /** @var CustomerInterface $customer */ - $customer = $user->getCustomer(); - - /** @var list $rootAliases */ - $rootAliases = $queryBuilder->getRootAliases(); - - $queryBuilder - ->andWhere(sprintf('%s.customer = :customer', $rootAliases[0])) - ->setParameter('customer', $customer->getId(), Types::INTEGER) - ; - } -} diff --git a/src/Resources/config/api_resources/GiftCard.xml b/src/Resources/config/api_resources/GiftCard.xml deleted file mode 100644 index 15b15dae..00000000 --- a/src/Resources/config/api_resources/GiftCard.xml +++ /dev/null @@ -1,160 +0,0 @@ - - - - - sylius - - - - GET - /admin/gift-cards - - admin:gift_card:read - - - - - POST - /admin/gift-cards - - admin:gift_card:read - - - admin:gift_card:create - - - - - GET - /admin/gift-cards/balance - setono_sylius_gift_card.controller.action.get_balance - false - - Get the gift cards balance. - - - admin:gift_card_balance:read - - Setono\SyliusGiftCardPlugin\Model\GiftCardBalanceCollection - - - - GET - /shop/gift-cards - - Retrieves the collection of GiftCard ressources associated to the logged in customer. - - - shop:gift_card:read - - - - - - - GET - /admin/gift-cards/{code} - - Use $code to retrieve a gift card resource. - - - admin:gift_card:read - - - - - GET - /admin/gift-cards/{code}/resend-email - setono_sylius_gift_card_plugin.api.resend_gift_card_email - - Resend the gift card email to the customer. - - - - - GET - /admin/gift-cards/{code}/pdf - setono_sylius_gift_card_plugin.api.download_gift_card_pdf - - Download the gift card as a PDF. - - Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse - - - - PUT - /admin/gift-cards/{code} - - admin:gift_card:read - - - admin:gift_card:update - - - - - DELETE - /admin/gift-cards/{code} - - - - GET - /shop/gift-cards/{code} - - Use $code to retrieve a gift card resource. You can use this to 'search' for gift cards. - - - shop:gift_card:read - - - - - GET - /shop/gift-cards/{code}/pdf - setono_sylius_gift_card_plugin.api.download_gift_card_pdf - - Download the gift card as a PDF. - - Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse - - - - PATCH - /shop/gift-cards/{code}/add-to-order - input - Setono\SyliusGiftCardPlugin\Api\Command\AddGiftCardToOrder - - Apply a gift card to your order. - - - shop:gift_card:read - - - shop:gift_card:add_to_order - - - - - PATCH - /shop/gift-cards/{code}/remove-from-order - input - Setono\SyliusGiftCardPlugin\Api\Command\RemoveGiftCardFromOrder - - Remove a gift card from your order. - - - shop:gift_card:read - - - shop:gift_card:remove_from_order - - - - - - - - diff --git a/src/Resources/config/api_resources/GiftCardConfiguration.xml b/src/Resources/config/api_resources/GiftCardConfiguration.xml deleted file mode 100644 index 091d40a5..00000000 --- a/src/Resources/config/api_resources/GiftCardConfiguration.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - admin/gift-card-configurations - sylius - - - - GET - - - admin:gift_card_configuration:read - - - - - POST - - input - Setono\SyliusGiftCardPlugin\Api\Command\CreateGiftCardConfiguration - - admin:gift_card_configuration:create - - setono_sylius_gift_card_configuration - - - - - - GET - /{code} - - admin:gift_card_configuration:read - - - - - PUT - /{code} - - admin:gift_card_configuration:read - - - admin:gift_card_configuration:update - - - - - DELETE - /{code} - - - - PATCH - /{code}/associate-channel - input - Setono\SyliusGiftCardPlugin\Api\Command\AssociateConfigurationToChannel - - admin:gift_card_configuration:read - - - admin:gift_card_configuration:associate_channel - - - Associate a channel to the configuration - - - - - - - - - diff --git a/src/Resources/config/api_resources/GiftCardConfigurationImage.xml b/src/Resources/config/api_resources/GiftCardConfigurationImage.xml deleted file mode 100644 index 4a693d48..00000000 --- a/src/Resources/config/api_resources/GiftCardConfigurationImage.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - admin - sylius - - - - POST - setono_sylius_gift_card_plugin.api.upload_gift_card_configuration_image - false - - - - - - object - - - string - - - string - binary - - - string - iri-reference - - - - - - - - - admin:gift_card_configuration_image:read - - - - - - - GET - - admin:gift_card_configuration_image:read - - - - - DELETE - - - - - - - - - diff --git a/src/Resources/config/api_resources/Order.xml b/src/Resources/config/api_resources/Order.xml deleted file mode 100644 index 8369296c..00000000 --- a/src/Resources/config/api_resources/Order.xml +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - - sylius - - - - GET - admin/orders - - admin:order:read - - - - - POST - /shop/orders - input - Sylius\Bundle\ApiBundle\Command\Cart\PickupCart - - shop:order:read - - - shop:order:create - - - Pickups a new cart. Provided locale code has to be one of available for a particular channel. - - - - - GET - /shop/orders - - - shop:order:read - - - - - - - - GET - /admin/orders/{tokenValue} - - admin:order:read - - - - - GET - /shop/orders/{tokenValue} - - shop:cart:read - - - - - DELETE - /shop/orders/{tokenValue} - - Deletes cart - - - shop:order:read - - - - - PATCH - /admin/orders/{tokenValue}/cancel - false - Sylius\Bundle\ApiBundle\Applicator\OrderStateMachineTransitionApplicatorInterface:cancel - - - admin:order:read - - - - admin:order:update - - - Cancels Order - - - - - POST - /shop/orders/{tokenValue}/items - input - Setono\SyliusGiftCardPlugin\Api\Command\AddItemToCart - - shop:cart:read - - - shop:cart:add_item - - - Adds Item to cart - - - - - PATCH - - sylius - - /shop/orders/{tokenValue}/shipments/{shipmentId} - input - Sylius\Bundle\ApiBundle\Command\Checkout\ChooseShippingMethod - - shop:cart:select_shipping_method - - - shop:cart:read - - - Selects shipping methods for particular shipment - - - tokenValue - path - true - - string - - - - shipmentId - path - true - - string - - - - - - - - PATCH - /shop/orders/{tokenValue}/payments/{paymentId} - input - Sylius\Bundle\ApiBundle\Command\Checkout\ChoosePaymentMethod - - shop:cart:select_payment_method - - - shop:cart:read - - - Selects payment methods for particular payment - - - tokenValue - path - true - - string - - - - paymentId - path - true - - string - - - - - - - - PATCH - /shop/account/orders/{tokenValue}/payments/{paymentId} - input - Sylius\Bundle\ApiBundle\Command\Account\ChangePaymentMethod - - shop:order:account:change_payment_method - - - shop:order:account:read - - - Change the payment method as logged shop user - - - tokenValue - path - true - - string - - - - paymentId - path - true - - string - - - - - - - - GET - Sylius\Bundle\ApiBundle\Controller\Payment\GetPaymentConfiguration - /shop/orders/{tokenValue}/payments/{paymentId}/configuration - - Retrieve payment method configuration - - - tokenValue - path - true - - string - - - - paymentId - path - true - - string - - - - - - - - PATCH - /shop/orders/{tokenValue}/complete - - sylius - sylius_checkout_complete - - input - Sylius\Bundle\ApiBundle\Command\Checkout\CompleteOrder - - shop:cart:complete - - - shop:cart:read - - - Completes checkout - - - - - DELETE - /shop/orders/{tokenValue}/items/{itemId} - input - Sylius\Bundle\ApiBundle\Controller\DeleteOrderItemAction - false - - shop:cart:remove_item - - - - - tokenValue - path - true - - string - - - - itemId - path - true - - string - - - - - - - - PATCH - /shop/orders/{tokenValue}/items/{orderItemId} - input - Sylius\Bundle\ApiBundle\Command\Cart\ChangeItemQuantityInCart - - shop:cart:read - - - shop:cart:change_quantity - - - Changes quantity of order item - - - tokenValue - path - true - - string - - - - orderItemId - path - true - - string - - - - - - - - PUT - /shop/orders/{tokenValue} - input - Sylius\Bundle\ApiBundle\Command\Checkout\UpdateCart - - shop:cart:update - - - shop:cart:read - - - Addresses cart to given location, logged in Customer does not have to provide an email. Applies coupon to cart. - - - - - - - GET - /shop/orders/{tokenValue}/items - - - - GET - /admin/orders/{tokenValue}/shipments - - - - GET - /admin/orders/{tokenValue}/payments - - - - GET - /shop/orders/{tokenValue}/adjustments - - - - GET - /shop/orders/{tokenValue}/payments/{payments}/methods - - - - GET - /shop/orders/{tokenValue}/shipments/{shipments}/methods - - - - GET - /shop/orders/{tokenValue}/items/{items}/adjustments - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Resources/config/routes.yaml b/src/Resources/config/routes.yaml index b134a7ff..cf4a20c6 100644 --- a/src/Resources/config/routes.yaml +++ b/src/Resources/config/routes.yaml @@ -11,7 +11,3 @@ setono_sylius_gift_card_admin: setono_sylius_gift_card_admin_ajax: resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes/admin_ajax.yaml" prefix: /admin/ajax - -setono_sylius_gift_card_admin_api: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes/admin_api.yaml" - prefix: /api/v{version} diff --git a/src/Resources/config/routes/admin_api.yaml b/src/Resources/config/routes/admin_api.yaml deleted file mode 100644 index 350b36ad..00000000 --- a/src/Resources/config/routes/admin_api.yaml +++ /dev/null @@ -1,7 +0,0 @@ -setono_sylius_gift_card_admin_api_gift_card: - resource: | - alias: setono_sylius_gift_card.gift_card - section: admin_api - form: Setono\SyliusGiftCardPlugin\Form\Type\GiftCardType - serialization_version: $version - type: sylius.resource_api diff --git a/src/Resources/config/serialization/Command/AddGiftCardToOrder.xml b/src/Resources/config/serialization/Command/AddGiftCardToOrder.xml deleted file mode 100644 index 5cdc4d30..00000000 --- a/src/Resources/config/serialization/Command/AddGiftCardToOrder.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - shop:gift_card:add_to_order - - - diff --git a/src/Resources/config/serialization/Command/AddItemToCartCommand.xml b/src/Resources/config/serialization/Command/AddItemToCartCommand.xml deleted file mode 100644 index bce69317..00000000 --- a/src/Resources/config/serialization/Command/AddItemToCartCommand.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - shop:cart:add_item - - - shop:cart:add_item - - - shop:cart:add_item - - - shop:cart:add_item - - - diff --git a/src/Resources/config/serialization/Command/AssociateConfigurationToChannel.xml b/src/Resources/config/serialization/Command/AssociateConfigurationToChannel.xml deleted file mode 100644 index 1505ed77..00000000 --- a/src/Resources/config/serialization/Command/AssociateConfigurationToChannel.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - admin:gift_card_configuration:associate_channel - - - - admin:gift_card_configuration:associate_channel - - - diff --git a/src/Resources/config/serialization/Command/CreateGiftCardConfiguration.xml b/src/Resources/config/serialization/Command/CreateGiftCardConfiguration.xml deleted file mode 100644 index 03883740..00000000 --- a/src/Resources/config/serialization/Command/CreateGiftCardConfiguration.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - admin:gift_card_configuration:create - - - admin:gift_card_configuration:create - - - admin:gift_card_configuration:create - - - admin:gift_card_configuration:create - - - admin:gift_card_configuration:create - - - admin:gift_card_configuration:create - - - admin:gift_card_configuration:create - - - diff --git a/src/Resources/config/serialization/Command/RemoveGiftCardFromOrder.xml b/src/Resources/config/serialization/Command/RemoveGiftCardFromOrder.xml deleted file mode 100644 index 0dffd2b2..00000000 --- a/src/Resources/config/serialization/Command/RemoveGiftCardFromOrder.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - shop:gift_card:remove_from_order - - - diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index dda2fd7e..3e32b51e 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -3,7 +3,6 @@ xmlns="http://symfony.com/schema/dic/services" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - diff --git a/src/Resources/config/services/api.xml b/src/Resources/config/services/api.xml deleted file mode 100644 index afba0b51..00000000 --- a/src/Resources/config/services/api.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - diff --git a/src/Resources/config/services/api/command_handler.xml b/src/Resources/config/services/api/command_handler.xml deleted file mode 100644 index cacbbfb8..00000000 --- a/src/Resources/config/services/api/command_handler.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Resources/config/services/api/controller.xml b/src/Resources/config/services/api/controller.xml deleted file mode 100644 index 2324a2a3..00000000 --- a/src/Resources/config/services/api/controller.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Resources/config/services/api/data_persister.xml b/src/Resources/config/services/api/data_persister.xml deleted file mode 100644 index 131c397c..00000000 --- a/src/Resources/config/services/api/data_persister.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - diff --git a/src/Resources/config/services/api/data_transformer.xml b/src/Resources/config/services/api/data_transformer.xml deleted file mode 100644 index c72cf769..00000000 --- a/src/Resources/config/services/api/data_transformer.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/Resources/config/services/api/doctrine.xml b/src/Resources/config/services/api/doctrine.xml deleted file mode 100644 index 822ffeed..00000000 --- a/src/Resources/config/services/api/doctrine.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - diff --git a/src/Resources/config/validation/CreateGiftCardConfiguration.xml b/src/Resources/config/validation/CreateGiftCardConfiguration.xml deleted file mode 100644 index 4527b4d5..00000000 --- a/src/Resources/config/validation/CreateGiftCardConfiguration.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/Behat/Context/Api/Admin/ManagingGiftCardConfigurationsContext.php b/tests/Behat/Context/Api/Admin/ManagingGiftCardConfigurationsContext.php deleted file mode 100644 index 2ef92e00..00000000 --- a/tests/Behat/Context/Api/Admin/ManagingGiftCardConfigurationsContext.php +++ /dev/null @@ -1,238 +0,0 @@ -client = $client; - $this->responseChecker = $responseChecker; - $this->iriConverter = $iriConverter; - } - - /** - * @When I browse gift card configurations - */ - public function iBrowseGiftCardConfigurations(): void - { - $this->client->index(); - } - - /** - * @When I want to create a new gift card configuration - */ - public function iWantToCreateGiftCardConfiguration(): void - { - $this->client->buildCreateRequest(); - } - - /** - * @When I want to update gift card configuration :code - */ - public function iWantToUpdateGiftCardConfiguration(string $code): void - { - $this->client->buildUpdateRequest($code); - } - - /** - * @When /^I associate gift card configuration ([^"]+) to (channel "[^"]+") and locale ([^"]+)$/ - */ - public function iAssociateGiftCardConfigurationToChannelAndLocale( - string $code, - ChannelInterface $channel, - string $localeCode, - ): void { - $request = Request::customItemAction( - 'admin', - 'gift-card-configurations', - $code, - HTTPRequest::METHOD_PATCH, - 'associate-channel', - ); - - $request->setContent([ - 'localeCode' => $localeCode, - 'channelCode' => $channel->getCode(), - ]); - - $this->client->executeCustomRequest($request); - } - - /** - * @When I (try to) add it - */ - public function iAddIt(): void - { - $this->client->create(); - } - - /** - * @When I save my changes - */ - public function iSaveMyChanges(): void - { - $this->client->update(); - } - - /** - * @When I delete gift card configuration :code - */ - public function iDeleteGiftCardConfiguration(string $code): void - { - $this->client->delete($code); - } - - /** - * @Then /^I should see a gift card configuration with code "([^"]+)"$/ - */ - public function iShouldSeeGiftCardConfiguration(string $code): void - { - $response = $this->client->show($code); - - Assert::same($this->responseChecker->getValue($response, 'code'), $code); - } - - /** - * @Then /^I should not see a gift card configuration with code "([^"]+)"$/ - */ - public function iShouldNotSeeGiftCardConfiguration(string $code): void - { - $response = $this->client->index(); - - Assert::false( - $this->responseChecker->hasItemWithValue($response, 'code', $code), - sprintf('Gift card configuration with code %s still exists, but it should not', $code), - ); - } - - /** - * @When I specify its code as :code - */ - public function iSpecifyItsCodeAs(string $code): void - { - $this->client->addRequestData('code', $code); - } - - /** - * @When I enable it - */ - public function iEnableIt(): void - { - $this->client->addRequestData('enabled', true); - } - - /** - * @When I disable it - */ - public function iDisableIt(): void - { - $this->client->addRequestData('enabled', false); - } - - /** - * @When I specify it as default configuration - */ - public function iSpecifyItAsDefaultConfiguration(): void - { - $this->client->addRequestData('default', true); - } - - /** - * @Then It should be enabled - */ - public function itShouldBeEnabled(): void - { - $response = $this->client->getLastResponse(); - - Assert::true($this->responseChecker->getValue($response, 'enabled')); - } - - /** - * @Then It should not be enabled - * @Then It should be disabled - */ - public function itShouldNotBeEnabled(): void - { - $response = $this->client->getLastResponse(); - - Assert::false($this->responseChecker->getValue($response, 'enabled')); - } - - /** - * @Then It should be default configuration - */ - public function itShouldBeDefaultConfiguration(): void - { - $response = $this->client->getLastResponse(); - - Assert::true($this->responseChecker->getValue($response, 'default')); - } - - /** - * @Then It should not be default configuration - */ - public function itShouldNotBeDefaultConfiguration(): void - { - $response = $this->client->getLastResponse(); - - Assert::false($this->responseChecker->getValue($response, 'default')); - } - - /** - * @Then /^It should have channel configuration for (channel "[^"]+") and locale ([^"]+)$/ - */ - public function itShouldHave(ChannelInterface $channel, string $localeCode): void - { - $response = $this->client->getLastResponse(); - - $channelConfigurations = $this->responseChecker->getValue($response, 'channelConfigurations'); - Assert::same($channelConfigurations[0]['channel'], $this->iriConverter->getIriFromItem($channel)); - Assert::same($channelConfigurations[0]['locale'], $this->iriConverter->getIriFromResourceClass(Locale::class) . '/' . $localeCode); - } - - /** - * @Then I should be notified that it has been successfully created - */ - public function iShouldBeNotifiedThatItHasBeenSuccessfullyCreated(): void - { - Assert::true($this->responseChecker->isCreationSuccessful($this->client->getLastResponse())); - } - - /** - * @Then I should be notified that it has been successfully updated - */ - public function iShouldBeNotifiedThatItHasBeenSuccessfullyUpdated(): void - { - Assert::true($this->responseChecker->isUpdateSuccessful($this->client->getLastResponse())); - } - - /** - * @Then I should be notified that it has been successfully deleted - */ - public function iShouldBeNotifiedThatItHasBeenSuccessfullyDelete(): void - { - Assert::true($this->responseChecker->isDeletionSuccessful($this->client->getLastResponse())); - } -} diff --git a/tests/Behat/Context/Api/Admin/ManagingGiftCardsBalanceContext.php b/tests/Behat/Context/Api/Admin/ManagingGiftCardsBalanceContext.php deleted file mode 100644 index dfe97e19..00000000 --- a/tests/Behat/Context/Api/Admin/ManagingGiftCardsBalanceContext.php +++ /dev/null @@ -1,53 +0,0 @@ -client = $client; - $this->responseChecker = $responseChecker; - } - - /** - * @When I browse gift cards balance - */ - public function iBrowseGiftCardsBalance(): void - { - $this->client->index(); - } - - /** - * @Then /^I should see a gift card balance of ("[^"]+") in ("[^"]+" currency)$/ - */ - public function iShouldSeeGiftCardPricedAtForCustomer(int $price, CurrencyInterface $currency): void - { - $response = $this->client->getLastResponse(); - - $items = $this->responseChecker->getCollection($response); - foreach ($items as $item) { - if ($item['total'] === $price) { - Assert::same($item['currencyCode'], $currency->getCode()); - - return; - } - } - - Assert::false(true); - } -} diff --git a/tests/Behat/Context/Api/Admin/ManagingGiftCardsContext.php b/tests/Behat/Context/Api/Admin/ManagingGiftCardsContext.php deleted file mode 100644 index 4139c661..00000000 --- a/tests/Behat/Context/Api/Admin/ManagingGiftCardsContext.php +++ /dev/null @@ -1,244 +0,0 @@ -client = $client; - $this->responseChecker = $responseChecker; - $this->iriConverter = $iriConverter; - } - - /** - * @When I browse gift cards - */ - public function iBrowseGiftCards(): void - { - $this->client->index(); - } - - /** - * @When I want to create a new gift card - */ - public function iWantToCreateGiftCard(): void - { - $this->client->buildCreateRequest(); - } - - /** - * @When I (try to) add it - */ - public function iAddIt(): void - { - $this->client->create(); - } - - /** - * @When I open the gift card :code page - */ - public function iOpenGiftCardPage(string $code): void - { - $this->client->show($code); - } - - /** - * @When I want to edit the gift card :code - */ - public function iWantToEditGiftCard(string $code): void - { - $this->client->buildUpdateRequest($code); - } - - /** - * @When I save my changes - */ - public function iSaveMyChanges(): void - { - $this->client->update(); - } - - /** - * @When I delete the gift card :code - */ - public function iDeleteGiftCard(string $code): void - { - $this->client->delete($code); - } - - /** - * @Then /^I should see a gift card with code "([^"]+)" valued at ("[^"]+")$/ - * @Then /^I should see a gift card with code "([^"]+)" valued at ("[^"]+") associated to the customer "([^"]+)"$/ - */ - public function iShouldSeeGiftCardPricedAtForCustomer(string $code, int $price, string $customerEmail = null): void - { - $response = $this->client->show($code); - - $giftCardPrice = $this->responseChecker->getValue($response, 'amount'); - Assert::same($price, $giftCardPrice); - - if (null !== $customerEmail) { - $giftCardCustomer = $this->responseChecker->getValue($response, 'customer'); - Assert::same($customerEmail, $giftCardCustomer['email']); - } - } - - /** - * @Then this gift card should have api origin - */ - public function giftCardShouldHaveAPIOrigin(): void - { - $response = $this->client->getLastResponse(); - - $origin = $this->responseChecker->getValue($response, 'origin'); - Assert::same(GiftCardInterface::ORIGIN_API, $origin); - } - - /** - * @Then /^I should no longer see a gift card with code "([^"]+)"$/ - */ - public function iShouldNotSeeGiftCard(string $code): void - { - $response = $this->client->index(); - - Assert::false( - $this->responseChecker->hasItemWithValue($response, 'code', $code), - sprintf('Gift card with code %s still exists, but it should not', $code), - ); - } - - /** - * @When I do not specify its customer - * @When I specify its customer as :customer - */ - public function iSpecifyItsCustomerAs(?CustomerInterface $customer = null): void - { - $this->client->addRequestData('customer', null !== $customer ? $this->iriConverter->getIriFromItem($customer) : null); - } - - /** - * @When I specify its code as :code - */ - public function iSpecifyItsCodeAs(string $code): void - { - $this->client->addRequestData('code', $code); - } - - /** - * @When /^I specify its amount as ("[^"]+")$/ - */ - public function iSpecifyItsAmountAs(string $amount): void - { - $this->client->addRequestData('amount', (int) $amount); - } - - /** - * @When I specify its currency code as :currency - */ - public function iSpecifyItsCurrencyCodeAs(string $currencyCode): void - { - $this->client->addRequestData('currencyCode', $currencyCode); - } - - /** - * @When I specify its channel as :channel - */ - public function iSpecifyItsChannelAs(ChannelInterface $channel): void - { - $this->client->addRequestData('channel', $this->iriConverter->getIriFromItem($channel)); - } - - /** - * @When I disable it - */ - public function iDisableIt(): void - { - $this->client->addRequestData('enabled', false); - } - - /** - * @Then I should be notified that it has been successfully created - */ - public function iShouldBeNotifiedThatItHasBeenSuccessfullyCreated(): void - { - Assert::true($this->responseChecker->isCreationSuccessful($this->client->getLastResponse())); - } - - /** - * @Then I should be notified that it has been successfully updated - */ - public function iShouldBeNotifiedThatItHasBeenSuccessfullyUpdated(): void - { - Assert::true($this->responseChecker->isUpdateSuccessful($this->client->getLastResponse())); - } - - /** - * @Then I should be notified that it has been successfully deleted - */ - public function iShouldBeNotifiedThatItHasBeenSuccessfullyDelete(): void - { - Assert::true($this->responseChecker->isDeletionSuccessful($this->client->getLastResponse())); - } - - /** - * @Then /^It should be valued at ("[^"]+")$/ - */ - public function itShouldBeValuedAt(int $amount): void - { - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'amount'), $amount); - } - - /** - * @Then /^It should be initially valued at ("[^"]+")$/ - */ - public function itShouldBeInitiallyValuedAt(int $amount): void - { - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'initialAmount'), $amount); - } - - /** - * @Then It should be on channel :channel - */ - public function itShouldBeOnChannel(ChannelInterface $channel): void - { - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'channel')['code'], $channel->getCode()); - } - - /** - * @Then It should have :currency currency - */ - public function itShouldHaveCurrency(CurrencyInterface $currency): void - { - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'currencyCode'), $currency->getCode()); - } - - /** - * @Then It should be disabled - */ - public function itShouldBeDisabled(): void - { - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'enabled'), false); - } -} diff --git a/tests/Behat/Context/Api/Shop/CartContext.php b/tests/Behat/Context/Api/Shop/CartContext.php deleted file mode 100644 index f4f9f05d..00000000 --- a/tests/Behat/Context/Api/Shop/CartContext.php +++ /dev/null @@ -1,73 +0,0 @@ -cartsClient = $cartsClient; - $this->responseChecker = $responseChecker; - $this->sharedStorage = $sharedStorage; - $this->productVariantResolver = $productVariantResolver; - $this->iriConverter = $iriConverter; - } - - /** - * @When /^I add (this product) to the cart with amount ("[^"]+") and custom message "([^"]+)"$/ - */ - public function iAddProductWithAmountAndMessage(ProductInterface $product, int $amount, string $message): void - { - $tokenValue = $tokenValue ?? $this->pickupCart(); - - $request = Request::customItemAction('shop', 'orders', $tokenValue, HttpRequest::METHOD_PATCH, 'items'); - - $request->updateContent([ - 'productVariant' => $this->productVariantResolver->getVariant($product)->getCode(), - 'quantity' => 1, - 'amount' => $amount, - 'customMessage' => $message, - ]); - - $this->cartsClient->executeCustomRequest($request); - } - - private function pickupCart(): string - { - $this->cartsClient->buildCreateRequest(); - $this->cartsClient->addRequestData('localeCode', null); - - $tokenValue = $this->responseChecker->getValue($this->cartsClient->create(), 'tokenValue'); - - $this->sharedStorage->set('cart_token', $tokenValue); - - return $tokenValue; - } -} diff --git a/tests/Behat/Context/Api/Shop/ManagingGiftCardsContext.php b/tests/Behat/Context/Api/Shop/ManagingGiftCardsContext.php deleted file mode 100644 index ee4f8777..00000000 --- a/tests/Behat/Context/Api/Shop/ManagingGiftCardsContext.php +++ /dev/null @@ -1,159 +0,0 @@ -client = $client; - $this->responseChecker = $responseChecker; - $this->sharedStorage = $sharedStorage; - } - - /** - * @When I browse gift cards - */ - public function iBrowseGiftCards(): void - { - $this->client->index(); - } - - /** - * @When I open the gift card :code page - */ - public function iOpenGiftCardPage(string $code): void - { - $this->client->show($code); - } - - /** - * @Given I apply gift card with code :code - */ - public function iApplyGiftCardToOrder(string $code): void - { - $this->applyGiftCardToOrder($code); - } - - /** - * @Given I remove gift card with code :code - */ - public function iRemoveGiftCardFromOrder(string $code): void - { - $this->removeGiftCardFromOrder($code); - } - - /** - * @Then /^Gift cards list should contain a gift card with code "([^"]+)"$/ - */ - public function giftCardsListShouldContain(string $code): void - { - $response = $this->client->index(); - - Assert::notEmpty($this->responseChecker->getCollectionItemsWithValue($response, 'code', $code)); - } - - /** - * @Then /^Gift cards list should not contain a gift card with code "([^"]+)"$/ - */ - public function giftCardsListShouldNotContain(string $code): void - { - $response = $this->client->index(); - - Assert::isEmpty($this->responseChecker->getCollectionItemsWithValue($response, 'code', $code)); - } - - /** - * @Then /^It should be valued at ("[^"]+")$/ - */ - public function itShouldBeValuedAt(int $amount): void - { - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'amount'), $amount); - } - - /** - * @Then /^It should be initially valued at ("[^"]+")$/ - */ - public function itShouldBeInitiallyValuedAt(int $amount): void - { - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'initialAmount'), $amount); - } - - /** - * @Then It should have :currency currency - */ - public function itShouldHaveCurrency(CurrencyInterface $currency): void - { - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'currencyCode'), $currency->getCode()); - } - - /** - * @Then the gift card :code should be disabled - */ - public function theGiftCardShouldBeDisabled(string $code): void - { - $this->client->show($code); - - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'enabled'), false); - } - - /** - * @Then the gift card :code should (still) be enabled - */ - public function theGiftCardShouldBeEnabled(string $code): void - { - $this->client->show($code); - - Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'enabled'), true); - } - - private function applyGiftCardToOrder(string $giftCardCode): void - { - $request = Request::customItemAction( - 'shop', - 'gift-cards', - $giftCardCode, - HTTPRequest::METHOD_PATCH, - 'add-to-order', - ); - - $request->setContent(['orderTokenValue' => $this->sharedStorage->get('cart_token')]); - - $this->client->executeCustomRequest($request); - } - - private function removeGiftCardFromOrder(string $giftCardCode): void - { - $request = Request::customItemAction( - 'shop', - 'gift-cards', - $giftCardCode, - HTTPRequest::METHOD_PATCH, - 'remove-from-order', - ); - - $request->setContent(['orderTokenValue' => $this->sharedStorage->get('cart_token')]); - - $this->client->executeCustomRequest($request); - } -} diff --git a/tests/Behat/Context/Setup/GiftCardContext.php b/tests/Behat/Context/Setup/GiftCardContext.php index 4c751f63..df0a4b87 100644 --- a/tests/Behat/Context/Setup/GiftCardContext.php +++ b/tests/Behat/Context/Setup/GiftCardContext.php @@ -6,14 +6,16 @@ use Behat\Behat\Context\Context; use Doctrine\Persistence\ObjectManager; -use Setono\SyliusGiftCardPlugin\Api\Command\AddGiftCardToOrder; +use Setono\SyliusGiftCardPlugin\Applicator\GiftCardApplicatorInterface; use Setono\SyliusGiftCardPlugin\Factory\GiftCardFactoryInterface; +use Setono\SyliusGiftCardPlugin\Model\OrderInterface; use Setono\SyliusGiftCardPlugin\Model\ProductInterface; use Setono\SyliusGiftCardPlugin\Repository\GiftCardRepositoryInterface; +use Setono\SyliusGiftCardPlugin\Repository\OrderRepositoryInterface; use Sylius\Behat\Service\SharedStorageInterface; use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\CustomerInterface; -use Symfony\Component\Messenger\MessageBusInterface; +use Webmozart\Assert\Assert; final class GiftCardContext implements Context { @@ -25,20 +27,24 @@ final class GiftCardContext implements Context private ObjectManager $productManager; - private MessageBusInterface $messageBus; + private OrderRepositoryInterface $orderRepository; + + private GiftCardApplicatorInterface $giftCardApplicator; public function __construct( SharedStorageInterface $sharedStorage, GiftCardRepositoryInterface $giftCardRepository, GiftCardFactoryInterface $giftCardFactory, ObjectManager $productManager, - MessageBusInterface $messageBus, + OrderRepositoryInterface $orderRepository, + GiftCardApplicatorInterface $giftCardApplicator, ) { $this->sharedStorage = $sharedStorage; $this->giftCardRepository = $giftCardRepository; $this->giftCardFactory = $giftCardFactory; $this->productManager = $productManager; - $this->messageBus = $messageBus; + $this->orderRepository = $orderRepository; + $this->giftCardApplicator = $giftCardApplicator; } /** @@ -116,8 +122,11 @@ public function theStoreHasGiftCardWithCodeForCustomer( public function iApplyGiftCardToOrder(string $code): void { $cartToken = $this->sharedStorage->get('cart_token'); - $message = new AddGiftCardToOrder($cartToken); - $message->setGiftCardCode($code); - $this->messageBus->dispatch($message); + + /** @var OrderInterface|null $order */ + $order = $this->orderRepository->findOneBy(['tokenValue' => $cartToken]); + Assert::notNull($order); + + $this->giftCardApplicator->apply($order, $code); } } diff --git a/tests/Behat/Resources/api/clients.xml b/tests/Behat/Resources/api/clients.xml deleted file mode 100644 index bf39b963..00000000 --- a/tests/Behat/Resources/api/clients.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - gift-card-configurations - admin - - - - gift-cards - admin - - - - gift-cards/balance - admin - - - - - gift-cards - shop - - - diff --git a/tests/Behat/Resources/context/api.xml b/tests/Behat/Resources/context/api.xml deleted file mode 100644 index c288acde..00000000 --- a/tests/Behat/Resources/context/api.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/Behat/Resources/context/setup.xml b/tests/Behat/Resources/context/setup.xml index 843ff317..265ff9fa 100644 --- a/tests/Behat/Resources/context/setup.xml +++ b/tests/Behat/Resources/context/setup.xml @@ -17,7 +17,8 @@ - + + diff --git a/tests/Behat/Resources/contexts.xml b/tests/Behat/Resources/contexts.xml index 08adb3d6..3b4b5538 100644 --- a/tests/Behat/Resources/contexts.xml +++ b/tests/Behat/Resources/contexts.xml @@ -3,7 +3,6 @@ - diff --git a/tests/Behat/Resources/suites.yml b/tests/Behat/Resources/suites.yml index 35a31110..b1ad8e87 100644 --- a/tests/Behat/Resources/suites.yml +++ b/tests/Behat/Resources/suites.yml @@ -2,10 +2,3 @@ imports: - suites/ui/managing_gift_cards.yml - suites/ui/buying_gift_card.yml - suites/ui/applying_gift_card.yml - - - suites/api/applying_gift_card.yml - - suites/api/buying_gift_card.yml - - suites/api/managing_gift_card_configurations.yml - - suites/api/managing_gift_cards.yml - - suites/api/managing_gift_cards_balance.yml - - suites/api/managing_shop_gift_cards.yml diff --git a/tests/Behat/Resources/suites/api/applying_gift_card.yml b/tests/Behat/Resources/suites/api/applying_gift_card.yml deleted file mode 100644 index 8d75473e..00000000 --- a/tests/Behat/Resources/suites/api/applying_gift_card.yml +++ /dev/null @@ -1,39 +0,0 @@ -default: - suites: - ui_applying_gift_card: - contexts: - - sylius.behat.context.hook.doctrine_orm - - - sylius.behat.context.transform.cart - - sylius.behat.context.transform.channel - - sylius.behat.context.transform.lexical - - sylius.behat.context.transform.locale - - sylius.behat.context.transform.order - - sylius.behat.context.transform.product - - sylius.behat.context.transform.shared_storage - - sylius.behat.context.transform.user - - - sylius.behat.context.setup.cart - - sylius.behat.context.setup.channel - - sylius.behat.context.setup.checkout - - sylius.behat.context.setup.customer - - sylius.behat.context.setup.locale - - sylius.behat.context.setup.payment - - sylius.behat.context.setup.product - - sylius.behat.context.setup.promotion - - sylius.behat.context.setup.shipping - - sylius.behat.context.setup.shop_api_security - - sylius.behat.context.setup.user - - sylius.behat.context.setup.zone - - - sylius.behat.context.api.shop.cart - - sylius.behat.context.api.shop.channel - - sylius.behat.context.api.shop.checkout - - sylius.behat.context.api.shop.order - - - setono_sylius_gift_card.behat.context.transform.gift_card - - setono_sylius_gift_card.behat.context.setup.gift_card - - - setono_sylius_gift_card.behat.context.api.shop.managing_gift_cards - filters: - tags: "@applying_gift_card && @api" diff --git a/tests/Behat/Resources/suites/api/buying_gift_card.yml b/tests/Behat/Resources/suites/api/buying_gift_card.yml deleted file mode 100644 index 3bf6cbc1..00000000 --- a/tests/Behat/Resources/suites/api/buying_gift_card.yml +++ /dev/null @@ -1,24 +0,0 @@ -default: - suites: - api_buying_gift_card: - contexts: - - sylius.behat.context.hook.doctrine_orm - - sylius.behat.context.hook.email_spool - - - sylius.behat.context.transform.lexical - - sylius.behat.context.transform.product - - sylius.behat.context.transform.shared_storage - - - sylius.behat.context.setup.channel - - sylius.behat.context.setup.payment - - sylius.behat.context.setup.product - - sylius.behat.context.setup.shop_security - - sylius.behat.context.setup.shipping - - - setono_sylius_gift_card.behat.context.setup.gift_card - - - sylius.behat.context.api.shop.cart - - - setono_sylius_gift_card.behat.context.api.shop.cart - filters: - tags: "@buying_gift_card && @api" diff --git a/tests/Behat/Resources/suites/api/managing_gift_card_configurations.yml b/tests/Behat/Resources/suites/api/managing_gift_card_configurations.yml deleted file mode 100644 index a10fb734..00000000 --- a/tests/Behat/Resources/suites/api/managing_gift_card_configurations.yml +++ /dev/null @@ -1,25 +0,0 @@ -default: - suites: - api_managing_gift_card_configurations: - contexts: - - sylius.behat.context.hook.doctrine_orm - - - sylius.behat.context.transform.lexical - - sylius.behat.context.transform.locale - - sylius.behat.context.transform.shared_storage - - sylius.behat.context.transform.channel - - sylius.behat.context.transform.currency - - sylius.behat.context.transform.customer - - - sylius.behat.context.setup.admin_api_security - - sylius.behat.context.setup.locale - - sylius.behat.context.setup.channel - - sylius.behat.context.setup.customer - - - setono_sylius_gift_card.behat.context.setup.gift_card_configuration - - setono_sylius_gift_card.behat.context.transform.gift_card_configuration - - - setono_sylius_gift_card.behat.context.api.admin.managing_gift_card_configurations - filters: - tags: "@managing_gift_card_configurations && @api" - javascript: false diff --git a/tests/Behat/Resources/suites/api/managing_gift_cards.yml b/tests/Behat/Resources/suites/api/managing_gift_cards.yml deleted file mode 100644 index bbae7769..00000000 --- a/tests/Behat/Resources/suites/api/managing_gift_cards.yml +++ /dev/null @@ -1,23 +0,0 @@ -default: - suites: - api_managing_gift_cards: - contexts: - - sylius.behat.context.hook.doctrine_orm - - - sylius.behat.context.transform.lexical - - sylius.behat.context.transform.shared_storage - - sylius.behat.context.transform.channel - - sylius.behat.context.transform.currency - - sylius.behat.context.transform.customer - - - sylius.behat.context.setup.admin_api_security - - sylius.behat.context.setup.channel - - sylius.behat.context.setup.customer - - - setono_sylius_gift_card.behat.context.setup.gift_card - - setono_sylius_gift_card.behat.context.transform.gift_card - - - setono_sylius_gift_card.behat.context.api.admin.managing_gift_cards - filters: - tags: "@managing_gift_cards && @api" - javascript: false diff --git a/tests/Behat/Resources/suites/api/managing_gift_cards_balance.yml b/tests/Behat/Resources/suites/api/managing_gift_cards_balance.yml deleted file mode 100644 index b3e9712e..00000000 --- a/tests/Behat/Resources/suites/api/managing_gift_cards_balance.yml +++ /dev/null @@ -1,21 +0,0 @@ -default: - suites: - api_managing_gift_cards_balance: - contexts: - - sylius.behat.context.hook.doctrine_orm - - - sylius.behat.context.transform.lexical - - sylius.behat.context.transform.shared_storage - - sylius.behat.context.transform.channel - - sylius.behat.context.transform.currency - - - sylius.behat.context.setup.admin_api_security - - sylius.behat.context.setup.channel - - sylius.behat.context.setup.currency - - - setono_sylius_gift_card.behat.context.setup.gift_card - - - setono_sylius_gift_card.behat.context.api.admin.managing_gift_cards_balance - filters: - tags: "@managing_gift_cards_balance && @api" - javascript: false diff --git a/tests/Behat/Resources/suites/api/managing_shop_gift_cards.yml b/tests/Behat/Resources/suites/api/managing_shop_gift_cards.yml deleted file mode 100644 index 1cbfae86..00000000 --- a/tests/Behat/Resources/suites/api/managing_shop_gift_cards.yml +++ /dev/null @@ -1,24 +0,0 @@ -default: - suites: - api_managing_shop_gift_cards: - contexts: - - sylius.behat.context.hook.doctrine_orm - - - sylius.behat.context.transform.lexical - - sylius.behat.context.transform.shared_storage - - sylius.behat.context.transform.channel - - sylius.behat.context.transform.currency - - sylius.behat.context.transform.customer - - - sylius.behat.context.setup.channel - - sylius.behat.context.setup.customer - - sylius.behat.context.setup.shop_api_security - - sylius.behat.context.setup.user - - - setono_sylius_gift_card.behat.context.setup.gift_card - - setono_sylius_gift_card.behat.context.transform.gift_card - - - setono_sylius_gift_card.behat.context.api.shop.managing_gift_cards - filters: - tags: "@managing_shop_gift_cards && @api" - javascript: false diff --git a/tests/Unit/Api/Command/AddGiftCardToOrderTest.php b/tests/Unit/Api/Command/AddGiftCardToOrderTest.php deleted file mode 100644 index eb9688ac..00000000 --- a/tests/Unit/Api/Command/AddGiftCardToOrderTest.php +++ /dev/null @@ -1,34 +0,0 @@ -assertInstanceOf(GiftCardCodeAwareInterface::class, $command); - } - - /** - * @test - */ - public function it_has_nullable_gift_card_code(): void - { - $command = new AddGiftCardToOrder('order_token_vaue'); - - $this->assertNull($command->getGiftCardCode()); - $command->setGiftCardCode('gc_code'); - $this->assertEquals('gc_code', $command->getGiftCardCode()); - } -} diff --git a/tests/Unit/Api/Command/AddItemToCartTest.php b/tests/Unit/Api/Command/AddItemToCartTest.php deleted file mode 100644 index 34f7e6db..00000000 --- a/tests/Unit/Api/Command/AddItemToCartTest.php +++ /dev/null @@ -1,54 +0,0 @@ -assertInstanceOf(AddItemToCart::class, $command); - } - - /** - * @test - */ - public function it_has_its_parents_properties(): void - { - $command = new AddItemToCart('variant', 1); - - $this->assertEquals('variant', $command->productVariantCode); - $this->assertEquals(1, $command->quantity); - } - - /** - * @test - */ - public function it_has_nullable_amount(): void - { - $command = new AddItemToCart('variant', 1); - $this->assertNull($command->getAmount()); - $command = new AddItemToCart('variant', 1, 150); - $this->assertEquals(150, $command->getAmount()); - } - - /** - * @test - */ - public function it_has_nullable_custom_message(): void - { - $command = new AddItemToCart('variant', 1); - $this->assertNull($command->getCustomMessage()); - $command = new AddItemToCart('variant', 1, null, 'Custom message'); - $this->assertEquals('Custom message', $command->getCustomMessage()); - } -} diff --git a/tests/Unit/Api/Command/AssociateConfigurationToChannelTest.php b/tests/Unit/Api/Command/AssociateConfigurationToChannelTest.php deleted file mode 100644 index 85ba15e6..00000000 --- a/tests/Unit/Api/Command/AssociateConfigurationToChannelTest.php +++ /dev/null @@ -1,34 +0,0 @@ -assertInstanceOf(ConfigurationCodeAwareInterface::class, $command); - } - - /** - * @test - */ - public function it_has_nullable_configuration_code(): void - { - $command = new AssociateConfigurationToChannel('locale_code', 'channel_code'); - - $this->assertNull($command->getConfigurationCode()); - $command->setConfigurationCode('configuration_code'); - $this->assertEquals('configuration_code', $command->getConfigurationCode()); - } -} diff --git a/tests/Unit/Api/Command/CreateGiftCardConfigurationTest.php b/tests/Unit/Api/Command/CreateGiftCardConfigurationTest.php deleted file mode 100644 index adb52290..00000000 --- a/tests/Unit/Api/Command/CreateGiftCardConfigurationTest.php +++ /dev/null @@ -1,57 +0,0 @@ -assertInstanceOf(CreateGiftCardConfiguration::class, $command); - } - - /** - * @test - */ - public function it_has_nullable_default_validity_period(): void - { - $command = new CreateGiftCardConfiguration('code', false, false); - $this->assertNull($command->defaultValidityPeriod); - } - - /** - * @test - */ - public function it_has_nullable_page_size(): void - { - $command = new CreateGiftCardConfiguration('code', false, false); - $this->assertNull($command->pageSize); - } - - /** - * @test - */ - public function it_has_nullable_orientation(): void - { - $command = new CreateGiftCardConfiguration('code', false, false); - $this->assertNull($command->orientation); - } - - /** - * @test - */ - public function it_has_nullable_template(): void - { - $command = new CreateGiftCardConfiguration('code', false, false); - $this->assertNull($command->template); - } -} diff --git a/tests/Unit/Api/Command/RemoveGiftCardFromOrderTest.php b/tests/Unit/Api/Command/RemoveGiftCardFromOrderTest.php deleted file mode 100644 index b17422c1..00000000 --- a/tests/Unit/Api/Command/RemoveGiftCardFromOrderTest.php +++ /dev/null @@ -1,34 +0,0 @@ -assertInstanceOf(GiftCardCodeAwareInterface::class, $command); - } - - /** - * @test - */ - public function it_has_nullable_gift_card_code(): void - { - $command = new RemoveGiftCardFromOrder('order_token_vaue'); - - $this->assertNull($command->getGiftCardCode()); - $command->setGiftCardCode('gc_code'); - $this->assertEquals('gc_code', $command->getGiftCardCode()); - } -} diff --git a/tests/Unit/Api/CommandHandler/AddGiftCardToOrderHandlerTest.php b/tests/Unit/Api/CommandHandler/AddGiftCardToOrderHandlerTest.php deleted file mode 100644 index 17abca48..00000000 --- a/tests/Unit/Api/CommandHandler/AddGiftCardToOrderHandlerTest.php +++ /dev/null @@ -1,117 +0,0 @@ -setGiftCardCode('gc_code'); - - $giftCardRepository = $this->prophesize(GiftCardRepositoryInterface::class); - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $giftCardApplicator = $this->prophesize(GiftCardApplicatorInterface::class); - - $giftCardRepository->findOneByCode('gc_code')->willReturn($giftCard); - $orderRepository->findOneBy(['tokenValue' => 'order_token_value'])->willReturn($order); - $giftCardApplicator->apply($order, $giftCard)->shouldBeCalled(); - - $addGiftCardToOrderHandler = new AddGiftCardToOrderHandler( - $giftCardRepository->reveal(), - $orderRepository->reveal(), - $giftCardApplicator->reveal(), - ); - $addGiftCardToOrderHandler($command); - } - - /** - * @test - */ - public function it_throws_error_if_gift_card_code_is_null(): void - { - $command = new AddGiftCardToOrder('order_token_value'); - - $giftCardRepository = $this->prophesize(GiftCardRepositoryInterface::class); - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $giftCardApplicator = $this->prophesize(GiftCardApplicatorInterface::class); - - $this->expectException(InvalidArgumentException::class); - - $addGiftCardToOrderHandler = new AddGiftCardToOrderHandler( - $giftCardRepository->reveal(), - $orderRepository->reveal(), - $giftCardApplicator->reveal(), - ); - $addGiftCardToOrderHandler($command); - } - - /** - * @test - */ - public function it_throws_error_if_gift_card_not_found(): void - { - $command = new AddGiftCardToOrder('order_token_value'); - $command->setGiftCardCode('gc_code'); - - $giftCardRepository = $this->prophesize(GiftCardRepositoryInterface::class); - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $giftCardApplicator = $this->prophesize(GiftCardApplicatorInterface::class); - - $this->expectException(InvalidArgumentException::class); - - $addGiftCardToOrderHandler = new AddGiftCardToOrderHandler( - $giftCardRepository->reveal(), - $orderRepository->reveal(), - $giftCardApplicator->reveal(), - ); - $addGiftCardToOrderHandler($command); - } - - /** - * @test - */ - public function it_throws_exception_if_order_not_found(): void - { - $giftCard = new GiftCard(); - - $command = new AddGiftCardToOrder('order_token_value'); - $command->setGiftCardCode('gc_code'); - - $giftCardRepository = $this->prophesize(GiftCardRepositoryInterface::class); - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $giftCardApplicator = $this->prophesize(GiftCardApplicatorInterface::class); - - $giftCardRepository->findOneByCode('gc_code')->willReturn($giftCard); - - $this->expectException(InvalidArgumentException::class); - - $addGiftCardToOrderHandler = new AddGiftCardToOrderHandler( - $giftCardRepository->reveal(), - $orderRepository->reveal(), - $giftCardApplicator->reveal(), - ); - $addGiftCardToOrderHandler($command); - } -} diff --git a/tests/Unit/Api/CommandHandler/AddItemToCartHandlerTest.php b/tests/Unit/Api/CommandHandler/AddItemToCartHandlerTest.php deleted file mode 100644 index ea9c923d..00000000 --- a/tests/Unit/Api/CommandHandler/AddItemToCartHandlerTest.php +++ /dev/null @@ -1,236 +0,0 @@ -prophesize(OrderRepositoryInterface::class); - $productVariantRepository = $this->prophesize(ProductVariantRepositoryInterface::class); - $orderModifier = $this->prophesize(OrderModifierInterface::class); - $cartItemFactory = $this->prophesize(CartItemFactoryInterface::class); - $orderItemQuantityModifier = $this->prophesize(OrderItemQuantityModifierInterface::class); - $giftCardFactory = $this->prophesize(GiftCardFactoryInterface::class); - $giftCardManager = $this->prophesize(EntityManagerInterface::class); - - $handler = new AddItemToCartHandler( - $orderRepository->reveal(), - $productVariantRepository->reveal(), - $orderModifier->reveal(), - $cartItemFactory->reveal(), - $orderItemQuantityModifier->reveal(), - $giftCardFactory->reveal(), - $giftCardManager->reveal(), - ); - - $this->assertInstanceOf(AddItemToCartHandler::class, $handler); - } - - /** - * @test - */ - public function it_adds_configurable_gift_card_to_cart(): void - { - $orderTokenValue = 'orderTokenValue'; - - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $productVariantRepository = $this->prophesize(ProductVariantRepositoryInterface::class); - $orderModifier = $this->prophesize(OrderModifierInterface::class); - $cartItemFactory = $this->prophesize(CartItemFactoryInterface::class); - $orderItemQuantityModifier = $this->prophesize(OrderItemQuantityModifierInterface::class); - $giftCardFactory = $this->prophesize(GiftCardFactoryInterface::class); - $giftCardManager = $this->prophesize(EntityManagerInterface::class); - - $product = new Product(); - $product->setGiftCard(true); - $product->setGiftCardAmountConfigurable(true); - $productVariant = new ProductVariant(); - $productVariant->setProduct($product); - $cart = new Order(); - $cart->setTokenValue($orderTokenValue); - $cartItem = new OrderItem(); - - $productVariantRepository - ->findOneBy(['code' => 'variant']) - ->willReturn($productVariant); - $orderRepository - ->findCartByTokenValue($orderTokenValue) - ->willReturn($cart); - $cartItemFactory - ->createNew() - ->willReturn($cartItem); - - $orderItemQuantityModifier->modify($cartItem, 1)->shouldBeCalled(); - $orderModifier->addToOrder($cart, $cartItem)->shouldBeCalled(); - - $cartItemUnit = new OrderItemUnit($cartItem); - $cartItem->addUnit($cartItemUnit); - - $giftCard = new GiftCard(); - $giftCardFactory - ->createFromOrderItemUnitAndCart($cartItemUnit, $cart) - ->willReturn($giftCard); - $giftCardManager->persist($giftCard)->shouldBeCalled(); - - $handler = new AddItemToCartHandler( - $orderRepository->reveal(), - $productVariantRepository->reveal(), - $orderModifier->reveal(), - $cartItemFactory->reveal(), - $orderItemQuantityModifier->reveal(), - $giftCardFactory->reveal(), - $giftCardManager->reveal(), - ); - $message = new SetonoSyliusGiftCardAddItemToCart('variant', 1, 1500, 'Custom message'); - $message->setOrderTokenValue($orderTokenValue); - $handler($message); - } - - /** - * @test - */ - public function it_adds_simple_item_to_cart(): void - { - $orderTokenValue = 'orderTokenValue'; - - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $productVariantRepository = $this->prophesize(ProductVariantRepositoryInterface::class); - $orderModifier = $this->prophesize(OrderModifierInterface::class); - $cartItemFactory = $this->prophesize(CartItemFactoryInterface::class); - $orderItemQuantityModifier = $this->prophesize(OrderItemQuantityModifierInterface::class); - $giftCardFactory = $this->prophesize(GiftCardFactoryInterface::class); - $giftCardManager = $this->prophesize(EntityManagerInterface::class); - - $productVariant = $this->prophesize(ProductVariant::class); - $cart = new Order(); - $cart->setTokenValue($orderTokenValue); - $cartItem = $this->prophesize(OrderItem::class); - $cartItem->setVariant($productVariant)->shouldBeCalled(); - - $productVariantRepository - ->findOneBy(['code' => 'variant']) - ->willReturn($productVariant); - $orderRepository - ->findCartByTokenValue($orderTokenValue) - ->willReturn($cart); - $cartItemFactory - ->createNew() - ->willReturn($cartItem); - - $productVariant->getProduct()->shouldNotBeCalled(); - - $orderItemQuantityModifier->modify($cartItem, 1)->shouldBeCalled(); - $orderModifier->addToOrder($cart, $cartItem)->shouldBeCalled(); - - $cartItem->getUnits()->shouldNotBeCalled(); - - $handler = new AddItemToCartHandler( - $orderRepository->reveal(), - $productVariantRepository->reveal(), - $orderModifier->reveal(), - $cartItemFactory->reveal(), - $orderItemQuantityModifier->reveal(), - $giftCardFactory->reveal(), - $giftCardManager->reveal(), - ); - $message = new SyliusAddItemToCart('variant', 1); - $message->setOrderTokenValue($orderTokenValue); - $handler($message); - } - - /** - * @test - */ - public function it_adds_simple_gift_card_to_cart(): void - { - $orderTokenValue = 'orderTokenValue'; - - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $productVariantRepository = $this->prophesize(ProductVariantRepositoryInterface::class); - $orderModifier = $this->prophesize(OrderModifierInterface::class); - $cartItemFactory = $this->prophesize(CartItemFactoryInterface::class); - $orderItemQuantityModifier = $this->prophesize(OrderItemQuantityModifierInterface::class); - $giftCardFactory = $this->prophesize(GiftCardFactoryInterface::class); - $giftCardManager = $this->prophesize(EntityManagerInterface::class); - - $product = new Product(); - $product->setGiftCard(true); - $product->setGiftCardAmountConfigurable(false); - $productVariant = new ProductVariant(); - $productVariant->setProduct($product); - $cart = new Order(); - $cart->setTokenValue($orderTokenValue); - $cartItem = $this->prophesize(OrderItem::class); - $cartItem->setVariant($productVariant)->shouldBeCalled(); - - $productVariantRepository - ->findOneBy(['code' => 'variant']) - ->willReturn($productVariant); - $orderRepository - ->findCartByTokenValue($orderTokenValue) - ->willReturn($cart); - $cartItemFactory - ->createNew() - ->willReturn($cartItem); - - $cartItem->setUnitPrice(Argument::any())->shouldNotBeCalled(); - $cartItem->setImmutable(true)->shouldNotBeCalled(); - - $orderItemQuantityModifier->modify($cartItem, 1)->shouldBeCalled(); - $orderModifier->addToOrder($cart, $cartItem)->shouldBeCalled(); - - $cartItemUnit = new OrderItemUnit($cartItem->reveal()); - $cartItem->addUnit($cartItemUnit)->shouldBeCalled(); - $cartItem - ->getUnits() - ->willReturn(new ArrayCollection([$cartItemUnit])); - - $giftCard = new GiftCard(); - $giftCardFactory - ->createFromOrderItemUnitAndCart($cartItemUnit, $cart) - ->willReturn($giftCard); - $giftCardManager->persist($giftCard)->shouldBeCalled(); - - $handler = new AddItemToCartHandler( - $orderRepository->reveal(), - $productVariantRepository->reveal(), - $orderModifier->reveal(), - $cartItemFactory->reveal(), - $orderItemQuantityModifier->reveal(), - $giftCardFactory->reveal(), - $giftCardManager->reveal(), - ); - $message = new SetonoSyliusGiftCardAddItemToCart('variant', 1); - $message->setOrderTokenValue($orderTokenValue); - $handler($message); - } -} diff --git a/tests/Unit/Api/CommandHandler/AssociateConfigurationToChannelHandlerTest.php b/tests/Unit/Api/CommandHandler/AssociateConfigurationToChannelHandlerTest.php deleted file mode 100644 index 54c0b619..00000000 --- a/tests/Unit/Api/CommandHandler/AssociateConfigurationToChannelHandlerTest.php +++ /dev/null @@ -1,250 +0,0 @@ -prophesize(RepositoryInterface::class); - $channelRepository = $this->prophesize(ChannelRepositoryInterface::class); - $localeRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationFactory = $this->prophesize(FactoryInterface::class); - - $command = new AssociateConfigurationToChannel('en_GB', 'super_channel'); - $command->setConfigurationCode('super_configuration'); - - $giftCardConfigurationRepository - ->findOneBy(['code' => 'super_configuration']) - ->willReturn($configuration); - $channelRepository - ->findOneByCode('super_channel') - ->willReturn($channel); - $localeRepository - ->findOneBy(['code' => 'en_GB']) - ->willReturn($locale); - - $giftCardChannelConfigurationRepository - ->findOneBy([ - 'configuration' => $configuration, - 'channel' => $channel, - 'locale' => $locale, - ]) - ->willReturn(null); - - $giftCardChannelConfigurationFactory->createNew()->willReturn($giftCardChannelConfiguration); - - $handler = new AssociateConfigurationToChannelHandler( - $giftCardConfigurationRepository->reveal(), - $channelRepository->reveal(), - $localeRepository->reveal(), - $giftCardChannelConfigurationRepository->reveal(), - $giftCardChannelConfigurationFactory->reveal(), - ); - $returnedConfiguration = $handler($command); - - self::assertEquals(1, $returnedConfiguration->getChannelConfigurations()->count()); - /** @var GiftCardChannelConfiguration $returnedChannelConfiguration */ - $returnedChannelConfiguration = $returnedConfiguration->getChannelConfigurations()->first(); - - self::assertEquals($channel, $returnedChannelConfiguration->getChannel()); - self::assertEquals($locale, $returnedChannelConfiguration->getLocale()); - } - - /** - * @test - */ - public function it_does_nothing_if_association_already_exists(): void - { - $configuration = new GiftCardConfiguration(); - $channel = new Channel(); - $locale = new Locale(); - $existingGiftCardChannelConfiguration = new GiftCardChannelConfiguration(); - - $giftCardConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $channelRepository = $this->prophesize(ChannelRepositoryInterface::class); - $localeRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationFactory = $this->prophesize(FactoryInterface::class); - - $command = new AssociateConfigurationToChannel('en_GB', 'super_channel'); - $command->setConfigurationCode('super_configuration'); - - $giftCardConfigurationRepository - ->findOneBy(['code' => 'super_configuration']) - ->willReturn($configuration); - $channelRepository - ->findOneByCode('super_channel') - ->willReturn($channel); - $localeRepository - ->findOneBy(['code' => 'en_GB']) - ->willReturn($locale); - - $giftCardChannelConfigurationRepository - ->findOneBy([ - 'configuration' => $configuration, - 'channel' => $channel, - 'locale' => $locale, - ]) - ->willReturn(new ArrayCollection([$existingGiftCardChannelConfiguration])); - - $giftCardChannelConfigurationFactory->createNew()->shouldNotBeCalled(); - - $handler = new AssociateConfigurationToChannelHandler( - $giftCardConfigurationRepository->reveal(), - $channelRepository->reveal(), - $localeRepository->reveal(), - $giftCardChannelConfigurationRepository->reveal(), - $giftCardChannelConfigurationFactory->reveal(), - ); - $returnedConfiguration = $handler($command); - - self::assertEquals(0, $returnedConfiguration->getChannelConfigurations()->count()); - } - - /** - * @test - */ - public function it_throws_exception_if_configuration_code_empty(): void - { - $giftCardConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $channelRepository = $this->prophesize(ChannelRepositoryInterface::class); - $localeRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationFactory = $this->prophesize(FactoryInterface::class); - - $command = new AssociateConfigurationToChannel('en_GB', 'super_channel'); - - $this->expectException(InvalidArgumentException::class); - - $handler = new AssociateConfigurationToChannelHandler( - $giftCardConfigurationRepository->reveal(), - $channelRepository->reveal(), - $localeRepository->reveal(), - $giftCardChannelConfigurationRepository->reveal(), - $giftCardChannelConfigurationFactory->reveal(), - ); - $handler($command); - } - - /** - * @test - */ - public function it_throws_exception_if_configuration_not_found(): void - { - $giftCardConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $channelRepository = $this->prophesize(ChannelRepositoryInterface::class); - $localeRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationFactory = $this->prophesize(FactoryInterface::class); - - $command = new AssociateConfigurationToChannel('en_GB', 'super_channel'); - $command->setConfigurationCode('super_configuration'); - - $this->expectException(InvalidArgumentException::class); - - $handler = new AssociateConfigurationToChannelHandler( - $giftCardConfigurationRepository->reveal(), - $channelRepository->reveal(), - $localeRepository->reveal(), - $giftCardChannelConfigurationRepository->reveal(), - $giftCardChannelConfigurationFactory->reveal(), - ); - $handler($command); - } - - /** - * @test - */ - public function it_throws_eception_if_channel_not_found(): void - { - $configuration = new GiftCardConfiguration(); - - $giftCardConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $channelRepository = $this->prophesize(ChannelRepositoryInterface::class); - $localeRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationFactory = $this->prophesize(FactoryInterface::class); - - $command = new AssociateConfigurationToChannel('en_GB', 'super_channel'); - $command->setConfigurationCode('super_configuration'); - - $giftCardConfigurationRepository - ->findOneBy(['code' => 'super_configuration']) - ->willReturn($configuration); - - $this->expectException(InvalidArgumentException::class); - - $handler = new AssociateConfigurationToChannelHandler( - $giftCardConfigurationRepository->reveal(), - $channelRepository->reveal(), - $localeRepository->reveal(), - $giftCardChannelConfigurationRepository->reveal(), - $giftCardChannelConfigurationFactory->reveal(), - ); - $handler($command); - } - - /** - * @test - */ - public function if_throws_exception_if_locale_not_found(): void - { - $configuration = new GiftCardConfiguration(); - $channel = new Channel(); - - $giftCardConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $channelRepository = $this->prophesize(ChannelRepositoryInterface::class); - $localeRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationRepository = $this->prophesize(RepositoryInterface::class); - $giftCardChannelConfigurationFactory = $this->prophesize(FactoryInterface::class); - - $command = new AssociateConfigurationToChannel('en_GB', 'super_channel'); - $command->setConfigurationCode('super_configuration'); - - $giftCardConfigurationRepository - ->findOneBy(['code' => 'super_configuration']) - ->willReturn($configuration); - $channelRepository - ->findOneByCode('super_channel') - ->willReturn($channel); - - $this->expectException(InvalidArgumentException::class); - - $handler = new AssociateConfigurationToChannelHandler( - $giftCardConfigurationRepository->reveal(), - $channelRepository->reveal(), - $localeRepository->reveal(), - $giftCardChannelConfigurationRepository->reveal(), - $giftCardChannelConfigurationFactory->reveal(), - ); - $handler($command); - } -} diff --git a/tests/Unit/Api/CommandHandler/CreateGiftCardConfigurationHandlerTest.php b/tests/Unit/Api/CommandHandler/CreateGiftCardConfigurationHandlerTest.php deleted file mode 100644 index 2649006f..00000000 --- a/tests/Unit/Api/CommandHandler/CreateGiftCardConfigurationHandlerTest.php +++ /dev/null @@ -1,86 +0,0 @@ -prophesize(GiftCardConfigurationFactoryInterface::class)->reveal(), - $this->prophesize(ObjectManager::class)->reveal(), - ); - - $this->assertInstanceOf(CreateGiftCardConfigurationHandler::class, $handler); - } - - /** - * @test - */ - public function it_creates_gift_card_configuration(): void - { - $giftCardConfigurationFactory = $this->prophesize(GiftCardConfigurationFactoryInterface::class); - $giftCardConfigurationManager = $this->prophesize(ObjectManager::class); - - $giftCardConfiguration = $this->prophesize(GiftCardConfigurationInterface::class); - - $giftCardConfigurationFactory->createNew()->willReturn($giftCardConfiguration->reveal()); - - $handler = new CreateGiftCardConfigurationHandler( - $giftCardConfigurationFactory->reveal(), - $giftCardConfigurationManager->reveal(), - ); - - $giftCardConfigurationManager->persist($giftCardConfiguration->reveal())->shouldBeCalled(); - - $command = new CreateGiftCardConfiguration('test', false, false); - $handler->__invoke($command); - } - - /** - * @test - */ - public function it_does_not_set_values_if_null(): void - { - $giftCardConfigurationFactory = $this->prophesize(GiftCardConfigurationFactoryInterface::class); - $giftCardConfigurationManager = $this->prophesize(ObjectManager::class); - - $giftCardConfiguration = $this->prophesize(GiftCardConfigurationInterface::class); - - $giftCardConfigurationFactory->createNew()->willReturn($giftCardConfiguration->reveal()); - - $handler = new CreateGiftCardConfigurationHandler( - $giftCardConfigurationFactory->reveal(), - $giftCardConfigurationManager->reveal(), - ); - - $giftCardConfigurationManager->persist($giftCardConfiguration->reveal())->shouldBeCalled(); - - $giftCardConfiguration->setCode('test')->shouldBeCalled(); - $giftCardConfiguration->setEnabled(false)->shouldBeCalled(); - $giftCardConfiguration->setDefault(false)->shouldBeCalled(); - $giftCardConfiguration->setDefaultValidityPeriod(Argument::any())->shouldNotBeCalled(); - $giftCardConfiguration->setPageSize(Argument::any())->shouldNotBeCalled(); - $giftCardConfiguration->setOrientation(Argument::any())->shouldNotBeCalled(); - $giftCardConfiguration->setTemplate(Argument::any())->shouldNotBeCalled(); - - $command = new CreateGiftCardConfiguration('test', false, false); - $handler->__invoke($command); - } -} diff --git a/tests/Unit/Api/CommandHandler/RemoveGiftCardFromOrderHandlerTest.php b/tests/Unit/Api/CommandHandler/RemoveGiftCardFromOrderHandlerTest.php deleted file mode 100644 index 5ec6209b..00000000 --- a/tests/Unit/Api/CommandHandler/RemoveGiftCardFromOrderHandlerTest.php +++ /dev/null @@ -1,117 +0,0 @@ -setGiftCardCode('gc_code'); - - $giftCardRepository = $this->prophesize(GiftCardRepositoryInterface::class); - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $giftCardApplicator = $this->prophesize(GiftCardApplicatorInterface::class); - - $giftCardRepository->findOneByCode('gc_code')->willReturn($giftCard); - $orderRepository->findOneBy(['tokenValue' => 'order_token_value'])->willReturn($order); - $giftCardApplicator->remove($order, $giftCard)->shouldBeCalled(); - - $removeGiftCardFromOrderHandler = new RemoveGiftCardFromOrderHandler( - $giftCardRepository->reveal(), - $orderRepository->reveal(), - $giftCardApplicator->reveal(), - ); - $removeGiftCardFromOrderHandler($command); - } - - /** - * @test - */ - public function it_throws_error_if_gift_card_code_is_null(): void - { - $command = new RemoveGiftCardFromOrder('order_token_value'); - - $giftCardRepository = $this->prophesize(GiftCardRepositoryInterface::class); - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $giftCardApplicator = $this->prophesize(GiftCardApplicatorInterface::class); - - $this->expectException(InvalidArgumentException::class); - - $removeGiftCardFromOrderHandler = new RemoveGiftCardFromOrderHandler( - $giftCardRepository->reveal(), - $orderRepository->reveal(), - $giftCardApplicator->reveal(), - ); - $removeGiftCardFromOrderHandler($command); - } - - /** - * @test - */ - public function it_throws_error_if_gift_card_not_found(): void - { - $command = new RemoveGiftCardFromOrder('order_token_value'); - $command->setGiftCardCode('gc_code'); - - $giftCardRepository = $this->prophesize(GiftCardRepositoryInterface::class); - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $giftCardApplicator = $this->prophesize(GiftCardApplicatorInterface::class); - - $this->expectException(InvalidArgumentException::class); - - $removeGiftCardFromOrderHandler = new RemoveGiftCardFromOrderHandler( - $giftCardRepository->reveal(), - $orderRepository->reveal(), - $giftCardApplicator->reveal(), - ); - $removeGiftCardFromOrderHandler($command); - } - - /** - * @test - */ - public function it_throws_exception_if_order_not_found(): void - { - $giftCard = new GiftCard(); - - $command = new RemoveGiftCardFromOrder('order_token_value'); - $command->setGiftCardCode('gc_code'); - - $giftCardRepository = $this->prophesize(GiftCardRepositoryInterface::class); - $orderRepository = $this->prophesize(OrderRepositoryInterface::class); - $giftCardApplicator = $this->prophesize(GiftCardApplicatorInterface::class); - - $giftCardRepository->findOneByCode('gc_code')->willReturn($giftCard); - - $this->expectException(InvalidArgumentException::class); - - $removeGiftCardFromOrderHandler = new RemoveGiftCardFromOrderHandler( - $giftCardRepository->reveal(), - $orderRepository->reveal(), - $giftCardApplicator->reveal(), - ); - $removeGiftCardFromOrderHandler($command); - } -} diff --git a/tests/Unit/Api/Controller/Action/DownloadGiftCardPdfActionTest.php b/tests/Unit/Api/Controller/Action/DownloadGiftCardPdfActionTest.php deleted file mode 100644 index 5ae20137..00000000 --- a/tests/Unit/Api/Controller/Action/DownloadGiftCardPdfActionTest.php +++ /dev/null @@ -1,46 +0,0 @@ -Gift card content'); - - $configurationProvider = $this->prophesize(GiftCardConfigurationProviderInterface::class); - $giftCardPDFRenderer = $this->prophesize(PdfRendererInterface::class); - - $configurationProvider->getConfigurationForGiftCard($giftCard)->willReturn($configuration); - $giftCardPDFRenderer - ->render($giftCard, $configuration) - ->willReturn($expectedPdfResponse); - - $downloadGiftCardPdfAction = new DownloadGiftCardPdfAction( - $configurationProvider->reveal(), - $giftCardPDFRenderer->reveal(), - ); - - $response = $downloadGiftCardPdfAction($giftCard); - - $this->assertEquals($expectedPdfResponse, $response); - } -} diff --git a/tests/Unit/Api/Controller/Action/GiftCardBalanceActionTest.php b/tests/Unit/Api/Controller/Action/GiftCardBalanceActionTest.php deleted file mode 100644 index 0d5f0e91..00000000 --- a/tests/Unit/Api/Controller/Action/GiftCardBalanceActionTest.php +++ /dev/null @@ -1,56 +0,0 @@ -setCurrencyCode('EUR'); - $giftCard1->setAmount(25); - $giftCard2 = new GiftCard(); - $giftCard2->setCurrencyCode('EUR'); - $giftCard2->setAmount(56); - - $giftCard3 = new GiftCard(); - $giftCard3->setCurrencyCode('USD'); - $giftCard3->setAmount(31); - $giftCard4 = new GiftCard(); - $giftCard4->setCurrencyCode('USD'); - $giftCard4->setAmount(84); - $giftCard5 = new GiftCard(); - $giftCard5->setCurrencyCode('USD'); - $giftCard5->setAmount(86); - - $expectedBalanceCollection = new GiftCardBalanceCollection(); - $expectedBalanceCollection->addGiftCard($giftCard1); - $expectedBalanceCollection->addGiftCard($giftCard2); - $expectedBalanceCollection->addGiftCard($giftCard3); - $expectedBalanceCollection->addGiftCard($giftCard4); - $expectedBalanceCollection->addGiftCard($giftCard5); - - $giftCardRepository = $this->prophesize(GiftCardRepositoryInterface::class); - - $giftCardRepository->findEnabled()->willReturn([$giftCard1, $giftCard2, $giftCard3, $giftCard4, $giftCard5]); - - $giftCardBalanceAction = new GiftCardBalanceAction($giftCardRepository->reveal()); - $returnedBalanceCollection = $giftCardBalanceAction(); - - self::assertEquals($expectedBalanceCollection, $returnedBalanceCollection); - } -} diff --git a/tests/Unit/Api/Controller/Action/ResendGiftCardEmailActionTest.php b/tests/Unit/Api/Controller/Action/ResendGiftCardEmailActionTest.php deleted file mode 100644 index 9e6178f0..00000000 --- a/tests/Unit/Api/Controller/Action/ResendGiftCardEmailActionTest.php +++ /dev/null @@ -1,82 +0,0 @@ -setOrder($order); - $orderItemUnit = new OrderItemUnit($orderItem); - - $giftCard->setOrderItemUnit($orderItemUnit); - - $expectedResponse = new Response(null, Response::HTTP_NO_CONTENT); - - $giftCardEmailManager = $this->prophesize(GiftCardEmailManagerInterface::class); - $giftCardEmailManager->sendEmailWithGiftCardsFromOrder($order, [$giftCard])->shouldBeCalled(); - - $resendGiftCardEmailAction = new ResendGiftCardEmailAction($giftCardEmailManager->reveal()); - $response = $resendGiftCardEmailAction($giftCard); - - self::assertEquals($expectedResponse, $response); - } - - /** - * @test - */ - public function it_resends_email_for_customer(): void - { - $giftCard = new GiftCard(); - $customer = new Customer(); - - $giftCard->setCustomer($customer); - - $expectedResponse = new Response(null, Response::HTTP_NO_CONTENT); - - $giftCardEmailManager = $this->prophesize(GiftCardEmailManagerInterface::class); - $giftCardEmailManager->sendEmailToCustomerWithGiftCard($customer, $giftCard)->shouldBeCalled(); - - $resendGiftCardEmailAction = new ResendGiftCardEmailAction($giftCardEmailManager->reveal()); - $response = $resendGiftCardEmailAction($giftCard); - - self::assertEquals($expectedResponse, $response); - } - - /** - * @test - */ - public function it_throws_error_if_gift_card_has_no_order_nor_customer(): void - { - $giftCard = new GiftCard(); - - $giftCardEmailManager = $this->prophesize(GiftCardEmailManagerInterface::class); - - $this->expectException(BadRequestHttpException::class); - - $resendGiftCardEmailAction = new ResendGiftCardEmailAction($giftCardEmailManager->reveal()); - $resendGiftCardEmailAction($giftCard); - } -} diff --git a/tests/Unit/Api/Controller/Action/UploadGiftCardConfigurationImageActionTest.php b/tests/Unit/Api/Controller/Action/UploadGiftCardConfigurationImageActionTest.php deleted file mode 100644 index 69f90985..00000000 --- a/tests/Unit/Api/Controller/Action/UploadGiftCardConfigurationImageActionTest.php +++ /dev/null @@ -1,214 +0,0 @@ - 'background', - 'owner' => 'super-iri', - ], [], [], [ - 'file' => $file, - ]); - $giftCardConfigurationImageFactory = $this->prophesize(FactoryInterface::class); - $iriConverter = $this->prophesize(IriConverterInterface::class); - $imageUploader = $this->prophesize(ImageUploaderInterface::class); - $giftCardConfigurationImageRepository = $this->prophesize(RepositoryInterface::class); - - $giftCardConfigurationImageFactory - ->createNew() - ->willReturn($image); - - $iriConverter - ->getItemFromIri('super-iri') - ->willReturn($owner); - - $uploadGiftCardConfigurationImageAction = new UploadGiftCardConfigurationImageAction( - $giftCardConfigurationImageFactory->reveal(), - $giftCardConfigurationImageRepository->reveal(), - $imageUploader->reveal(), - $iriConverter->reveal(), - ); - $returnedImage = $uploadGiftCardConfigurationImageAction($request); - - self::assertSame($owner, $returnedImage->getOwner()); - self::assertSame('background', $returnedImage->getType()); - self::assertSame($file, $returnedImage->getFile()); - } - - /** - * @test - */ - public function it_throws_error_if_image_empty(): void - { - $image = new GiftCardConfigurationImage(); - - $request = new Request([], [ - 'type' => null, - 'owner' => 'super-iri', - ]); - $giftCardConfigurationImageFactory = $this->prophesize(FactoryInterface::class); - $iriConverter = $this->prophesize(IriConverterInterface::class); - $imageUploader = $this->prophesize(ImageUploaderInterface::class); - $giftCardConfigurationImageRepository = $this->prophesize(RepositoryInterface::class); - - $giftCardConfigurationImageFactory - ->createNew() - ->willReturn($image); - - $this->expectException(InvalidArgumentException::class); - - $uploadGiftCardConfigurationImageAction = new UploadGiftCardConfigurationImageAction( - $giftCardConfigurationImageFactory->reveal(), - $giftCardConfigurationImageRepository->reveal(), - $imageUploader->reveal(), - $iriConverter->reveal(), - ); - $uploadGiftCardConfigurationImageAction($request); - } - - /** - * @test - */ - public function it_throws_error_if_owner_iri_empty(): void - { - $file = new UploadedFile(__DIR__ . '/file.jpg', 'file.jpg'); - $image = new GiftCardConfigurationImage(); - - $request = new Request([], [ - 'type' => 'background', - 'owner' => 'super-iri', - ], [], [], [ - 'file' => $file, - ]); - $giftCardConfigurationImageFactory = $this->prophesize(FactoryInterface::class); - $iriConverter = $this->prophesize(IriConverterInterface::class); - $imageUploader = $this->prophesize(ImageUploaderInterface::class); - $giftCardConfigurationImageRepository = $this->prophesize(RepositoryInterface::class); - - $giftCardConfigurationImageFactory - ->createNew() - ->willReturn($image); - - $this->expectException(InvalidArgumentException::class); - - $uploadGiftCardConfigurationImageAction = new UploadGiftCardConfigurationImageAction( - $giftCardConfigurationImageFactory->reveal(), - $giftCardConfigurationImageRepository->reveal(), - $imageUploader->reveal(), - $iriConverter->reveal(), - ); - $uploadGiftCardConfigurationImageAction($request); - } - - /** - * @test - */ - public function it_throws_error_if_owner_not_found(): void - { - $file = new UploadedFile(__DIR__ . '/file.jpg', 'file.jpg'); - $image = new GiftCardConfigurationImage(); - - $request = new Request([], [ - 'type' => 'background', - 'owner' => 'super-iri', - ], [], [], [ - 'file' => $file, - ]); - $giftCardConfigurationImageFactory = $this->prophesize(FactoryInterface::class); - $iriConverter = $this->prophesize(IriConverterInterface::class); - $imageUploader = $this->prophesize(ImageUploaderInterface::class); - $giftCardConfigurationImageRepository = $this->prophesize(RepositoryInterface::class); - - $giftCardConfigurationImageFactory - ->createNew() - ->willReturn($image); - - $iriConverter - ->getItemFromIri('super-iri') - ->willReturn(null); - - $this->expectException(InvalidArgumentException::class); - - $uploadGiftCardConfigurationImageAction = new UploadGiftCardConfigurationImageAction( - $giftCardConfigurationImageFactory->reveal(), - $giftCardConfigurationImageRepository->reveal(), - $imageUploader->reveal(), - $iriConverter->reveal(), - ); - $uploadGiftCardConfigurationImageAction($request); - } - - /** - * @test - */ - public function it_deletes_old_image_of_same_type(): void - { - $file = new UploadedFile(__DIR__ . '/file.jpg', 'file.jpg'); - $image = new GiftCardConfigurationImage(); - $oldImage = new GiftCardConfigurationImage(); - $oldImage->setType('background'); - $owner = new GiftCardConfiguration(); - - $owner->addImage($oldImage); - - $request = new Request([], [ - 'type' => 'background', - 'owner' => 'super-iri', - ], [], [], [ - 'file' => $file, - ]); - $giftCardConfigurationImageFactory = $this->prophesize(FactoryInterface::class); - $iriConverter = $this->prophesize(IriConverterInterface::class); - $imageUploader = $this->prophesize(ImageUploaderInterface::class); - $giftCardConfigurationImageRepository = $this->prophesize(RepositoryInterface::class); - - $giftCardConfigurationImageFactory - ->createNew() - ->willReturn($image); - - $iriConverter - ->getItemFromIri('super-iri') - ->willReturn($owner); - - $giftCardConfigurationImageRepository->remove($oldImage)->shouldBeCalled(); - - $uploadGiftCardConfigurationImageAction = new UploadGiftCardConfigurationImageAction( - $giftCardConfigurationImageFactory->reveal(), - $giftCardConfigurationImageRepository->reveal(), - $imageUploader->reveal(), - $iriConverter->reveal(), - ); - $returnedImage = $uploadGiftCardConfigurationImageAction($request); - - self::assertEquals(1, $owner->getImagesByType('background')->count()); - $image = $owner->getImagesByType('background')->first(); - self::assertEquals($returnedImage, $image); - } -} diff --git a/tests/Unit/Api/Controller/Action/file.jpg b/tests/Unit/Api/Controller/Action/file.jpg deleted file mode 100644 index 889021d3f7a3f2fc7d1202fe6399bd8b38e81722..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82565 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::class); - $dataPersister = new GiftCardDataPersister($decoratedDataPersister->reveal()); - - $this->assertTrue($dataPersister->supports(new GiftCard())); - } - - /** - * @test - */ - public function it_removes_data(): void - { - $decoratedDataPersister = $this->prophesize(ContextAwareDataPersisterInterface::class); - $dataPersister = new GiftCardDataPersister($decoratedDataPersister->reveal()); - - $data = new GiftCard(); - $context = []; - $decoratedDataPersister->remove($data, $context)->shouldBeCalled(); - $dataPersister->remove($data, $context); - } - - /** - * @test - */ - public function it_persists_data(): void - { - $decoratedDataPersister = $this->prophesize(ContextAwareDataPersisterInterface::class); - $dataPersister = new GiftCardDataPersister($decoratedDataPersister->reveal()); - - $data = new GiftCard(); - $context = []; - $decoratedDataPersister->persist($data, $context)->shouldBeCalled(); - $decoratedDataPersister->persist($data, $context)->willReturn($data); - /** @var GiftCardInterface $giftCard */ - $giftCard = $dataPersister->persist($data, $context); - - $this->assertSame(GiftCardInterface::ORIGIN_API, $giftCard->getOrigin()); - } -} diff --git a/tests/Unit/Api/DataTransformer/GiftCardCodeAwareInputCommandDataTransformerTest.php b/tests/Unit/Api/DataTransformer/GiftCardCodeAwareInputCommandDataTransformerTest.php deleted file mode 100644 index 324be62e..00000000 --- a/tests/Unit/Api/DataTransformer/GiftCardCodeAwareInputCommandDataTransformerTest.php +++ /dev/null @@ -1,44 +0,0 @@ -supportsTransformation('anything')); - self::assertTrue($dataTransformer->supportsTransformation(new AddGiftCardToOrder('token_value'))); - } - - /** - * @test - */ - public function it_adds_gift_card_code_to_object(): void - { - $dataTransformer = new GiftCardCodeAwareInputCommandDataTransformer(); - - $addGiftCardToOrder = new AddGiftCardToOrder('token_value'); - $giftCard = new GiftCard(); - $giftCard->setCode('gc_code'); - - $transformedCommand = $dataTransformer->transform( - $addGiftCardToOrder, - GiftCardCodeAwareInterface::class, - ['object_to_populate' => $giftCard], - ); - self::assertEquals('gc_code', $transformedCommand->getGiftCardCode()); - } -} diff --git a/tests/Unit/Api/Doctrine/QueryCollectionExtension/GiftCardsByLoggedInUserExtensionTest.php b/tests/Unit/Api/Doctrine/QueryCollectionExtension/GiftCardsByLoggedInUserExtensionTest.php deleted file mode 100644 index 83c3e657..00000000 --- a/tests/Unit/Api/Doctrine/QueryCollectionExtension/GiftCardsByLoggedInUserExtensionTest.php +++ /dev/null @@ -1,146 +0,0 @@ -setCustomer($customer); - - $userContext = $this->prophesize(UserContextInterface::class); - $queryBuilder = $this->prophesize(QueryBuilder::class); - $queryNameGenerator = $this->prophesize(QueryNameGeneratorInterface::class); - - $userContext - ->getUser() - ->willReturn($shopUser); - $queryBuilder - ->getRootAliases() - ->willReturn([0 => 'root_alias']); - - $queryBuilder - ->andWhere('root_alias.customer = :customer') - ->willReturn($queryBuilder->reveal()); - - $queryBuilder - ->setParameter('customer', $customer->getId(), Types::INTEGER) - ->shouldBeCalled(); - - $giftCardsByLoggedInUserExtension = new GiftCardsByLoggedInUserExtension($userContext->reveal()); - $giftCardsByLoggedInUserExtension->applyToCollection( - $queryBuilder->reveal(), - $queryNameGenerator->reveal(), - GiftCardInterface::class, - ); - } - - /** - * @test - */ - public function it_does_not_apply_filter_for_other_collections(): void - { - $shopUser = new ShopUser(); - $customer = new Customer(); - $shopUser->setCustomer($customer); - - $userContext = $this->prophesize(UserContextInterface::class); - $queryBuilder = $this->prophesize(QueryBuilder::class); - $queryNameGenerator = $this->prophesize(QueryNameGeneratorInterface::class); - - $userContext - ->getUser() - ->shouldNotBeCalled(); - $queryBuilder - ->andWhere('root_alias.customer = :customer') - ->shouldNotBeCalled(); - - $giftCardsByLoggedInUserExtension = new GiftCardsByLoggedInUserExtension($userContext->reveal()); - $giftCardsByLoggedInUserExtension->applyToCollection( - $queryBuilder->reveal(), - $queryNameGenerator->reveal(), - ShopUser::class, - ); - } - - /** - * @test - */ - public function it_does_not_apply_filter_if_user_is_admin(): void - { - $user = new AdminUser(); - - $userContext = $this->prophesize(UserContextInterface::class); - $queryBuilder = $this->prophesize(QueryBuilder::class); - $queryNameGenerator = $this->prophesize(QueryNameGeneratorInterface::class); - - $userContext - ->getUser() - ->willReturn($user); - $queryBuilder - ->getRootAliases() - ->shouldNotBeCalled(); - - $queryBuilder - ->andWhere('root_alias.customer = :customer') - ->shouldNotBeCalled(); - - $giftCardsByLoggedInUserExtension = new GiftCardsByLoggedInUserExtension($userContext->reveal()); - $giftCardsByLoggedInUserExtension->applyToCollection( - $queryBuilder->reveal(), - $queryNameGenerator->reveal(), - GiftCardInterface::class, - ); - } - - /** - * @test - */ - public function it_throws_exception_if_user_is_logged_out(): void - { - $userContext = $this->prophesize(UserContextInterface::class); - $queryBuilder = $this->prophesize(QueryBuilder::class); - $queryNameGenerator = $this->prophesize(QueryNameGeneratorInterface::class); - - $userContext - ->getUser() - ->willReturn(null); - $queryBuilder - ->getRootAliases() - ->shouldNotBeCalled(); - - $queryBuilder - ->andWhere('root_alias.customer = :customer') - ->shouldNotBeCalled(); - - $this->expectException(AccessDeniedException::class); - $giftCardsByLoggedInUserExtension = new GiftCardsByLoggedInUserExtension($userContext->reveal()); - $giftCardsByLoggedInUserExtension->applyToCollection( - $queryBuilder->reveal(), - $queryNameGenerator->reveal(), - GiftCardInterface::class, - ); - } -} From 08d30ca548250b21ea5be4a9e5bfe70451714de2 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:31:24 +0200 Subject: [PATCH 05/60] Remove leftover winzou state_machine config and orphaned JMS serializer file --- .../config/serializer/Model.GiftCard.yml | 44 ------------------- .../config/state_machine/sylius_order.yaml | 16 ------- .../state_machine/sylius_order_checkout.yaml | 8 ---- .../state_machine/sylius_order_payment.yaml | 12 ----- 4 files changed, 80 deletions(-) delete mode 100644 src/Resources/config/serializer/Model.GiftCard.yml delete mode 100644 src/Resources/config/state_machine/sylius_order.yaml delete mode 100644 src/Resources/config/state_machine/sylius_order_checkout.yaml delete mode 100644 src/Resources/config/state_machine/sylius_order_payment.yaml diff --git a/src/Resources/config/serializer/Model.GiftCard.yml b/src/Resources/config/serializer/Model.GiftCard.yml deleted file mode 100644 index fe281f95..00000000 --- a/src/Resources/config/serializer/Model.GiftCard.yml +++ /dev/null @@ -1,44 +0,0 @@ -Setono\SyliusGiftCardPlugin\Model\GiftCard: - exclusion_policy: ALL - xml_root_name: setono_sylius_gift_card - properties: - code: - expose: true - type: string - groups: [Default, Detailed] - currencyCode: - expose: true - type: string - groups: [Default, Detailed] - amount: - expose: true - type: integer - groups: [Default, Detailed] - initialAmount: - expose: true - type: integer - groups: [Default, Detailed] - enabled: - expose: true - type: boolean - groups: [Default, Detailed] - createdAt: - expose: true - type: DateTime - groups: [Default, Detailed] - virtual_properties: - getCustomerIdentification: - serialized_name: customer - expose: true - type: array - groups: [Default, Detailed] - getOrderIdentification: - serialized_name: order - expose: true - type: array - groups: [Default, Detailed] - getChannelCode: - serialized_name: channel - expose: true - type: string - groups: [Default, Detailed] diff --git a/src/Resources/config/state_machine/sylius_order.yaml b/src/Resources/config/state_machine/sylius_order.yaml deleted file mode 100644 index 1cf79315..00000000 --- a/src/Resources/config/state_machine/sylius_order.yaml +++ /dev/null @@ -1,16 +0,0 @@ -winzou_state_machine: - sylius_order: - callbacks: - after: - setono_decrement_gift_card_amount: - on: ["create"] - do: ["@setono_sylius_gift_card.modifier.order_gift_card_amount", "decrement"] - args: ["object"] - setono_increment_gift_card_amount: - on: ["cancel"] - do: ["@setono_sylius_gift_card.modifier.order_gift_card_amount", "increment"] - args: ["object"] - setono_order_cancellation_gift_card: - on: ["cancel"] - do: ["@setono_sylius_gift_card.operator.order_gift_card", "disable"] - args: ["object"] diff --git a/src/Resources/config/state_machine/sylius_order_checkout.yaml b/src/Resources/config/state_machine/sylius_order_checkout.yaml deleted file mode 100644 index 12c9d934..00000000 --- a/src/Resources/config/state_machine/sylius_order_checkout.yaml +++ /dev/null @@ -1,8 +0,0 @@ -winzou_state_machine: - sylius_order_checkout: - callbacks: - after: - setono_gift_card_associate_to_customer: - on: ["complete"] - do: ["@setono_sylius_gift_card.operator.order_gift_card", "associateToCustomer"] - args: ["object"] diff --git a/src/Resources/config/state_machine/sylius_order_payment.yaml b/src/Resources/config/state_machine/sylius_order_payment.yaml deleted file mode 100644 index a30259eb..00000000 --- a/src/Resources/config/state_machine/sylius_order_payment.yaml +++ /dev/null @@ -1,12 +0,0 @@ -winzou_state_machine: - sylius_order_payment: - callbacks: - after: - setono_gift_card_enable: - on: ["pay"] - do: ["@setono_sylius_gift_card.operator.order_gift_card", "enable"] - args: ["object"] - setono_gift_card_send: - on: ["pay"] - do: ["@setono_sylius_gift_card.operator.order_gift_card", "send"] - args: ["object"] From 41b05071ffdc0cfb8634216f6417b38ea53cd075 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:31:35 +0200 Subject: [PATCH 06/60] Port shop UI hooks to sylius/twig-hooks The sylius_ui "events" block system (SonataBlock-style) was removed in Sylius 2 in favor of sylius/twig-hooks. Ported the add-to-cart gift card fields and the cart summary applied-gift-cards block to twig hooks (hookable_metadata.context.* accessor pattern). The admin CRUD javascripts and shop account gift card index hooks still need porting - left as TODO in app/config.yaml since they used the removed block system too. --- src/Resources/config/sylius_ui.yaml | 18 +++++++------ .../Cart/Summary/_appliedGiftCards.html.twig | 25 +++++++++++++++++++ .../_addToCartGiftCardInformation.html.twig | 2 ++ 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 src/Resources/views/Shop/Cart/Summary/_appliedGiftCards.html.twig diff --git a/src/Resources/config/sylius_ui.yaml b/src/Resources/config/sylius_ui.yaml index 7a641d5e..4b3e0c91 100644 --- a/src/Resources/config/sylius_ui.yaml +++ b/src/Resources/config/sylius_ui.yaml @@ -1,7 +1,11 @@ -sylius_ui: - events: - sylius.shop.product.show.add_to_cart_form: - blocks: - setono_sylius_gift_card_information: - template: '@SetonoSyliusGiftCardPlugin/Shop/Product/Show/_addToCartGiftCardInformation.html.twig' - priority: 10 +sylius_twig_hooks: + hooks: + 'sylius_shop.product.show.content.info.summary.add_to_cart': + setono_sylius_gift_card_information: + template: '@SetonoSyliusGiftCardPlugin/Shop/Product/Show/_addToCartGiftCardInformation.html.twig' + priority: 50 + + 'sylius_shop.cart.index.content.form.sections.general.summary': + setono_sylius_gift_card_applied_gift_cards: + template: '@SetonoSyliusGiftCardPlugin/Shop/Cart/Summary/_appliedGiftCards.html.twig' + priority: 150 diff --git a/src/Resources/views/Shop/Cart/Summary/_appliedGiftCards.html.twig b/src/Resources/views/Shop/Cart/Summary/_appliedGiftCards.html.twig new file mode 100644 index 00000000..54698b16 --- /dev/null +++ b/src/Resources/views/Shop/Cart/Summary/_appliedGiftCards.html.twig @@ -0,0 +1,25 @@ +{% import "@SyliusShop/shared/macro/money.html.twig" as money %} + +{% set cart = hookable_metadata.context.cart %} +{% set giftCardAdjustment = constant('Setono\\SyliusGiftCardPlugin\\Model\\AdjustmentInterface::ORDER_GIFT_CARD_ADJUSTMENT') %} +{% set giftCardAdjustments = cart.getAdjustments(giftCardAdjustment) %} + +{% if giftCardAdjustments.count > 0 %} +
+ {{ 'setono_sylius_gift_card.ui.applied_gift_cards'|trans }} + + {% for adjustment in giftCardAdjustments %} +
+
+ {{ adjustment.originCode }} + + + +
+
+ {{ money.convertAndFormat(-adjustment.amount) }} +
+
+ {% endfor %} +
+{% endif %} diff --git a/src/Resources/views/Shop/Product/Show/_addToCartGiftCardInformation.html.twig b/src/Resources/views/Shop/Product/Show/_addToCartGiftCardInformation.html.twig index cacb1589..65ddeff3 100644 --- a/src/Resources/views/Shop/Product/Show/_addToCartGiftCardInformation.html.twig +++ b/src/Resources/views/Shop/Product/Show/_addToCartGiftCardInformation.html.twig @@ -1,3 +1,5 @@ +{% set form = hookable_metadata.context.form %} + {% if form.giftCardInformation is defined %} {% set giftCardInformationForm = form.giftCardInformation %} {% if giftCardInformationForm.amount is defined %} From 4de9e092e09e51991036592b80b84934195e3f3d Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:32:00 +0200 Subject: [PATCH 07/60] Fix remaining Sylius 2 / Symfony 7 compat breaks found while booting the container - AddAdjustmentsToOrderAdjustmentClearerPass: the order adjustments clearer argument is now the %sylius.order_processing.adjustment_clearing_types% container parameter, not a mutable service-definition argument - renamed service ids: sylius.image_uploader -> sylius.uploader.image, sylius.money_formatter -> sylius.formatter.money, sylius.product_variant_resolver.default -> sylius.resolver.product_variant.default - GiftCardFactory: Sylius\Bundle\ShippingBundle\Provider\DateTimeProvider was removed; replaced with Symfony\Component\Clock\ClockInterface - GiftCardNormalizer/GiftCardConfigurationNormalizer: Symfony 7 removed ContextAwareNormalizerInterface, methods merged into NormalizerInterface (which now requires getSupportedTypes()) --- .../AddAdjustmentsToOrderAdjustmentClearerPass.php | 11 ++++------- src/Factory/GiftCardFactory.php | 13 +++---------- src/Resources/config/services/factory.xml | 2 +- src/Resources/config/services/fixture.xml | 2 +- src/Resources/config/services/form.xml | 2 +- src/Resources/config/services/serializer.xml | 2 +- .../Normalizer/GiftCardConfigurationNormalizer.php | 11 +++++++++-- src/Serializer/Normalizer/GiftCardNormalizer.php | 11 +++++++++-- 8 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/DependencyInjection/Compiler/AddAdjustmentsToOrderAdjustmentClearerPass.php b/src/DependencyInjection/Compiler/AddAdjustmentsToOrderAdjustmentClearerPass.php index ceb73b3b..1750df3d 100644 --- a/src/DependencyInjection/Compiler/AddAdjustmentsToOrderAdjustmentClearerPass.php +++ b/src/DependencyInjection/Compiler/AddAdjustmentsToOrderAdjustmentClearerPass.php @@ -7,23 +7,20 @@ use Setono\SyliusGiftCardPlugin\Model\AdjustmentInterface; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Webmozart\Assert\Assert; final class AddAdjustmentsToOrderAdjustmentClearerPass implements CompilerPassInterface { public function process(ContainerBuilder $container): void { - if (!$container->has('sylius.order_processing.order_adjustments_clearer')) { + if (!$container->hasParameter('sylius.order_processing.adjustment_clearing_types')) { return; } - $clearerDefinition = $container->getDefinition('sylius.order_processing.order_adjustments_clearer'); - - $adjustmentsToRemove = $clearerDefinition->getArgument(0); - Assert::isArray($adjustmentsToRemove); + $adjustmentsToRemove = $container->getParameter('sylius.order_processing.adjustment_clearing_types'); + \assert(\is_array($adjustmentsToRemove)); $adjustmentsToRemove[] = AdjustmentInterface::ORDER_GIFT_CARD_ADJUSTMENT; - $clearerDefinition->setArgument(0, $adjustmentsToRemove); + $container->setParameter('sylius.order_processing.adjustment_clearing_types', $adjustmentsToRemove); } } diff --git a/src/Factory/GiftCardFactory.php b/src/Factory/GiftCardFactory.php index c044cf17..2cac0a4d 100644 --- a/src/Factory/GiftCardFactory.php +++ b/src/Factory/GiftCardFactory.php @@ -5,12 +5,11 @@ namespace Setono\SyliusGiftCardPlugin\Factory; use DateTimeImmutable; -use DateTimeInterface; use Setono\SyliusGiftCardPlugin\Generator\GiftCardCodeGeneratorInterface; use Setono\SyliusGiftCardPlugin\Model\GiftCardInterface; use Setono\SyliusGiftCardPlugin\Model\OrderItemUnitInterface; use Setono\SyliusGiftCardPlugin\Provider\GiftCardConfigurationProviderInterface; -use Sylius\Bundle\ShippingBundle\Provider\DateTimeProvider; +use Symfony\Component\Clock\ClockInterface; use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; @@ -24,8 +23,7 @@ public function __construct( private readonly FactoryInterface $decoratedFactory, private readonly GiftCardCodeGeneratorInterface $giftCardCodeGenerator, private readonly GiftCardConfigurationProviderInterface $giftCardConfigurationProvider, - /** @psalm-suppress DeprecatedInterface */ - private readonly DateTimeProvider $dateTimeProvider, + private readonly ClockInterface $clock, private readonly CurrencyContextInterface $currencyContext, ) { } @@ -47,12 +45,7 @@ public function createForChannel(ChannelInterface $channel): GiftCardInterface $channelConfiguration = $this->giftCardConfigurationProvider->getConfigurationForGiftCard($giftCard); $validityPeriod = $channelConfiguration->getDefaultValidityPeriod(); if (null !== $validityPeriod) { - $today = $this->dateTimeProvider->today(); - // Since the interface is types to DateTimeInterface, the modify method does not exist - // whereas it does in DateTime and DateTimeImmutable - Assert::isInstanceOf($today, DateTimeImmutable::class); - /** @var DateTimeInterface $today */ - $today = $today->modify('+' . $validityPeriod); + $today = $this->clock->now()->modify('+' . $validityPeriod); $giftCard->setExpiresAt($today); } diff --git a/src/Resources/config/services/factory.xml b/src/Resources/config/services/factory.xml index 7b1dfadc..094b31a3 100644 --- a/src/Resources/config/services/factory.xml +++ b/src/Resources/config/services/factory.xml @@ -10,7 +10,7 @@ - + diff --git a/src/Resources/config/services/fixture.xml b/src/Resources/config/services/fixture.xml index 71763f39..fc2e3031 100644 --- a/src/Resources/config/services/fixture.xml +++ b/src/Resources/config/services/fixture.xml @@ -19,7 +19,7 @@ - + diff --git a/src/Resources/config/services/form.xml b/src/Resources/config/services/form.xml index 2b17d91b..eb6e07a6 100644 --- a/src/Resources/config/services/form.xml +++ b/src/Resources/config/services/form.xml @@ -63,7 +63,7 @@ %setono_sylius_gift_card.order.model.gift_card_information.class% %setono_sylius_gift_card.form.type.add_to_cart_gift_card_information.validation_groups% - + diff --git a/src/Resources/config/services/serializer.xml b/src/Resources/config/services/serializer.xml index b746ac67..abc728fb 100644 --- a/src/Resources/config/services/serializer.xml +++ b/src/Resources/config/services/serializer.xml @@ -7,7 +7,7 @@ - + diff --git a/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php b/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php index 042630ba..f87198f1 100644 --- a/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php +++ b/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php @@ -8,11 +8,11 @@ use Setono\SyliusGiftCardPlugin\Exception\UnexpectedTypeException; use Setono\SyliusGiftCardPlugin\Model\GiftCardConfigurationInterface; use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Webmozart\Assert\Assert; -final class GiftCardConfigurationNormalizer implements ContextAwareNormalizerInterface +final class GiftCardConfigurationNormalizer implements NormalizerInterface { private ObjectNormalizer $objectNormalizer; @@ -81,4 +81,11 @@ public function supportsNormalization($data, $format = null, array $context = [] true, ); } + + public function getSupportedTypes(?string $format): array + { + return [ + GiftCardConfigurationInterface::class => false, + ]; + } } diff --git a/src/Serializer/Normalizer/GiftCardNormalizer.php b/src/Serializer/Normalizer/GiftCardNormalizer.php index 403eb7d6..e39244c1 100644 --- a/src/Serializer/Normalizer/GiftCardNormalizer.php +++ b/src/Serializer/Normalizer/GiftCardNormalizer.php @@ -8,11 +8,11 @@ use Setono\SyliusGiftCardPlugin\Exception\UnexpectedTypeException; use Setono\SyliusGiftCardPlugin\Model\GiftCardInterface; use Sylius\Bundle\MoneyBundle\Formatter\MoneyFormatterInterface; -use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Webmozart\Assert\Assert; -final class GiftCardNormalizer implements ContextAwareNormalizerInterface +final class GiftCardNormalizer implements NormalizerInterface { private ObjectNormalizer $objectNormalizer; @@ -57,4 +57,11 @@ public function supportsNormalization($data, $format = null, array $context = [] return $data instanceof GiftCardInterface && in_array('setono:sylius-gift-card:render', $groups, true); } + + public function getSupportedTypes(?string $format): array + { + return [ + GiftCardInterface::class => false, + ]; + } } From a1e28e79a0304bfb86a61fed6e9967af4bc98958 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:33:55 +0200 Subject: [PATCH 08/60] Convert Doctrine annotations to PHP 8 attributes in Model traits Symfony 7 / the plugin's Doctrine setup no longer registers the doctrine/annotations reader, so the old @ORM docblock annotations on ProductTrait/OrderTrait/OrderItemUnitTrait were silently ignored - verified via doctrine:schema:create, which produced sylius_product without the giftCard/giftCardAmountConfigurable columns and no setono_sylius_gift_card__order_gift_cards join table. Both are present after converting to attributes. --- src/Model/OrderItemUnitTrait.php | 2 +- src/Model/OrderTrait.php | 13 +++++-------- src/Model/ProductTrait.php | 4 ++-- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Model/OrderItemUnitTrait.php b/src/Model/OrderItemUnitTrait.php index 80cf5cd6..cb4d41b9 100644 --- a/src/Model/OrderItemUnitTrait.php +++ b/src/Model/OrderItemUnitTrait.php @@ -8,7 +8,7 @@ trait OrderItemUnitTrait { - /** @ORM\OneToOne (targetEntity="Setono\SyliusGiftCardPlugin\Model\GiftCardInterface", mappedBy="orderItemUnit") */ + #[ORM\OneToOne(targetEntity: GiftCardInterface::class, mappedBy: 'orderItemUnit')] protected ?GiftCardInterface $giftCard = null; public function getGiftCard(): ?GiftCardInterface diff --git a/src/Model/OrderTrait.php b/src/Model/OrderTrait.php index e28519a2..cfa5b2a8 100644 --- a/src/Model/OrderTrait.php +++ b/src/Model/OrderTrait.php @@ -16,15 +16,12 @@ trait OrderTrait { /** - * @var Collection|GiftCardInterface[] - * - * @ORM\ManyToMany(targetEntity="Setono\SyliusGiftCardPlugin\Model\GiftCardInterface", inversedBy="appliedOrders") - * - * @ORM\JoinTable(name="setono_sylius_gift_card__order_gift_cards", - * joinColumns={@ORM\JoinColumn(name="order_id", referencedColumnName="id", onDelete="CASCADE")}, - * inverseJoinColumns={@ORM\JoinColumn(name="gift_card_id", referencedColumnName="id", onDelete="CASCADE")} - * ) + * @var Collection */ + #[ORM\ManyToMany(targetEntity: GiftCardInterface::class, inversedBy: 'appliedOrders')] + #[ORM\JoinTable(name: 'setono_sylius_gift_card__order_gift_cards')] + #[ORM\JoinColumn(name: 'order_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\InverseJoinColumn(name: 'gift_card_id', referencedColumnName: 'id', onDelete: 'CASCADE')] protected Collection $giftCards; public function __construct() diff --git a/src/Model/ProductTrait.php b/src/Model/ProductTrait.php index e4bad295..34a04c3a 100644 --- a/src/Model/ProductTrait.php +++ b/src/Model/ProductTrait.php @@ -8,10 +8,10 @@ trait ProductTrait { - /** @ORM\Column(type="boolean", options={"default": false}) */ + #[ORM\Column(type: 'boolean', options: ['default' => false])] protected bool $giftCard = false; - /** @ORM\Column(type="boolean", options={"default": false}) */ + #[ORM\Column(type: 'boolean', options: ['default' => false])] protected bool $giftCardAmountConfigurable = false; public function isGiftCard(): bool From 3ce54a83184db55647e24be39bb86640b0648576 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:34:25 +0200 Subject: [PATCH 09/60] Fix ECS style (import order, doc comment) --- src/Factory/GiftCardFactory.php | 2 +- src/Model/OrderTrait.php | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Factory/GiftCardFactory.php b/src/Factory/GiftCardFactory.php index 2cac0a4d..3371a7b5 100644 --- a/src/Factory/GiftCardFactory.php +++ b/src/Factory/GiftCardFactory.php @@ -9,12 +9,12 @@ use Setono\SyliusGiftCardPlugin\Model\GiftCardInterface; use Setono\SyliusGiftCardPlugin\Model\OrderItemUnitInterface; use Setono\SyliusGiftCardPlugin\Provider\GiftCardConfigurationProviderInterface; -use Symfony\Component\Clock\ClockInterface; use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Currency\Context\CurrencyContextInterface; use Sylius\Component\Resource\Factory\FactoryInterface; +use Symfony\Component\Clock\ClockInterface; use Webmozart\Assert\Assert; final class GiftCardFactory implements GiftCardFactoryInterface diff --git a/src/Model/OrderTrait.php b/src/Model/OrderTrait.php index cfa5b2a8..5c91d127 100644 --- a/src/Model/OrderTrait.php +++ b/src/Model/OrderTrait.php @@ -15,9 +15,7 @@ */ trait OrderTrait { - /** - * @var Collection - */ + /** @var Collection */ #[ORM\ManyToMany(targetEntity: GiftCardInterface::class, inversedBy: 'appliedOrders')] #[ORM\JoinTable(name: 'setono_sylius_gift_card__order_gift_cards')] #[ORM\JoinColumn(name: 'order_id', referencedColumnName: 'id', onDelete: 'CASCADE')] From 91133b0e0eac75e34a6ee981dceb02a362969913 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:39:00 +0200 Subject: [PATCH 10/60] Fix psalm errors surfaced by Sylius 2/Symfony 7/newer psalm - psalm.xml: ignore tests/TestApplication instead of tests/Application, drop suppressions for the removed ApiPlatform interfaces, add scoped suppressions for Configuration.php's NodeBuilder generic invariance and the deprecated XmlFileLoader - psalm-baseline.xml: drop the single entry, it was for the now-deleted ApiPlatform upload action - CancelOrderGiftCardListener: assert against the plugin's own OrderInterface (needed by OrderGiftCardAmountModifierInterface), not Sylius core's - GiftCardFactory: assert clock->now()->modify() didn't return false - normalizers: NormalizerInterface requires the first param be named $data - StringFieldType/GiftCardVoter: add missing param types (mixed) - GiftCardConfigurationRepository: QueryBuilder::setParameters() now requires an ArrayCollection, not an associative array - switched to chained setParameter() calls --- psalm-baseline.xml | 6 ------ psalm.xml | 18 +++++++++--------- .../ORM/GiftCardConfigurationRepository.php | 6 ++---- .../Workflow/CancelOrderGiftCardListener.php | 2 +- src/Factory/GiftCardFactory.php | 1 + src/Grid/FieldTypes/StringFieldType.php | 2 +- src/Security/GiftCardVoter.php | 10 ++++------ .../GiftCardConfigurationNormalizer.php | 15 ++++++--------- .../Normalizer/GiftCardNormalizer.php | 15 ++++++--------- 9 files changed, 30 insertions(+), 45 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 14bad85e..f4acb63c 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,9 +1,3 @@ - - - LegacyIriConverterInterface|IriConverterInterface - LegacyIriConverterInterface|IriConverterInterface - - diff --git a/psalm.xml b/psalm.xml index 6962ce05..03408942 100644 --- a/psalm.xml +++ b/psalm.xml @@ -15,7 +15,7 @@ - + @@ -31,11 +31,16 @@ - + - + - + + + + + + @@ -46,10 +51,5 @@ - - - - - diff --git a/src/Doctrine/ORM/GiftCardConfigurationRepository.php b/src/Doctrine/ORM/GiftCardConfigurationRepository.php index 951e2030..e88e0d4f 100644 --- a/src/Doctrine/ORM/GiftCardConfigurationRepository.php +++ b/src/Doctrine/ORM/GiftCardConfigurationRepository.php @@ -19,10 +19,8 @@ public function findOneByChannelAndLocale(ChannelInterface $channel, LocaleInter ->join('o.channelConfigurations', 'c') ->andWhere('c.channel = :channel') ->andWhere('c.locale = :locale') - ->setParameters([ - 'channel' => $channel, - 'locale' => $locale, - ]) + ->setParameter('channel', $channel) + ->setParameter('locale', $locale) ->getQuery() ->getOneOrNullResult() ; diff --git a/src/EventListener/Workflow/CancelOrderGiftCardListener.php b/src/EventListener/Workflow/CancelOrderGiftCardListener.php index 8e1bdd2d..66f7661e 100644 --- a/src/EventListener/Workflow/CancelOrderGiftCardListener.php +++ b/src/EventListener/Workflow/CancelOrderGiftCardListener.php @@ -4,9 +4,9 @@ namespace Setono\SyliusGiftCardPlugin\EventListener\Workflow; +use Setono\SyliusGiftCardPlugin\Model\OrderInterface; use Setono\SyliusGiftCardPlugin\Modifier\OrderGiftCardAmountModifierInterface; use Setono\SyliusGiftCardPlugin\Operator\OrderGiftCardOperatorInterface; -use Sylius\Component\Core\Model\OrderInterface; use Symfony\Component\Workflow\Event\CompletedEvent; use Webmozart\Assert\Assert; diff --git a/src/Factory/GiftCardFactory.php b/src/Factory/GiftCardFactory.php index 3371a7b5..8b20f042 100644 --- a/src/Factory/GiftCardFactory.php +++ b/src/Factory/GiftCardFactory.php @@ -46,6 +46,7 @@ public function createForChannel(ChannelInterface $channel): GiftCardInterface $validityPeriod = $channelConfiguration->getDefaultValidityPeriod(); if (null !== $validityPeriod) { $today = $this->clock->now()->modify('+' . $validityPeriod); + Assert::notFalse($today); $giftCard->setExpiresAt($today); } diff --git a/src/Grid/FieldTypes/StringFieldType.php b/src/Grid/FieldTypes/StringFieldType.php index 56876464..ad902eb3 100644 --- a/src/Grid/FieldTypes/StringFieldType.php +++ b/src/Grid/FieldTypes/StringFieldType.php @@ -21,7 +21,7 @@ public function __construct(PropertyAccessorInterface $propertyAccessor) $this->propertyAccessor = $propertyAccessor; } - public function render(Field $field, $data, array $options): string + public function render(Field $field, mixed $data, array $options): string { try { if (!is_object($data) && !is_array($data)) { diff --git a/src/Security/GiftCardVoter.php b/src/Security/GiftCardVoter.php index 2ae72cb4..4a479583 100644 --- a/src/Security/GiftCardVoter.php +++ b/src/Security/GiftCardVoter.php @@ -17,7 +17,7 @@ final class GiftCardVoter extends Voter { public const READ = 'read'; - protected function supports($attribute, $subject): bool + protected function supports(mixed $attribute, mixed $subject): bool { if (self::READ !== $attribute) { return false; @@ -30,12 +30,10 @@ protected function supports($attribute, $subject): bool return true; } - /** - * @param string $attribute - * @param GiftCardInterface $subject - */ - protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool + protected function voteOnAttribute(mixed $attribute, mixed $subject, TokenInterface $token): bool { + Assert::isInstanceOf($subject, GiftCardInterface::class); + /** @var UserInterface|ShopUserInterface|AdminUserInterface|null $user */ $user = $token->getUser(); if (!$user instanceof UserInterface) { diff --git a/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php b/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php index f87198f1..32a6dbd7 100644 --- a/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php +++ b/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php @@ -31,12 +31,13 @@ public function __construct( } /** - * @param GiftCardConfigurationInterface|mixed $object - * @param string $format + * @param GiftCardConfigurationInterface|mixed $data + * @param array $context */ - public function normalize($object, $format = null, array $context = []): array + public function normalize($data, ?string $format = null, array $context = []): array { - Assert::isInstanceOf($object, GiftCardConfigurationInterface::class); + Assert::isInstanceOf($data, GiftCardConfigurationInterface::class); + $object = $data; $data = $this->objectNormalizer->normalize($object, $format, $context); if (!is_array($data) && !$data instanceof ArrayObject) { @@ -67,11 +68,7 @@ public function normalize($object, $format = null, array $context = []): array return $data; } - /** - * @param mixed $data - * @param string $format - */ - public function supportsNormalization($data, $format = null, array $context = []): bool + public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool { $groups = (array) ($context['groups'] ?? []); diff --git a/src/Serializer/Normalizer/GiftCardNormalizer.php b/src/Serializer/Normalizer/GiftCardNormalizer.php index e39244c1..82b49484 100644 --- a/src/Serializer/Normalizer/GiftCardNormalizer.php +++ b/src/Serializer/Normalizer/GiftCardNormalizer.php @@ -25,12 +25,13 @@ public function __construct(ObjectNormalizer $objectNormalizer, MoneyFormatterIn } /** - * @param GiftCardInterface|mixed $object - * @param string $format + * @param GiftCardInterface|mixed $data + * @param array $context */ - public function normalize($object, $format = null, array $context = []): array + public function normalize($data, ?string $format = null, array $context = []): array { - Assert::isInstanceOf($object, GiftCardInterface::class); + Assert::isInstanceOf($data, GiftCardInterface::class); + $object = $data; $data = $this->objectNormalizer->normalize($object, $format, $context); if (!is_array($data) && !$data instanceof ArrayObject) { @@ -47,11 +48,7 @@ public function normalize($object, $format = null, array $context = []): array return $data; } - /** - * @param mixed $data - * @param string $format - */ - public function supportsNormalization($data, $format = null, array $context = []): bool + public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool { $groups = (array) ($context['groups'] ?? []); From 87faf7ede68da14347930f059a09816ea2d20b72 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:42:45 +0200 Subject: [PATCH 11/60] Fix phpunit tests broken by the test-app move and DateTimeProvider removal - Renamed Tests\Application\Model\* references to Tests\TestApplication\Entity\* across the Unit suite, following the tests/TestApplication move - GiftCardFactoryTest: replaced Sylius\Bundle\ShippingBundle\Provider\Calendar/ DateTimeProvider (removed in Sylius 2) with Symfony\Component\Clock\MockClock 2 pre-existing failures in AddToCartTypeExtensionTest are left as-is: the test mocks getProduct()/getVariant() calls that don't match what AddToCartTypeExtension actually calls today (getVariant()?->getProduct()) - confirmed via `git diff 0.12.x` that neither the test nor the source under test changed in this migration, so this is a pre-existing staleness bug, not something introduced by the Sylius 2 upgrade. --- tests/Unit/Factory/GiftCardFactoryTest.php | 25 ++++++++----------- .../Extension/AddToCartTypeExtensionTest.php | 8 +++--- tests/Unit/Model/GiftCardTest.php | 2 +- tests/Unit/Model/OrderItemTraitTest.php | 4 +-- tests/Unit/Model/ProductTraitTest.php | 2 +- tests/Unit/Operator/GiftCardOperatorTest.php | 8 +++--- tests/Unit/Order/AddToCartCommandTest.php | 4 +-- .../Factory/AddToCardCommandFactoryTest.php | 4 +-- .../GiftCardInformationFactoryTest.php | 2 +- .../OrderEligibleTotalProviderTest.php | 2 +- 10 files changed, 29 insertions(+), 32 deletions(-) diff --git a/tests/Unit/Factory/GiftCardFactoryTest.php b/tests/Unit/Factory/GiftCardFactoryTest.php index 94031a27..05f177d7 100644 --- a/tests/Unit/Factory/GiftCardFactoryTest.php +++ b/tests/Unit/Factory/GiftCardFactoryTest.php @@ -12,11 +12,10 @@ use Setono\SyliusGiftCardPlugin\Model\GiftCardConfiguration; use Setono\SyliusGiftCardPlugin\Model\GiftCardInterface; use Setono\SyliusGiftCardPlugin\Provider\GiftCardConfigurationProviderInterface; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Order; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItem; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItemUnit; -use Sylius\Bundle\ShippingBundle\Provider\Calendar; -use Sylius\Bundle\ShippingBundle\Provider\DateTimeProvider; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Order; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItemUnit; +use Symfony\Component\Clock\MockClock; use Sylius\Component\Core\Model\Channel; use Sylius\Component\Core\Model\Customer; use Sylius\Component\Currency\Context\CurrencyContextInterface; @@ -45,7 +44,7 @@ public function it_creates_a_new_gift_card_with_code(): void $decoratedFactory->reveal(), $giftCardCodeGenerator->reveal(), $configurationProvider->reveal(), - new Calendar(), + new MockClock(), $currencyContext->reveal(), ); $createdGiftCard = $factory->createNew(); @@ -75,7 +74,7 @@ public function it_creates_a_new_gift_card_for_channel(): void $decoratedFactory->reveal(), $giftCardCodeGenerator->reveal(), $configurationProvider->reveal(), - new Calendar(), + new MockClock(), $currencyContext->reveal(), ); $createdGiftCard = $factory->createForChannel($channel); @@ -99,19 +98,17 @@ public function it_creates_a_new_gift_card_for_channel_with_expiration_date(): v $decoratedFactory = $this->prophesize(FactoryInterface::class); $giftCardCodeGenerator = $this->prophesize(GiftCardCodeGeneratorInterface::class); $configurationProvider = $this->prophesize(GiftCardConfigurationProviderInterface::class); - $calendar = $this->prophesize(DateTimeProvider::class); $currencyContext = $this->prophesize(CurrencyContextInterface::class); $decoratedFactory->createNew()->willReturn($giftCard); $giftCardCodeGenerator->generate()->willReturn('super-code'); $configurationProvider->getConfigurationForGiftCard($giftCard)->willReturn($giftCardConfiguration); - $calendar->today()->willReturn(new \DateTimeImmutable('2022-01-01 12:00:00')); $factory = new GiftCardFactory( $decoratedFactory->reveal(), $giftCardCodeGenerator->reveal(), $configurationProvider->reveal(), - $calendar->reveal(), + new MockClock('2022-01-01 12:00:00', new \DateTimeZone(date_default_timezone_get())), $currencyContext->reveal(), ); $createdGiftCard = $factory->createForChannel($channel); @@ -142,7 +139,7 @@ public function it_creates_a_new_gift_card_for_channel_from_admin(): void $decoratedFactory->reveal(), $giftCardCodeGenerator->reveal(), $configurationProvider->reveal(), - new Calendar(), + new MockClock(), $currencyContext->reveal(), ); $createdGiftCard = $factory->createForChannelFromAdmin($channel); @@ -179,7 +176,7 @@ public function it_creates_a_new_gift_card_for_order_item_unit_and_cart(): void $decoratedFactory->reveal(), $giftCardCodeGenerator->reveal(), $configurationProvider->reveal(), - new Calendar(), + new MockClock(), $currencyContext->reveal(), ); $createdGiftCard = $factory->createFromOrderItemUnitAndCart($orderItemUnit->reveal(), $cart); @@ -226,7 +223,7 @@ public function it_creates_a_new_gift_card_for_order_item_unit(): void $decoratedFactory->reveal(), $giftCardCodeGenerator->reveal(), $configurationProvider->reveal(), - new Calendar(), + new MockClock(), $currencyContext->reveal(), ); $createdGiftCard = $factory->createFromOrderItemUnit($orderItemUnit->reveal()); @@ -261,7 +258,7 @@ public function it_creates_example_gift_card(): void $decoratedFactory->reveal(), $giftCardCodeGenerator->reveal(), $configurationProvider->reveal(), - new Calendar(), + new MockClock(), $currencyContext->reveal(), ); $returnedGiftCard = $factory->createExample(); diff --git a/tests/Unit/Form/Extension/AddToCartTypeExtensionTest.php b/tests/Unit/Form/Extension/AddToCartTypeExtensionTest.php index f5d988bc..41bed40f 100644 --- a/tests/Unit/Form/Extension/AddToCartTypeExtensionTest.php +++ b/tests/Unit/Form/Extension/AddToCartTypeExtensionTest.php @@ -13,10 +13,10 @@ use Setono\SyliusGiftCardPlugin\Model\GiftCardInterface; use Setono\SyliusGiftCardPlugin\Order\AddToCartCommand; use Setono\SyliusGiftCardPlugin\Order\GiftCardInformationInterface; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Order; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItem; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItemUnit; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Product; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Order; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItemUnit; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Product; use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\ChannelPricingInterface; use Sylius\Component\Core\Model\ProductVariantInterface; diff --git a/tests/Unit/Model/GiftCardTest.php b/tests/Unit/Model/GiftCardTest.php index f9b76d0e..0b7d922a 100644 --- a/tests/Unit/Model/GiftCardTest.php +++ b/tests/Unit/Model/GiftCardTest.php @@ -8,7 +8,7 @@ use Prophecy\PhpUnit\ProphecyTrait; use Setono\SyliusGiftCardPlugin\Model\GiftCard; use Setono\SyliusGiftCardPlugin\Model\OrderItemUnitInterface; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItem; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem; use Sylius\Component\Core\Model\Channel; use Sylius\Component\Core\Model\Customer; use Sylius\Component\Core\Model\Order; diff --git a/tests/Unit/Model/OrderItemTraitTest.php b/tests/Unit/Model/OrderItemTraitTest.php index 336e314f..8cad4e4e 100644 --- a/tests/Unit/Model/OrderItemTraitTest.php +++ b/tests/Unit/Model/OrderItemTraitTest.php @@ -5,8 +5,8 @@ namespace Setono\SyliusGiftCardPlugin\Tests\Unit\Model; use PHPUnit\Framework\TestCase; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItem; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Product; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Product; use Sylius\Component\Core\Model\ProductVariant; final class OrderItemTraitTest extends TestCase diff --git a/tests/Unit/Model/ProductTraitTest.php b/tests/Unit/Model/ProductTraitTest.php index a8148aac..8d1f098e 100644 --- a/tests/Unit/Model/ProductTraitTest.php +++ b/tests/Unit/Model/ProductTraitTest.php @@ -5,7 +5,7 @@ namespace Setono\SyliusGiftCardPlugin\Tests\Unit\Model; use PHPUnit\Framework\TestCase; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Product; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Product; final class ProductTraitTest extends TestCase { diff --git a/tests/Unit/Operator/GiftCardOperatorTest.php b/tests/Unit/Operator/GiftCardOperatorTest.php index 06d42c9a..d8ce5427 100644 --- a/tests/Unit/Operator/GiftCardOperatorTest.php +++ b/tests/Unit/Operator/GiftCardOperatorTest.php @@ -11,10 +11,10 @@ use Setono\SyliusGiftCardPlugin\EmailManager\GiftCardEmailManagerInterface; use Setono\SyliusGiftCardPlugin\Model\GiftCard; use Setono\SyliusGiftCardPlugin\Operator\OrderGiftCardOperator; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Order; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItem; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItemUnit; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Product; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Order; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItemUnit; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Product; use Sylius\Component\Core\Model\Customer; use Sylius\Component\Core\Model\ProductVariant; diff --git a/tests/Unit/Order/AddToCartCommandTest.php b/tests/Unit/Order/AddToCartCommandTest.php index f8be01ec..7eea5d1a 100644 --- a/tests/Unit/Order/AddToCartCommandTest.php +++ b/tests/Unit/Order/AddToCartCommandTest.php @@ -7,8 +7,8 @@ use PHPUnit\Framework\TestCase; use Setono\SyliusGiftCardPlugin\Order\AddToCartCommand; use Setono\SyliusGiftCardPlugin\Order\GiftCardInformation; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Order; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItem; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Order; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem; final class AddToCartCommandTest extends TestCase { diff --git a/tests/Unit/Order/Factory/AddToCardCommandFactoryTest.php b/tests/Unit/Order/Factory/AddToCardCommandFactoryTest.php index a7c4e725..07fc2038 100644 --- a/tests/Unit/Order/Factory/AddToCardCommandFactoryTest.php +++ b/tests/Unit/Order/Factory/AddToCardCommandFactoryTest.php @@ -9,8 +9,8 @@ use Setono\SyliusGiftCardPlugin\Order\Factory\AddToCartCommandFactory; use Setono\SyliusGiftCardPlugin\Order\Factory\GiftCardInformationFactory; use Setono\SyliusGiftCardPlugin\Order\GiftCardInformation; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Order; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItem; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Order; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem; final class AddToCardCommandFactoryTest extends TestCase { diff --git a/tests/Unit/Order/Factory/GiftCardInformationFactoryTest.php b/tests/Unit/Order/Factory/GiftCardInformationFactoryTest.php index 6d2ce10d..0523b8f2 100644 --- a/tests/Unit/Order/Factory/GiftCardInformationFactoryTest.php +++ b/tests/Unit/Order/Factory/GiftCardInformationFactoryTest.php @@ -7,7 +7,7 @@ use PHPUnit\Framework\TestCase; use Setono\SyliusGiftCardPlugin\Order\Factory\GiftCardInformationFactory; use Setono\SyliusGiftCardPlugin\Order\GiftCardInformation; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\OrderItem; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem; final class GiftCardInformationFactoryTest extends TestCase { diff --git a/tests/Unit/Provider/OrderEligibleTotalProviderTest.php b/tests/Unit/Provider/OrderEligibleTotalProviderTest.php index d4e81726..d4b3f85d 100644 --- a/tests/Unit/Provider/OrderEligibleTotalProviderTest.php +++ b/tests/Unit/Provider/OrderEligibleTotalProviderTest.php @@ -8,7 +8,7 @@ use Prophecy\PhpUnit\ProphecyTrait; use Setono\SyliusGiftCardPlugin\Model\GiftCard; use Setono\SyliusGiftCardPlugin\Provider\OrderEligibleTotalProvider; -use Setono\SyliusGiftCardPlugin\Tests\Application\Model\Order; +use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Order; final class OrderEligibleTotalProviderTest extends TestCase { From 49031baf418ec4c90290707ae72290230f954142 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:44:50 +0200 Subject: [PATCH 12/60] Rewrite CI workflow for the single Sylius 2 / PHP 8.4 / Symfony 7.4 target Replaces the old coding-standards/dependency-analysis/static-code-analysis/ unit-tests/integration-tests/code-coverage job matrix (PHP 8.1-8.2 x Symfony 5.4/6.4 x lowest/highest deps) with a single job/matrix-cell modeled on SyliusMailchimpPlugin's build.yml: pins Symfony via extra.symfony.require and Sylius via a direct composer require, runs ecs/psalm/phpspec/phpunit/behat in sequence, uses mirromutth/mysql-action instead of the runner's preinstalled MySQL, and boots the app via vendor/sylius/test-application's own yarn assets. Removed composer-require-checker.json/composer-unused.php - only used by the now-removed dependency-analysis job. --- .github/workflows/build.yaml | 347 +++++++++------------------------- composer-require-checker.json | 20 -- composer-unused.php | 12 -- 3 files changed, 88 insertions(+), 291 deletions(-) delete mode 100644 composer-require-checker.json delete mode 100644 composer-unused.php diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4f085c8f..36ad73ca 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -2,7 +2,7 @@ name: "build" on: push: branches: - - "0.*.x" + - "sylius-2" paths-ignore: - "**/*.md" pull_request: @@ -10,24 +10,27 @@ on: - "**/*.md" workflow_dispatch: ~ -env: - APP_ENV: "test" - DATABASE_URL: "mysql://root:root@127.0.0.1/sylius?serverVersion=8.0" - PHP_EXTENSIONS: "intl, mbstring" - jobs: - coding-standards: - name: "Coding Standards (PHP ${{ matrix.php-version }} | Dependency versions: ${{ matrix.dependencies }})" + tests: + name: "Sylius ${{ matrix.sylius }}, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MySQL ${{ matrix.mysql }}" runs-on: "ubuntu-latest" strategy: + fail-fast: false matrix: - php-version: - - "8.1" # Always use the lowest version of PHP since a higher version would create actual syntax errors in lower versions - - dependencies: - - "highest" + php: ["8.4"] + symfony: ["^7.4"] + sylius: ["~2.2.0"] + node: ["22.x"] + mysql: ["8.4"] + + env: + APP_ENV: "test" + BEHAT_BASE_URL: "https://127.0.0.1:8080/" + BEHAT_CHROME_URL: "http://127.0.0.1:9222" + DATABASE_URL: "mysql://root:root@127.0.0.1/sylius?serverVersion=${{ matrix.mysql }}" + PHP_EXTENSIONS: "intl, mbstring" steps: - name: "Checkout" @@ -36,248 +39,116 @@ jobs: - name: "Setup PHP, with composer and extensions" uses: "shivammathur/setup-php@v2" with: - php-version: "${{ matrix.php-version }}" + php-version: "${{ matrix.php }}" extensions: "${{ env.PHP_EXTENSIONS }}" + tools: "flex,symfony" coverage: "none" - - name: "Install composer dependencies" - uses: "ramsey/composer-install@v3" + - name: "Setup Node" + uses: "actions/setup-node@v4" with: - dependency-versions: "${{ matrix.dependencies }}" - - - name: "Validate composer" - run: "composer validate --strict" - - - name: "Check composer normalized" - run: "composer normalize --dry-run" + node-version: "${{ matrix.node }}" - - name: "Check style" - run: "composer check-style" - - - name: "Lint yaml files" - run: "(cd tests/Application && bin/console lint:yaml ../../src/Resources)" - - - name: "Lint twig files" - run: "(cd tests/Application && bin/console lint:twig ../../src/Resources)" - - dependency-analysis: - name: "Dependency Analysis (PHP ${{ matrix.php-version }} | Dependency versions: ${{ matrix.dependencies }} | Symfony: ${{ matrix.symfony }})" - - runs-on: "ubuntu-latest" + - name: "Shutdown default MySQL" + run: "sudo service mysql stop" - strategy: - matrix: - php-version: - - "8.1" - - "8.2" - - dependencies: - - "lowest" - - "highest" - - symfony: - - "~5.4.0" - - "~6.4.0" - - steps: - - name: "Checkout" - uses: "actions/checkout@v4" - - - name: "Setup PHP, with composer and extensions" - uses: "shivammathur/setup-php@v2" + - name: "Setup MySQL" + uses: "mirromutth/mysql-action@v1.1" with: - coverage: "none" - extensions: "${{ env.PHP_EXTENSIONS }}" - php-version: "${{ matrix.php-version }}" - tools: "composer-require-checker, composer-unused, flex" - - - name: "Remove require-dev section in composer.json" - run: "composer config --unset require-dev" - - - name: "Install composer dependencies" - uses: "ramsey/composer-install@v3" - env: - SYMFONY_REQUIRE: "${{ matrix.symfony }}" - with: - dependency-versions: "${{ matrix.dependencies }}" - - - name: "Run maglnet/composer-require-checker" - run: "composer-require-checker check --config-file=$(pwd)/composer-require-checker.json" - - - name: "Run composer-unused/composer-unused" - run: "composer-unused" - - static-code-analysis: - name: "Static Code Analysis (PHP ${{ matrix.php-version }} | Dependency versions: ${{ matrix.dependencies }} | Symfony: ${{ matrix.symfony }})" + mysql version: "${{ matrix.mysql }}" + mysql root password: "root" - runs-on: "ubuntu-latest" - - strategy: - matrix: - php-version: - - "8.1" - - "8.2" - - dependencies: - - "lowest" - - "highest" + - name: "Output PHP version for Symfony CLI" + run: "php -v | head -n 1 | awk '{ print $2 }' > .php-version" - symfony: - - "~5.4.0" - - "~6.4.0" + - name: "Validate composer" + run: "composer validate --ansi --strict" - steps: - - name: "Checkout" - uses: "actions/checkout@v4" + - name: "Check composer normalized" + run: "composer normalize --dry-run" - - name: "Setup PHP, with composer and extensions" - uses: "shivammathur/setup-php@v2" - with: - coverage: "none" - extensions: "${{ env.PHP_EXTENSIONS }}" - php-version: "${{ matrix.php-version }}" - tools: "flex" + - name: "Get Composer cache directory" + id: "composer-cache" + run: "echo \"dir=$(composer config cache-files-dir)\" >> $GITHUB_OUTPUT" - - name: "Remove sylius/sylius from composer.json" - run: "composer remove --dev --no-update --no-plugins --no-scripts sylius/sylius" - - - name: "Install composer dependencies" - uses: "ramsey/composer-install@v3" - env: - SYMFONY_REQUIRE: "${{ matrix.symfony }}" + - name: "Cache Composer" + uses: "actions/cache@v4" with: - dependency-versions: "${{ matrix.dependencies }}" + path: "${{ steps.composer-cache.outputs.dir }}" + key: "${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json **/composer.lock') }}" + restore-keys: | + ${{ runner.os }}-php-${{ matrix.php }}-composer- - - name: "Static analysis" - run: "vendor/bin/psalm --php-version=${{ matrix.php-version }}" + - name: "Restrict Symfony version" + if: "matrix.symfony != ''" + run: | + composer global require --no-progress --no-scripts --no-plugins "symfony/flex:^2.4" + composer global config --no-plugins allow-plugins.symfony/flex true + composer config extra.symfony.require "${{ matrix.symfony }}" - unit-tests: - name: "Unit tests (PHP ${{ matrix.php-version }} | Dependency versions: ${{ matrix.dependencies }} | Symfony: ${{ matrix.symfony }})" + - name: "Restrict Sylius version" + if: "matrix.sylius != ''" + run: "composer require \"sylius/sylius:${{ matrix.sylius }}\" --no-update --no-scripts --no-interaction" - runs-on: "ubuntu-latest" + - name: "Install composer dependencies" + run: "composer install --no-interaction" - strategy: - matrix: - php-version: - - "8.1" - - "8.2" + - name: "Lint container" + run: "vendor/bin/console lint:container" - dependencies: - - "highest" + - name: "Lint yaml files" + run: "vendor/bin/console lint:yaml src/Resources" - symfony: - - "~5.4.0" - - "~6.4.0" + - name: "Lint twig files" + run: "vendor/bin/console lint:twig src/Resources" - steps: - - name: "Checkout" - uses: "actions/checkout@v4" + - name: "Check style" + run: "composer check-style" - - name: "Setup PHP, with composer and extensions" - uses: "shivammathur/setup-php@v2" - with: - coverage: "none" - extensions: "${{ env.PHP_EXTENSIONS }}" - php-version: "${{ matrix.php-version }}" - tools: "flex" + - name: "Static analysis" + run: "vendor/bin/psalm --no-cache" - - name: "Remove sylius/sylius from composer.json" - run: "composer remove --dev --no-update --no-plugins --no-scripts sylius/sylius" - - - name: "Install composer dependencies" - uses: "ramsey/composer-install@v3" - env: - SYMFONY_REQUIRE: "${{ matrix.symfony }}" - with: - dependency-versions: "${{ matrix.dependencies }}" + - name: "Run phpspec" + run: "vendor/bin/phpspec run --ansi -f progress --no-interaction" - name: "Run phpunit" run: "composer phpunit" - integration-tests: - name: "Integration tests (PHP ${{ matrix.php-version }} | Dependency versions: ${{ matrix.dependencies }} | Symfony: ${{ matrix.symfony }})" - - runs-on: "ubuntu-latest" - - strategy: - matrix: - php-version: - - "8.1" - - "8.2" - - dependencies: - - "highest" - - symfony: - - "~6.4" - - steps: - - name: "Start MySQL" - run: "sudo /etc/init.d/mysql start" - - - name: "Checkout" - uses: "actions/checkout@v4" - - - name: "Setup PHP, with composer and extensions" - uses: "shivammathur/setup-php@v2" - with: - coverage: "none" - extensions: "${{ env.PHP_EXTENSIONS }}" - php-version: "${{ matrix.php-version }}" - tools: "flex,symfony" - - - name: "Setup node" - uses: "actions/setup-node@v4" - with: - node-version: "18" + - name: "Get Yarn cache directory" + id: "yarn-cache" + run: "echo \"dir=$(yarn cache dir)\" >> $GITHUB_OUTPUT" - - name: "Install composer dependencies" - uses: "ramsey/composer-install@v3" - env: - SYMFONY_REQUIRE: "${{ matrix.symfony }}" + - name: "Cache Yarn" + uses: "actions/cache@v4" with: - dependency-versions: "${{ matrix.dependencies }}" - - - name: "Install wkhtmltopdf" - run: "sudo apt-get install wkhtmltopdf" + path: "${{ steps.yarn-cache.outputs.dir }}" + key: "${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/package.json **/yarn.lock') }}" + restore-keys: | + ${{ runner.os }}-node-${{ matrix.node }}-yarn- - - name: "Lint container" - run: '(cd tests/Application && bin/console lint:container)' + - name: "Install JS dependencies" + run: "(cd vendor/sylius/test-application && yarn install)" - name: "Create database" - run: "(cd tests/Application && bin/console doctrine:database:create)" + run: "vendor/bin/console doctrine:database:create -vvv" - name: "Create database schema" - run: "(cd tests/Application && bin/console doctrine:schema:create)" + run: "vendor/bin/console doctrine:schema:create -vvv" - name: "Validate Doctrine mapping" - run: "(cd tests/Application && bin/console doctrine:schema:validate)" - - - name: "Get Yarn cache directory" - id: "yarn-cache" - run: "echo \"::set-output name=dir::$(yarn cache dir)\"" - - - name: "Cache Yarn" - uses: "actions/cache@v2" - with: - path: "${{ steps.yarn-cache.outputs.dir }}" - key: "yarn-${{ hashFiles('**/package.json **/yarn.lock') }}" - restore-keys: "yarn-" - - - name: "Install JS dependencies" - run: "(cd tests/Application && yarn install)" + run: "vendor/bin/console doctrine:schema:validate" - name: "Install assets" - run: "(cd tests/Application && bin/console assets:install public -vvv)" + run: "vendor/bin/console assets:install -vvv" - name: "Build assets" - run: "(cd tests/Application && yarn build)" + run: "(cd vendor/sylius/test-application && yarn build)" - - name: "Output PHP version for Symfony CLI" - run: "php -v | head -n 1 | awk '{ print $2 }' > .php-version" + - name: "Warm up cache" + run: "vendor/bin/console cache:warmup -vvv" - name: "Install certificates" - run: "symfony server:ca:install" + run: "symfony server:ca:install || true" - name: "Run Chrome Headless" run: "google-chrome-stable --enable-automation --disable-background-networking --no-default-browser-check --no-first-run --disable-popup-blocking --disable-default-apps --allow-insecure-localhost --disable-translate --disable-extensions --no-sandbox --enable-features=Metal --headless --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server='direct://' --proxy-bypass-list='*' http://127.0.0.1 > /dev/null 2>&1 &" @@ -290,14 +161,7 @@ jobs: done - name: "Run webserver" - run: "(cd tests/Application && symfony server:start --port=8080 --dir=public --daemon)" - - - name: "Wait for webserver to start" - run: | - until symfony server:list | grep /public > /dev/null 2>&1 - do - sleep 1 - done + run: "symfony server:start --port=8080 --daemon" - name: "Run behat" run: "vendor/bin/behat --colors --strict -vvv --no-interaction || vendor/bin/behat --colors --strict -vvv --no-interaction --rerun" @@ -306,43 +170,8 @@ jobs: uses: "actions/upload-artifact@v4" if: "failure()" with: - name: "Behat logs" + name: "Behat logs - ${{ matrix.sylius }}-${{ github.run_id }}-${{ github.run_number }}" path: "etc/build/" if-no-files-found: "ignore" - - code-coverage: - name: "Code Coverage (PHP ${{ matrix.php-version }} | Dependency versions: ${{ matrix.dependencies }})" - - runs-on: "ubuntu-latest" - - strategy: - matrix: - php-version: - - "8.2" - - dependencies: - - "highest" - - steps: - - name: "Checkout" - uses: "actions/checkout@v4" - - - name: "Setup PHP, with composer and extensions" - uses: "shivammathur/setup-php@v2" - with: - coverage: "pcov" - extensions: "${{ env.PHP_EXTENSIONS }}" - php-version: "${{ matrix.php-version }}" - - - name: "Install composer dependencies" - uses: "ramsey/composer-install@v3" - with: - dependency-versions: "${{ matrix.dependencies }}" - - - name: "Collect code coverage with pcov and phpunit/phpunit" - run: "vendor/bin/phpunit --coverage-clover=.build/logs/clover.xml" - - - name: "Send code coverage report to Codecov.io" - env: - CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}" - run: "bash <(curl -s https://codecov.io/bash)" + compression-level: 6 + overwrite: true diff --git a/composer-require-checker.json b/composer-require-checker.json deleted file mode 100644 index 3cc0b605..00000000 --- a/composer-require-checker.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "symbol-whitelist": [ - "array", - "bool", - "callable", - "false", - "float", - "int", - "iterable", - "null", - "object", - "parent", - "self", - "static", - "string", - "true", - "void", - "ApiPlatform\\Core\\Bridge\\Doctrine\\Orm\\Util\\QueryNameGeneratorInterface" - ] -} diff --git a/composer-unused.php b/composer-unused.php deleted file mode 100644 index c6ffb76c..00000000 --- a/composer-unused.php +++ /dev/null @@ -1,12 +0,0 @@ -addNamedFilter(NamedFilter::fromString('knplabs/knp-snappy-bundle')) - ; -}; From 1fd4d903258035d4d1ebdd1012adfb03f4f15054 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:46:58 +0200 Subject: [PATCH 13/60] Remove dead sylius_template_event() calls (lint:twig failures) sylius_template_event was the Twig function backing the removed SonataBlock-style sylius_ui events system - it no longer exists in Sylius 2. Removed the 3 calls in the shop account gift card index views. Also removed the shipped templates/bundles/SyliusShopBundle/Cart/summary.html.twig reference override: it's the full Sylius 1.x cart summary template (superseded by the sylius_shop.cart.index.content.form.sections.general.summary twig hook added earlier) and its sylius_template_event() call made it fail lint:twig too. --- .../Account/GiftCard/Index/_header.html.twig | 2 -- .../Shop/Account/GiftCard/index.html.twig | 4 --- .../SyliusShopBundle/Cart/summary.html.twig | 35 ------------------- 3 files changed, 41 deletions(-) delete mode 100644 src/Resources/views/templates/bundles/SyliusShopBundle/Cart/summary.html.twig diff --git a/src/Resources/views/Shop/Account/GiftCard/Index/_header.html.twig b/src/Resources/views/Shop/Account/GiftCard/Index/_header.html.twig index baadd430..c99d3f0f 100644 --- a/src/Resources/views/Shop/Account/GiftCard/Index/_header.html.twig +++ b/src/Resources/views/Shop/Account/GiftCard/Index/_header.html.twig @@ -1,5 +1,3 @@

{{ 'setono_sylius_gift_card.ui.gift_cards'|trans }} - - {{ sylius_template_event('setono_sylius_gift_card.shop.account.gift_card.index.header', {'giftCards': resources}) }}

diff --git a/src/Resources/views/Shop/Account/GiftCard/index.html.twig b/src/Resources/views/Shop/Account/GiftCard/index.html.twig index 04f74852..7b38f946 100644 --- a/src/Resources/views/Shop/Account/GiftCard/index.html.twig +++ b/src/Resources/views/Shop/Account/GiftCard/index.html.twig @@ -7,9 +7,5 @@ {% block subcontent %} {% include '@SetonoSyliusGiftCardPlugin/Shop/Account/GiftCard/Index/_header.html.twig' %} - {{ sylius_template_event('setono_sylius_gift_card.shop.account.gift_card.index.after_content_header', {'giftCards': resources}) }} - {{ sylius_grid_render(resources, '@SyliusShop/Grid/_default.html.twig') }} - - {{ sylius_template_event('setono_sylius_gift_card.shop.account.gift_card.index.after_grid', {'giftCards': resources}) }} {% endblock %} diff --git a/src/Resources/views/templates/bundles/SyliusShopBundle/Cart/summary.html.twig b/src/Resources/views/templates/bundles/SyliusShopBundle/Cart/summary.html.twig deleted file mode 100644 index 9acd8d33..00000000 --- a/src/Resources/views/templates/bundles/SyliusShopBundle/Cart/summary.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{# @var \Setono\SyliusGiftCardPlugin\Model\OrderInterface cart #} -{% import "@SyliusShop/Common/Macro/money.html.twig" as money %} - -{% set giftCardAdjustment = constant('Setono\\SyliusGiftCardPlugin\\Model\\AdjustmentInterface::ORDER_GIFT_CARD_ADJUSTMENT') %} -{% set giftCardAdjustments = cart.getAdjustments(giftCardAdjustment) %} - -{% if giftCardAdjustments.count > 0 %} -
- - {{ 'setono_sylius_gift_card.ui.applied_gift_cards'|trans }} - - - {{ sylius_template_event('setono_sylius_gift_card.shop.cart.summary.applied_gift_cards', {'cart': cart}) }} - - - - {% for adjustment in giftCardAdjustments %} - {# @var \Setono\SyliusGiftCardPlugin\Model\AdjustmentInterface adjustment #} - - - - - {% endfor %} - -
- {{ adjustment.originCode }} - - - - - - {{ money.convertAndFormat(-adjustment.amount) }} -
-
-{% endif %} From 0ebe7a4f5d1b6d6938457d12dcc8e5525b7c6259 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 10:47:44 +0200 Subject: [PATCH 14/60] Fix ECS import order --- tests/Unit/Factory/GiftCardFactoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Factory/GiftCardFactoryTest.php b/tests/Unit/Factory/GiftCardFactoryTest.php index 05f177d7..09be4625 100644 --- a/tests/Unit/Factory/GiftCardFactoryTest.php +++ b/tests/Unit/Factory/GiftCardFactoryTest.php @@ -15,11 +15,11 @@ use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\Order; use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItem; use Setono\SyliusGiftCardPlugin\Tests\TestApplication\Entity\OrderItemUnit; -use Symfony\Component\Clock\MockClock; use Sylius\Component\Core\Model\Channel; use Sylius\Component\Core\Model\Customer; use Sylius\Component\Currency\Context\CurrencyContextInterface; use Sylius\Component\Resource\Factory\FactoryInterface; +use Symfony\Component\Clock\MockClock; final class GiftCardFactoryTest extends TestCase { From 77d9ebc0146d95ea524ac88717a74da735239597 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 12:37:08 +0200 Subject: [PATCH 15/60] Add Docker Compose setup, modeled on SyliusMailchimpPlugin compose.yml (php/mysql/nginx/chrome/chrome-proxy/mailhog), compose.override.dist.yml (dev overrides: xdebug, port 80 for nginx, node build), compose.test.yml (APP_ENV=test for behat.sh). Same images/ports as the Mailchimp plugin, just renamed the MySQL volume and DATABASE_URL to this plugin's db name. --- .dockerignore | 32 +++++++++++++++++ .gitignore | 6 ++++ behat.sh | 29 +++++++++++++++ compose.override.dist.yml | 66 ++++++++++++++++++++++++++++++++++ compose.test.yml | 4 +++ compose.yml | 40 +++++++++++++++++++++ docker/nginx/chrome-proxy.conf | 22 ++++++++++++ docker/xdebug.ini | 5 +++ 8 files changed, 204 insertions(+) create mode 100644 .dockerignore create mode 100755 behat.sh create mode 100644 compose.override.dist.yml create mode 100644 compose.test.yml create mode 100644 compose.yml create mode 100644 docker/nginx/chrome-proxy.conf create mode 100644 docker/xdebug.ini diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..81d9a543 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,32 @@ +**/*.log +**/*.md +**/*.php~ +**/._* +**/.dockerignore +**/.DS_Store +**/.git/ +**/.gitattributes +**/.github +**/.gitignore +**/.gitkeep +**/.gitmodules +**/.idea +**/Dockerfile +**/Thumbs.db +**/docker-compose*.yaml +**/docker-compose*.yml +.editorconfig +.php_cs.cache +.travis.yml +composer.phar +docker/mysql/data/ +etc/build/* +node_modules/ +var/* +vendor/ +public/assets/ +public/build/ +public/bundles/ +public/css/ +public/js/ +public/media/ diff --git a/.gitignore b/.gitignore index 1b2c7949..8a497fe2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,9 @@ /phpspec.yml /.phpunit.result.cache .php-version + +/compose.override.yml +/php.ini + +/tests/TestApplication/.env.local +/tests/TestApplication/.env.*.local diff --git a/behat.sh b/behat.sh new file mode 100755 index 00000000..377be24f --- /dev/null +++ b/behat.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Run Behat tests in Docker with APP_ENV=test. +# PHP-FPM is temporarily restarted with APP_ENV=test, then restored to APP_ENV=dev. +# +# Usage: ./behat.sh [behat arguments...] +# Example: ./behat.sh features/shop/applying_gift_card.feature +# ./behat.sh features/shop/applying_gift_card.feature:13 + +set -e + +COMPOSE_FILES="-f compose.yml -f compose.override.yml -f compose.test.yml" + +echo "→ Restarting PHP-FPM with APP_ENV=test..." +docker compose $COMPOSE_FILES up -d --no-deps --wait php + +echo "→ Ensuring Chrome and nginx are running..." +docker compose up -d --wait chrome chrome-proxy +docker compose exec nginx nginx -s reload +sleep 1 + +echo "→ Running Behat..." +docker compose $COMPOSE_FILES exec php vendor/bin/behat "$@" +BEHAT_EXIT=$? + +echo "→ Restoring PHP-FPM with APP_ENV=dev..." +docker compose up -d --no-deps --wait php +docker compose exec nginx nginx -s reload + +exit $BEHAT_EXIT diff --git a/compose.override.dist.yml b/compose.override.dist.yml new file mode 100644 index 00000000..bc1fdaf7 --- /dev/null +++ b/compose.override.dist.yml @@ -0,0 +1,66 @@ +services: + php: + image: ghcr.io/sylius/sylius-php:8.3-fixuid-xdebug-alpine + user: ${DOCKER_USER:-1000:1000} + depends_on: + mysql: + condition: service_healthy + environment: + # You can move these environment variables to your .env.local file + APP_ENV: ${ENV:-prod} + APP_SECRET: EDITME + DATABASE_URL: "mysql://root@mysql/setono_sylius_gift_card_plugin_%kernel.environment%" + MAILER_DSN: smtp://mailhog:1025 + MESSENGER_TRANSPORT_DSN: doctrine://default + SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN: doctrine://default + SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN: doctrine://default?queue_name=main_failed + SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN: doctrine://default?queue_name=catalog_promotion_removal + SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN: doctrine://default?queue_name=catalog_promotion_removal_failed + SYLIUS_MESSENGER_TRANSPORT_PAYMENT_REQUEST_DSN: sync:// + SYLIUS_MESSENGER_TRANSPORT_PAYMENT_REQUEST_FAILED_DSN: sync:// + PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} + XDEBUG_MODE: debug + XDEBUG_CONFIG: >- + client_host=host.docker.internal + client_port=9003 + # This should correspond to the server declared in PHPStorm `Preferences | Languages & Frameworks | PHP | Servers` + # Then PHPStorm will use the corresponding path mappings + PHP_IDE_CONFIG: serverName=sylius + extra_hosts: + - "host.docker.internal:host-gateway" + volumes: + - .:/srv/sylius:rw,cached + # if you develop on Linux, you may use a bind-mounted host directory instead +# - ./var:/srv/sylius/var:rw + - ./public:/srv/sylius/public:rw,delegated + # if you develop on Linux, you may use a bind-mounted host directory instead +# - ./public/media:/srv/sylius/public/media:rw + - public-media:/srv/sylius/public/media:rw + nginx: + environment: + WORKING_DIR: /srv/sylius/vendor/sylius/test-application + volumes: + - .:/srv/sylius:ro + # if you develop on Linux, you may use a bind-mounted host directory instead +# - ./public/media:/srv/sylius/public/media:ro + ports: + - "80:80" + nodejs: + image: node:${NODE_VERSION:-20}-alpine + user: ${DOCKER_USER:-1000:1000} + working_dir: /srv/sylius + entrypoint: [ "/bin/sh","-c" ] + command: + - | + cd vendor/sylius/test-application + yarn install + yarn build + volumes: + - .:/srv/sylius:rw,cached + - ./public:/srv/sylius/public:rw,delegated + mailhog: + ports: + - "8025:8025" + +volumes: + public-media: diff --git a/compose.test.yml b/compose.test.yml new file mode 100644 index 00000000..a7be56cf --- /dev/null +++ b/compose.test.yml @@ -0,0 +1,4 @@ +services: + php: + environment: + APP_ENV: test diff --git a/compose.yml b/compose.yml new file mode 100644 index 00000000..63085f07 --- /dev/null +++ b/compose.yml @@ -0,0 +1,40 @@ +services: + php: + image: ghcr.io/sylius/sylius-php:8.4-alpine + mysql: + image: mysql:8.4 + platform: linux/amd64 + healthcheck: + test: '/usr/bin/mysql --execute "SHOW databases;"' + timeout: 3s + interval: 1s + retries: 10 + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: 1 + cap_add: + - SYS_NICE # prevent "mbind: Operation not permitted" errors + ports: + - ${MYSQL_PORT:-3306}:3306 + volumes: + - setono-sylius-gift-card-plugin-mysql-data:/var/lib/mysql:rw + nginx: + image: ghcr.io/sylius/sylius-nginx:latest + depends_on: + - php + chrome: + image: chromedp/headless-shell:stable + command: --remote-allow-origins=* + + chrome-proxy: + image: nginx:alpine + volumes: + - ./docker/nginx/chrome-proxy.conf:/etc/nginx/conf.d/default.conf:ro + depends_on: + - chrome + + mailhog: + # do not use in production! + image: axllent/mailpit:latest + +volumes: + setono-sylius-gift-card-plugin-mysql-data: diff --git a/docker/nginx/chrome-proxy.conf b/docker/nginx/chrome-proxy.conf new file mode 100644 index 00000000..88e01e57 --- /dev/null +++ b/docker/nginx/chrome-proxy.conf @@ -0,0 +1,22 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 9222; + + sub_filter '"ws://localhost/' '"ws://chrome-proxy:9222/'; + sub_filter_once off; + sub_filter_types application/json; + + location / { + proxy_pass http://chrome:9222; + proxy_set_header Host localhost; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_buffering off; + proxy_read_timeout 86400; + } +} diff --git a/docker/xdebug.ini b/docker/xdebug.ini new file mode 100644 index 00000000..f241f128 --- /dev/null +++ b/docker/xdebug.ini @@ -0,0 +1,5 @@ +zend_extension=xdebug +xdebug.mode=debug +xdebug.start_with_request=yes +xdebug.client_host=host.docker.internal +xdebug.client_port=9003 From baca7259ac1b7b5981ca1b3620522a9616cc58fc Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 12:54:40 +0200 Subject: [PATCH 16/60] Fix docker setup: untrack local-only files, real override.yml, mysql port 33062 - .gitignore now matches SyliusMailchimpPlugin's: /docker/, behat.sh and compose.test.yml are local dev conveniences, not meant to be committed - compose.override.dist.yml rewritten to match Mailchimp's actual (not the stale dist template) compose.override.yml: sylius-php:8.4-xdebug-alpine, working_dir /app, node service for asset building, nginx on 8081 - MySQL port default changed to 33062 - generated the real (gitignored) compose.override.yml from the dist file --- .gitignore | 13 +++--- behat.sh | 29 ------------- compose.override.dist.yml | 75 ++++++++++------------------------ compose.test.yml | 4 -- compose.yml | 2 +- docker/nginx/chrome-proxy.conf | 22 ---------- docker/xdebug.ini | 5 --- 7 files changed, 29 insertions(+), 121 deletions(-) delete mode 100755 behat.sh delete mode 100644 compose.test.yml delete mode 100644 docker/nginx/chrome-proxy.conf delete mode 100644 docker/xdebug.ini diff --git a/.gitignore b/.gitignore index 8a497fe2..e97c7064 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,20 @@ /vendor/ +/var/ /node_modules/ /composer.lock -/var/ +/docker/ /etc/build/* !/etc/build/.gitignore -/tests/Application/yarn.lock - +/.phpunit.result.cache /behat.yml +/behat.sh /phpspec.yml -/.phpunit.result.cache -.php-version - /compose.override.yml +/compose.test.yml + +/.php-version /php.ini /tests/TestApplication/.env.local diff --git a/behat.sh b/behat.sh deleted file mode 100755 index 377be24f..00000000 --- a/behat.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env bash -# Run Behat tests in Docker with APP_ENV=test. -# PHP-FPM is temporarily restarted with APP_ENV=test, then restored to APP_ENV=dev. -# -# Usage: ./behat.sh [behat arguments...] -# Example: ./behat.sh features/shop/applying_gift_card.feature -# ./behat.sh features/shop/applying_gift_card.feature:13 - -set -e - -COMPOSE_FILES="-f compose.yml -f compose.override.yml -f compose.test.yml" - -echo "→ Restarting PHP-FPM with APP_ENV=test..." -docker compose $COMPOSE_FILES up -d --no-deps --wait php - -echo "→ Ensuring Chrome and nginx are running..." -docker compose up -d --wait chrome chrome-proxy -docker compose exec nginx nginx -s reload -sleep 1 - -echo "→ Running Behat..." -docker compose $COMPOSE_FILES exec php vendor/bin/behat "$@" -BEHAT_EXIT=$? - -echo "→ Restoring PHP-FPM with APP_ENV=dev..." -docker compose up -d --no-deps --wait php -docker compose exec nginx nginx -s reload - -exit $BEHAT_EXIT diff --git a/compose.override.dist.yml b/compose.override.dist.yml index bc1fdaf7..b5e94aff 100644 --- a/compose.override.dist.yml +++ b/compose.override.dist.yml @@ -1,66 +1,33 @@ services: php: - image: ghcr.io/sylius/sylius-php:8.3-fixuid-xdebug-alpine - user: ${DOCKER_USER:-1000:1000} - depends_on: - mysql: - condition: service_healthy + image: ghcr.io/sylius/sylius-php:8.4-xdebug-alpine + working_dir: /app + volumes: + - .:/app + - ./docker/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini:ro environment: - # You can move these environment variables to your .env.local file - APP_ENV: ${ENV:-prod} - APP_SECRET: EDITME - DATABASE_URL: "mysql://root@mysql/setono_sylius_gift_card_plugin_%kernel.environment%" - MAILER_DSN: smtp://mailhog:1025 - MESSENGER_TRANSPORT_DSN: doctrine://default - SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN: doctrine://default - SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN: doctrine://default?queue_name=main_failed - SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN: doctrine://default?queue_name=catalog_promotion_removal - SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN: doctrine://default?queue_name=catalog_promotion_removal_failed - SYLIUS_MESSENGER_TRANSPORT_PAYMENT_REQUEST_DSN: sync:// - SYLIUS_MESSENGER_TRANSPORT_PAYMENT_REQUEST_FAILED_DSN: sync:// - PHP_DATE_TIMEZONE: ${PHP_DATE_TIMEZONE:-UTC} - XDEBUG_MODE: debug + APP_ENV: dev + DATABASE_URL: mysql://root@mysql/setono_sylius_gift_card_plugin_%kernel.environment% + BEHAT_BASE_URL: http://nginx/ + BEHAT_CHROME_URL: http://chrome-proxy:9222 XDEBUG_CONFIG: >- client_host=host.docker.internal client_port=9003 - # This should correspond to the server declared in PHPStorm `Preferences | Languages & Frameworks | PHP | Servers` - # Then PHPStorm will use the corresponding path mappings - PHP_IDE_CONFIG: serverName=sylius + PHP_IDE_CONFIG: serverName=SetonoSyliusGiftCardPlugin extra_hosts: - "host.docker.internal:host-gateway" - volumes: - - .:/srv/sylius:rw,cached - # if you develop on Linux, you may use a bind-mounted host directory instead -# - ./var:/srv/sylius/var:rw - - ./public:/srv/sylius/public:rw,delegated - # if you develop on Linux, you may use a bind-mounted host directory instead -# - ./public/media:/srv/sylius/public/media:rw - - public-media:/srv/sylius/public/media:rw + mysql: + ports: + - ${MYSQL_PORT:-33062}:3306 nginx: + ports: + - ${NGINX_PORT:-8081}:80 environment: - WORKING_DIR: /srv/sylius/vendor/sylius/test-application + WORKING_DIR: /app/vendor/sylius/test-application volumes: - - .:/srv/sylius:ro - # if you develop on Linux, you may use a bind-mounted host directory instead -# - ./public/media:/srv/sylius/public/media:ro - ports: - - "80:80" - nodejs: - image: node:${NODE_VERSION:-20}-alpine - user: ${DOCKER_USER:-1000:1000} - working_dir: /srv/sylius - entrypoint: [ "/bin/sh","-c" ] - command: - - | - cd vendor/sylius/test-application - yarn install - yarn build + - .:/app + node: + image: node:22-alpine + working_dir: /app/vendor/sylius/test-application volumes: - - .:/srv/sylius:rw,cached - - ./public:/srv/sylius/public:rw,delegated - mailhog: - ports: - - "8025:8025" - -volumes: - public-media: + - .:/app diff --git a/compose.test.yml b/compose.test.yml deleted file mode 100644 index a7be56cf..00000000 --- a/compose.test.yml +++ /dev/null @@ -1,4 +0,0 @@ -services: - php: - environment: - APP_ENV: test diff --git a/compose.yml b/compose.yml index 63085f07..cf6a7479 100644 --- a/compose.yml +++ b/compose.yml @@ -14,7 +14,7 @@ services: cap_add: - SYS_NICE # prevent "mbind: Operation not permitted" errors ports: - - ${MYSQL_PORT:-3306}:3306 + - ${MYSQL_PORT:-33062}:3306 volumes: - setono-sylius-gift-card-plugin-mysql-data:/var/lib/mysql:rw nginx: diff --git a/docker/nginx/chrome-proxy.conf b/docker/nginx/chrome-proxy.conf deleted file mode 100644 index 88e01e57..00000000 --- a/docker/nginx/chrome-proxy.conf +++ /dev/null @@ -1,22 +0,0 @@ -map $http_upgrade $connection_upgrade { - default upgrade; - '' close; -} - -server { - listen 9222; - - sub_filter '"ws://localhost/' '"ws://chrome-proxy:9222/'; - sub_filter_once off; - sub_filter_types application/json; - - location / { - proxy_pass http://chrome:9222; - proxy_set_header Host localhost; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_buffering off; - proxy_read_timeout 86400; - } -} diff --git a/docker/xdebug.ini b/docker/xdebug.ini deleted file mode 100644 index f241f128..00000000 --- a/docker/xdebug.ini +++ /dev/null @@ -1,5 +0,0 @@ -zend_extension=xdebug -xdebug.mode=debug -xdebug.start_with_request=yes -xdebug.client_host=host.docker.internal -xdebug.client_port=9003 From 112fcf0ea0a5e0d01dc693500501454b85a86288 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 17:35:27 +0200 Subject: [PATCH 17/60] Move src/Resources content to root-level dirs (Sylius 2 convention) Follows SyliusMailchimpPlugin's layout: config/, templates/, translations/, public/ and fixtures/ now live as siblings of src/ at the repo root, instead of nested under src/Resources/{config,views,translations,...} (the Sylius 1.x convention). src/ is now pure PHP. - SetonoSyliusGiftCardPlugin::getPath() now returns the repo root (was the default: the directory containing the bundle class, i.e. src/) - getConfigFilesPath() overridden to config/doctrine/model, since Sylius\Bundle\ResourceBundle\AbstractResourceBundle hardcodes the "Resources/config/doctrine" segment when computing where to look for the plugin's own Doctrine ORM mapping - this plugin uses AbstractResourceBundle (registerResources()) unlike Mailchimp's plain Bundle, so this override is needed on top of the getPath() change - every "@SetonoSyliusGiftCardPlugin/Resources/..." reference (imports in config/*.yaml, tests/TestApplication/config/*) had the "Resources/" segment stripped; SetonoSyliusGiftCardExtension's FileLocator path updated from "../Resources/config" to "../../config" - verified: container lints, doctrine:schema:create still produces the gift-card tables/columns (getConfigFilesPath override works), ecs/psalm clean, phpunit/phpspec results unchanged from before the move Also fixed a real bug this move introduces: Symfony's assets:install command defaults its target to a relative "public" dir checked against the CURRENT WORKING DIRECTORY, not kernel.project_dir - since the plugin repo root now itself contains a public/ dir, running the command from the repo root (as CI does) would self-pollute it with a symlink loop instead of installing into vendor/sylius/test-application/public. Fixed by passing the target explicitly in build.yaml. README.md paths updated to match; dropped the stale "Api platform support" section and "Copy Api Resources" instructions (ApiPlatform was already removed earlier in the migration). CLAUDE.md rewritten to describe the current Sylius 2 architecture instead of the pre-migration Sylius 1.x/ApiPlatform one. --- .github/workflows/build.yaml | 6 +-- CLAUDE.md | 35 +++++++++------ README.md | 40 +++--------------- .../config => config}/app/config.yaml | 4 +- .../config => config}/app/fixtures.yaml | 2 +- .../doctrine/model/GiftCard.orm.xml | 0 .../GiftCardChannelConfiguration.orm.xml | 0 .../model/GiftCardConfiguration.orm.xml | 0 .../model/GiftCardConfigurationImage.orm.xml | 0 {src/Resources/config => config}/grids.yaml | 8 ++-- ...tono_sylius_gift_card_admin_gift_card.yaml | 0 ...ft_card_admin_gift_card_configuration.yaml | 0 ...ylius_gift_card_admin_gift_card_order.yaml | 0 ...etono_sylius_gift_card_shop_gift_card.yaml | 0 {src/Resources/config => config}/routes.yaml | 6 +-- .../config => config}/routes/admin.yaml | 0 .../config => config}/routes/admin_ajax.yaml | 0 .../config => config}/routes/shop.yaml | 0 config/routes_no_locale.yaml | 14 ++++++ .../serialization/Channel.xml | 0 .../serialization/Customer.xml | 0 .../serialization/GiftCard.xml | 0 .../serialization/GiftCardBalance.xml | 0 .../GiftCardChannelConfiguration.xml | 0 .../serialization/GiftCardConfiguration.xml | 0 .../GiftCardConfigurationImage.xml | 0 .../serialization/Product.xml | 0 {src/Resources/config => config}/services.xml | 0 .../config => config}/services/applicator.xml | 0 .../config => config}/services/controller.xml | 0 .../services/event_listener.xml | 0 .../config => config}/services/factory.xml | 0 .../services/field_types.xml | 0 .../config => config}/services/fixture.xml | 0 .../config => config}/services/form.xml | 0 .../config => config}/services/generator.xml | 0 .../config => config}/services/menu.xml | 0 .../config => config}/services/misc.xml | 0 .../config => config}/services/modifier.xml | 0 .../config => config}/services/order.xml | 0 .../services/order_processor.xml | 0 .../services/promotion_rule.xml | 0 .../config => config}/services/provider.xml | 0 .../config => config}/services/renderer.xml | 0 .../config => config}/services/resolver.xml | 0 .../config => config}/services/serializer.xml | 0 .../config => config}/services/twig.xml | 0 .../config => config}/services/validator.xml | 0 .../config => config}/services/voter.xml | 0 .../config => config}/sylius_ui.yaml | 0 .../validation/AddGiftCardToOrderCommand.xml | 0 .../validation/AddToCardCommand.xml | 0 .../AddToCardGiftCardInformation.xml | 0 .../config => config}/validation/GiftCard.xml | 0 .../GiftCardChannelConfiguration.xml | 0 .../validation/GiftCardConfiguration.xml | 0 .../validation/GiftCardConfigurationImage.xml | 0 .../validation/GiftCardSearchCommand.xml | 0 ecs.php | 4 -- .../default_background.png | Bin .../public => public}/setono-logo.png | Bin ...sylius-gift-card-add-gift-card-to-order.js | 0 ...ono-sylius-gift-card-live-pdf-rendering.js | 0 ...ylius-gift-card-send-notification-email.js | 0 .../SetonoSyliusGiftCardExtension.php | 2 +- src/Model/GiftCard.php | 3 -- src/Resources/config/routes_no_locale.yaml | 14 ------ src/SetonoSyliusGiftCardPlugin.php | 10 +++++ .../GiftCard/Create/_javascripts.html.twig | 0 .../GiftCard/Grid/Action/create.html.twig | 0 .../Grid/Action/delete_conditional.html.twig | 0 .../Grid/Action/gift_card_balance.html.twig | 0 .../Grid/Action/list_conditional.html.twig | 0 .../Grid/Action/resend_email.html.twig | 0 .../GiftCard/Grid/Field/amount.html.twig | 0 .../Field/channel_configurations.html.twig | 0 .../GiftCard/Grid/Field/customer.html.twig | 0 .../Grid/Field/item_units_order.html.twig | 0 .../Admin/GiftCard/_form.html.twig | 0 .../Admin/GiftCard/create.html.twig | 0 .../Create/_breadcrumb.html.twig | 0 .../Index/_breadcrumb.html.twig | 0 .../Update/_breadcrumb.html.twig | 0 .../Update/_javascripts.html.twig | 0 .../GiftCardConfiguration/_form.html.twig | 0 .../_javascripts.html.twig | 0 .../Grid/Field/coveredByGiftCards.html.twig | 0 .../Admin/giftCardBalance.html.twig | 0 .../Cart/_giftCard.html.twig | 0 .../Email/giftCardToCustomer.html.twig | 0 .../Email/giftCardsFromOrder.html.twig | 0 .../GiftCard/Grid/Field/amount.html.twig | 0 .../Grid/Field/initial_amount.html.twig | 0 .../GiftCard/Index/_breadcrumb.html.twig | 0 .../Account/GiftCard/Index/_header.html.twig | 0 .../Shop/Account/GiftCard/index.html.twig | 0 .../Cart/Summary/_appliedGiftCards.html.twig | 0 .../Shop/GiftCard/search.html.twig | 0 .../_addToCartGiftCardInformation.html.twig | 0 .../Shop/addGiftCardToOrder.html.twig | 0 .../Form/imagesTheme.html.twig | 0 .../Order/Show/Summary/_totals.html.twig | 0 .../Cart/Summary/_totals.html.twig | 0 .../Checkout/_summary.html.twig | 0 .../Common/Order/Table/_totals.html.twig | 0 tests/TestApplication/config/config.yaml | 4 +- tests/TestApplication/config/routes.yaml | 2 +- .../flashes.da.yml | 0 .../flashes.en.yml | 0 .../flashes.fr.yml | 0 .../messages.da.yml | 0 .../messages.en.yml | 0 .../messages.fr.yml | 0 .../validators.da.yml | 0 .../validators.en.yml | 0 .../validators.fr.yml | 0 116 files changed, 68 insertions(+), 86 deletions(-) rename {src/Resources/config => config}/app/config.yaml (84%) rename {src/Resources/config => config}/app/fixtures.yaml (96%) rename {src/Resources/config => config}/doctrine/model/GiftCard.orm.xml (100%) rename {src/Resources/config => config}/doctrine/model/GiftCardChannelConfiguration.orm.xml (100%) rename {src/Resources/config => config}/doctrine/model/GiftCardConfiguration.orm.xml (100%) rename {src/Resources/config => config}/doctrine/model/GiftCardConfigurationImage.orm.xml (100%) rename {src/Resources/config => config}/grids.yaml (56%) rename {src/Resources/config => config}/grids/setono_sylius_gift_card_admin_gift_card.yaml (100%) rename {src/Resources/config => config}/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml (100%) rename {src/Resources/config => config}/grids/setono_sylius_gift_card_admin_gift_card_order.yaml (100%) rename {src/Resources/config => config}/grids/setono_sylius_gift_card_shop_gift_card.yaml (100%) rename {src/Resources/config => config}/routes.yaml (52%) rename {src/Resources/config => config}/routes/admin.yaml (100%) rename {src/Resources/config => config}/routes/admin_ajax.yaml (100%) rename {src/Resources/config => config}/routes/shop.yaml (100%) create mode 100644 config/routes_no_locale.yaml rename {src/Resources/config => config}/serialization/Channel.xml (100%) rename {src/Resources/config => config}/serialization/Customer.xml (100%) rename {src/Resources/config => config}/serialization/GiftCard.xml (100%) rename {src/Resources/config => config}/serialization/GiftCardBalance.xml (100%) rename {src/Resources/config => config}/serialization/GiftCardChannelConfiguration.xml (100%) rename {src/Resources/config => config}/serialization/GiftCardConfiguration.xml (100%) rename {src/Resources/config => config}/serialization/GiftCardConfigurationImage.xml (100%) rename {src/Resources/config => config}/serialization/Product.xml (100%) rename {src/Resources/config => config}/services.xml (100%) rename {src/Resources/config => config}/services/applicator.xml (100%) rename {src/Resources/config => config}/services/controller.xml (100%) rename {src/Resources/config => config}/services/event_listener.xml (100%) rename {src/Resources/config => config}/services/factory.xml (100%) rename {src/Resources/config => config}/services/field_types.xml (100%) rename {src/Resources/config => config}/services/fixture.xml (100%) rename {src/Resources/config => config}/services/form.xml (100%) rename {src/Resources/config => config}/services/generator.xml (100%) rename {src/Resources/config => config}/services/menu.xml (100%) rename {src/Resources/config => config}/services/misc.xml (100%) rename {src/Resources/config => config}/services/modifier.xml (100%) rename {src/Resources/config => config}/services/order.xml (100%) rename {src/Resources/config => config}/services/order_processor.xml (100%) rename {src/Resources/config => config}/services/promotion_rule.xml (100%) rename {src/Resources/config => config}/services/provider.xml (100%) rename {src/Resources/config => config}/services/renderer.xml (100%) rename {src/Resources/config => config}/services/resolver.xml (100%) rename {src/Resources/config => config}/services/serializer.xml (100%) rename {src/Resources/config => config}/services/twig.xml (100%) rename {src/Resources/config => config}/services/validator.xml (100%) rename {src/Resources/config => config}/services/voter.xml (100%) rename {src/Resources/config => config}/sylius_ui.yaml (100%) rename {src/Resources/config => config}/validation/AddGiftCardToOrderCommand.xml (100%) rename {src/Resources/config => config}/validation/AddToCardCommand.xml (100%) rename {src/Resources/config => config}/validation/AddToCardGiftCardInformation.xml (100%) rename {src/Resources/config => config}/validation/GiftCard.xml (100%) rename {src/Resources/config => config}/validation/GiftCardChannelConfiguration.xml (100%) rename {src/Resources/config => config}/validation/GiftCardConfiguration.xml (100%) rename {src/Resources/config => config}/validation/GiftCardConfigurationImage.xml (100%) rename {src/Resources/config => config}/validation/GiftCardSearchCommand.xml (100%) rename {src/Resources/fixtures => fixtures}/default_background.png (100%) rename {src/Resources/public => public}/setono-logo.png (100%) rename {src/Resources/public => public}/setono-sylius-gift-card-add-gift-card-to-order.js (100%) rename {src/Resources/public => public}/setono-sylius-gift-card-live-pdf-rendering.js (100%) rename {src/Resources/public => public}/setono-sylius-gift-card-send-notification-email.js (100%) delete mode 100644 src/Resources/config/routes_no_locale.yaml rename {src/Resources/views => templates}/Admin/GiftCard/Create/_javascripts.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/Grid/Action/create.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/Grid/Action/delete_conditional.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/Grid/Action/gift_card_balance.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/Grid/Action/list_conditional.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/Grid/Action/resend_email.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/Grid/Field/amount.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/Grid/Field/channel_configurations.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/Grid/Field/customer.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/Grid/Field/item_units_order.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/_form.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCard/create.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCardConfiguration/Create/_breadcrumb.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCardConfiguration/Index/_breadcrumb.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCardConfiguration/Update/_breadcrumb.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCardConfiguration/Update/_javascripts.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCardConfiguration/_form.html.twig (100%) rename {src/Resources/views => templates}/Admin/GiftCardConfiguration/_javascripts.html.twig (100%) rename {src/Resources/views => templates}/Admin/Order/Grid/Field/coveredByGiftCards.html.twig (100%) rename {src/Resources/views => templates}/Admin/giftCardBalance.html.twig (100%) rename {src/Resources/views => templates}/Cart/_giftCard.html.twig (100%) rename {src/Resources/views => templates}/Email/giftCardToCustomer.html.twig (100%) rename {src/Resources/views => templates}/Email/giftCardsFromOrder.html.twig (100%) rename {src/Resources/views => templates}/Shop/Account/GiftCard/Grid/Field/amount.html.twig (100%) rename {src/Resources/views => templates}/Shop/Account/GiftCard/Grid/Field/initial_amount.html.twig (100%) rename {src/Resources/views => templates}/Shop/Account/GiftCard/Index/_breadcrumb.html.twig (100%) rename {src/Resources/views => templates}/Shop/Account/GiftCard/Index/_header.html.twig (100%) rename {src/Resources/views => templates}/Shop/Account/GiftCard/index.html.twig (100%) rename {src/Resources/views => templates}/Shop/Cart/Summary/_appliedGiftCards.html.twig (100%) rename {src/Resources/views => templates}/Shop/GiftCard/search.html.twig (100%) rename {src/Resources/views => templates}/Shop/Product/Show/_addToCartGiftCardInformation.html.twig (100%) rename {src/Resources/views => templates}/Shop/addGiftCardToOrder.html.twig (100%) rename {src/Resources/views => templates}/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig (100%) rename {src/Resources/views => templates}/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig (100%) rename {src/Resources/views => templates}/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig (100%) rename {src/Resources/views => templates}/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig (100%) rename {src/Resources/views => templates}/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig (100%) rename {src/Resources/translations => translations}/flashes.da.yml (100%) rename {src/Resources/translations => translations}/flashes.en.yml (100%) rename {src/Resources/translations => translations}/flashes.fr.yml (100%) rename {src/Resources/translations => translations}/messages.da.yml (100%) rename {src/Resources/translations => translations}/messages.en.yml (100%) rename {src/Resources/translations => translations}/messages.fr.yml (100%) rename {src/Resources/translations => translations}/validators.da.yml (100%) rename {src/Resources/translations => translations}/validators.en.yml (100%) rename {src/Resources/translations => translations}/validators.fr.yml (100%) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 36ad73ca..a71033ae 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -97,10 +97,10 @@ jobs: run: "vendor/bin/console lint:container" - name: "Lint yaml files" - run: "vendor/bin/console lint:yaml src/Resources" + run: "vendor/bin/console lint:yaml config" - name: "Lint twig files" - run: "vendor/bin/console lint:twig src/Resources" + run: "vendor/bin/console lint:twig templates" - name: "Check style" run: "composer check-style" @@ -139,7 +139,7 @@ jobs: run: "vendor/bin/console doctrine:schema:validate" - name: "Install assets" - run: "vendor/bin/console assets:install -vvv" + run: "vendor/bin/console assets:install vendor/sylius/test-application/public -vvv" - name: "Build assets" run: "(cd vendor/sylius/test-application && yarn build)" diff --git a/CLAUDE.md b/CLAUDE.md index 17d78a86..8e1c6788 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project -`setono/sylius-gift-card-plugin` — a Sylius plugin adding gift card functionality (buy gift cards, spend them on orders, check balances, admin management, API Platform support). PHP >= 8.1, Symfony 5.4 || 6.4, Sylius ~1.12. Development branches follow the `0.*.x` naming scheme (current: `0.12.x`). +`setono/sylius-gift-card-plugin` — a Sylius plugin adding gift card functionality (buy gift cards, spend them on orders, check balances, admin management). PHP ^8.2, Symfony ^6.4 || ^7.4, Sylius ^2.0. Development branch: `sylius-2`. + +Note: this plugin does not expose an ApiPlatform API — that layer was dropped during the Sylius 2 migration and is intentionally out of scope. ## Commands @@ -19,38 +21,45 @@ vendor/bin/phpspec run # phpspec specs (spec/ directory) vendor/bin/behat # Behat acceptance tests (requires running test app, see below) ``` -Note: the README mentions `composer tests`, `composer try` and `composer all` — those scripts do not exist in composer.json; use the commands above. - ### Test application -`tests/Application/` contains a full Sylius app used as the kernel for PHPUnit (bootstrap `tests/Application/config/bootstrap.php`) and Behat. Run its console with `(cd tests/Application && bin/console ...)`. Behat (behat.yml.dist) expects the app served at `http://localhost:8080`, a MySQL database, built assets (`yarn install && yarn build` inside tests/Application), and headless Chrome for `@javascript` scenarios — see the `integration-tests` job in `.github/workflows/build.yaml` for the full setup sequence. +`tests/TestApplication/` holds only this plugin's overrides (entity models, repositories, config, template overrides) on top of the `sylius/test-application` package (the actual Sylius 2 test kernel lives in `vendor/sylius/test-application`). Its `.env` sets `SYLIUS_TEST_APP_BUNDLES_REPLACE_PATH`/`SYLIUS_TEST_APP_CONFIGS_TO_IMPORT`/`SYLIUS_TEST_APP_ROUTES_TO_IMPORT`, read by `Sylius\TestApplication\Kernel`. `tests/TestApplication/config/bundles.php` is a full bundle list (not just plugin additions) because the plugin bundle must be registered before `SyliusGridBundle` for its resource parameters to exist when grid config loads — the additive `SYLIUS_TEST_APP_BUNDLES_PATH` env var would append it after core bundles instead. + +Local dev can run entirely in Docker: `compose.yml` + `compose.override.dist.yml` (copy to `compose.override.yml`, gitignored) bring up php/mysql/nginx/chrome/chrome-proxy/mailhog; `behat.sh` runs Behat with `APP_ENV=test` inside the container. `docker/` and `behat.sh`/`compose.test.yml` are gitignored local-dev conveniences, not committed. -CI additionally runs `composer validate --strict`, `composer normalize --dry-run`, `composer-require-checker`, `composer-unused`, yaml/twig/container lints, and Doctrine schema validation. +CI (`.github/workflows/build.yaml`) runs a single job/matrix-cell (PHP 8.4, Symfony ^7.4, Sylius ~2.2.0): composer validate, container/yaml/twig lint, ecs, psalm, phpspec, phpunit, then boots the real app (MySQL, node assets, headless Chrome) and runs Behat. ## Architecture -Namespace `Setono\SyliusGiftCardPlugin\` maps to `src/`; tests are `Setono\SyliusGiftCardPlugin\Tests\` in `tests/`. Bundle class is `src/SetonoSyliusGiftCardPlugin.php`; services are XML files under `src/Resources/config/services/` (one per area: applicator, factory, order_processor, ...) imported by `services.xml`. Resource/grid/route/serializer/API configs also live under `src/Resources/config/`. The bundle must be registered before SyliusGridBundle in host apps (parameter resolution order). +Namespace `Setono\SyliusGiftCardPlugin\` maps to `src/`; tests are `Setono\SyliusGiftCardPlugin\Tests\` in `tests/`. Bundle class is `src/SetonoSyliusGiftCardPlugin.php` — it overrides `getPath()` to return the repo root (not `src/`) and `getConfigFilesPath()` to `config/doctrine/model`, so plugin resources live as root-level siblings of `src/` (Sylius 2 convention, matching `sylius/sylius`'s own plugins), not nested under a Sylius-1.x-style `src/Resources/` tree: + +- `config/` — DI service XML (`services.xml` importing `config/services/*.xml`), `app/config.yaml` (+ `app/fixtures.yaml`), `grids.yaml` (+ `grids/*.yaml`), `routes.yaml`/`routes_no_locale.yaml` (+ `routes/*.yaml`), `sylius_ui.yaml` (now `sylius_twig_hooks` config, despite the filename), `doctrine/model/*.orm.xml`, `serialization/*.xml`, `validation/*.xml` +- `templates/` — Twig views (`Admin/`, `Shop/`, `Email/`, plus `templates/bundles/...` reference overrides for host apps to copy) +- `translations/`, `public/` (assets copied via `assets:install`), `fixtures/` (fixture data files) +- `src/DependencyInjection/SetonoSyliusGiftCardExtension.php` loads `config/services.xml` via a `FileLocator` pointed at `../../config` relative to itself + +The bundle must still be registered before `SyliusGridBundle` in host apps (parameter resolution order) — this is unrelated to the resource-path convention above. ### Domain model `GiftCard` holds a code, `amount`/`initialAmount` (integers, minor units per Sylius money convention), currency, channel, optional customer/expiry, and an enabled toggle. When bought in the shop it is linked 1:1 to an `OrderItemUnit`. `GiftCardConfiguration` (+ `GiftCardChannelConfiguration` join entity) defines per-channel/locale settings: PDF template, default validity period, images. -Host applications integrate by applying the plugin's traits/interfaces to their entities — `ProductTrait` (adds `isGiftCard` and `giftCardAmountConfigurable` flags), `OrderTrait` (applied gift cards collection), `OrderItemTrait`, `OrderItemUnitTrait` (gift card relation), and repository traits in `src/Doctrine/ORM/`. The README documents the exact setup; `tests/Application/` shows a working example. +Host applications integrate by applying the plugin's traits/interfaces to their entities — `ProductTrait` (adds `isGiftCard` and `giftCardAmountConfigurable` flags, PHP attributes not annotations), `OrderTrait` (applied gift cards collection), `OrderItemTrait`, `OrderItemUnitTrait` (gift card relation), and repository traits in `src/Doctrine/ORM/`. The README documents the exact setup; `tests/TestApplication/` shows a working example. ### Two distinct gift card flows -**Buying a gift card** (product flagged as gift card): the gift card entity is created at add-to-cart time via `GiftCardFactory::createFromOrderItemUnitAndCart()` — called from `Form/Extension/AddToCartTypeExtension` (shop form flow, POST_SUBMIT listener) and `Api/CommandHandler/AddItemToCartHandler` (API flow). The card starts disabled; winzou state machine callbacks (`src/Resources/config/state_machine/`) drive its lifecycle through `Operator/OrderGiftCardOperator`: checkout complete → `associateToCustomer`, payment paid → `enable` + `send` (email with PDF), order cancel → `disable`. "Configurable" gift card products let the customer choose the amount. +**Buying a gift card** (product flagged as gift card): the gift card entity is created at add-to-cart time via `GiftCardFactory::createFromOrderItemUnitAndCart()`, called from `Form/Extension/AddToCartTypeExtension` (shop form flow, POST_SUBMIT listener). The card starts disabled; Symfony Workflow event listeners (`src/EventListener/Workflow/*`, tagged on `workflow..completed.`) drive its lifecycle through `Operator/OrderGiftCardOperator`: checkout complete → `associateToCustomer`, payment paid → `enable` + `send` (email with PDF), order cancel → `disable`. Sylius 2 defaults to the `symfony_workflow` state machine adapter (not winzou), which is why these are plain kernel event listeners rather than winzou callback config. "Configurable" gift card products let the customer choose the amount. -**Spending a gift card**: `Applicator/GiftCardApplicator` validates (enabled, not expired, channel matches) and attaches the card to the order, then reprocesses it. `OrderProcessor/OrderGiftCardProcessor` (a Sylius order processor) converts each applied card into a negative order adjustment (`AdjustmentInterface::ORDER_GIFT_CARD_ADJUSTMENT`, origin code = gift card code) capped at the eligible order total. Actual balance mutation happens via state machine callbacks on `Modifier/OrderGiftCardAmountModifier`: decrement on order create, increment back on cancel. Both flows can coexist on one order. - -### API - -API Platform resources are declared in `src/Resources/config/api_resources/` with messenger commands/handlers in `src/Api/Command` and `src/Api/CommandHandler`. The plugin replaces the input of Sylius' shop `add item to cart` operation with its own `AddItemToCart` command (carrying gift card info); host apps must copy/adjust `Order.xml` as described in the README. +**Spending a gift card**: `Applicator/GiftCardApplicator` validates (enabled, not expired, channel matches) and attaches the card to the order, then reprocesses it. `OrderProcessor/OrderGiftCardProcessor` (a Sylius order processor) converts each applied card into a negative order adjustment (`AdjustmentInterface::ORDER_GIFT_CARD_ADJUSTMENT`, origin code = gift card code) capped at the eligible order total. Actual balance mutation happens via the same workflow listeners, calling `Modifier/OrderGiftCardAmountModifier`: decrement on order create, increment back on cancel. Both flows can coexist on one order. ### PDF rendering Gift cards render to PDF via knp-snappy/wkhtmltopdf (`Renderer/PdfRenderer`), with template content and rendering options coming from the gift card's configuration (`Provider/`). Admin supports live preview of example PDFs. +### UI hooks + +Sylius 2 replaced the old `sylius_ui: events:` (SonataBlock-style) system with `sylius/twig-hooks`. `config/sylius_ui.yaml` (filename kept for continuity) now declares `sylius_twig_hooks` entries for the shop add-to-cart gift-card fields and the cart-summary applied-gift-cards block. The admin CRUD javascripts (image preview, live PDF rendering, send-customer-email checkbox) and the shop account gift card index hooks still use the removed block system and need porting to twig-hooks — see the `TODO` comment in `config/app/config.yaml`. + ### Test layout - `tests/Unit/` — PHPUnit (includes DI/config tests using matthiasnoback's symfony-config-test / dependency-injection-test) diff --git a/README.md b/README.md index 89ed61ab..ef9e128c 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,6 @@ can be used for auditing. ![Screenshot showing gift card admin create page](docs/images/admin-gift-card-create.png) -## Api platform support - -Everything related to Gift Card can be done via API. Whether it is admin or shop actions - ## Installation ### Require plugin with composer: @@ -39,7 +35,7 @@ $ composer require setono/sylius-gift-card-plugin # config/packages/setono_sylius_gift_card.yaml imports: # ... - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/config.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/app/config.yaml" } ``` ### (Optional) Import fixtures @@ -50,7 +46,7 @@ If you wish to have some gift cards to play with in your application during deve # config/packages/setono_sylius_gift_card.yaml imports: # ... - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/fixtures.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/app/fixtures.yaml" } ``` ### Import routing: @@ -58,7 +54,7 @@ imports: ```yaml # config/routes.yaml setono_sylius_gift_card: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes.yaml" + resource: "@SetonoSyliusGiftCardPlugin/config/routes.yaml" ``` or if your app doesn't use locales: @@ -66,7 +62,7 @@ or if your app doesn't use locales: ```yaml # config/routes.yaml setono_sylius_gift_card: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes_no_locale.yaml" + resource: "@SetonoSyliusGiftCardPlugin/config/routes_no_locale.yaml" ``` ### Add plugin class to your `bundles.php`: @@ -86,7 +82,7 @@ $bundles = [ ### Copy templates -You will find the templates you need to override in the [test application](https://github.com/Setono/SyliusGiftCardPlugin/tree/master/tests/Application/templates). +You will find the templates you need to override in the [test application](https://github.com/Setono/SyliusGiftCardPlugin/tree/master/tests/TestApplication/templates). ### Extend entities @@ -273,32 +269,6 @@ sylius_product: model: App\Entity\Product\Product ``` -### Copy Api Resources - -Resources declaration that need to be copied are: -* [Order.xml](src/Resources/config/api_resources/Order.xml) - -If you already have them overriden, just change the following routes: - -**[Order.xml](src/Resources/config/api_resources/Order.xml)** -```xml - - PATCH - /shop/orders/{tokenValue}/items - input - Setono\SyliusGiftCardPlugin\Api\Command\AddItemToCart - - shop:cart:read - - - shop:cart:add_item - - - Adds Item to cart - - -``` - ### Update your database: ```bash diff --git a/src/Resources/config/app/config.yaml b/config/app/config.yaml similarity index 84% rename from src/Resources/config/app/config.yaml rename to config/app/config.yaml index 6159de34..413ec0bc 100644 --- a/src/Resources/config/app/config.yaml +++ b/config/app/config.yaml @@ -1,6 +1,6 @@ imports: - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/grids.yaml" } - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/sylius_ui.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/grids.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/sylius_ui.yaml" } sylius_mailer: emails: diff --git a/src/Resources/config/app/fixtures.yaml b/config/app/fixtures.yaml similarity index 96% rename from src/Resources/config/app/fixtures.yaml rename to config/app/fixtures.yaml index db52d513..72a7993b 100644 --- a/src/Resources/config/app/fixtures.yaml +++ b/config/app/fixtures.yaml @@ -35,6 +35,6 @@ sylius_fixtures: custom: default_configuration: code: 'default_configuration' - background_image: '@SetonoSyliusGiftCardPlugin/Resources/fixtures/default_background.png' + background_image: '@SetonoSyliusGiftCardPlugin/fixtures/default_background.png' enabled: true default: true diff --git a/src/Resources/config/doctrine/model/GiftCard.orm.xml b/config/doctrine/model/GiftCard.orm.xml similarity index 100% rename from src/Resources/config/doctrine/model/GiftCard.orm.xml rename to config/doctrine/model/GiftCard.orm.xml diff --git a/src/Resources/config/doctrine/model/GiftCardChannelConfiguration.orm.xml b/config/doctrine/model/GiftCardChannelConfiguration.orm.xml similarity index 100% rename from src/Resources/config/doctrine/model/GiftCardChannelConfiguration.orm.xml rename to config/doctrine/model/GiftCardChannelConfiguration.orm.xml diff --git a/src/Resources/config/doctrine/model/GiftCardConfiguration.orm.xml b/config/doctrine/model/GiftCardConfiguration.orm.xml similarity index 100% rename from src/Resources/config/doctrine/model/GiftCardConfiguration.orm.xml rename to config/doctrine/model/GiftCardConfiguration.orm.xml diff --git a/src/Resources/config/doctrine/model/GiftCardConfigurationImage.orm.xml b/config/doctrine/model/GiftCardConfigurationImage.orm.xml similarity index 100% rename from src/Resources/config/doctrine/model/GiftCardConfigurationImage.orm.xml rename to config/doctrine/model/GiftCardConfigurationImage.orm.xml diff --git a/src/Resources/config/grids.yaml b/config/grids.yaml similarity index 56% rename from src/Resources/config/grids.yaml rename to config/grids.yaml index ed91fe09..628fc6f5 100644 --- a/src/Resources/config/grids.yaml +++ b/config/grids.yaml @@ -1,8 +1,8 @@ imports: - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/grids/setono_sylius_gift_card_admin_gift_card.yaml" } - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml" } - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/grids/setono_sylius_gift_card_admin_gift_card_order.yaml" } - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/grids/setono_sylius_gift_card_shop_gift_card.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/grids/setono_sylius_gift_card_admin_gift_card.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/grids/setono_sylius_gift_card_admin_gift_card_order.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/grids/setono_sylius_gift_card_shop_gift_card.yaml" } sylius_grid: templates: diff --git a/src/Resources/config/grids/setono_sylius_gift_card_admin_gift_card.yaml b/config/grids/setono_sylius_gift_card_admin_gift_card.yaml similarity index 100% rename from src/Resources/config/grids/setono_sylius_gift_card_admin_gift_card.yaml rename to config/grids/setono_sylius_gift_card_admin_gift_card.yaml diff --git a/src/Resources/config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml b/config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml similarity index 100% rename from src/Resources/config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml rename to config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml diff --git a/src/Resources/config/grids/setono_sylius_gift_card_admin_gift_card_order.yaml b/config/grids/setono_sylius_gift_card_admin_gift_card_order.yaml similarity index 100% rename from src/Resources/config/grids/setono_sylius_gift_card_admin_gift_card_order.yaml rename to config/grids/setono_sylius_gift_card_admin_gift_card_order.yaml diff --git a/src/Resources/config/grids/setono_sylius_gift_card_shop_gift_card.yaml b/config/grids/setono_sylius_gift_card_shop_gift_card.yaml similarity index 100% rename from src/Resources/config/grids/setono_sylius_gift_card_shop_gift_card.yaml rename to config/grids/setono_sylius_gift_card_shop_gift_card.yaml diff --git a/src/Resources/config/routes.yaml b/config/routes.yaml similarity index 52% rename from src/Resources/config/routes.yaml rename to config/routes.yaml index cf4a20c6..7c5ede59 100644 --- a/src/Resources/config/routes.yaml +++ b/config/routes.yaml @@ -1,13 +1,13 @@ setono_sylius_gift_card_shop: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes/shop.yaml" + resource: "@SetonoSyliusGiftCardPlugin/config/routes/shop.yaml" prefix: /{_locale} requirements: _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$ setono_sylius_gift_card_admin: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes/admin.yaml" + resource: "@SetonoSyliusGiftCardPlugin/config/routes/admin.yaml" prefix: /admin setono_sylius_gift_card_admin_ajax: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes/admin_ajax.yaml" + resource: "@SetonoSyliusGiftCardPlugin/config/routes/admin_ajax.yaml" prefix: /admin/ajax diff --git a/src/Resources/config/routes/admin.yaml b/config/routes/admin.yaml similarity index 100% rename from src/Resources/config/routes/admin.yaml rename to config/routes/admin.yaml diff --git a/src/Resources/config/routes/admin_ajax.yaml b/config/routes/admin_ajax.yaml similarity index 100% rename from src/Resources/config/routes/admin_ajax.yaml rename to config/routes/admin_ajax.yaml diff --git a/src/Resources/config/routes/shop.yaml b/config/routes/shop.yaml similarity index 100% rename from src/Resources/config/routes/shop.yaml rename to config/routes/shop.yaml diff --git a/config/routes_no_locale.yaml b/config/routes_no_locale.yaml new file mode 100644 index 00000000..ef353138 --- /dev/null +++ b/config/routes_no_locale.yaml @@ -0,0 +1,14 @@ +setono_sylius_gift_card_shop: + resource: "@SetonoSyliusGiftCardPlugin/config/routes/shop.yaml" + +setono_sylius_gift_card_admin: + resource: "@SetonoSyliusGiftCardPlugin/config/routes/admin.yaml" + prefix: /admin + +setono_sylius_gift_card_admin_ajax: + resource: "@SetonoSyliusGiftCardPlugin/config/routes/admin_ajax.yaml" + prefix: /admin/ajax + +setono_sylius_gift_card_admin_api: + resource: "@SetonoSyliusGiftCardPlugin/config/routes/admin_api.yaml" + prefix: /api/v{version} diff --git a/src/Resources/config/serialization/Channel.xml b/config/serialization/Channel.xml similarity index 100% rename from src/Resources/config/serialization/Channel.xml rename to config/serialization/Channel.xml diff --git a/src/Resources/config/serialization/Customer.xml b/config/serialization/Customer.xml similarity index 100% rename from src/Resources/config/serialization/Customer.xml rename to config/serialization/Customer.xml diff --git a/src/Resources/config/serialization/GiftCard.xml b/config/serialization/GiftCard.xml similarity index 100% rename from src/Resources/config/serialization/GiftCard.xml rename to config/serialization/GiftCard.xml diff --git a/src/Resources/config/serialization/GiftCardBalance.xml b/config/serialization/GiftCardBalance.xml similarity index 100% rename from src/Resources/config/serialization/GiftCardBalance.xml rename to config/serialization/GiftCardBalance.xml diff --git a/src/Resources/config/serialization/GiftCardChannelConfiguration.xml b/config/serialization/GiftCardChannelConfiguration.xml similarity index 100% rename from src/Resources/config/serialization/GiftCardChannelConfiguration.xml rename to config/serialization/GiftCardChannelConfiguration.xml diff --git a/src/Resources/config/serialization/GiftCardConfiguration.xml b/config/serialization/GiftCardConfiguration.xml similarity index 100% rename from src/Resources/config/serialization/GiftCardConfiguration.xml rename to config/serialization/GiftCardConfiguration.xml diff --git a/src/Resources/config/serialization/GiftCardConfigurationImage.xml b/config/serialization/GiftCardConfigurationImage.xml similarity index 100% rename from src/Resources/config/serialization/GiftCardConfigurationImage.xml rename to config/serialization/GiftCardConfigurationImage.xml diff --git a/src/Resources/config/serialization/Product.xml b/config/serialization/Product.xml similarity index 100% rename from src/Resources/config/serialization/Product.xml rename to config/serialization/Product.xml diff --git a/src/Resources/config/services.xml b/config/services.xml similarity index 100% rename from src/Resources/config/services.xml rename to config/services.xml diff --git a/src/Resources/config/services/applicator.xml b/config/services/applicator.xml similarity index 100% rename from src/Resources/config/services/applicator.xml rename to config/services/applicator.xml diff --git a/src/Resources/config/services/controller.xml b/config/services/controller.xml similarity index 100% rename from src/Resources/config/services/controller.xml rename to config/services/controller.xml diff --git a/src/Resources/config/services/event_listener.xml b/config/services/event_listener.xml similarity index 100% rename from src/Resources/config/services/event_listener.xml rename to config/services/event_listener.xml diff --git a/src/Resources/config/services/factory.xml b/config/services/factory.xml similarity index 100% rename from src/Resources/config/services/factory.xml rename to config/services/factory.xml diff --git a/src/Resources/config/services/field_types.xml b/config/services/field_types.xml similarity index 100% rename from src/Resources/config/services/field_types.xml rename to config/services/field_types.xml diff --git a/src/Resources/config/services/fixture.xml b/config/services/fixture.xml similarity index 100% rename from src/Resources/config/services/fixture.xml rename to config/services/fixture.xml diff --git a/src/Resources/config/services/form.xml b/config/services/form.xml similarity index 100% rename from src/Resources/config/services/form.xml rename to config/services/form.xml diff --git a/src/Resources/config/services/generator.xml b/config/services/generator.xml similarity index 100% rename from src/Resources/config/services/generator.xml rename to config/services/generator.xml diff --git a/src/Resources/config/services/menu.xml b/config/services/menu.xml similarity index 100% rename from src/Resources/config/services/menu.xml rename to config/services/menu.xml diff --git a/src/Resources/config/services/misc.xml b/config/services/misc.xml similarity index 100% rename from src/Resources/config/services/misc.xml rename to config/services/misc.xml diff --git a/src/Resources/config/services/modifier.xml b/config/services/modifier.xml similarity index 100% rename from src/Resources/config/services/modifier.xml rename to config/services/modifier.xml diff --git a/src/Resources/config/services/order.xml b/config/services/order.xml similarity index 100% rename from src/Resources/config/services/order.xml rename to config/services/order.xml diff --git a/src/Resources/config/services/order_processor.xml b/config/services/order_processor.xml similarity index 100% rename from src/Resources/config/services/order_processor.xml rename to config/services/order_processor.xml diff --git a/src/Resources/config/services/promotion_rule.xml b/config/services/promotion_rule.xml similarity index 100% rename from src/Resources/config/services/promotion_rule.xml rename to config/services/promotion_rule.xml diff --git a/src/Resources/config/services/provider.xml b/config/services/provider.xml similarity index 100% rename from src/Resources/config/services/provider.xml rename to config/services/provider.xml diff --git a/src/Resources/config/services/renderer.xml b/config/services/renderer.xml similarity index 100% rename from src/Resources/config/services/renderer.xml rename to config/services/renderer.xml diff --git a/src/Resources/config/services/resolver.xml b/config/services/resolver.xml similarity index 100% rename from src/Resources/config/services/resolver.xml rename to config/services/resolver.xml diff --git a/src/Resources/config/services/serializer.xml b/config/services/serializer.xml similarity index 100% rename from src/Resources/config/services/serializer.xml rename to config/services/serializer.xml diff --git a/src/Resources/config/services/twig.xml b/config/services/twig.xml similarity index 100% rename from src/Resources/config/services/twig.xml rename to config/services/twig.xml diff --git a/src/Resources/config/services/validator.xml b/config/services/validator.xml similarity index 100% rename from src/Resources/config/services/validator.xml rename to config/services/validator.xml diff --git a/src/Resources/config/services/voter.xml b/config/services/voter.xml similarity index 100% rename from src/Resources/config/services/voter.xml rename to config/services/voter.xml diff --git a/src/Resources/config/sylius_ui.yaml b/config/sylius_ui.yaml similarity index 100% rename from src/Resources/config/sylius_ui.yaml rename to config/sylius_ui.yaml diff --git a/src/Resources/config/validation/AddGiftCardToOrderCommand.xml b/config/validation/AddGiftCardToOrderCommand.xml similarity index 100% rename from src/Resources/config/validation/AddGiftCardToOrderCommand.xml rename to config/validation/AddGiftCardToOrderCommand.xml diff --git a/src/Resources/config/validation/AddToCardCommand.xml b/config/validation/AddToCardCommand.xml similarity index 100% rename from src/Resources/config/validation/AddToCardCommand.xml rename to config/validation/AddToCardCommand.xml diff --git a/src/Resources/config/validation/AddToCardGiftCardInformation.xml b/config/validation/AddToCardGiftCardInformation.xml similarity index 100% rename from src/Resources/config/validation/AddToCardGiftCardInformation.xml rename to config/validation/AddToCardGiftCardInformation.xml diff --git a/src/Resources/config/validation/GiftCard.xml b/config/validation/GiftCard.xml similarity index 100% rename from src/Resources/config/validation/GiftCard.xml rename to config/validation/GiftCard.xml diff --git a/src/Resources/config/validation/GiftCardChannelConfiguration.xml b/config/validation/GiftCardChannelConfiguration.xml similarity index 100% rename from src/Resources/config/validation/GiftCardChannelConfiguration.xml rename to config/validation/GiftCardChannelConfiguration.xml diff --git a/src/Resources/config/validation/GiftCardConfiguration.xml b/config/validation/GiftCardConfiguration.xml similarity index 100% rename from src/Resources/config/validation/GiftCardConfiguration.xml rename to config/validation/GiftCardConfiguration.xml diff --git a/src/Resources/config/validation/GiftCardConfigurationImage.xml b/config/validation/GiftCardConfigurationImage.xml similarity index 100% rename from src/Resources/config/validation/GiftCardConfigurationImage.xml rename to config/validation/GiftCardConfigurationImage.xml diff --git a/src/Resources/config/validation/GiftCardSearchCommand.xml b/config/validation/GiftCardSearchCommand.xml similarity index 100% rename from src/Resources/config/validation/GiftCardSearchCommand.xml rename to config/validation/GiftCardSearchCommand.xml diff --git a/ecs.php b/ecs.php index 6e01c257..6397e610 100644 --- a/ecs.php +++ b/ecs.php @@ -10,8 +10,4 @@ 'src', 'tests', ]); - $config->skip([ - 'tests/Application/node_modules/**', - 'tests/Application/var/**', - ]); }; diff --git a/src/Resources/fixtures/default_background.png b/fixtures/default_background.png similarity index 100% rename from src/Resources/fixtures/default_background.png rename to fixtures/default_background.png diff --git a/src/Resources/public/setono-logo.png b/public/setono-logo.png similarity index 100% rename from src/Resources/public/setono-logo.png rename to public/setono-logo.png diff --git a/src/Resources/public/setono-sylius-gift-card-add-gift-card-to-order.js b/public/setono-sylius-gift-card-add-gift-card-to-order.js similarity index 100% rename from src/Resources/public/setono-sylius-gift-card-add-gift-card-to-order.js rename to public/setono-sylius-gift-card-add-gift-card-to-order.js diff --git a/src/Resources/public/setono-sylius-gift-card-live-pdf-rendering.js b/public/setono-sylius-gift-card-live-pdf-rendering.js similarity index 100% rename from src/Resources/public/setono-sylius-gift-card-live-pdf-rendering.js rename to public/setono-sylius-gift-card-live-pdf-rendering.js diff --git a/src/Resources/public/setono-sylius-gift-card-send-notification-email.js b/public/setono-sylius-gift-card-send-notification-email.js similarity index 100% rename from src/Resources/public/setono-sylius-gift-card-send-notification-email.js rename to public/setono-sylius-gift-card-send-notification-email.js diff --git a/src/DependencyInjection/SetonoSyliusGiftCardExtension.php b/src/DependencyInjection/SetonoSyliusGiftCardExtension.php index 5d603e8d..edf8ddf4 100644 --- a/src/DependencyInjection/SetonoSyliusGiftCardExtension.php +++ b/src/DependencyInjection/SetonoSyliusGiftCardExtension.php @@ -30,7 +30,7 @@ public function load(array $configs, ContainerBuilder $container): void * @psalm-suppress PossiblyNullArgument */ $config = $this->processConfiguration($this->getConfiguration([], $container), $configs); - $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../../config')); $container->setParameter('setono_sylius_gift_card.code_length', $config['code_length']); $container->setParameter( diff --git a/src/Model/GiftCard.php b/src/Model/GiftCard.php index 9bbf37b2..26c70120 100644 --- a/src/Model/GiftCard.php +++ b/src/Model/GiftCard.php @@ -210,9 +210,6 @@ public function setChannel(ChannelInterface $channel): void $this->channel = $channel; } - /** - * API specific methods. See src/Resources/config/serializer/Model.GiftCard.yml - */ public function getCustomerIdentification(): ?array { $customer = $this->getCustomer(); diff --git a/src/Resources/config/routes_no_locale.yaml b/src/Resources/config/routes_no_locale.yaml deleted file mode 100644 index 988acf3d..00000000 --- a/src/Resources/config/routes_no_locale.yaml +++ /dev/null @@ -1,14 +0,0 @@ -setono_sylius_gift_card_shop: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes/shop.yaml" - -setono_sylius_gift_card_admin: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes/admin.yaml" - prefix: /admin - -setono_sylius_gift_card_admin_ajax: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes/admin_ajax.yaml" - prefix: /admin/ajax - -setono_sylius_gift_card_admin_api: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes/admin_api.yaml" - prefix: /api/v{version} diff --git a/src/SetonoSyliusGiftCardPlugin.php b/src/SetonoSyliusGiftCardPlugin.php index 6535c739..d19b0d1d 100644 --- a/src/SetonoSyliusGiftCardPlugin.php +++ b/src/SetonoSyliusGiftCardPlugin.php @@ -29,4 +29,14 @@ public function getSupportedDrivers(): array SyliusResourceBundle::DRIVER_DOCTRINE_ORM, ]; } + + public function getPath(): string + { + return \dirname(__DIR__); + } + + protected function getConfigFilesPath(): string + { + return sprintf('%s/config/doctrine/%s', $this->getPath(), strtolower($this->getDoctrineMappingDirectory())); + } } diff --git a/src/Resources/views/Admin/GiftCard/Create/_javascripts.html.twig b/templates/Admin/GiftCard/Create/_javascripts.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Create/_javascripts.html.twig rename to templates/Admin/GiftCard/Create/_javascripts.html.twig diff --git a/src/Resources/views/Admin/GiftCard/Grid/Action/create.html.twig b/templates/Admin/GiftCard/Grid/Action/create.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Grid/Action/create.html.twig rename to templates/Admin/GiftCard/Grid/Action/create.html.twig diff --git a/src/Resources/views/Admin/GiftCard/Grid/Action/delete_conditional.html.twig b/templates/Admin/GiftCard/Grid/Action/delete_conditional.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Grid/Action/delete_conditional.html.twig rename to templates/Admin/GiftCard/Grid/Action/delete_conditional.html.twig diff --git a/src/Resources/views/Admin/GiftCard/Grid/Action/gift_card_balance.html.twig b/templates/Admin/GiftCard/Grid/Action/gift_card_balance.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Grid/Action/gift_card_balance.html.twig rename to templates/Admin/GiftCard/Grid/Action/gift_card_balance.html.twig diff --git a/src/Resources/views/Admin/GiftCard/Grid/Action/list_conditional.html.twig b/templates/Admin/GiftCard/Grid/Action/list_conditional.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Grid/Action/list_conditional.html.twig rename to templates/Admin/GiftCard/Grid/Action/list_conditional.html.twig diff --git a/src/Resources/views/Admin/GiftCard/Grid/Action/resend_email.html.twig b/templates/Admin/GiftCard/Grid/Action/resend_email.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Grid/Action/resend_email.html.twig rename to templates/Admin/GiftCard/Grid/Action/resend_email.html.twig diff --git a/src/Resources/views/Admin/GiftCard/Grid/Field/amount.html.twig b/templates/Admin/GiftCard/Grid/Field/amount.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Grid/Field/amount.html.twig rename to templates/Admin/GiftCard/Grid/Field/amount.html.twig diff --git a/src/Resources/views/Admin/GiftCard/Grid/Field/channel_configurations.html.twig b/templates/Admin/GiftCard/Grid/Field/channel_configurations.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Grid/Field/channel_configurations.html.twig rename to templates/Admin/GiftCard/Grid/Field/channel_configurations.html.twig diff --git a/src/Resources/views/Admin/GiftCard/Grid/Field/customer.html.twig b/templates/Admin/GiftCard/Grid/Field/customer.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Grid/Field/customer.html.twig rename to templates/Admin/GiftCard/Grid/Field/customer.html.twig diff --git a/src/Resources/views/Admin/GiftCard/Grid/Field/item_units_order.html.twig b/templates/Admin/GiftCard/Grid/Field/item_units_order.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/Grid/Field/item_units_order.html.twig rename to templates/Admin/GiftCard/Grid/Field/item_units_order.html.twig diff --git a/src/Resources/views/Admin/GiftCard/_form.html.twig b/templates/Admin/GiftCard/_form.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/_form.html.twig rename to templates/Admin/GiftCard/_form.html.twig diff --git a/src/Resources/views/Admin/GiftCard/create.html.twig b/templates/Admin/GiftCard/create.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCard/create.html.twig rename to templates/Admin/GiftCard/create.html.twig diff --git a/src/Resources/views/Admin/GiftCardConfiguration/Create/_breadcrumb.html.twig b/templates/Admin/GiftCardConfiguration/Create/_breadcrumb.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCardConfiguration/Create/_breadcrumb.html.twig rename to templates/Admin/GiftCardConfiguration/Create/_breadcrumb.html.twig diff --git a/src/Resources/views/Admin/GiftCardConfiguration/Index/_breadcrumb.html.twig b/templates/Admin/GiftCardConfiguration/Index/_breadcrumb.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCardConfiguration/Index/_breadcrumb.html.twig rename to templates/Admin/GiftCardConfiguration/Index/_breadcrumb.html.twig diff --git a/src/Resources/views/Admin/GiftCardConfiguration/Update/_breadcrumb.html.twig b/templates/Admin/GiftCardConfiguration/Update/_breadcrumb.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCardConfiguration/Update/_breadcrumb.html.twig rename to templates/Admin/GiftCardConfiguration/Update/_breadcrumb.html.twig diff --git a/src/Resources/views/Admin/GiftCardConfiguration/Update/_javascripts.html.twig b/templates/Admin/GiftCardConfiguration/Update/_javascripts.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCardConfiguration/Update/_javascripts.html.twig rename to templates/Admin/GiftCardConfiguration/Update/_javascripts.html.twig diff --git a/src/Resources/views/Admin/GiftCardConfiguration/_form.html.twig b/templates/Admin/GiftCardConfiguration/_form.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCardConfiguration/_form.html.twig rename to templates/Admin/GiftCardConfiguration/_form.html.twig diff --git a/src/Resources/views/Admin/GiftCardConfiguration/_javascripts.html.twig b/templates/Admin/GiftCardConfiguration/_javascripts.html.twig similarity index 100% rename from src/Resources/views/Admin/GiftCardConfiguration/_javascripts.html.twig rename to templates/Admin/GiftCardConfiguration/_javascripts.html.twig diff --git a/src/Resources/views/Admin/Order/Grid/Field/coveredByGiftCards.html.twig b/templates/Admin/Order/Grid/Field/coveredByGiftCards.html.twig similarity index 100% rename from src/Resources/views/Admin/Order/Grid/Field/coveredByGiftCards.html.twig rename to templates/Admin/Order/Grid/Field/coveredByGiftCards.html.twig diff --git a/src/Resources/views/Admin/giftCardBalance.html.twig b/templates/Admin/giftCardBalance.html.twig similarity index 100% rename from src/Resources/views/Admin/giftCardBalance.html.twig rename to templates/Admin/giftCardBalance.html.twig diff --git a/src/Resources/views/Cart/_giftCard.html.twig b/templates/Cart/_giftCard.html.twig similarity index 100% rename from src/Resources/views/Cart/_giftCard.html.twig rename to templates/Cart/_giftCard.html.twig diff --git a/src/Resources/views/Email/giftCardToCustomer.html.twig b/templates/Email/giftCardToCustomer.html.twig similarity index 100% rename from src/Resources/views/Email/giftCardToCustomer.html.twig rename to templates/Email/giftCardToCustomer.html.twig diff --git a/src/Resources/views/Email/giftCardsFromOrder.html.twig b/templates/Email/giftCardsFromOrder.html.twig similarity index 100% rename from src/Resources/views/Email/giftCardsFromOrder.html.twig rename to templates/Email/giftCardsFromOrder.html.twig diff --git a/src/Resources/views/Shop/Account/GiftCard/Grid/Field/amount.html.twig b/templates/Shop/Account/GiftCard/Grid/Field/amount.html.twig similarity index 100% rename from src/Resources/views/Shop/Account/GiftCard/Grid/Field/amount.html.twig rename to templates/Shop/Account/GiftCard/Grid/Field/amount.html.twig diff --git a/src/Resources/views/Shop/Account/GiftCard/Grid/Field/initial_amount.html.twig b/templates/Shop/Account/GiftCard/Grid/Field/initial_amount.html.twig similarity index 100% rename from src/Resources/views/Shop/Account/GiftCard/Grid/Field/initial_amount.html.twig rename to templates/Shop/Account/GiftCard/Grid/Field/initial_amount.html.twig diff --git a/src/Resources/views/Shop/Account/GiftCard/Index/_breadcrumb.html.twig b/templates/Shop/Account/GiftCard/Index/_breadcrumb.html.twig similarity index 100% rename from src/Resources/views/Shop/Account/GiftCard/Index/_breadcrumb.html.twig rename to templates/Shop/Account/GiftCard/Index/_breadcrumb.html.twig diff --git a/src/Resources/views/Shop/Account/GiftCard/Index/_header.html.twig b/templates/Shop/Account/GiftCard/Index/_header.html.twig similarity index 100% rename from src/Resources/views/Shop/Account/GiftCard/Index/_header.html.twig rename to templates/Shop/Account/GiftCard/Index/_header.html.twig diff --git a/src/Resources/views/Shop/Account/GiftCard/index.html.twig b/templates/Shop/Account/GiftCard/index.html.twig similarity index 100% rename from src/Resources/views/Shop/Account/GiftCard/index.html.twig rename to templates/Shop/Account/GiftCard/index.html.twig diff --git a/src/Resources/views/Shop/Cart/Summary/_appliedGiftCards.html.twig b/templates/Shop/Cart/Summary/_appliedGiftCards.html.twig similarity index 100% rename from src/Resources/views/Shop/Cart/Summary/_appliedGiftCards.html.twig rename to templates/Shop/Cart/Summary/_appliedGiftCards.html.twig diff --git a/src/Resources/views/Shop/GiftCard/search.html.twig b/templates/Shop/GiftCard/search.html.twig similarity index 100% rename from src/Resources/views/Shop/GiftCard/search.html.twig rename to templates/Shop/GiftCard/search.html.twig diff --git a/src/Resources/views/Shop/Product/Show/_addToCartGiftCardInformation.html.twig b/templates/Shop/Product/Show/_addToCartGiftCardInformation.html.twig similarity index 100% rename from src/Resources/views/Shop/Product/Show/_addToCartGiftCardInformation.html.twig rename to templates/Shop/Product/Show/_addToCartGiftCardInformation.html.twig diff --git a/src/Resources/views/Shop/addGiftCardToOrder.html.twig b/templates/Shop/addGiftCardToOrder.html.twig similarity index 100% rename from src/Resources/views/Shop/addGiftCardToOrder.html.twig rename to templates/Shop/addGiftCardToOrder.html.twig diff --git a/src/Resources/views/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig b/templates/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig similarity index 100% rename from src/Resources/views/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig rename to templates/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig diff --git a/src/Resources/views/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig b/templates/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig similarity index 100% rename from src/Resources/views/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig rename to templates/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig diff --git a/src/Resources/views/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig b/templates/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig similarity index 100% rename from src/Resources/views/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig rename to templates/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig diff --git a/src/Resources/views/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig b/templates/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig similarity index 100% rename from src/Resources/views/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig rename to templates/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig diff --git a/src/Resources/views/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig b/templates/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig similarity index 100% rename from src/Resources/views/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig rename to templates/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig diff --git a/tests/TestApplication/config/config.yaml b/tests/TestApplication/config/config.yaml index beb6606e..da6dca56 100644 --- a/tests/TestApplication/config/config.yaml +++ b/tests/TestApplication/config/config.yaml @@ -1,6 +1,6 @@ imports: - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/config.yaml" } - - { resource: "@SetonoSyliusGiftCardPlugin/Resources/config/app/fixtures.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/app/config.yaml" } + - { resource: "@SetonoSyliusGiftCardPlugin/config/app/fixtures.yaml" } - { resource: "services_test.php" } twig: diff --git a/tests/TestApplication/config/routes.yaml b/tests/TestApplication/config/routes.yaml index c1e265d0..1dc350e9 100644 --- a/tests/TestApplication/config/routes.yaml +++ b/tests/TestApplication/config/routes.yaml @@ -1,2 +1,2 @@ setono_sylius_gift_card: - resource: "@SetonoSyliusGiftCardPlugin/Resources/config/routes.yaml" + resource: "@SetonoSyliusGiftCardPlugin/config/routes.yaml" diff --git a/src/Resources/translations/flashes.da.yml b/translations/flashes.da.yml similarity index 100% rename from src/Resources/translations/flashes.da.yml rename to translations/flashes.da.yml diff --git a/src/Resources/translations/flashes.en.yml b/translations/flashes.en.yml similarity index 100% rename from src/Resources/translations/flashes.en.yml rename to translations/flashes.en.yml diff --git a/src/Resources/translations/flashes.fr.yml b/translations/flashes.fr.yml similarity index 100% rename from src/Resources/translations/flashes.fr.yml rename to translations/flashes.fr.yml diff --git a/src/Resources/translations/messages.da.yml b/translations/messages.da.yml similarity index 100% rename from src/Resources/translations/messages.da.yml rename to translations/messages.da.yml diff --git a/src/Resources/translations/messages.en.yml b/translations/messages.en.yml similarity index 100% rename from src/Resources/translations/messages.en.yml rename to translations/messages.en.yml diff --git a/src/Resources/translations/messages.fr.yml b/translations/messages.fr.yml similarity index 100% rename from src/Resources/translations/messages.fr.yml rename to translations/messages.fr.yml diff --git a/src/Resources/translations/validators.da.yml b/translations/validators.da.yml similarity index 100% rename from src/Resources/translations/validators.da.yml rename to translations/validators.da.yml diff --git a/src/Resources/translations/validators.en.yml b/translations/validators.en.yml similarity index 100% rename from src/Resources/translations/validators.en.yml rename to translations/validators.en.yml diff --git a/src/Resources/translations/validators.fr.yml b/translations/validators.fr.yml similarity index 100% rename from src/Resources/translations/validators.fr.yml rename to translations/validators.fr.yml From ae8f332f17888f7434822dba628993d7cd832907 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 17:36:06 +0200 Subject: [PATCH 18/60] Fix redundant templates/templates/bundles nesting from the Resources move --- .../bundles/SyliusAdminBundle/Form/imagesTheme.html.twig | 0 .../SyliusAdminBundle/Order/Show/Summary/_totals.html.twig | 0 .../bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig | 0 .../bundles/SyliusShopBundle/Checkout/_summary.html.twig | 0 .../bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename templates/{templates => }/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig (100%) rename templates/{templates => }/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig (100%) rename templates/{templates => }/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig (100%) rename templates/{templates => }/bundles/SyliusShopBundle/Checkout/_summary.html.twig (100%) rename templates/{templates => }/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig (100%) diff --git a/templates/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig b/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig similarity index 100% rename from templates/templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig rename to templates/bundles/SyliusAdminBundle/Form/imagesTheme.html.twig diff --git a/templates/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig b/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig similarity index 100% rename from templates/templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig rename to templates/bundles/SyliusAdminBundle/Order/Show/Summary/_totals.html.twig diff --git a/templates/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig b/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig similarity index 100% rename from templates/templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig rename to templates/bundles/SyliusShopBundle/Cart/Summary/_totals.html.twig diff --git a/templates/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig b/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig similarity index 100% rename from templates/templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig rename to templates/bundles/SyliusShopBundle/Checkout/_summary.html.twig diff --git a/templates/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig b/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig similarity index 100% rename from templates/templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig rename to templates/bundles/SyliusShopBundle/Common/Order/Table/_totals.html.twig From d438efb81f71b95eb27fdb8a9d6baedc91eedd48 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 17:49:14 +0200 Subject: [PATCH 19/60] Add bin/console symlink to vendor/bin/console, like SyliusMailchimpPlugin vendor/bin/console is the only real console binary (this plugin has no root app), but plain `bin/console` is the conventional entry point people expect (e.g. dcrp bin/console). bin/create_console_symlink.php recreates the symlink on post-install-cmd/post-update-cmd. --- bin/console | 1 + bin/create_console_symlink.php | 53 ++++++++++++++++++++++++++++++++++ composer.json | 11 ++++++- 3 files changed, 64 insertions(+), 1 deletion(-) create mode 120000 bin/console create mode 100755 bin/create_console_symlink.php diff --git a/bin/console b/bin/console new file mode 120000 index 00000000..46e506e4 --- /dev/null +++ b/bin/console @@ -0,0 +1 @@ +../vendor/bin/console \ No newline at end of file diff --git a/bin/create_console_symlink.php b/bin/create_console_symlink.php new file mode 100755 index 00000000..9dbf03cb --- /dev/null +++ b/bin/create_console_symlink.php @@ -0,0 +1,53 @@ + {$targetRelativeFromBin}"); +} + +@chmod($linkPath, 0755); +info("Created symlink: bin/console -> {$targetRelativeFromBin}"); diff --git a/composer.json b/composer.json index 231d788a..5c22328e 100644 --- a/composer.json +++ b/composer.json @@ -103,6 +103,15 @@ "analyse": "psalm", "check-style": "ecs check", "fix-style": "ecs check --fix", - "phpunit": "phpunit" + "phpunit": "phpunit", + "post-install-cmd": [ + "@create-console-symlink" + ], + "post-update-cmd": [ + "@create-console-symlink" + ], + "create-console-symlink": [ + "@php bin/create_console_symlink.php" + ] } } From 835a5b3719eebbb2b387fc99218b0ff67ee44ad1 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Tue, 28 Jul 2026 18:04:01 +0200 Subject: [PATCH 20/60] Remove unused infection/infection dev dependency Not used anywhere (no infection.json, not run in composer scripts or CI). It was the source of the "Safe\gmdate()/mktime(): Implicitly marking parameter as nullable is deprecated" warnings on PHP 8.4 - it pulls in thecodingmachine/safe, which was never updated for PHP 8.4's implicit- nullable-parameter deprecation. --- composer.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/composer.json b/composer.json index 5c22328e..e65bbc60 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,6 @@ "dmore/behat-chrome-extension": "^1.4", "dmore/chrome-mink-driver": "^2.9", "doctrine/doctrine-bundle": "^2.13", - "infection/infection": "^0.27.10", "lexik/jwt-authentication-bundle": "^3.1", "matthiasnoback/symfony-config-test": "^5.1", "matthiasnoback/symfony-dependency-injection-test": "^5.1", @@ -82,7 +81,6 @@ "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": false, "ergebnis/composer-normalize": true, - "infection/extension-installer": true, "php-http/discovery": false, "symfony/thanks": false, "symfony/runtime": true, From b30c9d1948da1e740f255a222e8ab0c048ec0d12 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Wed, 29 Jul 2026 09:33:37 +0200 Subject: [PATCH 21/60] Ship a Doctrine migration for the plugin's schema, auto-registered Host apps use doctrine:migrations:migrate, not doctrine:schema:create - without this, installing the plugin left the mapped entities with no matching tables (as seen: "Table ...__order_gift_cards doesn't exist" even after running the app's own migrations). Generating migrations at install time (e.g. asking the host app to run doctrine:migrations:diff) would be the actual bad practice - it produces different SQL depending on the app's exact prior state, DBAL version, and platform. The correct pattern (same one SyliusMailchimpPlugin uses) is for the plugin to ship a pre-written migration and register it into the host app's migration chain automatically via Sylius\Bundle\CoreBundle\DependencyInjection\PrependDoctrineMigrationsTrait, ordered to run after Sylius\Bundle\CoreBundle\Migrations. Version20260729000001 creates the 5 gift-card tables and adds the two gift-card columns to sylius_product. The exact DDL (column types, index/ FK constraint names) was generated via doctrine:schema:create --dump-sql against real MySQL 8.4 rather than hand-written, then verified by running it against a real dev database and confirming doctrine:schema:validate shows no drift attributable to it (the one remaining diff is pre-existing messenger_messages index naming, unrelated to this plugin). --- .../SetonoSyliusGiftCardExtension.php | 28 ++++++++++- src/Migrations/Version20260729000001.php | 48 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/Migrations/Version20260729000001.php diff --git a/src/DependencyInjection/SetonoSyliusGiftCardExtension.php b/src/DependencyInjection/SetonoSyliusGiftCardExtension.php index edf8ddf4..fc2cf379 100644 --- a/src/DependencyInjection/SetonoSyliusGiftCardExtension.php +++ b/src/DependencyInjection/SetonoSyliusGiftCardExtension.php @@ -4,13 +4,17 @@ namespace Setono\SyliusGiftCardPlugin\DependencyInjection; +use Sylius\Bundle\CoreBundle\DependencyInjection\PrependDoctrineMigrationsTrait; use Sylius\Bundle\ResourceBundle\DependencyInjection\Extension\AbstractResourceExtension; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; -final class SetonoSyliusGiftCardExtension extends AbstractResourceExtension +final class SetonoSyliusGiftCardExtension extends AbstractResourceExtension implements PrependExtensionInterface { + use PrependDoctrineMigrationsTrait; + public function load(array $configs, ContainerBuilder $container): void { /** @@ -64,4 +68,26 @@ public function load(array $configs, ContainerBuilder $container): void $loader->load('services.xml'); } + + public function prepend(ContainerBuilder $container): void + { + $this->prependDoctrineMigrations($container); + } + + protected function getMigrationsNamespace(): string + { + return 'DoctrineMigrations'; + } + + protected function getMigrationsDirectory(): string + { + return '@SetonoSyliusGiftCardPlugin/src/Migrations'; + } + + protected function getNamespacesOfMigrationsExecutedBefore(): array + { + return [ + 'Sylius\Bundle\CoreBundle\Migrations', + ]; + } } diff --git a/src/Migrations/Version20260729000001.php b/src/Migrations/Version20260729000001.php new file mode 100644 index 00000000..4383b5ec --- /dev/null +++ b/src/Migrations/Version20260729000001.php @@ -0,0 +1,48 @@ +addSql('CREATE TABLE setono_sylius_gift_card__configuration (id INT AUTO_INCREMENT NOT NULL, code VARCHAR(255) NOT NULL, enabled TINYINT(1) NOT NULL, is_default TINYINT(1) DEFAULT 0 NOT NULL, defaultValidityPeriod VARCHAR(255) DEFAULT NULL, pageSize VARCHAR(255) DEFAULT NULL, orientation VARCHAR(255) DEFAULT NULL, template LONGTEXT NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME DEFAULT NULL, UNIQUE INDEX UNIQ_ADC64AD077153098 (code), PRIMARY KEY(id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE setono_sylius_gift_card__gift_card (id INT AUTO_INCREMENT NOT NULL, order_item_unit_id INT DEFAULT NULL, customer_id INT DEFAULT NULL, channel_id INT NOT NULL, code VARCHAR(255) NOT NULL, enabled TINYINT(1) NOT NULL, amount INT NOT NULL, initialAmount INT NOT NULL, currencyCode VARCHAR(3) NOT NULL, customMessage LONGTEXT DEFAULT NULL, origin VARCHAR(255) DEFAULT NULL, expiresAt DATETIME DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME DEFAULT NULL, UNIQUE INDEX UNIQ_A5B7155477153098 (code), UNIQUE INDEX UNIQ_A5B71554F720C233 (order_item_unit_id), INDEX IDX_A5B715549395C3F3 (customer_id), INDEX IDX_A5B7155472F5A1AA (channel_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE setono_sylius_gift_card__configuration_image (id INT AUTO_INCREMENT NOT NULL, owner_id INT NOT NULL, type VARCHAR(255) DEFAULT NULL, path VARCHAR(255) NOT NULL, INDEX IDX_CDFECBED7E3C61F9 (owner_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE setono_sylius_gift_card__channel_configuration (id INT AUTO_INCREMENT NOT NULL, channel_id INT NOT NULL, configuration_id INT NOT NULL, locale_id INT NOT NULL, INDEX IDX_571F956572F5A1AA (channel_id), INDEX IDX_571F956573F32DD8 (configuration_id), INDEX IDX_571F9565E559DFD1 (locale_id), UNIQUE INDEX unique_channel_locale (channel_id, locale_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE setono_sylius_gift_card__order_gift_cards (order_id INT NOT NULL, gift_card_id INT NOT NULL, INDEX IDX_429AE86C8D9F6D38 (order_id), INDEX IDX_429AE86C2696A98F (gift_card_id), PRIMARY KEY(order_id, gift_card_id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB'); + + $this->addSql('ALTER TABLE setono_sylius_gift_card__gift_card ADD CONSTRAINT FK_A5B71554F720C233 FOREIGN KEY (order_item_unit_id) REFERENCES sylius_order_item_unit (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE setono_sylius_gift_card__gift_card ADD CONSTRAINT FK_A5B715549395C3F3 FOREIGN KEY (customer_id) REFERENCES sylius_customer (id) ON DELETE SET NULL'); + $this->addSql('ALTER TABLE setono_sylius_gift_card__gift_card ADD CONSTRAINT FK_A5B7155472F5A1AA FOREIGN KEY (channel_id) REFERENCES sylius_channel (id)'); + $this->addSql('ALTER TABLE setono_sylius_gift_card__configuration_image ADD CONSTRAINT FK_CDFECBED7E3C61F9 FOREIGN KEY (owner_id) REFERENCES setono_sylius_gift_card__configuration (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE setono_sylius_gift_card__channel_configuration ADD CONSTRAINT FK_571F956572F5A1AA FOREIGN KEY (channel_id) REFERENCES sylius_channel (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE setono_sylius_gift_card__channel_configuration ADD CONSTRAINT FK_571F956573F32DD8 FOREIGN KEY (configuration_id) REFERENCES setono_sylius_gift_card__configuration (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE setono_sylius_gift_card__channel_configuration ADD CONSTRAINT FK_571F9565E559DFD1 FOREIGN KEY (locale_id) REFERENCES sylius_locale (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE setono_sylius_gift_card__order_gift_cards ADD CONSTRAINT FK_429AE86C8D9F6D38 FOREIGN KEY (order_id) REFERENCES sylius_order (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE setono_sylius_gift_card__order_gift_cards ADD CONSTRAINT FK_429AE86C2696A98F FOREIGN KEY (gift_card_id) REFERENCES setono_sylius_gift_card__gift_card (id) ON DELETE CASCADE'); + + $this->addSql('ALTER TABLE sylius_product ADD giftCard TINYINT(1) DEFAULT 0 NOT NULL, ADD giftCardAmountConfigurable TINYINT(1) DEFAULT 0 NOT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE sylius_product DROP giftCard, DROP giftCardAmountConfigurable'); + + $this->addSql('DROP TABLE setono_sylius_gift_card__order_gift_cards'); + $this->addSql('DROP TABLE setono_sylius_gift_card__channel_configuration'); + $this->addSql('DROP TABLE setono_sylius_gift_card__configuration_image'); + $this->addSql('DROP TABLE setono_sylius_gift_card__gift_card'); + $this->addSql('DROP TABLE setono_sylius_gift_card__configuration'); + } +} From b445d0807c99a4e91067eb907bdae8972e1ff8de Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Wed, 29 Jul 2026 14:49:46 +0200 Subject: [PATCH 22/60] Align tooling conventions with SyliusMailchimpPlugin, fix dependency resolution - .editorconfig: adopt the standard Symfony/Sylius-plugin template - .gitignore: add /drivers/, /phpunit.xml (matching Mailchimp) - assets/{admin,shop}: Webpack Encore entrypoint scaffolding - tests/TestApplication: import packages/*.yaml, add dev monolog config composer.json: re-added the runtime/dev dependencies this plugin actually needs that got dropped during the alignment (sylius/grid-bundle, sylius/resource-bundle, sylius/mailer-bundle, doctrine/orm|dbal| collections|persistence, doctrine/doctrine-bundle, lexik/jwt- authentication-bundle, babdev/pagerfanta-bundle, the symfony/* components this plugin's own src/ code directly imports) - Mailchimp doesn't need these since it isn't a Sylius resource-bundle plugin and has a much smaller direct Symfony surface. Fixed two real dependency resolution failures surfaced while reconciling: - psalm/plugin-phpunit ^0.20.2 (needed for vimeo/psalm ^6.13, Mailchimp's version) requires psalm/psalm-plugin-api, which conflicts with psalm <7.0 - no stable psalm 7 exists yet. Reverted to psalm/plugin-phpunit ^0.18.4 (pulls psalm ^5.x, still compatible with weirdan/doctrine- psalm-plugin) and dropped the vimeo/psalm ^6.13 pin; also removed psalm.xml's phpVersion="8.4" since psalm 5.x doesn't recognize that version string. - extra.symfony.require: "^7.4" made Composer's native symfony-version restriction reject every friends-of-behat/mink-extension release that doesn't explicitly declare a ^7.4-compatible symfony/config (i.e. every release before v2.7.5), producing an unsatisfiable set even though our own per-package ranges were broad enough. Removed it - the CI workflow already sets it dynamically via `composer config extra.symfony.require` before install, so nothing is lost there. Also added explicit requires for friends-of-behat/mink-extension and its siblings (mirroring Mailchimp) so the solver can't wander into pre-2.7 releases at all. - dropped setono/sylius-behat-pack (unused, last released 2021, was pinning an ancient friends-of-behat/mink fork via its own requirements) Verified after reconciliation: composer install succeeds fresh, container lints, ecs/psalm clean, phpunit/phpspec results unchanged (same 2+9 pre-existing unrelated failures as before this session). --- .editorconfig | 61 ++++++++++++++++++- .gitignore | 3 + assets/admin/controllers.json | 4 ++ assets/admin/entrypoint.js | 0 assets/shop/controllers.json | 4 ++ assets/shop/entrypoint.js | 0 composer.json | 38 ++++++++++-- tests/TestApplication/config/config.yaml | 1 + .../config/packages/monolog.yaml | 10 +++ 9 files changed, 114 insertions(+), 7 deletions(-) create mode 100644 assets/admin/controllers.json create mode 100644 assets/admin/entrypoint.js create mode 100644 assets/shop/controllers.json create mode 100644 assets/shop/entrypoint.js create mode 100644 tests/TestApplication/config/packages/monolog.yaml diff --git a/.editorconfig b/.editorconfig index 178a6505..b5f72a57 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,25 +1,82 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + root = true [*] +# Change these settings to your own preference indent_style = space indent_size = 4 +# We recommend you to keep these unchanged end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.feature] +indent_style = space +indent_size = 4 + +[*.js] +indent_style = space +indent_size = 2 + +[*.json] +indent_style = space indent_size = 2 [*.md] +indent_style = space +indent_size = 4 trim_trailing_whitespace = false +[*.neon] +indent_style = space +indent_size = 4 + +[*.php] +indent_style = space +indent_size = 4 + [*.sh] -indent_style = tab +indent_style = space +indent_size = 4 [*.{yaml,yml}] +indent_style = space +indent_size = 4 trim_trailing_whitespace = false -[{webpack.config.js,.eslintrc.js}] +[.babelrc] +indent_style = space indent_size = 2 + +[.gitmodules] +indent_style = tab +indent_size = 4 + +[.php_cs{,.dist}] +indent_style = space +indent_size = 4 + +[composer.json] +indent_style = space +indent_size = 4 + +[package.json] +indent_style = space +indent_size = 2 + +[phpspec.yml{,.dist}] +indent_style = space +indent_size = 4 + +[phpstan.neon] +indent_style = space +indent_size = 4 + +[phpunit.xml{,.dist}] +indent_style = space +indent_size = 4 diff --git a/.gitignore b/.gitignore index e97c7064..a24d6718 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /vendor/ /var/ /node_modules/ +/drivers/ /composer.lock /docker/ @@ -11,9 +12,11 @@ /behat.yml /behat.sh /phpspec.yml +/phpunit.xml /compose.override.yml /compose.test.yml +# Symfony CLI https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project /.php-version /php.ini diff --git a/assets/admin/controllers.json b/assets/admin/controllers.json new file mode 100644 index 00000000..e2ce9b5c --- /dev/null +++ b/assets/admin/controllers.json @@ -0,0 +1,4 @@ +{ + "controllers": [], + "entrypoints": [] +} diff --git a/assets/admin/entrypoint.js b/assets/admin/entrypoint.js new file mode 100644 index 00000000..e69de29b diff --git a/assets/shop/controllers.json b/assets/shop/controllers.json new file mode 100644 index 00000000..e2ce9b5c --- /dev/null +++ b/assets/shop/controllers.json @@ -0,0 +1,4 @@ +{ + "controllers": [], + "entrypoints": [] +} diff --git a/assets/shop/entrypoint.js b/assets/shop/entrypoint.js new file mode 100644 index 00000000..e69de29b diff --git a/composer.json b/composer.json index e65bbc60..f4506534 100644 --- a/composer.json +++ b/composer.json @@ -41,9 +41,19 @@ "require-dev": { "babdev/pagerfanta-bundle": "^4.4", "behat/behat": "^3.16", + "behat/mink": "^1.13", + "behat/mink-selenium2-driver": "^1.7", + "dbrekelmans/bdi": "^1.4", "dmore/behat-chrome-extension": "^1.4", "dmore/chrome-mink-driver": "^2.9", "doctrine/doctrine-bundle": "^2.13", + "friends-of-behat/mink-browserkit-driver": "^1.6", + "friends-of-behat/mink-debug-extension": "^2.1", + "friends-of-behat/mink-extension": "^2.7", + "friends-of-behat/page-object-extension": "^0.3", + "friends-of-behat/suite-settings-extension": "^1.1", + "friends-of-behat/symfony-extension": "^2.6", + "friends-of-behat/variadic-extension": "^1.6", "lexik/jwt-authentication-bundle": "^3.1", "matthiasnoback/symfony-config-test": "^5.1", "matthiasnoback/symfony-dependency-injection-test": "^5.1", @@ -51,13 +61,16 @@ "phpspec/phpspec": "^7.4", "phpspec/prophecy-phpunit": "^2.0.2", "phpunit/phpunit": "^9.6.17", - "polishsymfonycommunity/symfony-mocker-container": "^1.0.7", + "polishsymfonycommunity/symfony-mocker-container": "^1.0", "psalm/plugin-phpunit": "^0.18.4", "psalm/plugin-symfony": "^5.0", + "rector/rector": "^1.0", "setono/code-quality-pack": "^2.7", - "setono/sylius-behat-pack": "^0.2.2", + "sylius-labs/coding-standard": "^4.4", "sylius-labs/suite-tags-extension": "~0.2", + "sylius/sylius-rector": "^2.0", "sylius/test-application": "^2.0.0@alpha", + "symfony/browser-kit": "^6.4 || ^7.4", "symfony/debug-bundle": "^6.4 || ^7.4", "symfony/dotenv": "^6.4 || ^7.4", "symfony/intl": "^6.4 || ^7.4", @@ -92,16 +105,31 @@ "branch-alias": { "dev-sylius-2": "2.0-dev" }, - "symfony": { - "require": "^7.4" - }, "public-dir": "vendor/sylius/test-application/public" }, "scripts": { + "database-reset": [ + "vendor/bin/console doctrine:database:drop --force --if-exists", + "vendor/bin/console doctrine:database:create", + "vendor/bin/console doctrine:migration:migrate -n", + "vendor/bin/console sylius:fixtures:load -n" + ], + "frontend-clear": [ + "cd vendor/sylius/test-application && yarn install && yarn build", + "vendor/bin/console assets:install" + ], + "test-app-init": [ + "@database-reset", + "@frontend-clear" + ], "analyse": "psalm", "check-style": "ecs check", "fix-style": "ecs check --fix", "phpunit": "phpunit", + "behat": "behat --strict -vvv --no-interaction || behat --strict -vvv --no-interaction --rerun", + "auto-scripts": { + "security-checker security:check": "script" + }, "post-install-cmd": [ "@create-console-symlink" ], diff --git a/tests/TestApplication/config/config.yaml b/tests/TestApplication/config/config.yaml index da6dca56..0639c881 100644 --- a/tests/TestApplication/config/config.yaml +++ b/tests/TestApplication/config/config.yaml @@ -1,4 +1,5 @@ imports: + - { resource: "packages/*.yaml" } - { resource: "@SetonoSyliusGiftCardPlugin/config/app/config.yaml" } - { resource: "@SetonoSyliusGiftCardPlugin/config/app/fixtures.yaml" } - { resource: "services_test.php" } diff --git a/tests/TestApplication/config/packages/monolog.yaml b/tests/TestApplication/config/packages/monolog.yaml new file mode 100644 index 00000000..62e6ab01 --- /dev/null +++ b/tests/TestApplication/config/packages/monolog.yaml @@ -0,0 +1,10 @@ +when@dev: + monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: warning + firephp: + type: firephp + level: info From b4fb95f34fdd0bb11de095f5f918423bb2b3c294 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Wed, 29 Jul 2026 15:29:40 +0200 Subject: [PATCH 23/60] Pin symfony/type-info <7.4 to work around a Sylius/ApiPlatform crash symfony/type-info 7.4.0 added stricter validation in UnionType::__construct() that rejects unions combining the "object" builtin type with a concrete class (Cannot create union with both "object" and class type). ApiPlatform hits this while computing resource identifier metadata for Sylius's own API resources, crashing the app on every request (not just API calls, since Sylius's API routes are always imported as part of default routing) - see https://github.com/Sylius/Sylius/issues/18878. The linked fix (PR sylius/sylius#18904) only cleaned up the 2 occurrences that specific reporter hit; verified those are indeed present in our installed sylius/sylius 2.2.7, but at least one more (unidentified) occurrence still triggers the crash for us. Since upstream hasn't done an exhaustive cleanup yet, pin symfony/type-info to the last version before the stricter check (>=7.2 <7.4), matching the issue's suggested temporary fix. symfony/property-info also pinned to ^7.3 since 7.4.15 forces type-info ^7.4.7 - resolves to symfony/property-info 7.4.6, which is still compatible with type-info 7.3. Verified: container lints, debug:router sylius_api loads cleanly, boots in the real docker app (500 -> 302). ecs/psalm/phpunit/phpspec unchanged. --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f4506534..7c6e6adc 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,9 @@ "symfony/routing": "^6.4 || ^7.4", "symfony/security-core": "^6.4 || ^7.4", "symfony/serializer": "^6.4 || ^7.4", + "symfony/property-info": "^7.3", "symfony/translation-contracts": "^3.5", + "symfony/type-info": ">=7.2 <7.4", "symfony/validator": "^6.4 || ^7.4", "twig/twig": "^3.5", "webimpress/safe-writer": "^2.2", @@ -74,7 +76,6 @@ "symfony/debug-bundle": "^6.4 || ^7.4", "symfony/dotenv": "^6.4 || ^7.4", "symfony/intl": "^6.4 || ^7.4", - "symfony/property-info": "^6.4 || ^7.4", "symfony/web-profiler-bundle": "^6.4 || ^7.4", "symfony/webpack-encore-bundle": "^2.2", "weirdan/doctrine-psalm-plugin": "^2.9" From f237c03253299623a2cc0e48764acf79808aa64e Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Wed, 29 Jul 2026 15:51:36 +0200 Subject: [PATCH 24/60] Fix missing webpack assets and Symfony version inconsistency (500 on shop pages) Two separate issues surfaced on the shop homepage (/en_US/): 1. Webpack Encore assets were never built for vendor/sylius/test-application (no entrypoints.json). Built them via yarn install/build and re-ran assets:install with an explicit target (same footgun as the earlier assets:install fix - our own public/ dir shadows the default target resolution when run from the plugin's repo root). 2. symfony/framework-bundle and symfony/twig-bundle had resolved to v6.4.x while the rest of the stack (http-kernel, translation, messenger, etc.) was on v7.4.x, because our composer.json's "^6.4 || ^7.4" ranges let the solver pick either branch per-package independently, and removing extra.symfony.require earlier (to fix the mink-extension conflict) took away the mechanism that used to force them to agree. A 6.4 framework- bundle doesn't wire up symfony/type-info's LiveComponent integration, so any Twig Hook rendering a Live Component (e.g. the shop header) crashed with "Symfony TypeInfo is required to use LiveProps.". Fixed by explicitly requiring symfony/framework-bundle, symfony/twig- bundle and symfony/translation at ^7.4, and tightening every other "^6.4 || ^7.4" symfony/* requirement to plain ^7.4, removing the possibility of the solver drifting back onto the 6.4 branch for any of them. Also pinned sylius-labs/doctrine-migrations-extra-bundle to ^0.2.2 (the only release compatible with framework-bundle 7.4) since sylius/sylius's own "^0.2" range let the solver wander into ancient 0.2.0/0.2.1 otherwise. This in turn made psalm/plugin-phpunit unusable: it pins vimeo/psalm to 4.x/5.x, which needs nikic/php-parser ^4.x, but symfony/translation 7.4 conflicts with nikic/php-parser <5.0. Since psalm/plugin-phpunit only helps analyze tests/ (excluded from psalm.xml's scanned paths already), dropped it and moved to vimeo/psalm ^6.13 + psalm/plugin- symfony ^5.2 + weirdan/doctrine-psalm-plugin ^2.10 (all psalm-6- compatible), matching SyliusMailchimpPlugin's psalm major version. Verified: composer install resolves cleanly, framework-bundle/twig-bundle/ translation/type-info all consistent, container lints, real docker app now returns 200 on /en_US/ (was 500). --- composer.json | 46 ++++++++++--------- psalm.xml | 8 +++- src/Applicator/GiftCardApplicator.php | 2 + ...djustmentsToOrderAdjustmentClearerPass.php | 1 + .../Compiler/CreateServiceAliasesPass.php | 1 + src/DependencyInjection/Configuration.php | 1 + .../SetonoSyliusGiftCardExtension.php | 5 ++ .../ORM/GiftCardConfigurationRepository.php | 2 + src/Doctrine/ORM/GiftCardRepository.php | 6 +++ src/EmailManager/GiftCardEmailManager.php | 2 + ...DefaultGiftCardConfigurationSubscriber.php | 1 + .../GiftCardDeletionSubscriber.php | 1 + ...dEmailWithGiftCardToCustomerSubscriber.php | 1 + src/Factory/GiftCardConfigurationFactory.php | 1 + .../GiftCardConfigurationFactoryInterface.php | 1 + src/Factory/GiftCardFactory.php | 6 +++ src/Factory/GiftCardFactoryInterface.php | 1 + .../GiftCardToCodeDataTransformer.php | 2 + src/Form/Extension/AddToCartTypeExtension.php | 2 + src/Form/Extension/ProductTypeExtension.php | 2 + src/Form/Type/AddGiftCardToOrderType.php | 3 ++ .../Type/AddToCartGiftCardInformationType.php | 2 + .../Type/CustomerAutocompleteChoiceType.php | 4 ++ src/Form/Type/DatePeriodType.php | 1 + .../Type/GiftCardChannelConfigurationType.php | 2 + .../Type/GiftCardConfigurationImageType.php | 3 ++ src/Form/Type/GiftCardConfigurationType.php | 2 + src/Form/Type/GiftCardSearchType.php | 3 ++ src/Form/Type/GiftCardType.php | 4 +- src/Generator/GiftCardCodeGenerator.php | 2 + src/Grid/FieldTypes/StringFieldType.php | 2 + src/Migrations/Version20260729000001.php | 3 ++ src/Model/GiftCard.php | 36 +++++++++++++++ src/Model/GiftCardBalanceCollection.php | 6 +++ src/Model/GiftCardChannelConfiguration.php | 7 +++ src/Model/GiftCardConfiguration.php | 26 +++++++++++ src/Model/GiftCardInterface.php | 2 + src/Modifier/OrderGiftCardAmountModifier.php | 2 + src/Operator/OrderGiftCardOperator.php | 4 ++ src/Order/AddToCartCommand.php | 11 +++-- src/Order/AddToCartCommandInterface.php | 2 + src/Order/Factory/AddToCartCommandFactory.php | 1 + .../Factory/GiftCardInformationFactory.php | 1 + src/Order/GiftCardInformation.php | 10 ++-- src/OrderProcessor/OrderGiftCardProcessor.php | 1 + .../Checker/Rule/HasNoGiftCardRuleChecker.php | 1 + src/Provider/DatePeriodUnitProvider.php | 3 +- ...DefaultGiftCardTemplateContentProvider.php | 1 + .../GiftCardConfigurationProvider.php | 2 + src/Provider/OrderEligibleTotalProvider.php | 1 + src/Provider/PdfRenderingOptionsProvider.php | 1 + src/Renderer/PdfRenderer.php | 1 + src/Resolver/CustomerChannelResolver.php | 1 + src/Resolver/LocaleResolver.php | 3 ++ src/Resolver/RedirectUrlResolver.php | 1 + src/Security/GiftCardVoter.php | 2 + .../GiftCardConfigurationNormalizer.php | 3 ++ .../Normalizer/GiftCardNormalizer.php | 3 ++ src/SetonoSyliusGiftCardPlugin.php | 4 ++ src/Twig/Extension/PdfExtension.php | 1 + .../Constraints/DatePeriodValidator.php | 1 + .../DefaultGiftCardConfigurationMustExist.php | 1 + ...iftCardConfigurationMustExistValidator.php | 1 + .../GiftCardIsNotExpiredValidator.php | 1 + .../Constraints/HasBackgroundImage.php | 1 + .../HasBackgroundImageValidator.php | 1 + .../Pdf/ValidOrientationValidator.php | 1 + .../Pdf/ValidPageSizeValidator.php | 1 + 68 files changed, 237 insertions(+), 31 deletions(-) diff --git a/composer.json b/composer.json index 7c6e6adc..d7a8d6f3 100644 --- a/composer.json +++ b/composer.json @@ -16,26 +16,30 @@ "knplabs/knp-snappy": "^1.4", "knplabs/knp-snappy-bundle": "^1.9", "setono/doctrine-object-manager-trait": "^1.1", + "sylius-labs/doctrine-migrations-extra-bundle": "^0.2.2", "sylius/grid-bundle": "^1.16", "sylius/mailer-bundle": "^2.0", "sylius/resource-bundle": "^1.14", "sylius/sylius": "^2.0", - "symfony/config": "^6.4 || ^7.4", - "symfony/dependency-injection": "^6.4 || ^7.4", - "symfony/event-dispatcher": "^6.4 || ^7.4", - "symfony/form": "^6.4 || ^7.4", - "symfony/http-foundation": "^6.4 || ^7.4", - "symfony/http-kernel": "^6.4 || ^7.4", - "symfony/messenger": "^6.4 || ^7.4", - "symfony/options-resolver": "^6.4 || ^7.4", - "symfony/property-access": "^6.4 || ^7.4", - "symfony/routing": "^6.4 || ^7.4", - "symfony/security-core": "^6.4 || ^7.4", - "symfony/serializer": "^6.4 || ^7.4", + "symfony/config": "^7.4", + "symfony/dependency-injection": "^7.4", + "symfony/event-dispatcher": "^7.4", + "symfony/form": "^7.4", + "symfony/framework-bundle": "^7.4", + "symfony/http-foundation": "^7.4", + "symfony/http-kernel": "^7.4", + "symfony/messenger": "^7.4", + "symfony/options-resolver": "^7.4", + "symfony/property-access": "^7.4", + "symfony/routing": "^7.4", + "symfony/security-core": "^7.4", + "symfony/serializer": "^7.4", "symfony/property-info": "^7.3", + "symfony/translation": "^7.4", "symfony/translation-contracts": "^3.5", + "symfony/twig-bundle": "^7.4", "symfony/type-info": ">=7.2 <7.4", - "symfony/validator": "^6.4 || ^7.4", + "symfony/validator": "^7.4", "twig/twig": "^3.5", "webimpress/safe-writer": "^2.2", "webmozart/assert": "^1.11" @@ -64,21 +68,21 @@ "phpspec/prophecy-phpunit": "^2.0.2", "phpunit/phpunit": "^9.6.17", "polishsymfonycommunity/symfony-mocker-container": "^1.0", - "psalm/plugin-phpunit": "^0.18.4", - "psalm/plugin-symfony": "^5.0", + "psalm/plugin-symfony": "^5.2", "rector/rector": "^1.0", "setono/code-quality-pack": "^2.7", "sylius-labs/coding-standard": "^4.4", "sylius-labs/suite-tags-extension": "~0.2", "sylius/sylius-rector": "^2.0", "sylius/test-application": "^2.0.0@alpha", - "symfony/browser-kit": "^6.4 || ^7.4", - "symfony/debug-bundle": "^6.4 || ^7.4", - "symfony/dotenv": "^6.4 || ^7.4", - "symfony/intl": "^6.4 || ^7.4", - "symfony/web-profiler-bundle": "^6.4 || ^7.4", + "symfony/browser-kit": "^7.4", + "symfony/debug-bundle": "^7.4", + "symfony/dotenv": "^7.4", + "symfony/intl": "^7.4", + "symfony/web-profiler-bundle": "^7.4", "symfony/webpack-encore-bundle": "^2.2", - "weirdan/doctrine-psalm-plugin": "^2.9" + "vimeo/psalm": "^6.13", + "weirdan/doctrine-psalm-plugin": "^2.10" }, "prefer-stable": true, "autoload": { diff --git a/psalm.xml b/psalm.xml index 03408942..5e928033 100644 --- a/psalm.xml +++ b/psalm.xml @@ -20,7 +20,6 @@ - @@ -42,6 +41,13 @@ + + + + + + + diff --git a/src/Applicator/GiftCardApplicator.php b/src/Applicator/GiftCardApplicator.php index b6770512..3dd755fe 100644 --- a/src/Applicator/GiftCardApplicator.php +++ b/src/Applicator/GiftCardApplicator.php @@ -29,6 +29,7 @@ public function __construct( /** * @param string|GiftCardInterface $giftCard */ + #[\Override] public function apply(OrderInterface $order, $giftCard): void { if (is_string($giftCard)) { @@ -65,6 +66,7 @@ public function apply(OrderInterface $order, $giftCard): void /** * @param string|GiftCardInterface $giftCard */ + #[\Override] public function remove(OrderInterface $order, $giftCard): void { if (is_string($giftCard)) { diff --git a/src/DependencyInjection/Compiler/AddAdjustmentsToOrderAdjustmentClearerPass.php b/src/DependencyInjection/Compiler/AddAdjustmentsToOrderAdjustmentClearerPass.php index 1750df3d..d296463f 100644 --- a/src/DependencyInjection/Compiler/AddAdjustmentsToOrderAdjustmentClearerPass.php +++ b/src/DependencyInjection/Compiler/AddAdjustmentsToOrderAdjustmentClearerPass.php @@ -10,6 +10,7 @@ final class AddAdjustmentsToOrderAdjustmentClearerPass implements CompilerPassInterface { + #[\Override] public function process(ContainerBuilder $container): void { if (!$container->hasParameter('sylius.order_processing.adjustment_clearing_types')) { diff --git a/src/DependencyInjection/Compiler/CreateServiceAliasesPass.php b/src/DependencyInjection/Compiler/CreateServiceAliasesPass.php index 14c2f37d..104dd0b5 100644 --- a/src/DependencyInjection/Compiler/CreateServiceAliasesPass.php +++ b/src/DependencyInjection/Compiler/CreateServiceAliasesPass.php @@ -10,6 +10,7 @@ final class CreateServiceAliasesPass implements CompilerPassInterface { + #[\Override] public function process(ContainerBuilder $container): void { // if this service is already defined, we don't need to do anything. It means the Sylius version is < 1.11 diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 132e08c4..639058b7 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -26,6 +26,7 @@ final class Configuration implements ConfigurationInterface { + #[\Override] public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder('setono_sylius_gift_card'); diff --git a/src/DependencyInjection/SetonoSyliusGiftCardExtension.php b/src/DependencyInjection/SetonoSyliusGiftCardExtension.php index fc2cf379..09db4eab 100644 --- a/src/DependencyInjection/SetonoSyliusGiftCardExtension.php +++ b/src/DependencyInjection/SetonoSyliusGiftCardExtension.php @@ -15,6 +15,7 @@ final class SetonoSyliusGiftCardExtension extends AbstractResourceExtension impl { use PrependDoctrineMigrationsTrait; + #[\Override] public function load(array $configs, ContainerBuilder $container): void { /** @@ -69,21 +70,25 @@ public function load(array $configs, ContainerBuilder $container): void $loader->load('services.xml'); } + #[\Override] public function prepend(ContainerBuilder $container): void { $this->prependDoctrineMigrations($container); } + #[\Override] protected function getMigrationsNamespace(): string { return 'DoctrineMigrations'; } + #[\Override] protected function getMigrationsDirectory(): string { return '@SetonoSyliusGiftCardPlugin/src/Migrations'; } + #[\Override] protected function getNamespacesOfMigrationsExecutedBefore(): array { return [ diff --git a/src/Doctrine/ORM/GiftCardConfigurationRepository.php b/src/Doctrine/ORM/GiftCardConfigurationRepository.php index e88e0d4f..0af5e3db 100644 --- a/src/Doctrine/ORM/GiftCardConfigurationRepository.php +++ b/src/Doctrine/ORM/GiftCardConfigurationRepository.php @@ -13,6 +13,7 @@ class GiftCardConfigurationRepository extends EntityRepository implements GiftCardConfigurationRepositoryInterface { + #[\Override] public function findOneByChannelAndLocale(ChannelInterface $channel, LocaleInterface $locale): ?GiftCardConfigurationInterface { $obj = $this->createQueryBuilder('o') @@ -30,6 +31,7 @@ public function findOneByChannelAndLocale(ChannelInterface $channel, LocaleInter return $obj; } + #[\Override] public function findDefault(): ?GiftCardConfigurationInterface { $obj = $this->findOneBy([ diff --git a/src/Doctrine/ORM/GiftCardRepository.php b/src/Doctrine/ORM/GiftCardRepository.php index baf41728..43b37f40 100644 --- a/src/Doctrine/ORM/GiftCardRepository.php +++ b/src/Doctrine/ORM/GiftCardRepository.php @@ -15,6 +15,7 @@ class GiftCardRepository extends EntityRepository implements GiftCardRepositoryInterface { + #[\Override] public function createListQueryBuilder(): QueryBuilder { return $this->createQueryBuilder('o') @@ -23,6 +24,7 @@ public function createListQueryBuilder(): QueryBuilder ; } + #[\Override] public function findOneEnabledByCodeAndChannel(string $code, ChannelInterface $channel): ?GiftCardInterface { $giftCard = $this->findOneBy([ @@ -35,6 +37,7 @@ public function findOneEnabledByCodeAndChannel(string $code, ChannelInterface $c return $giftCard; } + #[\Override] public function findOneByCode(string $code): ?GiftCardInterface { $giftCard = $this->findOneBy([ @@ -45,6 +48,7 @@ public function findOneByCode(string $code): ?GiftCardInterface return $giftCard; } + #[\Override] public function findOneByOrderItemUnit(OrderItemUnitInterface $orderItemUnit): ?GiftCardInterface { $giftCard = $this->findOneBy([ @@ -55,6 +59,7 @@ public function findOneByOrderItemUnit(OrderItemUnitInterface $orderItemUnit): ? return $giftCard; } + #[\Override] public function findEnabled(): array { $giftCards = $this->findBy([ @@ -66,6 +71,7 @@ public function findEnabled(): array return $giftCards; } + #[\Override] public function createAccountListQueryBuilder(CustomerInterface $customer): QueryBuilder { $qb = $this->createListQueryBuilder(); diff --git a/src/EmailManager/GiftCardEmailManager.php b/src/EmailManager/GiftCardEmailManager.php index 2bafce64..4965e68e 100644 --- a/src/EmailManager/GiftCardEmailManager.php +++ b/src/EmailManager/GiftCardEmailManager.php @@ -45,6 +45,7 @@ public function __construct( $this->cacheDir = $cacheDir; } + #[\Override] public function sendEmailToCustomerWithGiftCard(CustomerInterface $customer, GiftCardInterface $giftCard): void { $email = $customer->getEmail(); @@ -72,6 +73,7 @@ public function sendEmailToCustomerWithGiftCard(CustomerInterface $customer, Gif }); } + #[\Override] public function sendEmailWithGiftCardsFromOrder(OrderInterface $order, array $giftCards): void { $customer = $order->getCustomer(); diff --git a/src/EventSubscriber/DefaultGiftCardConfigurationSubscriber.php b/src/EventSubscriber/DefaultGiftCardConfigurationSubscriber.php index f6a8ac3f..4a5ba744 100644 --- a/src/EventSubscriber/DefaultGiftCardConfigurationSubscriber.php +++ b/src/EventSubscriber/DefaultGiftCardConfigurationSubscriber.php @@ -22,6 +22,7 @@ public function __construct(GiftCardConfigurationRepositoryInterface $giftCardCo $this->giftCardConfigurationRepository = $giftCardConfigurationRepository; } + #[\Override] public static function getSubscribedEvents(): array { return [ diff --git a/src/EventSubscriber/GiftCardDeletionSubscriber.php b/src/EventSubscriber/GiftCardDeletionSubscriber.php index 5978e751..bf1c1c4b 100644 --- a/src/EventSubscriber/GiftCardDeletionSubscriber.php +++ b/src/EventSubscriber/GiftCardDeletionSubscriber.php @@ -11,6 +11,7 @@ final class GiftCardDeletionSubscriber implements EventSubscriberInterface { + #[\Override] public static function getSubscribedEvents(): array { return [ diff --git a/src/EventSubscriber/SendEmailWithGiftCardToCustomerSubscriber.php b/src/EventSubscriber/SendEmailWithGiftCardToCustomerSubscriber.php index 7a6c37d4..e913a182 100644 --- a/src/EventSubscriber/SendEmailWithGiftCardToCustomerSubscriber.php +++ b/src/EventSubscriber/SendEmailWithGiftCardToCustomerSubscriber.php @@ -23,6 +23,7 @@ public function __construct(GiftCardEmailManagerInterface $giftCardEmailManager) $this->giftCardEmailManager = $giftCardEmailManager; } + #[\Override] public static function getSubscribedEvents(): array { return [ diff --git a/src/Factory/GiftCardConfigurationFactory.php b/src/Factory/GiftCardConfigurationFactory.php index f51fc279..036e5104 100644 --- a/src/Factory/GiftCardConfigurationFactory.php +++ b/src/Factory/GiftCardConfigurationFactory.php @@ -30,6 +30,7 @@ public function __construct( $this->defaultPageSize = $defaultPageSize; } + #[\Override] public function createNew(): GiftCardConfigurationInterface { /** @var GiftCardConfigurationInterface $configuration */ diff --git a/src/Factory/GiftCardConfigurationFactoryInterface.php b/src/Factory/GiftCardConfigurationFactoryInterface.php index 209831a1..0422233e 100644 --- a/src/Factory/GiftCardConfigurationFactoryInterface.php +++ b/src/Factory/GiftCardConfigurationFactoryInterface.php @@ -9,5 +9,6 @@ interface GiftCardConfigurationFactoryInterface extends FactoryInterface { + #[\Override] public function createNew(): GiftCardConfigurationInterface; } diff --git a/src/Factory/GiftCardFactory.php b/src/Factory/GiftCardFactory.php index 8b20f042..7e41ce75 100644 --- a/src/Factory/GiftCardFactory.php +++ b/src/Factory/GiftCardFactory.php @@ -28,6 +28,7 @@ public function __construct( ) { } + #[\Override] public function createNew(): GiftCardInterface { /** @var GiftCardInterface $giftCard */ @@ -37,6 +38,7 @@ public function createNew(): GiftCardInterface return $giftCard; } + #[\Override] public function createForChannel(ChannelInterface $channel): GiftCardInterface { $giftCard = $this->createNew(); @@ -53,6 +55,7 @@ public function createForChannel(ChannelInterface $channel): GiftCardInterface return $giftCard; } + #[\Override] public function createForChannelFromAdmin(ChannelInterface $channel): GiftCardInterface { $giftCard = $this->createForChannel($channel); @@ -61,6 +64,7 @@ public function createForChannelFromAdmin(ChannelInterface $channel): GiftCardIn return $giftCard; } + #[\Override] public function createFromOrderItemUnit(OrderItemUnitInterface $orderItemUnit): GiftCardInterface { /** @var OrderInterface|null $order */ @@ -78,6 +82,7 @@ public function createFromOrderItemUnit(OrderItemUnitInterface $orderItemUnit): return $giftCard; } + #[\Override] public function createFromOrderItemUnitAndCart( OrderItemUnitInterface $orderItemUnit, OrderInterface $cart, @@ -98,6 +103,7 @@ public function createFromOrderItemUnitAndCart( return $giftCard; } + #[\Override] public function createExample(): GiftCardInterface { $giftCard = $this->createNew(); diff --git a/src/Factory/GiftCardFactoryInterface.php b/src/Factory/GiftCardFactoryInterface.php index 7ac4bb3b..8abd7826 100644 --- a/src/Factory/GiftCardFactoryInterface.php +++ b/src/Factory/GiftCardFactoryInterface.php @@ -12,6 +12,7 @@ interface GiftCardFactoryInterface extends FactoryInterface { + #[\Override] public function createNew(): GiftCardInterface; public function createForChannel(ChannelInterface $channel): GiftCardInterface; diff --git a/src/Form/DataTransformer/GiftCardToCodeDataTransformer.php b/src/Form/DataTransformer/GiftCardToCodeDataTransformer.php index 932312b8..becf36b6 100644 --- a/src/Form/DataTransformer/GiftCardToCodeDataTransformer.php +++ b/src/Form/DataTransformer/GiftCardToCodeDataTransformer.php @@ -28,6 +28,7 @@ public function __construct( /** * @param GiftCardInterface|mixed $value */ + #[\Override] public function transform($value): ?string { if (null === $value || '' === $value) { @@ -39,6 +40,7 @@ public function transform($value): ?string return $value->getCode(); } + #[\Override] public function reverseTransform($value): ?GiftCardInterface { if (null === $value || '' === $value) { diff --git a/src/Form/Extension/AddToCartTypeExtension.php b/src/Form/Extension/AddToCartTypeExtension.php index 16413fae..ec8f5f37 100644 --- a/src/Form/Extension/AddToCartTypeExtension.php +++ b/src/Form/Extension/AddToCartTypeExtension.php @@ -25,6 +25,7 @@ public function __construct( ) { } + #[\Override] public static function getExtendedTypes(): iterable { return [ @@ -32,6 +33,7 @@ public static function getExtendedTypes(): iterable ]; } + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'reworkFormForGiftCard']); diff --git a/src/Form/Extension/ProductTypeExtension.php b/src/Form/Extension/ProductTypeExtension.php index 88f624da..fc47c0c2 100644 --- a/src/Form/Extension/ProductTypeExtension.php +++ b/src/Form/Extension/ProductTypeExtension.php @@ -11,6 +11,7 @@ final class ProductTypeExtension extends AbstractTypeExtension { + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('giftCard', CheckboxType::class, [ @@ -23,6 +24,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ]); } + #[\Override] public static function getExtendedTypes(): iterable { return [ diff --git a/src/Form/Type/AddGiftCardToOrderType.php b/src/Form/Type/AddGiftCardToOrderType.php index 3e514d6f..0277b83b 100644 --- a/src/Form/Type/AddGiftCardToOrderType.php +++ b/src/Form/Type/AddGiftCardToOrderType.php @@ -26,6 +26,7 @@ public function __construct(DataTransformerInterface $giftCardToCodeDataTransfor $this->validationGroups = $validationGroups; } + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder @@ -41,6 +42,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder->get('giftCard')->addModelTransformer($this->giftCardToCodeDataTransformer); } + #[\Override] public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ @@ -49,6 +51,7 @@ public function configureOptions(OptionsResolver $resolver): void ]); } + #[\Override] public function getBlockPrefix(): string { return 'setono_sylius_gift_card_add_gift_card_to_order'; diff --git a/src/Form/Type/AddToCartGiftCardInformationType.php b/src/Form/Type/AddToCartGiftCardInformationType.php index 79291439..2e29d830 100644 --- a/src/Form/Type/AddToCartGiftCardInformationType.php +++ b/src/Form/Type/AddToCartGiftCardInformationType.php @@ -45,6 +45,7 @@ public function __construct( $this->channelContext = $channelContext; } + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options): void { @@ -84,6 +85,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ]); } + #[\Override] public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefault('data_class', $this->dataClass); diff --git a/src/Form/Type/CustomerAutocompleteChoiceType.php b/src/Form/Type/CustomerAutocompleteChoiceType.php index 25dd5d51..42b37a4c 100644 --- a/src/Form/Type/CustomerAutocompleteChoiceType.php +++ b/src/Form/Type/CustomerAutocompleteChoiceType.php @@ -20,6 +20,7 @@ public function __construct(UrlGeneratorInterface $urlGenerator) $this->urlGenerator = $urlGenerator; } + #[\Override] public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ @@ -29,6 +30,7 @@ public function configureOptions(OptionsResolver $resolver): void ]); } + #[\Override] public function buildView(FormView $view, FormInterface $form, array $options): void { $view->vars['remote_criteria_type'] = 'contains'; @@ -37,11 +39,13 @@ public function buildView(FormView $view, FormInterface $form, array $options): $view->vars['load_edit_url'] = $this->urlGenerator->generate('setono_sylius_gift_card_admin_ajax_customer_by_email'); } + #[\Override] public function getBlockPrefix(): string { return 'setono_sylius_gift_card_customer_autocomplete_choice'; } + #[\Override] public function getParent(): string { return ResourceAutocompleteChoiceType::class; diff --git a/src/Form/Type/DatePeriodType.php b/src/Form/Type/DatePeriodType.php index cf9dc367..3c7afaf3 100644 --- a/src/Form/Type/DatePeriodType.php +++ b/src/Form/Type/DatePeriodType.php @@ -19,6 +19,7 @@ public function __construct(DatePeriodUnitProviderInterface $datePeriodUnitProvi $this->datePeriodUnitProvider = $datePeriodUnitProvider; } + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('value', IntegerType::class, [ diff --git a/src/Form/Type/GiftCardChannelConfigurationType.php b/src/Form/Type/GiftCardChannelConfigurationType.php index 189f2695..a6371c77 100644 --- a/src/Form/Type/GiftCardChannelConfigurationType.php +++ b/src/Form/Type/GiftCardChannelConfigurationType.php @@ -11,6 +11,7 @@ final class GiftCardChannelConfigurationType extends AbstractResourceType { + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('channel', ChannelChoiceType::class, [ @@ -23,6 +24,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void ]); } + #[\Override] public function getBlockPrefix(): string { return 'setono_sylius_gift_card_gift_card_channel_configuration'; diff --git a/src/Form/Type/GiftCardConfigurationImageType.php b/src/Form/Type/GiftCardConfigurationImageType.php index 29f1c05f..20365828 100644 --- a/src/Form/Type/GiftCardConfigurationImageType.php +++ b/src/Form/Type/GiftCardConfigurationImageType.php @@ -10,6 +10,7 @@ final class GiftCardConfigurationImageType extends ImageType { + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { parent::buildForm($builder, $options); @@ -19,6 +20,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void } } + #[\Override] public function configureOptions(OptionsResolver $resolver): void { parent::configureOptions($resolver); @@ -27,6 +29,7 @@ public function configureOptions(OptionsResolver $resolver): void $resolver->setAllowedTypes('remove_type', ['bool']); } + #[\Override] public function getBlockPrefix(): string { return 'setono_sylius_gift_card_gift_card_configuration_image'; diff --git a/src/Form/Type/GiftCardConfigurationType.php b/src/Form/Type/GiftCardConfigurationType.php index bc58f366..3b448ed2 100644 --- a/src/Form/Type/GiftCardConfigurationType.php +++ b/src/Form/Type/GiftCardConfigurationType.php @@ -44,6 +44,7 @@ public function __construct( $this->preferredPageSizes = $preferredPageSizes; } + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('code', TextType::class, [ @@ -119,6 +120,7 @@ function (array $data): ?string { ); } + #[\Override] public function getBlockPrefix(): string { return 'setono_sylius_gift_card_gift_card_configuration'; diff --git a/src/Form/Type/GiftCardSearchType.php b/src/Form/Type/GiftCardSearchType.php index a4c84ee4..dbddbc16 100644 --- a/src/Form/Type/GiftCardSearchType.php +++ b/src/Form/Type/GiftCardSearchType.php @@ -23,6 +23,7 @@ public function __construct(DataTransformerInterface $giftCardToCodeDataTransfor $this->validationGroups = $validationGroups; } + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder @@ -38,6 +39,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $builder->get('giftCard')->addModelTransformer($this->giftCardToCodeDataTransformer); } + #[\Override] public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ @@ -46,6 +48,7 @@ public function configureOptions(OptionsResolver $resolver): void ]); } + #[\Override] public function getBlockPrefix(): string { return 'setono_sylius_gift_card_gift_card_search'; diff --git a/src/Form/Type/GiftCardType.php b/src/Form/Type/GiftCardType.php index 9557acfa..7f8dd0f2 100644 --- a/src/Form/Type/GiftCardType.php +++ b/src/Form/Type/GiftCardType.php @@ -42,6 +42,7 @@ public function __construct( $this->giftCardCodeGenerator = $giftCardCodeGenerator; } + #[\Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->addEventSubscriber(new AddCodeFormSubscriber()); @@ -118,10 +119,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void return null; } - return (int) round($amount * 100); + return (int) round($amount * 100.0); })); } + #[\Override] public function getBlockPrefix(): string { return 'setono_sylius_gift_card_gift_card'; diff --git a/src/Generator/GiftCardCodeGenerator.php b/src/Generator/GiftCardCodeGenerator.php index 8ec1baaf..4bbb4fd6 100644 --- a/src/Generator/GiftCardCodeGenerator.php +++ b/src/Generator/GiftCardCodeGenerator.php @@ -26,6 +26,7 @@ public function __construct(GiftCardRepositoryInterface $giftCardRepository, int $this->codeLength = $codeLength; } + #[\Override] public function generate(): string { do { @@ -34,6 +35,7 @@ public function generate(): string /** @psalm-suppress ArgumentTypeCoercion */ $code = bin2hex(random_bytes($this->codeLength)); $code = preg_replace('/[01]/', '', $code); // remove hard to read characters + Assert::notNull($code); $code = mb_strtoupper(mb_substr($code, 0, $this->codeLength)); } while (mb_strlen($code) !== $this->codeLength || $this->exists($code)); diff --git a/src/Grid/FieldTypes/StringFieldType.php b/src/Grid/FieldTypes/StringFieldType.php index ad902eb3..4f0eb040 100644 --- a/src/Grid/FieldTypes/StringFieldType.php +++ b/src/Grid/FieldTypes/StringFieldType.php @@ -21,6 +21,7 @@ public function __construct(PropertyAccessorInterface $propertyAccessor) $this->propertyAccessor = $propertyAccessor; } + #[\Override] public function render(Field $field, mixed $data, array $options): string { try { @@ -38,6 +39,7 @@ public function render(Field $field, mixed $data, array $options): string return htmlspecialchars((string) $value); } + #[\Override] public function configureOptions(OptionsResolver $resolver): void { } diff --git a/src/Migrations/Version20260729000001.php b/src/Migrations/Version20260729000001.php index 4383b5ec..4f71d39a 100644 --- a/src/Migrations/Version20260729000001.php +++ b/src/Migrations/Version20260729000001.php @@ -9,11 +9,13 @@ final class Version20260729000001 extends AbstractMigration { + #[\Override] public function getDescription(): string { return 'Create gift card tables and add gift card columns to sylius_product'; } + #[\Override] public function up(Schema $schema): void { $this->addSql('CREATE TABLE setono_sylius_gift_card__configuration (id INT AUTO_INCREMENT NOT NULL, code VARCHAR(255) NOT NULL, enabled TINYINT(1) NOT NULL, is_default TINYINT(1) DEFAULT 0 NOT NULL, defaultValidityPeriod VARCHAR(255) DEFAULT NULL, pageSize VARCHAR(255) DEFAULT NULL, orientation VARCHAR(255) DEFAULT NULL, template LONGTEXT NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME DEFAULT NULL, UNIQUE INDEX UNIQ_ADC64AD077153098 (code), PRIMARY KEY(id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB'); @@ -35,6 +37,7 @@ public function up(Schema $schema): void $this->addSql('ALTER TABLE sylius_product ADD giftCard TINYINT(1) DEFAULT 0 NOT NULL, ADD giftCardAmountConfigurable TINYINT(1) DEFAULT 0 NOT NULL'); } + #[\Override] public function down(Schema $schema): void { $this->addSql('ALTER TABLE sylius_product DROP giftCard, DROP giftCardAmountConfigurable'); diff --git a/src/Model/GiftCard.php b/src/Model/GiftCard.php index 26c70120..cee52b00 100644 --- a/src/Model/GiftCard.php +++ b/src/Model/GiftCard.php @@ -60,31 +60,37 @@ public function __toString(): string return (string) $this->code; } + #[\Override] public function getCode(): ?string { return $this->code; } + #[\Override] public function setCode(?string $code): void { $this->code = $code; } + #[\Override] public function getId(): ?int { return $this->id; } + #[\Override] public function isDeletable(): bool { return null === $this->orderItemUnit; } + #[\Override] public function getOrderItemUnit(): ?OrderItemUnitInterface { return $this->orderItemUnit; } + #[\Override] public function setOrderItemUnit(OrderItemUnitInterface $orderItemUnit): void { if ($this->orderItemUnit === $orderItemUnit) { @@ -96,6 +102,7 @@ public function setOrderItemUnit(OrderItemUnitInterface $orderItemUnit): void $orderItemUnit->setGiftCard($this); } + #[\Override] public function getOrder(): ?OrderInterface { $orderItemUnit = $this->getOrderItemUnit(); @@ -112,21 +119,25 @@ public function getOrder(): ?OrderInterface return $order; } + #[\Override] public function getCustomer(): ?CustomerInterface { return $this->customer; } + #[\Override] public function setCustomer(?CustomerInterface $customer): void { $this->customer = $customer; } + #[\Override] public function getInitialAmount(): ?int { return $this->initialAmount; } + #[\Override] public function setInitialAmount(int $initialAmount): void { if (null !== $this->initialAmount) { @@ -136,11 +147,13 @@ public function setInitialAmount(int $initialAmount): void $this->initialAmount = $initialAmount; } + #[\Override] public function getAmount(): int { return $this->amount; } + #[\Override] public function setAmount(int $amount): void { if (null === $this->initialAmount) { @@ -150,16 +163,19 @@ public function setAmount(int $amount): void $this->amount = $amount; } + #[\Override] public function getAppliedOrders(): Collection { return $this->appliedOrders; } + #[\Override] public function hasAppliedOrders(): bool { return !$this->getAppliedOrders()->isEmpty(); } + #[\Override] public function hasAppliedCompletedOrders(): bool { foreach ($this->appliedOrders as $appliedOrder) { @@ -171,6 +187,7 @@ public function hasAppliedCompletedOrders(): bool return false; } + #[\Override] public function addAppliedOrder(OrderInterface $order): void { if (!$this->hasAppliedOrder($order)) { @@ -178,6 +195,7 @@ public function addAppliedOrder(OrderInterface $order): void } } + #[\Override] public function removeAppliedOrder(OrderInterface $order): void { if ($this->hasAppliedOrder($order)) { @@ -185,31 +203,37 @@ public function removeAppliedOrder(OrderInterface $order): void } } + #[\Override] public function hasAppliedOrder(OrderInterface $order): bool { return $this->appliedOrders->contains($order); } + #[\Override] public function getCurrencyCode(): ?string { return $this->currencyCode; } + #[\Override] public function setCurrencyCode(string $currencyCode): void { $this->currencyCode = $currencyCode; } + #[\Override] public function getChannel(): ?ChannelInterface { return $this->channel; } + #[\Override] public function setChannel(ChannelInterface $channel): void { $this->channel = $channel; } + #[\Override] public function getCustomerIdentification(): ?array { $customer = $this->getCustomer(); @@ -223,6 +247,7 @@ public function getCustomerIdentification(): ?array ]; } + #[\Override] public function getOrderIdentification(): ?array { $order = $this->getOrder(); @@ -244,6 +269,7 @@ public function getOrderIdentification(): ?array ]; } + #[\Override] public function getChannelCode(): ?string { $channel = $this->getChannel(); @@ -254,41 +280,49 @@ public function getChannelCode(): ?string return $channel->getCode(); } + #[\Override] public function hasOrderOrCustomer(): bool { return null !== $this->getCustomer() || null !== $this->getOrder(); } + #[\Override] public function getCustomMessage(): ?string { return $this->customMessage; } + #[\Override] public function setCustomMessage(?string $customMessage): void { $this->customMessage = $customMessage; } + #[\Override] public function setOrigin(?string $origin): void { $this->origin = $origin; } + #[\Override] public function getOrigin(): ?string { return $this->origin; } + #[\Override] public function getExpiresAt(): ?DateTimeInterface { return $this->expiresAt; } + #[\Override] public function setExpiresAt(?DateTimeInterface $expiresAt): void { $this->expiresAt = $expiresAt; } + #[\Override] public function isExpired(DateTimeInterface $date = null): bool { if (null === $date) { @@ -303,11 +337,13 @@ public function isExpired(DateTimeInterface $date = null): bool return $date > $giftCardValidUntil; } + #[\Override] public function getSendNotificationEmail(): bool { return $this->sendNotificationEmail; } + #[\Override] public function setSendNotificationEmail(bool $sendNotificationEmail = true): void { $this->sendNotificationEmail = $sendNotificationEmail; diff --git a/src/Model/GiftCardBalanceCollection.php b/src/Model/GiftCardBalanceCollection.php index 15ca8895..25c6bf5d 100644 --- a/src/Model/GiftCardBalanceCollection.php +++ b/src/Model/GiftCardBalanceCollection.php @@ -42,11 +42,13 @@ public static function createFromGiftCards(iterable $giftCards): self return $collection; } + #[\Override] public function count(): int { return count($this->collection); } + #[\Override] public function current(): GiftCardBalance { $cur = current($this->collection); @@ -57,11 +59,13 @@ public function current(): GiftCardBalance return $cur; } + #[\Override] public function next(): void { next($this->collection); } + #[\Override] public function key(): ?string { $k = (string) key($this->collection); @@ -69,11 +73,13 @@ public function key(): ?string return '' === $k ? null : $k; } + #[\Override] public function valid(): bool { return key($this->collection) !== null; } + #[\Override] public function rewind(): void { reset($this->collection); diff --git a/src/Model/GiftCardChannelConfiguration.php b/src/Model/GiftCardChannelConfiguration.php index 46ade47e..83dcefb3 100644 --- a/src/Model/GiftCardChannelConfiguration.php +++ b/src/Model/GiftCardChannelConfiguration.php @@ -18,37 +18,44 @@ class GiftCardChannelConfiguration implements GiftCardChannelConfigurationInterf protected ?GiftCardConfigurationInterface $configuration = null; + #[\Override] public function getId(): ?int { return $this->id; } + #[\Override] public function getChannel(): ?ChannelInterface { return $this->channel; } + #[\Override] public function setChannel(?ChannelInterface $channel): void { Assert::notNull($channel); $this->channel = $channel; } + #[\Override] public function getLocale(): ?LocaleInterface { return $this->locale; } + #[\Override] public function setLocale(LocaleInterface $locale): void { $this->locale = $locale; } + #[\Override] public function getConfiguration(): ?GiftCardConfigurationInterface { return $this->configuration; } + #[\Override] public function setConfiguration(?GiftCardConfigurationInterface $configuration): void { $this->configuration = $configuration; diff --git a/src/Model/GiftCardConfiguration.php b/src/Model/GiftCardConfiguration.php index 48bb2322..55bcb560 100644 --- a/src/Model/GiftCardConfiguration.php +++ b/src/Model/GiftCardConfiguration.php @@ -47,26 +47,31 @@ public function __construct() $this->channelConfigurations = new ArrayCollection(); } + #[\Override] public function getId(): ?int { return $this->id; } + #[\Override] public function getCode(): ?string { return $this->code; } + #[\Override] public function setCode(?string $code): void { $this->code = $code; } + #[\Override] public function getImages(): Collection { return $this->images; } + #[\Override] public function getImagesByType(string $type): Collection { return $this->images->filter(function (ImageInterface $image) use ($type): bool { @@ -74,16 +79,19 @@ public function getImagesByType(string $type): Collection }); } + #[\Override] public function hasImages(): bool { return !$this->getImages()->isEmpty(); } + #[\Override] public function hasImage(ImageInterface $image): bool { return $this->getImages()->contains($image); } + #[\Override] public function addImage(ImageInterface $image): void { if (!$this->hasImage($image)) { @@ -92,6 +100,7 @@ public function addImage(ImageInterface $image): void } } + #[\Override] public function removeImage(ImageInterface $image): void { if ($this->hasImage($image)) { @@ -100,6 +109,7 @@ public function removeImage(ImageInterface $image): void } } + #[\Override] public function getBackgroundImage(): ?GiftCardConfigurationImageInterface { $images = $this->getImagesByType(GiftCardConfigurationImageInterface::TYPE_BACKGROUND); @@ -113,6 +123,7 @@ public function getBackgroundImage(): ?GiftCardConfigurationImageInterface return $image; } + #[\Override] public function setBackgroundImage(?GiftCardConfigurationImageInterface $image): void { $actualImage = $this->getBackgroundImage(); @@ -130,21 +141,25 @@ public function setBackgroundImage(?GiftCardConfigurationImageInterface $image): $this->addImage($image); } + #[\Override] public function getChannelConfigurations(): Collection { return $this->channelConfigurations; } + #[\Override] public function hasChannelConfigurations(): bool { return !$this->channelConfigurations->isEmpty(); } + #[\Override] public function hasChannelConfiguration(GiftCardChannelConfigurationInterface $channelConfiguration): bool { return $this->channelConfigurations->contains($channelConfiguration); } + #[\Override] public function addChannelConfiguration(GiftCardChannelConfigurationInterface $channelConfiguration): void { if (!$this->hasChannelConfiguration($channelConfiguration)) { @@ -153,6 +168,7 @@ public function addChannelConfiguration(GiftCardChannelConfigurationInterface $c } } + #[\Override] public function removeChannelConfiguration(GiftCardChannelConfigurationInterface $channelConfiguration): void { if ($this->hasChannelConfiguration($channelConfiguration)) { @@ -161,51 +177,61 @@ public function removeChannelConfiguration(GiftCardChannelConfigurationInterface } } + #[\Override] public function isDefault(): bool { return $this->default; } + #[\Override] public function setDefault(bool $default): void { $this->default = $default; } + #[\Override] public function getDefaultValidityPeriod(): ?string { return $this->defaultValidityPeriod; } + #[\Override] public function setDefaultValidityPeriod(?string $defaultValidityPeriod): void { $this->defaultValidityPeriod = $defaultValidityPeriod; } + #[\Override] public function getPageSize(): ?string { return $this->pageSize; } + #[\Override] public function setPageSize(?string $pageSize): void { $this->pageSize = $pageSize; } + #[\Override] public function getOrientation(): ?string { return $this->orientation; } + #[\Override] public function setOrientation(?string $orientation): void { $this->orientation = $orientation; } + #[\Override] public function getTemplate(): ?string { return $this->template; } + #[\Override] public function setTemplate(?string $template): void { $this->template = $template; diff --git a/src/Model/GiftCardInterface.php b/src/Model/GiftCardInterface.php index 770dde2e..0b88c50a 100644 --- a/src/Model/GiftCardInterface.php +++ b/src/Model/GiftCardInterface.php @@ -23,6 +23,7 @@ interface GiftCardInterface extends ResourceInterface, ToggleableInterface, Code public function __toString(): string; + #[\Override] public function getId(): ?int; /** @@ -70,6 +71,7 @@ public function getInitialAmount(): ?int; */ public function setInitialAmount(int $initialAmount): void; + #[\Override] public function isEnabled(): bool; public function getCurrencyCode(): ?string; diff --git a/src/Modifier/OrderGiftCardAmountModifier.php b/src/Modifier/OrderGiftCardAmountModifier.php index 75faca80..19f4722b 100644 --- a/src/Modifier/OrderGiftCardAmountModifier.php +++ b/src/Modifier/OrderGiftCardAmountModifier.php @@ -15,6 +15,7 @@ */ final class OrderGiftCardAmountModifier implements OrderGiftCardAmountModifierInterface { + #[\Override] public function decrement(OrderInterface $order): void { foreach ($order->getAdjustments(AdjustmentInterface::ORDER_GIFT_CARD_ADJUSTMENT) as $adjustment) { @@ -35,6 +36,7 @@ public function decrement(OrderInterface $order): void } } + #[\Override] public function increment(OrderInterface $order): void { foreach ($order->getAdjustments(AdjustmentInterface::ORDER_GIFT_CARD_ADJUSTMENT) as $adjustment) { diff --git a/src/Operator/OrderGiftCardOperator.php b/src/Operator/OrderGiftCardOperator.php index 5cdc3a2e..93909131 100644 --- a/src/Operator/OrderGiftCardOperator.php +++ b/src/Operator/OrderGiftCardOperator.php @@ -33,6 +33,7 @@ public function __construct( $this->giftCardOrderEmailManager = $giftCardOrderEmailManager; } + #[\Override] public function associateToCustomer(OrderInterface $order): void { $items = self::getOrderItemsThatAreGiftCards($order); @@ -58,6 +59,7 @@ public function associateToCustomer(OrderInterface $order): void $this->giftCardManager->flush(); } + #[\Override] public function enable(OrderInterface $order): void { $giftCards = $this->getGiftCards($order); @@ -77,6 +79,7 @@ public function enable(OrderInterface $order): void * Calls when Order this GiftCardCode was bought at * become cancelled */ + #[\Override] public function disable(OrderInterface $order): void { $giftCards = $this->getGiftCards($order); @@ -92,6 +95,7 @@ public function disable(OrderInterface $order): void $this->giftCardManager->flush(); } + #[\Override] public function send(OrderInterface $order): void { $giftCards = $this->getGiftCards($order); diff --git a/src/Order/AddToCartCommand.php b/src/Order/AddToCartCommand.php index 6a815e46..8385295d 100644 --- a/src/Order/AddToCartCommand.php +++ b/src/Order/AddToCartCommand.php @@ -7,13 +7,13 @@ use Setono\SyliusGiftCardPlugin\Model\OrderInterface; use Sylius\Component\Core\Model\OrderItemInterface; -class AddToCartCommand implements AddToCartCommandInterface +final class AddToCartCommand implements AddToCartCommandInterface { - protected OrderInterface $cart; + private OrderInterface $cart; - protected OrderItemInterface $cartItem; + private OrderItemInterface $cartItem; - protected GiftCardInformationInterface $giftCardInformation; + private GiftCardInformationInterface $giftCardInformation; public function __construct( OrderInterface $cart, @@ -25,16 +25,19 @@ public function __construct( $this->giftCardInformation = $giftCardInformation; } + #[\Override] public function getCart(): OrderInterface { return $this->cart; } + #[\Override] public function getCartItem(): OrderItemInterface { return $this->cartItem; } + #[\Override] public function getGiftCardInformation(): GiftCardInformationInterface { return $this->giftCardInformation; diff --git a/src/Order/AddToCartCommandInterface.php b/src/Order/AddToCartCommandInterface.php index fb205306..e526f628 100644 --- a/src/Order/AddToCartCommandInterface.php +++ b/src/Order/AddToCartCommandInterface.php @@ -10,8 +10,10 @@ interface AddToCartCommandInterface extends BaseCommandInterface { + #[\Override] public function getCart(): OrderInterface; + #[\Override] public function getCartItem(): OrderItemInterface; public function getGiftCardInformation(): GiftCardInformationInterface; diff --git a/src/Order/Factory/AddToCartCommandFactory.php b/src/Order/Factory/AddToCartCommandFactory.php index b257073b..9deebde5 100644 --- a/src/Order/Factory/AddToCartCommandFactory.php +++ b/src/Order/Factory/AddToCartCommandFactory.php @@ -27,6 +27,7 @@ public function __construct( $this->giftCardInformationFactory = $giftCardInformationFactory; } + #[\Override] public function createWithCartAndCartItem(OrderInterface $cart, OrderItemInterface $cartItem): AddToCartCommandInterface { return new $this->className($cart, $cartItem, $this->giftCardInformationFactory->createNew($cartItem)); diff --git a/src/Order/Factory/GiftCardInformationFactory.php b/src/Order/Factory/GiftCardInformationFactory.php index 5275433b..c35e7a03 100644 --- a/src/Order/Factory/GiftCardInformationFactory.php +++ b/src/Order/Factory/GiftCardInformationFactory.php @@ -20,6 +20,7 @@ public function __construct(string $className) $this->className = $className; } + #[\Override] public function createNew(OrderItemInterface $orderItem): GiftCardInformationInterface { return new $this->className($orderItem->getUnitPrice()); diff --git a/src/Order/GiftCardInformation.php b/src/Order/GiftCardInformation.php index 5d260746..51909c5f 100644 --- a/src/Order/GiftCardInformation.php +++ b/src/Order/GiftCardInformation.php @@ -4,11 +4,11 @@ namespace Setono\SyliusGiftCardPlugin\Order; -class GiftCardInformation implements GiftCardInformationInterface +final class GiftCardInformation implements GiftCardInformationInterface { - protected int $amount; + private int $amount; - protected ?string $customMessage; + private ?string $customMessage; public function __construct(int $amount, string $customMessage = null) { @@ -16,21 +16,25 @@ public function __construct(int $amount, string $customMessage = null) $this->customMessage = $customMessage; } + #[\Override] public function getAmount(): int { return $this->amount; } + #[\Override] public function setAmount(int $amount): void { $this->amount = $amount; } + #[\Override] public function getCustomMessage(): ?string { return $this->customMessage; } + #[\Override] public function setCustomMessage(?string $customMessage): void { $this->customMessage = $customMessage; diff --git a/src/OrderProcessor/OrderGiftCardProcessor.php b/src/OrderProcessor/OrderGiftCardProcessor.php index f31ff588..ca566b31 100644 --- a/src/OrderProcessor/OrderGiftCardProcessor.php +++ b/src/OrderProcessor/OrderGiftCardProcessor.php @@ -34,6 +34,7 @@ public function __construct( /** * @param BaseOrderInterface|OrderInterface $order */ + #[\Override] public function process(BaseOrderInterface $order): void { Assert::isInstanceOf($order, OrderInterface::class); diff --git a/src/Promotion/Checker/Rule/HasNoGiftCardRuleChecker.php b/src/Promotion/Checker/Rule/HasNoGiftCardRuleChecker.php index 710ede3c..1c7628de 100644 --- a/src/Promotion/Checker/Rule/HasNoGiftCardRuleChecker.php +++ b/src/Promotion/Checker/Rule/HasNoGiftCardRuleChecker.php @@ -14,6 +14,7 @@ final class HasNoGiftCardRuleChecker implements RuleCheckerInterface { public const TYPE = 'has_no_gift_card'; + #[\Override] public function isEligible(PromotionSubjectInterface $subject, array $configuration): bool { Assert::isInstanceOf($subject, OrderInterface::class); diff --git a/src/Provider/DatePeriodUnitProvider.php b/src/Provider/DatePeriodUnitProvider.php index 8445c49a..b9072a5b 100644 --- a/src/Provider/DatePeriodUnitProvider.php +++ b/src/Provider/DatePeriodUnitProvider.php @@ -4,8 +4,9 @@ namespace Setono\SyliusGiftCardPlugin\Provider; -class DatePeriodUnitProvider implements DatePeriodUnitProviderInterface +final class DatePeriodUnitProvider implements DatePeriodUnitProviderInterface { + #[\Override] public function getPeriodUnits(): array { return [ diff --git a/src/Provider/DefaultGiftCardTemplateContentProvider.php b/src/Provider/DefaultGiftCardTemplateContentProvider.php index 0886ecff..71580bd9 100644 --- a/src/Provider/DefaultGiftCardTemplateContentProvider.php +++ b/src/Provider/DefaultGiftCardTemplateContentProvider.php @@ -6,6 +6,7 @@ final class DefaultGiftCardTemplateContentProvider implements DefaultGiftCardTemplateContentProviderInterface { + #[\Override] public function getContent(): string { return <<managerRegistry = $managerRegistry; } + #[\Override] public function getConfiguration(BaseChannelInterface $channel, LocaleInterface $locale): GiftCardConfigurationInterface { $configuration = $this->giftCardConfigurationRepository->findOneByChannelAndLocale($channel, $locale); @@ -70,6 +71,7 @@ public function getConfiguration(BaseChannelInterface $channel, LocaleInterface return $configuration; } + #[\Override] public function getConfigurationForGiftCard(GiftCardInterface $giftCard): GiftCardConfigurationInterface { $channel = $giftCard->getChannel(); diff --git a/src/Provider/OrderEligibleTotalProvider.php b/src/Provider/OrderEligibleTotalProvider.php index f637e273..2b15c4af 100644 --- a/src/Provider/OrderEligibleTotalProvider.php +++ b/src/Provider/OrderEligibleTotalProvider.php @@ -9,6 +9,7 @@ final class OrderEligibleTotalProvider implements OrderEligibleTotalProviderInterface { + #[\Override] public function getEligibleTotal(OrderInterface $order, GiftCardInterface $giftCard): int { return $order->getTotal(); diff --git a/src/Provider/PdfRenderingOptionsProvider.php b/src/Provider/PdfRenderingOptionsProvider.php index 329bd148..2d1019c6 100644 --- a/src/Provider/PdfRenderingOptionsProvider.php +++ b/src/Provider/PdfRenderingOptionsProvider.php @@ -8,6 +8,7 @@ final class PdfRenderingOptionsProvider implements PdfRenderingOptionsProviderInterface { + #[\Override] public function getRenderingOptions(GiftCardConfigurationInterface $giftCardConfiguration): array { $options = []; diff --git a/src/Renderer/PdfRenderer.php b/src/Renderer/PdfRenderer.php index 06e6b7cf..496b9046 100644 --- a/src/Renderer/PdfRenderer.php +++ b/src/Renderer/PdfRenderer.php @@ -50,6 +50,7 @@ public function __construct( $this->normalizer = $normalizer; } + #[\Override] public function render( GiftCardInterface $giftCard, GiftCardConfigurationInterface $giftCardConfiguration = null, diff --git a/src/Resolver/CustomerChannelResolver.php b/src/Resolver/CustomerChannelResolver.php index 559135ce..abddabac 100644 --- a/src/Resolver/CustomerChannelResolver.php +++ b/src/Resolver/CustomerChannelResolver.php @@ -23,6 +23,7 @@ public function __construct( $this->channelRepository = $channelRepository; } + #[\Override] public function resolve(CustomerInterface $customer): ChannelInterface { $latestOrder = $this->orderRepository->findLatestByCustomer($customer); diff --git a/src/Resolver/LocaleResolver.php b/src/Resolver/LocaleResolver.php index 602c6949..ade5215e 100644 --- a/src/Resolver/LocaleResolver.php +++ b/src/Resolver/LocaleResolver.php @@ -24,6 +24,7 @@ public function __construct( $this->channelRepository = $channelRepository; } + #[\Override] public function resolveFromCustomer(CustomerInterface $customer): string { $latestOrder = $this->orderRepository->findLatestByCustomer($customer); @@ -34,6 +35,7 @@ public function resolveFromCustomer(CustomerInterface $customer): string return $this->resolve(); } + #[\Override] public function resolveFromOrder(OrderInterface $order): string { $localeCode = $order->getLocaleCode(); @@ -49,6 +51,7 @@ public function resolveFromOrder(OrderInterface $order): string return $this->resolve(); } + #[\Override] public function resolveFromChannel(ChannelInterface $channel): string { return $this->_resolveFromChannel($channel) ?? $this->resolve(); diff --git a/src/Resolver/RedirectUrlResolver.php b/src/Resolver/RedirectUrlResolver.php index a478b70c..35c8fc5a 100644 --- a/src/Resolver/RedirectUrlResolver.php +++ b/src/Resolver/RedirectUrlResolver.php @@ -18,6 +18,7 @@ public function __construct(UrlGeneratorInterface $router) $this->router = $router; } + #[\Override] public function getUrlToRedirectTo(Request $request, string $defaultRoute): string { /** @var mixed $redirect */ diff --git a/src/Security/GiftCardVoter.php b/src/Security/GiftCardVoter.php index 4a479583..a453696a 100644 --- a/src/Security/GiftCardVoter.php +++ b/src/Security/GiftCardVoter.php @@ -17,6 +17,7 @@ final class GiftCardVoter extends Voter { public const READ = 'read'; + #[\Override] protected function supports(mixed $attribute, mixed $subject): bool { if (self::READ !== $attribute) { @@ -30,6 +31,7 @@ protected function supports(mixed $attribute, mixed $subject): bool return true; } + #[\Override] protected function voteOnAttribute(mixed $attribute, mixed $subject, TokenInterface $token): bool { Assert::isInstanceOf($subject, GiftCardInterface::class); diff --git a/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php b/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php index 32a6dbd7..5367d562 100644 --- a/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php +++ b/src/Serializer/Normalizer/GiftCardConfigurationNormalizer.php @@ -34,6 +34,7 @@ public function __construct( * @param GiftCardConfigurationInterface|mixed $data * @param array $context */ + #[\Override] public function normalize($data, ?string $format = null, array $context = []): array { Assert::isInstanceOf($data, GiftCardConfigurationInterface::class); @@ -68,6 +69,7 @@ public function normalize($data, ?string $format = null, array $context = []): a return $data; } + #[\Override] public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool { $groups = (array) ($context['groups'] ?? []); @@ -79,6 +81,7 @@ public function supportsNormalization(mixed $data, ?string $format = null, array ); } + #[\Override] public function getSupportedTypes(?string $format): array { return [ diff --git a/src/Serializer/Normalizer/GiftCardNormalizer.php b/src/Serializer/Normalizer/GiftCardNormalizer.php index 82b49484..5231dede 100644 --- a/src/Serializer/Normalizer/GiftCardNormalizer.php +++ b/src/Serializer/Normalizer/GiftCardNormalizer.php @@ -28,6 +28,7 @@ public function __construct(ObjectNormalizer $objectNormalizer, MoneyFormatterIn * @param GiftCardInterface|mixed $data * @param array $context */ + #[\Override] public function normalize($data, ?string $format = null, array $context = []): array { Assert::isInstanceOf($data, GiftCardInterface::class); @@ -48,6 +49,7 @@ public function normalize($data, ?string $format = null, array $context = []): a return $data; } + #[\Override] public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool { $groups = (array) ($context['groups'] ?? []); @@ -55,6 +57,7 @@ public function supportsNormalization(mixed $data, ?string $format = null, array return $data instanceof GiftCardInterface && in_array('setono:sylius-gift-card:render', $groups, true); } + #[\Override] public function getSupportedTypes(?string $format): array { return [ diff --git a/src/SetonoSyliusGiftCardPlugin.php b/src/SetonoSyliusGiftCardPlugin.php index d19b0d1d..8d2a1df8 100644 --- a/src/SetonoSyliusGiftCardPlugin.php +++ b/src/SetonoSyliusGiftCardPlugin.php @@ -15,6 +15,7 @@ final class SetonoSyliusGiftCardPlugin extends AbstractResourceBundle { use SyliusPluginTrait; + #[\Override] public function build(ContainerBuilder $container): void { parent::build($container); @@ -23,6 +24,7 @@ public function build(ContainerBuilder $container): void $container->addCompilerPass(new CreateServiceAliasesPass()); } + #[\Override] public function getSupportedDrivers(): array { return [ @@ -30,11 +32,13 @@ public function getSupportedDrivers(): array ]; } + #[\Override] public function getPath(): string { return \dirname(__DIR__); } + #[\Override] protected function getConfigFilesPath(): string { return sprintf('%s/config/doctrine/%s', $this->getPath(), strtolower($this->getDoctrineMappingDirectory())); diff --git a/src/Twig/Extension/PdfExtension.php b/src/Twig/Extension/PdfExtension.php index 3b1728e0..6da63185 100644 --- a/src/Twig/Extension/PdfExtension.php +++ b/src/Twig/Extension/PdfExtension.php @@ -9,6 +9,7 @@ final class PdfExtension extends AbstractExtension { + #[\Override] public function getFunctions(): array { return [ diff --git a/src/Validator/Constraints/DatePeriodValidator.php b/src/Validator/Constraints/DatePeriodValidator.php index f8fa38df..35e8d211 100644 --- a/src/Validator/Constraints/DatePeriodValidator.php +++ b/src/Validator/Constraints/DatePeriodValidator.php @@ -22,6 +22,7 @@ public function __construct(DatePeriodUnitProviderInterface $datePeriodUnitProvi /** * @param mixed $value */ + #[\Override] public function validate($value, Constraint $constraint): void { if (!$constraint instanceof DatePeriod) { diff --git a/src/Validator/Constraints/DefaultGiftCardConfigurationMustExist.php b/src/Validator/Constraints/DefaultGiftCardConfigurationMustExist.php index 1b387664..e7b21f2b 100644 --- a/src/Validator/Constraints/DefaultGiftCardConfigurationMustExist.php +++ b/src/Validator/Constraints/DefaultGiftCardConfigurationMustExist.php @@ -10,6 +10,7 @@ final class DefaultGiftCardConfigurationMustExist extends Constraint { public string $message = 'setono_sylius_gift_card.gift_card_configuration.default_configuration_must_exist'; + #[\Override] public function getTargets(): array { return [self::CLASS_CONSTRAINT]; diff --git a/src/Validator/Constraints/DefaultGiftCardConfigurationMustExistValidator.php b/src/Validator/Constraints/DefaultGiftCardConfigurationMustExistValidator.php index d2344661..0efa5e19 100644 --- a/src/Validator/Constraints/DefaultGiftCardConfigurationMustExistValidator.php +++ b/src/Validator/Constraints/DefaultGiftCardConfigurationMustExistValidator.php @@ -22,6 +22,7 @@ public function __construct(GiftCardConfigurationRepositoryInterface $giftCardCo /** * @param mixed $value */ + #[\Override] public function validate($value, Constraint $constraint): void { if (!$constraint instanceof DefaultGiftCardConfigurationMustExist) { diff --git a/src/Validator/Constraints/GiftCardIsNotExpiredValidator.php b/src/Validator/Constraints/GiftCardIsNotExpiredValidator.php index 5ee77279..2be4dc37 100644 --- a/src/Validator/Constraints/GiftCardIsNotExpiredValidator.php +++ b/src/Validator/Constraints/GiftCardIsNotExpiredValidator.php @@ -15,6 +15,7 @@ final class GiftCardIsNotExpiredValidator extends ConstraintValidator /** * @param mixed $value */ + #[\Override] public function validate($value, Constraint $constraint): void { if (!$constraint instanceof GiftCardIsNotExpired) { diff --git a/src/Validator/Constraints/HasBackgroundImage.php b/src/Validator/Constraints/HasBackgroundImage.php index 06289d17..6f30e4ea 100644 --- a/src/Validator/Constraints/HasBackgroundImage.php +++ b/src/Validator/Constraints/HasBackgroundImage.php @@ -10,6 +10,7 @@ final class HasBackgroundImage extends Constraint { public string $message = 'setono_sylius_gift_card.gift_card_configuration.background_image_required'; + #[\Override] public function getTargets(): array { return [self::CLASS_CONSTRAINT]; diff --git a/src/Validator/Constraints/HasBackgroundImageValidator.php b/src/Validator/Constraints/HasBackgroundImageValidator.php index 1efd72a7..b1dedd98 100644 --- a/src/Validator/Constraints/HasBackgroundImageValidator.php +++ b/src/Validator/Constraints/HasBackgroundImageValidator.php @@ -14,6 +14,7 @@ final class HasBackgroundImageValidator extends ConstraintValidator /** * @param mixed $value */ + #[\Override] public function validate($value, Constraint $constraint): void { if (!$constraint instanceof HasBackgroundImage) { diff --git a/src/Validator/Constraints/Pdf/ValidOrientationValidator.php b/src/Validator/Constraints/Pdf/ValidOrientationValidator.php index 4c1d3a73..6b05e158 100644 --- a/src/Validator/Constraints/Pdf/ValidOrientationValidator.php +++ b/src/Validator/Constraints/Pdf/ValidOrientationValidator.php @@ -20,6 +20,7 @@ public function __construct(array $availableOrientations) /** * @param mixed $value */ + #[\Override] public function validate($value, Constraint $constraint): void { if (!$constraint instanceof ValidOrientation) { diff --git a/src/Validator/Constraints/Pdf/ValidPageSizeValidator.php b/src/Validator/Constraints/Pdf/ValidPageSizeValidator.php index 9258961b..c1628b5a 100644 --- a/src/Validator/Constraints/Pdf/ValidPageSizeValidator.php +++ b/src/Validator/Constraints/Pdf/ValidPageSizeValidator.php @@ -20,6 +20,7 @@ public function __construct(array $availableOrientations) /** * @param mixed $value */ + #[\Override] public function validate($value, Constraint $constraint): void { if (!$constraint instanceof ValidPageSize) { From f1dfbb5008493d78e61aabd04fe5c1d4853651d4 Mon Sep 17 00:00:00 2001 From: Luca Gallinari Date: Wed, 29 Jul 2026 17:25:43 +0200 Subject: [PATCH 25/60] Fix Sylius 1.x template/macro paths causing 500s on admin gift-cards pages The admin gift-cards index, its grid actions/fields, and the balance page still referenced Sylius 1.x template and macro paths (@SyliusAdmin/Crud, @SyliusUi/Macro/buttons.html.twig, @SyliusAdmin/Common/Macro/money.html.twig, PascalCase grid field paths) that no longer exist in Sylius 2's admin theme. Updated grid configs and templates to the current paths/idioms, and rewrote the balance page and grid action buttons using Sylius 2's Bootstrap/Tabler layout instead of the removed Semantic-UI helpers. Co-Authored-By: Claude Sonnet 5 --- ...tono_sylius_gift_card_admin_gift_card.yaml | 4 +- ...ft_card_admin_gift_card_configuration.yaml | 4 +- ...etono_sylius_gift_card_shop_gift_card.yaml | 2 +- config/routes/admin.yaml | 8 +- .../GiftCard/Grid/Action/create.html.twig | 11 ++- .../Grid/Action/delete_conditional.html.twig | 4 +- .../Grid/Action/gift_card_balance.html.twig | 13 +-- .../Grid/Action/list_conditional.html.twig | 10 +- .../Grid/Action/resend_email.html.twig | 8 +- .../GiftCard/Grid/Field/amount.html.twig | 2 +- .../Field/channel_configurations.html.twig | 4 +- templates/Admin/GiftCard/create.html.twig | 2 +- .../Grid/Field/coveredByGiftCards.html.twig | 2 +- templates/Admin/giftCardBalance.html.twig | 94 +++++++++---------- .../Order/Show/Summary/_totals.html.twig | 2 +- 15 files changed, 83 insertions(+), 87 deletions(-) diff --git a/config/grids/setono_sylius_gift_card_admin_gift_card.yaml b/config/grids/setono_sylius_gift_card_admin_gift_card.yaml index ee0bc509..1e7d4277 100644 --- a/config/grids/setono_sylius_gift_card_admin_gift_card.yaml +++ b/config/grids/setono_sylius_gift_card_admin_gift_card.yaml @@ -32,13 +32,13 @@ sylius_grid: label: sylius.ui.channel sortable: channel.code options: - template: "@SyliusAdmin/Order/Grid/Field/channel.html.twig" + template: "@SyliusAdmin/shared/grid/field/channel.html.twig" enabled: type: twig label: sylius.ui.enabled sortable: ~ options: - template: "@SyliusUi/Grid/Field/enabled.html.twig" + template: "@SyliusUi/grid/field/enabled.html.twig" createdAt: type: datetime label: sylius.ui.created diff --git a/config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml b/config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml index 043dd3da..a411ec38 100644 --- a/config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml +++ b/config/grids/setono_sylius_gift_card_admin_gift_card_configuration.yaml @@ -16,13 +16,13 @@ sylius_grid: label: sylius.ui.status sortable: ~ options: - template: '@SyliusUi/Grid/Field/enabled.html.twig' + template: '@SyliusUi/grid/field/enabled.html.twig' default: type: twig label: sylius.ui.default sortable: ~ options: - template: '@SyliusUi/Grid/Field/yesNo.html.twig' + template: '@SyliusUi/grid/field/yes_no.html.twig' channel_configurations: type: twig label: setono_sylius_gift_card.ui.channel_configurations diff --git a/config/grids/setono_sylius_gift_card_shop_gift_card.yaml b/config/grids/setono_sylius_gift_card_shop_gift_card.yaml index 15092629..eef7ed9a 100644 --- a/config/grids/setono_sylius_gift_card_shop_gift_card.yaml +++ b/config/grids/setono_sylius_gift_card_shop_gift_card.yaml @@ -36,7 +36,7 @@ sylius_grid: label: sylius.ui.enabled sortable: ~ options: - template: "@SyliusUi/Grid/Field/enabled.html.twig" + template: "@SyliusUi/grid/field/enabled.html.twig" createdAt: type: datetime label: sylius.ui.created diff --git a/config/routes/admin.yaml b/config/routes/admin.yaml index 31a37f97..dd053011 100644 --- a/config/routes/admin.yaml +++ b/config/routes/admin.yaml @@ -4,7 +4,7 @@ setono_sylius_gift_card_admin_gift_card: section: admin permission: true only: [index, update, delete, bulkDelete] - templates: '@SyliusAdmin\\Crud' + templates: '@SyliusAdmin\\shared\\crud' redirect: index grid: setono_sylius_gift_card_admin_gift_card vars: @@ -44,7 +44,7 @@ setono_sylius_gift_card_admin_gift_card_configuration: section: admin permission: true only: [index, create, update, delete, bulkDelete] - templates: '@SyliusAdmin\\Crud' + templates: '@SyliusAdmin\\shared\\crud' redirect: index grid: setono_sylius_gift_card_admin_gift_card_configuration vars: @@ -86,7 +86,7 @@ setono_sylius_gift_card_admin_gift_card_create: method: createForChannelFromAdmin arguments: channel: "expr:service('sylius.repository.channel').findOneByCode($channelCode)" - template: '@SyliusAdmin/Crud/create.html.twig' + template: '@SyliusAdmin/shared/crud/create.html.twig' grid: setono_sylius_gift_card_admin_gift_card section: admin redirect: @@ -109,7 +109,7 @@ setono_sylius_gift_card_admin_gift_card_orders_index: route: parameters: id: $id - template: '@SyliusAdmin/Crud/index.html.twig' + template: '@SyliusAdmin/shared/crud/index.html.twig' grid: setono_sylius_gift_card_admin_gift_card_order section: admin permission: true diff --git a/templates/Admin/GiftCard/Grid/Action/create.html.twig b/templates/Admin/GiftCard/Grid/Action/create.html.twig index a3907282..8f2832a0 100644 --- a/templates/Admin/GiftCard/Grid/Action/create.html.twig +++ b/templates/Admin/GiftCard/Grid/Action/create.html.twig @@ -1,8 +1,9 @@ -{# todo this should be a knp menu builder instead #} -