mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-05 20:57:12 +00:00
Allow doctrine/doctrine-bundle ^3.0 and doctrine/dbal ^4.0 (#19064)
Some checks are pending
Continuous Integration (Minimal) / Static checks (push) Waiting to run
Continuous Integration (Minimal) / Tests (MariaDB) (push) Blocked by required conditions
Continuous Integration (Minimal) / Tests (MySQL) (push) Blocked by required conditions
Continuous Integration (Minimal) / Javascript Tests (MySQL) (push) Blocked by required conditions
Continuous Integration (Minimal) / Tests (PostgreSQL) (push) Blocked by required conditions
Continuous Integration (Minimal) / Frontend (push) Blocked by required conditions
Continuous Integration (Minimal) / Packages (push) Blocked by required conditions
Some checks are pending
Continuous Integration (Minimal) / Static checks (push) Waiting to run
Continuous Integration (Minimal) / Tests (MariaDB) (push) Blocked by required conditions
Continuous Integration (Minimal) / Tests (MySQL) (push) Blocked by required conditions
Continuous Integration (Minimal) / Javascript Tests (MySQL) (push) Blocked by required conditions
Continuous Integration (Minimal) / Tests (PostgreSQL) (push) Blocked by required conditions
Continuous Integration (Minimal) / Frontend (push) Blocked by required conditions
Continuous Integration (Minimal) / Packages (push) Blocked by required conditions
| Q | A |-----------------|----- | Branch? | 2.3 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no<!-- don't forget to update the UPGRADE-*.md file --> | Related tickets | duplicates https://github.com/Sylius/Sylius/pull/18754, partially https://github.com/Sylius/Sylius/issues/18760 | License | MIT This PR is a duplication of #18754 (which targets the `symfony-8` branch). It reuses that PR's commits to bring the broadened Doctrine support into `2.3`. ### What it does Widens the supported Doctrine stack, **opt-in via `||`, no minimum is bumped**: - `doctrine/doctrine-bundle` `^2.13 || ^3.0` - `doctrine/dbal` `^3.9 || ^4.0` - `doctrine/persistence` `^3.3 || ^4.0` - `doctrine/data-fixtures` `^1.7 || ^2.2` (dev) Plus the compatibility work the newer stack requires: - DBAL 3.x/4.x compatibility layers (platform detection, `getSchemaManager()` → `createSchemaManager()`, `SqlitePlatform`/`SQLitePlatform`, `QueryBuilder::select()`); - a custom `ObjectType` registered as `object` (the built-in `object` type was removed in DBAL 4), covering the only two `type="object"` mappings: `PaymentSecurityToken.details` and `PaymentRequest.payload`; - config updates: removed `auto_generate_proxy_classes` (gone in DoctrineBundle 3), PSR-6 cache pools, and forced `SEQUENCE` identity generation on PostgreSQL to keep the schema backward compatible; - CI matrix entries to test both DoctrineBundle 2 and 3. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for DoctrineBundle 3 and DBAL 4. * Added a custom DBAL “object” type to keep payment data compatible. * **Documentation** * Added Sylius 2.3 upgrade notes, including Doctrine cache pool migration and PostgreSQL identity/sequence behavior. * **Bug Fixes** * Updated Doctrine ORM cache configuration to use Symfony cache pools (production and test setups). * Fixed timestamp handling to consistently store mutable `DateTime` values where required. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
commit
f745ee5aa0
72 changed files with 543 additions and 249 deletions
20
.github/workflows/ci_e2e-mariadb.yaml
vendored
20
.github/workflows/ci_e2e-mariadb.yaml
vendored
|
|
@ -44,7 +44,7 @@ jobs:
|
|||
phpunit-cli-api:
|
||||
needs: get-matrix
|
||||
runs-on: ubuntu-latest
|
||||
name: "PHPUnit, CLI, API, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MariaDB ${{ matrix.mariadb }}, State Machine Adapter ${{ matrix.state_machine_adapter }}${{ matrix.api_platform && format(', ApiPlatform {0}', matrix.api_platform) || '' }}"
|
||||
name: "PHPUnit, CLI, API, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MariaDB ${{ matrix.mariadb }}, State Machine Adapter ${{ matrix.state_machine_adapter }}${{ matrix.doctrine_bundle && format(', DoctrineBundle {0}', matrix.doctrine_bundle) || '' }}${{ matrix.api_platform && format(', ApiPlatform {0}', matrix.api_platform) || '' }}"
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
@ -73,6 +73,14 @@ jobs:
|
|||
composer require winzou/state-machine:^0.4 --no-update
|
||||
composer require winzou/state-machine-bundle:^0.6 --no-update
|
||||
|
||||
- name: Require Doctrine Bundle
|
||||
if: ${{ matrix.doctrine_bundle != '' && matrix.doctrine_bundle != null }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/doctrine-bundle:${{ matrix.doctrine_bundle }}"
|
||||
|
||||
- name: Require DBAL 3.x for DoctrineBundle 2.x
|
||||
if: ${{ matrix.doctrine_bundle == '^2.0' }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/dbal:^3.9"
|
||||
|
||||
- name: Prepare manifest.json files
|
||||
run: |
|
||||
mkdir -p public/build/admin
|
||||
|
|
@ -145,7 +153,7 @@ jobs:
|
|||
behat-ui:
|
||||
needs: get-matrix
|
||||
runs-on: ubuntu-latest
|
||||
name: "UI, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MariaDB ${{ matrix.mariadb }}, State Machine Adapter ${{ matrix.state_machine_adapter }}${{ matrix.api_platform && format(', ApiPlatform {0}', matrix.api_platform) || '' }}"
|
||||
name: "UI, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MariaDB ${{ matrix.mariadb }}, State Machine Adapter ${{ matrix.state_machine_adapter }}${{ matrix.doctrine_bundle && format(', DoctrineBundle {0}', matrix.doctrine_bundle) || '' }}${{ matrix.api_platform && format(', ApiPlatform {0}', matrix.api_platform) || '' }}"
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
@ -174,6 +182,14 @@ jobs:
|
|||
composer require winzou/state-machine:^0.4 --no-update
|
||||
composer require winzou/state-machine-bundle:^0.6 --no-update
|
||||
|
||||
- name: Require Doctrine Bundle
|
||||
if: ${{ matrix.doctrine_bundle != '' && matrix.doctrine_bundle != null }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/doctrine-bundle:${{ matrix.doctrine_bundle }}"
|
||||
|
||||
- name: Require DBAL 3.x for DoctrineBundle 2.x
|
||||
if: ${{ matrix.doctrine_bundle == '^2.0' }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/dbal:^3.9"
|
||||
|
||||
- name: Prepare manifest.json files
|
||||
run: |
|
||||
mkdir -p public/build/admin
|
||||
|
|
|
|||
28
.github/workflows/ci_e2e-mysql.yaml
vendored
28
.github/workflows/ci_e2e-mysql.yaml
vendored
|
|
@ -44,7 +44,7 @@ jobs:
|
|||
phpunit-cli-api:
|
||||
needs: get-matrix
|
||||
runs-on: ubuntu-latest
|
||||
name: "PHPUnit, CLI, API, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MySQL ${{ matrix.mysql }}"
|
||||
name: "PHPUnit, CLI, API, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MySQL ${{ matrix.mysql }}${{ matrix.doctrine_bundle && format(', DoctrineBundle {0}', matrix.doctrine_bundle) || '' }}"
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
@ -70,6 +70,14 @@ jobs:
|
|||
if: matrix.twig == '^2.12'
|
||||
run: composer require --no-update --no-scripts --no-interaction "twig/twig:${{ matrix.twig }}"
|
||||
|
||||
- name: Require Doctrine Bundle
|
||||
if: ${{ matrix.doctrine_bundle != '' && matrix.doctrine_bundle != null }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/doctrine-bundle:${{ matrix.doctrine_bundle }}"
|
||||
|
||||
- name: Require DBAL 3.x for DoctrineBundle 2.x
|
||||
if: ${{ matrix.doctrine_bundle == '^2.0' }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/dbal:^3.9"
|
||||
|
||||
- name: Prepare manifest.json files
|
||||
run: |
|
||||
mkdir -p public/build/admin
|
||||
|
|
@ -85,8 +93,8 @@ jobs:
|
|||
uses: SyliusLabs/BuildTestAppAction@v4
|
||||
with:
|
||||
build_type: "sylius"
|
||||
cache_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-symfony-${{ matrix.symfony }}"
|
||||
cache_restore_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-symfony-${{ matrix.symfony }}"
|
||||
cache_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-symfony-${{ matrix.symfony }}-doctrine-${{ matrix.doctrine_bundle || 'default' }}"
|
||||
cache_restore_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-symfony-${{ matrix.symfony }}-doctrine-${{ matrix.doctrine_bundle || 'default' }}"
|
||||
e2e: "yes"
|
||||
database: "mysql:${{ matrix.mysql }}"
|
||||
php_version: ${{ matrix.php }}
|
||||
|
|
@ -131,7 +139,7 @@ jobs:
|
|||
behat-ui:
|
||||
needs: get-matrix
|
||||
runs-on: ubuntu-latest
|
||||
name: "UI, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MySQL ${{ matrix.mysql }}"
|
||||
name: "UI, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, MySQL ${{ matrix.mysql }}${{ matrix.doctrine_bundle && format(', DoctrineBundle {0}', matrix.doctrine_bundle) || '' }}"
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
@ -157,6 +165,14 @@ jobs:
|
|||
if: matrix.twig == '^2.12'
|
||||
run: composer require --no-update --no-scripts --no-interaction "twig/twig:${{ matrix.twig }}"
|
||||
|
||||
- name: Require Doctrine Bundle
|
||||
if: ${{ matrix.doctrine_bundle != '' && matrix.doctrine_bundle != null }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/doctrine-bundle:${{ matrix.doctrine_bundle }}"
|
||||
|
||||
- name: Require DBAL 3.x for DoctrineBundle 2.x
|
||||
if: ${{ matrix.doctrine_bundle == '^2.0' }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/dbal:^3.9"
|
||||
|
||||
- name: Prepare manifest.json files
|
||||
run: |
|
||||
mkdir -p public/build/admin
|
||||
|
|
@ -172,8 +188,8 @@ jobs:
|
|||
uses: SyliusLabs/BuildTestAppAction@v4
|
||||
with:
|
||||
build_type: "sylius"
|
||||
cache_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-symfony-${{ matrix.symfony }}"
|
||||
cache_restore_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-symfony-${{ matrix.symfony }}"
|
||||
cache_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-symfony-${{ matrix.symfony }}-doctrine-${{ matrix.doctrine_bundle || 'default' }}"
|
||||
cache_restore_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-symfony-${{ matrix.symfony }}-doctrine-${{ matrix.doctrine_bundle || 'default' }}"
|
||||
e2e: "yes"
|
||||
database: "mysql:${{ matrix.mysql }}"
|
||||
php_version: ${{ matrix.php }}
|
||||
|
|
|
|||
28
.github/workflows/ci_e2e-pgsql.yaml
vendored
28
.github/workflows/ci_e2e-pgsql.yaml
vendored
|
|
@ -44,7 +44,7 @@ jobs:
|
|||
phpunit-cli-api:
|
||||
needs: get-matrix
|
||||
runs-on: ubuntu-latest
|
||||
name: "PHPUnit, CLI, API, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, PostgreSQL ${{ matrix.postgres }}"
|
||||
name: "PHPUnit, CLI, API, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, PostgreSQL ${{ matrix.postgres }}${{ matrix.doctrine_bundle && format(', DoctrineBundle {0}', matrix.doctrine_bundle) || '' }}"
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
@ -66,6 +66,14 @@ jobs:
|
|||
if: "${{ inputs.branch == '' }}"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Require Doctrine Bundle
|
||||
if: ${{ matrix.doctrine_bundle != '' && matrix.doctrine_bundle != null }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/doctrine-bundle:${{ matrix.doctrine_bundle }}"
|
||||
|
||||
- name: Require DBAL 3.x for DoctrineBundle 2.x
|
||||
if: ${{ matrix.doctrine_bundle == '^2.0' }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/dbal:^3.9"
|
||||
|
||||
- name: Prepare manifest.json files
|
||||
run: |
|
||||
mkdir -p public/build/admin
|
||||
|
|
@ -81,8 +89,8 @@ jobs:
|
|||
uses: SyliusLabs/BuildTestAppAction@v4
|
||||
with:
|
||||
build_type: "sylius"
|
||||
cache_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-php-${{ matrix.php }}-symfony-${{ matrix.symfony }}-"
|
||||
cache_restore_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-php-${{ matrix.php }}-symfony-${{ matrix.symfony }}-"
|
||||
cache_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-php-${{ matrix.php }}-symfony-${{ matrix.symfony }}-doctrine-${{ matrix.doctrine_bundle || 'default' }}-"
|
||||
cache_restore_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-php-${{ matrix.php }}-symfony-${{ matrix.symfony }}-doctrine-${{ matrix.doctrine_bundle || 'default' }}-"
|
||||
e2e: "yes"
|
||||
database: "postgres:${{ matrix.postgres }}"
|
||||
php_version: ${{ matrix.php }}
|
||||
|
|
@ -119,7 +127,7 @@ jobs:
|
|||
behat-ui:
|
||||
needs: get-matrix
|
||||
runs-on: ubuntu-latest
|
||||
name: "UI, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, PostgreSQL ${{ matrix.postgres }}"
|
||||
name: "UI, PHP ${{ matrix.php }}, Symfony ${{ matrix.symfony }}, PostgreSQL ${{ matrix.postgres }}${{ matrix.doctrine_bundle && format(', DoctrineBundle {0}', matrix.doctrine_bundle) || '' }}"
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
|
@ -141,6 +149,14 @@ jobs:
|
|||
if: "${{ inputs.branch == '' }}"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Require Doctrine Bundle
|
||||
if: ${{ matrix.doctrine_bundle != '' && matrix.doctrine_bundle != null }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/doctrine-bundle:${{ matrix.doctrine_bundle }}"
|
||||
|
||||
- name: Require DBAL 3.x for DoctrineBundle 2.x
|
||||
if: ${{ matrix.doctrine_bundle == '^2.0' }}
|
||||
run: composer require --no-update --no-scripts --no-interaction "doctrine/dbal:^3.9"
|
||||
|
||||
- name: Prepare manifest.json files
|
||||
run: |
|
||||
mkdir -p public/build/admin
|
||||
|
|
@ -156,8 +172,8 @@ jobs:
|
|||
uses: SyliusLabs/BuildTestAppAction@v4
|
||||
with:
|
||||
build_type: "sylius"
|
||||
cache_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-php-${{ matrix.php }}-symfony-${{ matrix.symfony }}-"
|
||||
cache_restore_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-php-${{ matrix.php }}-symfony-${{ matrix.symfony }}-"
|
||||
cache_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-php-${{ matrix.php }}-symfony-${{ matrix.symfony }}-doctrine-${{ matrix.doctrine_bundle || 'default' }}-"
|
||||
cache_restore_key: "${{ github.run_id }}-${{ runner.os }}-${{ hashFiles('composer.json') }}-php-${{ matrix.php }}-symfony-${{ matrix.symfony }}-doctrine-${{ matrix.doctrine_bundle || 'default' }}-"
|
||||
e2e: "yes"
|
||||
database: "postgres:${{ matrix.postgres }}"
|
||||
php_version: ${{ matrix.php }}
|
||||
|
|
|
|||
42
.github/workflows/matrix.json
vendored
42
.github/workflows/matrix.json
vendored
|
|
@ -22,14 +22,14 @@
|
|||
"php": "8.4",
|
||||
"symfony": "~6.4.0",
|
||||
"mariadb": "10.11.13",
|
||||
"dbal": "^3.0",
|
||||
"doctrine_bundle": "^2.0",
|
||||
"state_machine_adapter": "winzou_state_machine"
|
||||
},
|
||||
{
|
||||
"php": "8.5",
|
||||
"symfony": "~7.4.0",
|
||||
"mariadb": "11.4.7",
|
||||
"dbal": "^3.0",
|
||||
"doctrine_bundle": "^3.0",
|
||||
"state_machine_adapter": "symfony_workflow"
|
||||
}
|
||||
]
|
||||
|
|
@ -40,13 +40,15 @@
|
|||
"php": "8.4",
|
||||
"symfony": "~6.4.0",
|
||||
"mysql": "8.0",
|
||||
"twig": "^3.3"
|
||||
"twig": "^3.3",
|
||||
"doctrine_bundle": "^2.0"
|
||||
},
|
||||
{
|
||||
"php": "8.5",
|
||||
"symfony": "~7.4.0",
|
||||
"mysql": "8.4",
|
||||
"twig": "^3.3"
|
||||
"twig": "^3.3",
|
||||
"doctrine_bundle": "^3.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -103,12 +105,14 @@
|
|||
{
|
||||
"php": "8.4",
|
||||
"symfony": "~6.4.0",
|
||||
"postgres": "15.13"
|
||||
"postgres": "15.13",
|
||||
"doctrine_bundle": "^2.0"
|
||||
},
|
||||
{
|
||||
"php": "8.5",
|
||||
"symfony": "~7.4.0",
|
||||
"postgres": "17.5"
|
||||
"postgres": "17.5",
|
||||
"doctrine_bundle": "^3.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -155,6 +159,10 @@
|
|||
"mariadb": [
|
||||
"11.4.7"
|
||||
],
|
||||
"doctrine_bundle": [
|
||||
"^2.0",
|
||||
"^3.0"
|
||||
],
|
||||
"state_machine_adapter": [
|
||||
"symfony_workflow"
|
||||
],
|
||||
|
|
@ -163,6 +171,7 @@
|
|||
"php": "8.3",
|
||||
"symfony": "~7.4.0",
|
||||
"mariadb": "11.4.7",
|
||||
"doctrine_bundle": "^2.0",
|
||||
"state_machine_adapter": "winzou_state_machine"
|
||||
}
|
||||
]
|
||||
|
|
@ -182,12 +191,17 @@
|
|||
"twig": [
|
||||
"^3.3"
|
||||
],
|
||||
"doctrine_bundle": [
|
||||
"^2.0",
|
||||
"^3.0"
|
||||
],
|
||||
"include": [
|
||||
{
|
||||
"php": "8.3",
|
||||
"symfony": "~7.4.0",
|
||||
"mysql": "8.0",
|
||||
"twig": "^3.3"
|
||||
"twig": "^3.3",
|
||||
"doctrine_bundle": "^2.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -253,6 +267,20 @@
|
|||
"15.13",
|
||||
"16.9",
|
||||
"17.5"
|
||||
],
|
||||
"include": [
|
||||
{
|
||||
"php": "8.4",
|
||||
"symfony": "~6.4.0",
|
||||
"postgres": "15.13",
|
||||
"doctrine_bundle": "^2.0"
|
||||
},
|
||||
{
|
||||
"php": "8.5",
|
||||
"symfony": "~7.4.0",
|
||||
"postgres": "17.5",
|
||||
"doctrine_bundle": "^3.0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"frontend": {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,38 @@
|
|||
order_by_identifier: true
|
||||
```
|
||||
|
||||
2. Configuration changes related to the broadened Doctrine support (see the *Dependencies* section).
|
||||
These only matter once you opt into **DoctrineBundle 3** / **DBAL 4**:
|
||||
|
||||
- The `auto_generate_proxy_classes: "%kernel.debug%"` option was removed from Sylius' Doctrine configuration
|
||||
(it no longer exists in DoctrineBundle 3, and since PHP 8.4 Doctrine uses native lazy objects). If you are still
|
||||
on DoctrineBundle 2 and rely on this behavior, set it explicitly in your own application configuration.
|
||||
|
||||
- The ORM metadata/query/result cache configuration was switched from wrapped `Doctrine\Common\Cache` services
|
||||
to **PSR-6 cache pools** (`type: pool`). This change lives in the application configuration (`config/packages/{prod,test}/doctrine.yaml`),
|
||||
which is **not** updated automatically on existing installations, update those files in your project accordingly:
|
||||
|
||||
```diff
|
||||
doctrine:
|
||||
orm:
|
||||
entity_managers:
|
||||
default:
|
||||
metadata_cache_driver:
|
||||
- type: service
|
||||
- id: doctrine.system_cache_provider
|
||||
+ type: pool
|
||||
+ pool: doctrine.system_cache_pool
|
||||
```
|
||||
|
||||
As part of this switch, the `doctrine.result_cache_provider` and `doctrine.system_cache_provider` services
|
||||
(defined in Sylius' application configuration, wrapping the PSR-6 pools via `Doctrine\Common\Cache\Psr6\DoctrineProvider`)
|
||||
were **removed**. If you referenced them by id, use the cache pools directly (`doctrine.system_cache_pool`,
|
||||
`doctrine.result_cache_pool`) with `type: pool` as shown above.
|
||||
|
||||
- On **PostgreSQL**, Sylius now forces the `SEQUENCE` identity generation strategy
|
||||
(`identity_generation_preferences` for `PostgreSQLPlatform`) to keep the database schema backward compatible
|
||||
with existing installations.
|
||||
|
||||
## Dependencies
|
||||
|
||||
1. The `behat/transliterator` package has been **deprecated** and will be removed in Sylius 3.0.
|
||||
|
|
@ -68,6 +100,14 @@
|
|||
|
||||
If your application depends on these packages directly, require them explicitly in your `composer.json`.
|
||||
|
||||
4. The supported Doctrine version ranges have been **broadened** to allow the newer stack
|
||||
(`doctrine/doctrine-bundle` `^2.13 || ^3.0`, `doctrine/dbal` `^3.9 || ^4.0`,
|
||||
`doctrine/persistence` `^3.3 || ^4.0`, `doctrine/data-fixtures` `^1.7 || ^2.2`).
|
||||
|
||||
DBAL 4 removes the built-in `object` and `array` column types. Since Sylius maps two fields
|
||||
as `type="object"` (`PaymentSecurityToken.details` and `PaymentRequest.payload`), it registers
|
||||
a custom `Sylius\Bundle\PaymentBundle\Doctrine\DBAL\Type\ObjectType` to keep them working.
|
||||
|
||||
## Deprecations
|
||||
|
||||
1. Passing a `Sylius\Component\Core\Calculator\ProductVariantPricesCalculatorInterface` directly to the following catalog-facing classes is deprecated since Sylius 2.3.
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
"Behat\\Testwork\\Tester\\Setup\\Setup",
|
||||
"Behat\\Testwork\\Tester\\Setup\\Teardown",
|
||||
"Composer\\InstalledVersions",
|
||||
"Doctrine\\DBAL\\Platforms\\MariaDb1027Platform",
|
||||
"Doctrine\\DBAL\\Platforms\\MySqlPlatform",
|
||||
"enshrined\\svgSanitize\\Sanitizer",
|
||||
"FriendsOfBehat\\SymfonyExtension\\Mink\\Mink",
|
||||
|
|
|
|||
|
|
@ -38,14 +38,14 @@
|
|||
"behat/transliterator": "^1.5",
|
||||
"doctrine/collections": "^2.2",
|
||||
"doctrine/common": "^3.2",
|
||||
"doctrine/dbal": "^3.9",
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/dbal": "^3.9 || ^4.0",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/doctrine-migrations-bundle": "^3.3",
|
||||
"doctrine/event-manager": "^2.0",
|
||||
"doctrine/inflector": "^2.0",
|
||||
"doctrine/migrations": "^3.8",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"doctrine/persistence": "^3.3",
|
||||
"doctrine/persistence": "^3.3 || ^4.0",
|
||||
"egulias/email-validator": "^4.0",
|
||||
"fakerphp/faker": "^1.23",
|
||||
"gedmo/doctrine-extensions": "^3.20",
|
||||
|
|
@ -192,7 +192,7 @@
|
|||
"dmore/behat-chrome-extension": "^1.4",
|
||||
"dmore/chrome-mink-driver": "^2.9",
|
||||
"doctrine/cache": "^2.2",
|
||||
"doctrine/data-fixtures": "^1.7",
|
||||
"doctrine/data-fixtures": "^1.7 || ^2.2",
|
||||
"friends-of-behat/mink": "^1.11",
|
||||
"friends-of-behat/mink-browserkit-driver": "^1.6",
|
||||
"friends-of-behat/mink-debug-extension": "^2.1",
|
||||
|
|
@ -201,7 +201,7 @@
|
|||
"friends-of-behat/symfony-extension": "^2.6.2",
|
||||
"friends-of-behat/variadic-extension": "^1.6",
|
||||
"hwi/oauth-bundle": "^2.2",
|
||||
"lchrusciel/api-test-case": "^5.3",
|
||||
"lchrusciel/api-test-case": "^5.3.5",
|
||||
"matthiasnoback/symfony-config-test": "^6.0",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"nyholm/psr7": "^1.8",
|
||||
|
|
|
|||
|
|
@ -3,29 +3,14 @@ doctrine:
|
|||
entity_managers:
|
||||
default:
|
||||
metadata_cache_driver:
|
||||
type: service
|
||||
id: doctrine.system_cache_provider
|
||||
type: pool
|
||||
pool: doctrine.system_cache_pool
|
||||
query_cache_driver:
|
||||
type: service
|
||||
id: doctrine.system_cache_provider
|
||||
type: pool
|
||||
pool: doctrine.system_cache_pool
|
||||
result_cache_driver:
|
||||
type: service
|
||||
id: doctrine.result_cache_provider
|
||||
|
||||
services:
|
||||
doctrine.result_cache_provider:
|
||||
class: Doctrine\Common\Cache\Psr6\DoctrineProvider
|
||||
public: false
|
||||
factory: ['Doctrine\Common\Cache\Psr6\DoctrineProvider', 'wrap']
|
||||
arguments:
|
||||
- '@doctrine.result_cache_pool'
|
||||
doctrine.system_cache_provider:
|
||||
class: Doctrine\Common\Cache\Psr6\DoctrineProvider
|
||||
public: false
|
||||
factory: [ 'Doctrine\Common\Cache\Psr6\DoctrineProvider', 'wrap' ]
|
||||
arguments:
|
||||
- '@doctrine.system_cache_pool'
|
||||
|
||||
type: pool
|
||||
pool: doctrine.result_cache_pool
|
||||
|
||||
framework:
|
||||
cache:
|
||||
|
|
|
|||
|
|
@ -3,28 +3,14 @@ doctrine:
|
|||
entity_managers:
|
||||
default:
|
||||
metadata_cache_driver:
|
||||
type: service
|
||||
id: doctrine.system_cache_provider
|
||||
type: pool
|
||||
pool: doctrine.system_cache_pool
|
||||
query_cache_driver:
|
||||
type: service
|
||||
id: doctrine.system_cache_provider
|
||||
type: pool
|
||||
pool: doctrine.system_cache_pool
|
||||
result_cache_driver:
|
||||
type: service
|
||||
id: doctrine.result_cache_provider
|
||||
|
||||
services:
|
||||
doctrine.result_cache_provider:
|
||||
class: Doctrine\Common\Cache\Psr6\DoctrineProvider
|
||||
public: false
|
||||
factory: ['Doctrine\Common\Cache\Psr6\DoctrineProvider', 'wrap']
|
||||
arguments:
|
||||
- '@doctrine.result_cache_pool'
|
||||
doctrine.system_cache_provider:
|
||||
class: Doctrine\Common\Cache\Psr6\DoctrineProvider
|
||||
public: false
|
||||
factory: [ 'Doctrine\Common\Cache\Psr6\DoctrineProvider', 'wrap' ]
|
||||
arguments:
|
||||
- '@doctrine.system_cache_pool'
|
||||
type: pool
|
||||
pool: doctrine.result_cache_pool
|
||||
|
||||
framework:
|
||||
cache:
|
||||
|
|
|
|||
|
|
@ -59,3 +59,10 @@ parameters:
|
|||
identifier: arguments.count
|
||||
count: 1
|
||||
path: src/Sylius/Bundle/ShopBundle/Router/LocaleStrippingRouter.php
|
||||
|
||||
# DBAL 3.x/4.x compatibility - getSchemaManager() removed in DBAL 4.x
|
||||
-
|
||||
message: '/Call to an undefined method Doctrine\\DBAL\\Connection::getSchemaManager\(\)\./'
|
||||
identifier: method.notFound
|
||||
paths:
|
||||
- src/Sylius/Bundle/CoreBundle/Migrations/
|
||||
|
|
|
|||
|
|
@ -27,7 +27,10 @@ final class DoctrineORMContext implements Context
|
|||
#[BeforeScenario]
|
||||
public function purgeDatabase()
|
||||
{
|
||||
$this->entityManager->getConnection()->getConfiguration()->setSQLLogger(null);
|
||||
$configuration = $this->entityManager->getConnection()->getConfiguration();
|
||||
if (method_exists($configuration, 'setSQLLogger')) {
|
||||
$configuration->setSQLLogger(null);
|
||||
}
|
||||
$purger = new ORMPurger($this->entityManager);
|
||||
$purger->purge();
|
||||
$this->entityManager->clear();
|
||||
|
|
|
|||
|
|
@ -816,7 +816,7 @@ final readonly class OrderContext implements Context
|
|||
$customer->setFirstname('John');
|
||||
$customer->setLastname('Doe' . $i);
|
||||
|
||||
$customer->setCreatedAt($this->clock->now());
|
||||
$customer->setCreatedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
|
||||
$customers[] = $customer;
|
||||
|
||||
|
|
@ -923,7 +923,7 @@ final readonly class OrderContext implements Context
|
|||
$this->shipOrder($order);
|
||||
}
|
||||
|
||||
$order->setCheckoutCompletedAt($this->clock->now());
|
||||
$order->setCheckoutCompletedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
|
||||
$this->objectManager->persist($order);
|
||||
$this->sharedStorage->set('order', $order);
|
||||
|
|
@ -949,7 +949,7 @@ final readonly class OrderContext implements Context
|
|||
|
||||
$this->payOrder($order);
|
||||
|
||||
$order->setCheckoutCompletedAt($this->clock->now());
|
||||
$order->setCheckoutCompletedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
|
||||
$this->objectManager->persist($order);
|
||||
$this->sharedStorage->set('order', $order);
|
||||
|
|
@ -985,7 +985,7 @@ final readonly class OrderContext implements Context
|
|||
$this->shipOrder($order);
|
||||
}
|
||||
|
||||
$order->setCheckoutCompletedAt($this->clock->now());
|
||||
$order->setCheckoutCompletedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
|
||||
$this->objectManager->persist($order);
|
||||
}
|
||||
|
|
@ -1014,7 +1014,7 @@ final readonly class OrderContext implements Context
|
|||
);
|
||||
|
||||
$order->setState($isFulfilled ? BaseOrderInterface::STATE_FULFILLED : BaseOrderInterface::STATE_NEW);
|
||||
$order->setCheckoutCompletedAt($this->clock->now());
|
||||
$order->setCheckoutCompletedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
|
||||
$this->objectManager->persist($order);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@
|
|||
"phpstan/phpdoc-parser": ">= 2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/data-fixtures": "^1.7",
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/data-fixtures": "^1.7 || ^2.2",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ final class AllTaxons implements AllTaxonsInterface
|
|||
$queryBuilder = $this->entityManager->getConnection()->createQueryBuilder();
|
||||
|
||||
$queryBuilder
|
||||
->select([
|
||||
->select(
|
||||
'taxon.id as id',
|
||||
'taxon.tree_root as tree_root',
|
||||
'taxon.parent_id as parent_id',
|
||||
|
|
@ -53,7 +53,7 @@ final class AllTaxons implements AllTaxonsInterface
|
|||
'taxon.position as position',
|
||||
'taxon.enabled as enabled',
|
||||
'COALESCE(current_translation.name, fallback_translation.name) as name',
|
||||
])
|
||||
)
|
||||
->from('sylius_taxon', 'taxon')
|
||||
->leftJoin(
|
||||
'taxon',
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ final class ArchivingPromotionApplicator implements ArchivingPromotionApplicator
|
|||
|
||||
public function archive(PromotionInterface $data): PromotionInterface
|
||||
{
|
||||
$data->setArchivedAt($this->calendar->now());
|
||||
$data->setArchivedAt(\DateTime::createFromImmutable($this->calendar->now()));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ final readonly class ArchivingShippingMethodApplicator implements ArchivingShipp
|
|||
|
||||
public function archive(ShippingMethodInterface $data): ShippingMethodInterface
|
||||
{
|
||||
$data->setArchivedAt($this->clock->now());
|
||||
$data->setArchivedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ final readonly class RequestResetPasswordTokenHandler
|
|||
}
|
||||
|
||||
$user->setPasswordResetToken($this->generator->generate());
|
||||
$user->setPasswordRequestedAt($this->clock->now());
|
||||
$user->setPasswordRequestedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
|
||||
$this->commandBus->dispatch(
|
||||
new SendResetPasswordEmail(
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ final readonly class VerifyShopUserHandler
|
|||
);
|
||||
}
|
||||
|
||||
$user->setVerifiedAt($this->clock->now());
|
||||
$user->setVerifiedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
$user->setEmailVerificationToken(null);
|
||||
$user->enable();
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
],
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"doctrine/dbal": "^3.9",
|
||||
"doctrine/dbal": "^3.9 || ^4.0",
|
||||
"api-platform/doctrine-orm": "^4.2.1",
|
||||
"api-platform/symfony": "^4.2.1",
|
||||
"lexik/jwt-authentication-bundle": "^3.1",
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ final class ArchivingPromotionApplicatorTest extends TestCase
|
|||
|
||||
$this->clock->expects(self::once())->method('now')->willReturn($now);
|
||||
|
||||
$this->promotion->expects(self::once())->method('setArchivedAt')->with($now);
|
||||
$this->promotion->expects(self::once())->method('setArchivedAt')->with(\DateTime::createFromImmutable($now));
|
||||
|
||||
self::assertSame($this->promotion, $this->archivingPromotionApplicator->archive($this->promotion));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,12 +64,13 @@ final class RequestResetPasswordTokenHandlerTest extends TestCase
|
|||
->method('findOneByEmail')
|
||||
->with('test@email.com')
|
||||
->willReturn($shopUser);
|
||||
$this->clock->expects(self::once())->method('now')->willReturn(new \DateTimeImmutable());
|
||||
$now = new \DateTimeImmutable();
|
||||
$this->clock->expects(self::once())->method('now')->willReturn($now);
|
||||
$this->generator->expects(self::once())->method('generate')->willReturn('TOKEN');
|
||||
$shopUser->expects(self::once())->method('setPasswordResetToken')->with('TOKEN');
|
||||
$shopUser->expects(self::once())
|
||||
->method('setPasswordRequestedAt')
|
||||
->with(self::isInstanceOf(\DateTimeImmutable::class));
|
||||
->with(\DateTime::createFromImmutable($now));
|
||||
$sendResetPasswordEmail = new SendResetPasswordEmail('test@email.com', 'WEB', 'en_US');
|
||||
$this->messageBus->expects(self::once())
|
||||
->method('dispatch')
|
||||
|
|
|
|||
|
|
@ -55,11 +55,12 @@ final class VerifyShopUserHandlerTest extends TestCase
|
|||
->method('findOneBy')
|
||||
->with(['emailVerificationToken' => 'ToKeN'])
|
||||
->willReturn($user);
|
||||
$this->clock->expects(self::once())->method('now')->willReturn(new \DateTimeImmutable());
|
||||
$now = new \DateTimeImmutable();
|
||||
$this->clock->expects(self::once())->method('now')->willReturn($now);
|
||||
$user->expects(self::once())->method('getEmail')->willReturn('shop@example.com');
|
||||
$user->expects(self::once())
|
||||
->method('setVerifiedAt')
|
||||
->with($this->isInstanceOf(\DateTimeImmutable::class));
|
||||
->with(\DateTime::createFromImmutable($now));
|
||||
$user->expects(self::once())->method('setEmailVerificationToken')->with(null);
|
||||
$user->expects(self::once())->method('enable');
|
||||
$this->commandBus->expects(self::once())
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
"symfony/framework-bundle": "^6.4.1 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
"symfony/framework-bundle": "^6.4.1 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ final class RequestResetPasswordEmailHandler
|
|||
}
|
||||
|
||||
$adminUser->setPasswordResetToken($this->generator->generate());
|
||||
$adminUser->setPasswordRequestedAt($this->clock->now());
|
||||
$adminUser->setPasswordRequestedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
|
||||
$this->commandBus->dispatch(
|
||||
new SendResetPasswordEmail($adminUser->getEmail(), $adminUser->getLocaleCode()),
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\CoreBundle\DependencyInjection;
|
||||
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Sylius\Bundle\CoreBundle\Attribute\AsCatalogPromotionApplicatorCriteria;
|
||||
use Sylius\Bundle\CoreBundle\Attribute\AsCatalogPromotionPriceCalculator;
|
||||
use Sylius\Bundle\CoreBundle\Attribute\AsEntityObserver;
|
||||
|
|
@ -107,6 +109,7 @@ final class SyliusCoreExtension extends AbstractResourceExtension implements Pre
|
|||
$this->prependDefaultDriver($container, $config['driver']);
|
||||
$this->prependHwiOauth($container);
|
||||
$this->prependDoctrineMigrations($container);
|
||||
$this->prependDoctrineIdentityGenerationPreferences($container);
|
||||
}
|
||||
|
||||
protected function getMigrationsNamespace(): string
|
||||
|
|
@ -134,6 +137,21 @@ final class SyliusCoreExtension extends AbstractResourceExtension implements Pre
|
|||
}
|
||||
}
|
||||
|
||||
private function prependDoctrineIdentityGenerationPreferences(ContainerBuilder $container): void
|
||||
{
|
||||
if (!$container->hasExtension('doctrine')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$container->prependExtensionConfig('doctrine', [
|
||||
'orm' => [
|
||||
'identity_generation_preferences' => [
|
||||
PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE,
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function prependHwiOauth(ContainerBuilder $container): void
|
||||
{
|
||||
if (!$container->hasExtension('hwi_oauth')) {
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\CoreBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\AST\Node;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Query\TokenType;
|
||||
use Sylius\Bundle\CoreBundle\Doctrine\Platform\PlatformHelper;
|
||||
|
||||
final class Cast extends FunctionNode
|
||||
{
|
||||
|
|
@ -48,7 +48,7 @@ final class Cast extends FunctionNode
|
|||
|
||||
$type = $this->type;
|
||||
|
||||
if (is_a($platform, MySQLPlatform::class, true) && 'text' === $type) {
|
||||
if (PlatformHelper::isMysql($platform) && 'text' === $type) {
|
||||
$type = 'char';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,14 +13,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\CoreBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\AST\Node;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Query\TokenType;
|
||||
use Sylius\Bundle\CoreBundle\Doctrine\Platform\PlatformHelper;
|
||||
|
||||
final class Day extends FunctionNode
|
||||
{
|
||||
|
|
@ -41,15 +39,15 @@ final class Day extends FunctionNode
|
|||
{
|
||||
$platform = $sqlWalker->getConnection()->getDatabasePlatform();
|
||||
|
||||
if (is_a($platform, MySQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isMysql($platform)) {
|
||||
return sprintf('DAY(%s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, PostgreSQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isPostgreSQL($platform)) {
|
||||
return sprintf('EXTRACT(DAY FROM %s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, SqlitePlatform::class, true)) {
|
||||
if (PlatformHelper::isSqlite($platform)) {
|
||||
return sprintf('CAST(STRFTIME("%%d", %s) AS NUMBER)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,14 +13,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\CoreBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\AST\Node;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Query\TokenType;
|
||||
use Sylius\Bundle\CoreBundle\Doctrine\Platform\PlatformHelper;
|
||||
|
||||
final class Hour extends FunctionNode
|
||||
{
|
||||
|
|
@ -41,15 +39,15 @@ final class Hour extends FunctionNode
|
|||
{
|
||||
$platform = $sqlWalker->getConnection()->getDatabasePlatform();
|
||||
|
||||
if (is_a($platform, MySQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isMysql($platform)) {
|
||||
return sprintf('HOUR(%s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, PostgreSQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isPostgreSQL($platform)) {
|
||||
return sprintf('EXTRACT(HOUR FROM %s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, SqlitePlatform::class, true)) {
|
||||
if (PlatformHelper::isSqlite($platform)) {
|
||||
return sprintf('CAST(STRFTIME("%%H", %s) AS NUMBER)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,14 +13,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\CoreBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\AST\Node;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Query\TokenType;
|
||||
use Sylius\Bundle\CoreBundle\Doctrine\Platform\PlatformHelper;
|
||||
|
||||
final class Month extends FunctionNode
|
||||
{
|
||||
|
|
@ -41,15 +39,15 @@ final class Month extends FunctionNode
|
|||
{
|
||||
$platform = $sqlWalker->getConnection()->getDatabasePlatform();
|
||||
|
||||
if (is_a($platform, MySQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isMysql($platform)) {
|
||||
return sprintf('MONTH(%s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, PostgreSQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isPostgreSQL($platform)) {
|
||||
return sprintf('EXTRACT(MONTH FROM %s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, SqlitePlatform::class, true)) {
|
||||
if (PlatformHelper::isSqlite($platform)) {
|
||||
return sprintf('CAST(STRFTIME("%%m", %s) AS NUMBER)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,14 +13,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\CoreBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\AST\Node;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Query\TokenType;
|
||||
use Sylius\Bundle\CoreBundle\Doctrine\Platform\PlatformHelper;
|
||||
|
||||
final class Week extends FunctionNode
|
||||
{
|
||||
|
|
@ -41,15 +39,15 @@ final class Week extends FunctionNode
|
|||
{
|
||||
$platform = $sqlWalker->getConnection()->getDatabasePlatform();
|
||||
|
||||
if (is_a($platform, MySQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isMysql($platform)) {
|
||||
return sprintf('WEEK(%s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, PostgreSQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isPostgreSQL($platform)) {
|
||||
return sprintf('EXTRACT(WEEK FROM %s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, SqlitePlatform::class, true)) {
|
||||
if (PlatformHelper::isSqlite($platform)) {
|
||||
return sprintf('CAST(STRFTIME("%%W", %s) AS NUMBER)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,14 +13,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\CoreBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\AST\Node;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Query\TokenType;
|
||||
use Sylius\Bundle\CoreBundle\Doctrine\Platform\PlatformHelper;
|
||||
|
||||
final class Year extends FunctionNode
|
||||
{
|
||||
|
|
@ -41,15 +39,15 @@ final class Year extends FunctionNode
|
|||
{
|
||||
$platform = $sqlWalker->getConnection()->getDatabasePlatform();
|
||||
|
||||
if (is_a($platform, MySQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isMysql($platform)) {
|
||||
return sprintf('YEAR(%s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, PostgreSQLPlatform::class, true)) {
|
||||
if (PlatformHelper::isPostgreSQL($platform)) {
|
||||
return sprintf('EXTRACT(YEAR FROM %s)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
if (is_a($platform, SqlitePlatform::class, true)) {
|
||||
if (PlatformHelper::isSqlite($platform)) {
|
||||
return sprintf('CAST(STRFTIME("%%Y", %s) AS NUMBER)', $sqlWalker->walkArithmeticPrimary($this->date));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Bundle\CoreBundle\Doctrine\Platform;
|
||||
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
|
||||
final class PlatformHelper
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function isMysql(object $platform): bool
|
||||
{
|
||||
return is_a($platform, MySQLPlatform::class, true);
|
||||
}
|
||||
|
||||
public static function isPostgreSQL(object $platform): bool
|
||||
{
|
||||
return is_a($platform, PostgreSQLPlatform::class, true);
|
||||
}
|
||||
|
||||
/** Compatibility layer for DBAL 3.x (SqlitePlatform) and 4.x (SQLitePlatform). */
|
||||
public static function isSqlite(object $platform): bool
|
||||
{
|
||||
return str_contains(strtolower($platform::class), 'sqliteplatform');
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ use Doctrine\DBAL\Platforms\MySQLPlatform;
|
|||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Sylius\Bundle\CoreBundle\Doctrine\Platform\PlatformHelper;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
|
@ -121,12 +122,6 @@ final class DatabaseSetupCommandsProvider implements DatabaseSetupCommandsProvid
|
|||
|
||||
private function isSQLite(): bool
|
||||
{
|
||||
$platform = $this->entityManager->getConnection()->getDatabasePlatform();
|
||||
|
||||
if (class_exists(\Doctrine\DBAL\Platforms\SqlitePlatform::class) && is_a($platform, \Doctrine\DBAL\Platforms\SqlitePlatform::class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return PlatformHelper::isSqlite($this->entityManager->getConnection()->getDatabasePlatform());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ final class PriceChangeLogger implements PriceChangeLoggerInterface
|
|||
|
||||
$logEntry = $this->logEntryFactory->create(
|
||||
$channelPricing,
|
||||
$this->clock->now(),
|
||||
\DateTime::createFromImmutable($this->clock->now()),
|
||||
$channelPricing->getPrice(),
|
||||
$channelPricing->getOriginalPrice(),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ sylius_core:
|
|||
|
||||
doctrine:
|
||||
orm:
|
||||
auto_generate_proxy_classes: "%kernel.debug%"
|
||||
entity_managers:
|
||||
default:
|
||||
auto_mapping: true
|
||||
|
|
|
|||
|
|
@ -55,8 +55,9 @@ final class DatabasePlatformDataProvider implements DataProviderInterface
|
|||
{
|
||||
try {
|
||||
$platform = $connection->getDatabasePlatform();
|
||||
if ($platform instanceof AbstractPlatform) {
|
||||
return $platform->getName();
|
||||
$platformName = $this->getPlatformName($platform);
|
||||
if (null !== $platformName) {
|
||||
return $platformName;
|
||||
}
|
||||
} catch (\Throwable) {
|
||||
}
|
||||
|
|
@ -69,6 +70,27 @@ final class DatabasePlatformDataProvider implements DataProviderInterface
|
|||
return null;
|
||||
}
|
||||
|
||||
/** Compatibility layer for DBAL 3.x (getName()) and 4.x (class name based) */
|
||||
private function getPlatformName(AbstractPlatform $platform): ?string
|
||||
{
|
||||
// DBAL 3.x has getName() method
|
||||
if (method_exists($platform, 'getName')) {
|
||||
return $platform->getName();
|
||||
}
|
||||
|
||||
// DBAL 4.x removed getName(), use class name mapping
|
||||
$className = strtolower($platform::class);
|
||||
|
||||
return match (true) {
|
||||
str_contains($className, 'mysql') => 'mysql',
|
||||
str_contains($className, 'postgresql') => 'postgresql',
|
||||
str_contains($className, 'sqlite') => 'sqlite',
|
||||
str_contains($className, 'sqlserver'), str_contains($className, 'sqlsrv') => 'mssql',
|
||||
str_contains($className, 'oracle') => 'oracle',
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
private function mapDriverToDatabase(string $driver): ?string
|
||||
{
|
||||
return match (true) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
],
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"doctrine/dbal": "^3.9",
|
||||
"doctrine/dbal": "^3.9 || ^4.0",
|
||||
"doctrine/doctrine-migrations-bundle": "^3.3",
|
||||
"egulias/email-validator": "^4.0",
|
||||
"fakerphp/faker": "^1.23",
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
"phpstan/phpdoc-parser": ">= 2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"hwi/oauth-bundle": "^2.2",
|
||||
"matthiasnoback/symfony-config-test": "^6.0",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Tests\Sylius\Bundle\CoreBundle\Calculator;
|
||||
|
||||
use DateTime;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Sylius\Bundle\CoreBundle\Calculator\DelayStampCalculator;
|
||||
use Sylius\Bundle\CoreBundle\Calculator\DelayStampCalculatorInterface;
|
||||
|
|
@ -35,8 +34,8 @@ final class DelayStampCalculatorTest extends TestCase
|
|||
|
||||
public function testCalculatesDelayStampFromGivenDates(): void
|
||||
{
|
||||
$currentTime = new DateTime('2021-11-11 20:20');
|
||||
$targetTime = new DateTime('2021-11-11 20:21');
|
||||
$currentTime = new \DateTime('2021-11-11 20:20');
|
||||
$targetTime = new \DateTime('2021-11-11 20:21');
|
||||
|
||||
$expectedStamp = new DelayStamp(60000);
|
||||
|
||||
|
|
@ -47,8 +46,8 @@ final class DelayStampCalculatorTest extends TestCase
|
|||
|
||||
public function testReturns0DelayIfDatesTargetTimeIsSmallerThanCurrentTime(): void
|
||||
{
|
||||
$currentTime = new DateTime('2021-11-11 20:21');
|
||||
$targetTime = new DateTime('2021-11-11 19:05');
|
||||
$currentTime = new \DateTime('2021-11-11 20:21');
|
||||
$targetTime = new \DateTime('2021-11-11 19:05');
|
||||
|
||||
$expectedStamp = new DelayStamp(0);
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ final class RequestResetPasswordEmailHandlerTest extends TestCase
|
|||
$adminUser->expects($this->once())->method('getEmail')->willReturn('admin@example.com');
|
||||
$adminUser->expects($this->once())->method('getLocaleCode')->willReturn('en_US');
|
||||
$adminUser->expects($this->once())->method('setPasswordResetToken')->with('sometoken');
|
||||
$adminUser->expects($this->once())->method('setPasswordRequestedAt')->with($now);
|
||||
$adminUser->expects($this->once())->method('setPasswordRequestedAt')->with(\DateTime::createFromImmutable($now));
|
||||
|
||||
$expectedMessage = new SendResetPasswordEmail('admin@example.com', 'en_US');
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ final class AtomicOrderPromotionsUsageModifierTest extends TestCase
|
|||
$this->entityManager
|
||||
->expects($this->exactly(2))
|
||||
->method('lock')
|
||||
->willReturnCallback(function (object $entity, int $lockMode, mixed $version) use ($promotion, $coupon): void {
|
||||
->willReturnCallback(function (object $entity, int|LockMode $lockMode, mixed $version) use ($promotion, $coupon): void {
|
||||
$this->assertSame(LockMode::OPTIMISTIC, $lockMode);
|
||||
|
||||
if ($entity === $promotion) {
|
||||
|
|
@ -134,7 +134,7 @@ final class AtomicOrderPromotionsUsageModifierTest extends TestCase
|
|||
$this->entityManager
|
||||
->expects($this->exactly(2))
|
||||
->method('lock')
|
||||
->willReturnCallback(function (object $entity, int $lockMode, mixed $version) use ($promotion, $coupon): void {
|
||||
->willReturnCallback(function (object $entity, int|LockMode $lockMode, mixed $version) use ($promotion, $coupon): void {
|
||||
$this->assertSame(LockMode::OPTIMISTIC, $lockMode);
|
||||
|
||||
if ($entity === $promotion) {
|
||||
|
|
@ -202,7 +202,7 @@ final class AtomicOrderPromotionsUsageModifierTest extends TestCase
|
|||
$this->entityManager
|
||||
->expects($this->exactly(2))
|
||||
->method('lock')
|
||||
->willReturnCallback(function (object $entity, int $lockMode, mixed $version) use ($firstPromotion, $secondPromotion): void {
|
||||
->willReturnCallback(function (object $entity, int|LockMode $lockMode, mixed $version) use ($firstPromotion, $secondPromotion): void {
|
||||
$this->assertSame(LockMode::OPTIMISTIC, $lockMode);
|
||||
|
||||
if ($entity === $firstPromotion) {
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ final class PriceChangeLoggerTest extends TestCase
|
|||
$this->logEntryFactory
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($channelPricing, $now, $price, $originalPrice)
|
||||
->with($channelPricing, \DateTime::createFromImmutable($now), $price, $originalPrice)
|
||||
->willReturn($logEntry)
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
"symfony/intl": "^6.4 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
"webmozart/assert": "^1.11"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
"symfony/browser-kit": "^6.4 || ^7.4",
|
||||
"symfony/dependency-injection": "^6.4.1 || ^7.4",
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
"phpstan/phpdoc-parser": ">= 2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
"symfony/browser-kit": "^6.4 || ^7.4",
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
"symfony/framework-bundle": "^6.4.1 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
"webmozart/assert": "^1.11"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
"sylius/currency-bundle": "^2.0",
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
"symfony/service-contracts": "^3.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Bundle\PaymentBundle\Doctrine\DBAL\Type;
|
||||
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
/**
|
||||
* Provides the "object" type for DBAL 4.x compatibility.
|
||||
*
|
||||
* The "object" type was removed in DBAL 4.0. This custom type restores it
|
||||
* so that existing entity mappings using type="object" continue to work
|
||||
* across both DBAL 3.x and 4.x.
|
||||
*/
|
||||
final class ObjectType extends Type
|
||||
{
|
||||
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
|
||||
{
|
||||
return $platform->getClobTypeDeclarationSQL($column);
|
||||
}
|
||||
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform): string
|
||||
{
|
||||
return serialize($value);
|
||||
}
|
||||
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform): mixed
|
||||
{
|
||||
if ($value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_resource($value)) {
|
||||
$value = stream_get_contents($value);
|
||||
}
|
||||
|
||||
set_error_handler(static function (int $code, string $message): never {
|
||||
throw new \RuntimeException(sprintf('Could not unserialize object: %s', $message));
|
||||
});
|
||||
|
||||
try {
|
||||
return unserialize($value);
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return 'object';
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,11 @@ imports:
|
|||
parameters:
|
||||
env(SYLIUS_PAYMENT_ENCRYPTION_KEY_PATH): '%kernel.project_dir%/config/encryption/key'
|
||||
|
||||
doctrine:
|
||||
dbal:
|
||||
types:
|
||||
object: Sylius\Bundle\PaymentBundle\Doctrine\DBAL\Type\ObjectType
|
||||
|
||||
sylius_payment:
|
||||
payment_request:
|
||||
states_to_be_cancelled_when_payment_method_changed:
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
"symfony/messenger": "^6.4 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Bundle\ProductBundle\Doctrine\ORM\Query\AST\Function;
|
||||
|
||||
use Doctrine\DBAL\Exception;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
|
||||
|
|
@ -22,13 +21,10 @@ use Doctrine\ORM\Query\SqlWalker;
|
|||
*/
|
||||
abstract class AbstractPostgresqlJsonFunctionNode extends AbstractJsonFunctionNode
|
||||
{
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function validatePlatform(SqlWalker $sqlWalker): void
|
||||
{
|
||||
if (!$sqlWalker->getConnection()->getDatabasePlatform() instanceof PostgreSQLPlatform) {
|
||||
throw Exception::notSupported(static::FUNCTION_NAME);
|
||||
throw new \LogicException(sprintf('Function "%s" is not supported on this platform.', static::FUNCTION_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
"symfony/framework-bundle": "^6.4.1 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
"phpstan/phpdoc-parser": ">= 2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
"symfony/framework-bundle": "^6.4.1 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
"symfony/browser-kit": "^6.4 || ^7.4",
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@ final class ShippingDateAssigner implements ShippingDateAssignerInterface
|
|||
|
||||
public function assign(ShipmentInterface $shipment): void
|
||||
{
|
||||
$shipment->setShippedAt($this->clock->now());
|
||||
$shipment->setShippedAt(\DateTime::createFromImmutable($this->clock->now()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
"symfony/framework-bundle": "^6.4.1 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ final class ShippingDateAssignerTest extends TestCase
|
|||
$shipment = $this->createMock(ShipmentInterface::class);
|
||||
|
||||
$this->clock->expects($this->once())->method('now')->willReturn(new DateTimeImmutable('20-05-2019 20:20:20'));
|
||||
$shipment->expects($this->once())->method('setShippedAt')->with(new DateTimeImmutable('20-05-2019 20:20:20'));
|
||||
$shipment->expects($this->once())->method('setShippedAt')->with(new \DateTime('20-05-2019 20:20:20'));
|
||||
|
||||
$this->shippingDateAssigner->assign($shipment);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
"symfony/framework-bundle": "^6.4.1 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
"symfony/framework-bundle": "^6.4.1 || ^7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"doctrine/orm": "^2.18 || ^3.5",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
"symfony/dependency-injection": "^6.4.1 || ^7.4"
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
"webmozart/assert": "^1.11"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/doctrine-bundle": "^2.13",
|
||||
"doctrine/doctrine-bundle": "^2.13 || ^3.0",
|
||||
"hwi/oauth-bundle": "^2.2",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^6.0",
|
||||
"phpunit/phpunit": "^11.5",
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ final class PromotionCouponGenerator implements PromotionCouponGeneratorInterfac
|
|||
$coupon->setPromotion($promotion);
|
||||
$coupon->setCode($code);
|
||||
$coupon->setUsageLimit($instruction->getUsageLimit());
|
||||
$coupon->setExpiresAt($instruction->getExpiresAt());
|
||||
$expiresAt = $instruction->getExpiresAt();
|
||||
$coupon->setExpiresAt($expiresAt instanceof \DateTimeImmutable ? \DateTime::createFromImmutable($expiresAt) : $expiresAt);
|
||||
|
||||
$generatedCoupons[$code] = $coupon;
|
||||
|
||||
|
|
|
|||
|
|
@ -194,12 +194,6 @@
|
|||
"instaclick/php-webdriver": {
|
||||
"version": "1.4.7"
|
||||
},
|
||||
"knplabs/gaufrette": {
|
||||
"version": "v0.8.3"
|
||||
},
|
||||
"knplabs/knp-gaufrette-bundle": {
|
||||
"version": "v0.7.1"
|
||||
},
|
||||
"knplabs/knp-menu": {
|
||||
"version": "v3.1.2"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -263,7 +263,9 @@ trait OrderPlacerTrait
|
|||
): OrderInterface {
|
||||
$objectManager = $this->get('doctrine.orm.entity_manager');
|
||||
|
||||
$order->setCheckoutCompletedAt($checkoutCompletedAt);
|
||||
$order->setCheckoutCompletedAt(
|
||||
$checkoutCompletedAt !== null ? \DateTime::createFromImmutable($checkoutCompletedAt) : null,
|
||||
);
|
||||
|
||||
$objectManager->flush();
|
||||
|
||||
|
|
|
|||
|
|
@ -13,25 +13,14 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Tests\Functional\Doctrine\Mock;
|
||||
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver;
|
||||
|
||||
class ConnectionMock extends Connection
|
||||
{
|
||||
/** @var DatabasePlatformMock */
|
||||
private $_platformMock;
|
||||
|
||||
public function __construct(array $params = [], ?Driver $driver = null, ?Configuration $config = null, ?EventManager $eventManager = null)
|
||||
public function __construct(array $params = [], ?Driver $driver = null, ?Configuration $config = null)
|
||||
{
|
||||
$this->_platformMock = new DatabasePlatformMock();
|
||||
|
||||
parent::__construct($params, $driver ?? new DriverMock(), $config, $eventManager);
|
||||
}
|
||||
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
return $this->_platformMock;
|
||||
parent::__construct($params, $driver ?? new DriverMock(), $config);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,32 +23,39 @@ class DatabasePlatformMock extends AbstractPlatform
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getBooleanTypeDeclarationSQL(array $field)
|
||||
public function getBooleanTypeDeclarationSQL(array $field): string
|
||||
{
|
||||
return 'BOOLEAN';
|
||||
}
|
||||
|
||||
public function getIntegerTypeDeclarationSQL(array $field)
|
||||
public function getIntegerTypeDeclarationSQL(array $field): string
|
||||
{
|
||||
return 'INT';
|
||||
}
|
||||
|
||||
public function getBigIntTypeDeclarationSQL(array $field)
|
||||
public function getBigIntTypeDeclarationSQL(array $field): string
|
||||
{
|
||||
return 'BIGINT';
|
||||
}
|
||||
|
||||
public function getSmallIntTypeDeclarationSQL(array $field)
|
||||
public function getSmallIntTypeDeclarationSQL(array $field): string
|
||||
{
|
||||
return 'SMALLINT';
|
||||
}
|
||||
|
||||
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
|
||||
protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef): string
|
||||
{
|
||||
return 'INT';
|
||||
}
|
||||
|
||||
public function getVarcharTypeDeclarationSQL(array $field)
|
||||
public function getVarcharTypeDeclarationSQL(array $field): string
|
||||
{
|
||||
return 'VARCHAR';
|
||||
}
|
||||
|
||||
public function getClobTypeDeclarationSQL(array $field)
|
||||
public function getClobTypeDeclarationSQL(array $field): string
|
||||
{
|
||||
return 'CLOB';
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
|
|
|
|||
68
tests/Functional/Doctrine/Mock/Dbal4DriverConnectionMock.php
Normal file
68
tests/Functional/Doctrine/Mock/Dbal4DriverConnectionMock.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Tests\Functional\Doctrine\Mock;
|
||||
|
||||
use Doctrine\DBAL\Driver\Connection;
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
|
||||
class Dbal4DriverConnectionMock implements Connection
|
||||
{
|
||||
public function prepare(string $sql): Statement
|
||||
{
|
||||
return new Dbal4StatementMock();
|
||||
}
|
||||
|
||||
public function query(string $sql): Result
|
||||
{
|
||||
return new DriverResultMock();
|
||||
}
|
||||
|
||||
public function quote(string $value): string
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function exec(string $sql): int|string
|
||||
{
|
||||
throw new \BadMethodCallException('Not implemented');
|
||||
}
|
||||
|
||||
public function lastInsertId(): int|string
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function beginTransaction(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function commit(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function rollBack(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function getNativeConnection(): mixed
|
||||
{
|
||||
throw new \BadMethodCallException('Not implemented');
|
||||
}
|
||||
|
||||
public function getServerVersion(): string
|
||||
{
|
||||
return '3.0.0';
|
||||
}
|
||||
}
|
||||
30
tests/Functional/Doctrine/Mock/Dbal4StatementMock.php
Normal file
30
tests/Functional/Doctrine/Mock/Dbal4StatementMock.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Tests\Functional\Doctrine\Mock;
|
||||
|
||||
use Doctrine\DBAL\Driver\Result;
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
|
||||
class Dbal4StatementMock implements Statement
|
||||
{
|
||||
public function bindValue(int|string $param, mixed $value, ParameterType $type = ParameterType::STRING): void
|
||||
{
|
||||
}
|
||||
|
||||
public function execute(): Result
|
||||
{
|
||||
return new DriverResultMock();
|
||||
}
|
||||
}
|
||||
|
|
@ -20,47 +20,43 @@ use Doctrine\DBAL\ParameterType;
|
|||
|
||||
class DriverConnectionMock implements Connection
|
||||
{
|
||||
public function prepare($prepareString): Statement
|
||||
public function prepare(string $sql): Statement
|
||||
{
|
||||
return new StatementMock();
|
||||
}
|
||||
|
||||
public function query(?string $sql = null): Result
|
||||
public function query(string $sql): Result
|
||||
{
|
||||
return new DriverResultMock();
|
||||
}
|
||||
|
||||
public function quote($input, $type = ParameterType::STRING)
|
||||
public function quote($value, $type = ParameterType::STRING)
|
||||
{
|
||||
return (string) $input;
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
public function exec($statement): int
|
||||
public function exec(string $sql): int
|
||||
{
|
||||
throw new \BadMethodCallException('Not implemented');
|
||||
}
|
||||
|
||||
public function lastInsertId($name = null)
|
||||
public function lastInsertId($name = null): string|int|false
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function beginTransaction()
|
||||
public function beginTransaction(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function commit()
|
||||
public function commit(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rollBack()
|
||||
{
|
||||
}
|
||||
|
||||
public function errorCode()
|
||||
{
|
||||
}
|
||||
|
||||
public function errorInfo()
|
||||
public function rollBack(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,41 +13,18 @@ declare(strict_types=1);
|
|||
|
||||
namespace Sylius\Tests\Functional\Doctrine\Mock;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver;
|
||||
use Doctrine\DBAL\Driver\API\ExceptionConverter;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||
use Doctrine\DBAL\Driver\AbstractSQLiteDriver;
|
||||
use Doctrine\DBAL\Driver\Connection as DriverConnection;
|
||||
use Doctrine\DBAL\ServerVersionProvider;
|
||||
|
||||
class DriverMock implements Driver
|
||||
class DriverMock extends AbstractSQLiteDriver
|
||||
{
|
||||
public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
|
||||
public function connect(array $params): DriverConnection
|
||||
{
|
||||
if (is_a(DriverConnection::class, ServerVersionProvider::class, true)) {
|
||||
return new Dbal4DriverConnectionMock();
|
||||
}
|
||||
|
||||
return new DriverConnectionMock();
|
||||
}
|
||||
|
||||
public function getDatabasePlatform()
|
||||
{
|
||||
throw new \BadMethodCallException('Not implemented');
|
||||
}
|
||||
|
||||
public function getSchemaManager(Connection $conn, ?AbstractPlatform $platform = null): AbstractSchemaManager
|
||||
{
|
||||
throw new \BadMethodCallException('Not implemented');
|
||||
}
|
||||
|
||||
public function getExceptionConverter(): ExceptionConverter
|
||||
{
|
||||
throw new \BadMethodCallException('Not implemented');
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
throw new \BadMethodCallException('Not implemented');
|
||||
}
|
||||
|
||||
public function getDatabase(Connection $conn)
|
||||
{
|
||||
throw new \BadMethodCallException('Not implemented');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,26 +21,27 @@ use Doctrine\DBAL\Driver\Result;
|
|||
*/
|
||||
class DriverResultMock implements Result
|
||||
{
|
||||
/** @var list<array<string, mixed>> */
|
||||
private array $resultSet;
|
||||
|
||||
/**
|
||||
* Creates a new mock statement that will serve the provided fake result set to clients.
|
||||
*
|
||||
* @param array $resultSet The faked SQL result set.
|
||||
* @param list<array<string, mixed>> $resultSet The faked SQL result set.
|
||||
*/
|
||||
public function __construct(array $resultSet = [])
|
||||
{
|
||||
$this->resultSet = $resultSet;
|
||||
}
|
||||
|
||||
public function fetchNumeric()
|
||||
public function fetchNumeric(): array|false
|
||||
{
|
||||
$row = $this->fetchAssociative();
|
||||
|
||||
return $row === false ? false : array_values($row);
|
||||
}
|
||||
|
||||
public function fetchAssociative()
|
||||
public function fetchAssociative(): array|false
|
||||
{
|
||||
$current = current($this->resultSet);
|
||||
next($this->resultSet);
|
||||
|
|
@ -48,7 +49,7 @@ class DriverResultMock implements Result
|
|||
return $current;
|
||||
}
|
||||
|
||||
public function fetchOne()
|
||||
public function fetchOne(): mixed
|
||||
{
|
||||
$row = $this->fetchNumeric();
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,14 @@ use Traversable;
|
|||
|
||||
class StatementMock implements IteratorAggregate, Statement
|
||||
{
|
||||
public function bindValue($param, $value, $type = null)
|
||||
public function bindValue($param, $value, $type = null): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function bindParam($column, &$variable, $type = null, $length = null)
|
||||
public function bindParam($param, &$variable, $type = null, $length = null): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function execute($params = null): Result
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue