chore: cleanup, update project dependencies

This commit is contained in:
Björn Fromme
2026-04-29 09:58:40 +02:00
parent e4ef2f7adc
commit 18a97394e8
5 changed files with 50 additions and 569 deletions
Generated
+46 -45
View File
@@ -1005,16 +1005,16 @@
},
{
"name": "doctrine/migrations",
"version": "3.9.6",
"version": "3.9.7",
"source": {
"type": "git",
"url": "https://github.com/doctrine/migrations.git",
"reference": "ffd8355cdd8505fc650d9604f058bf62aedd80a1"
"reference": "96cb2a89b56c9efb0bac38e606dc0b0f13e650ec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/migrations/zipball/ffd8355cdd8505fc650d9604f058bf62aedd80a1",
"reference": "ffd8355cdd8505fc650d9604f058bf62aedd80a1",
"url": "https://api.github.com/repos/doctrine/migrations/zipball/96cb2a89b56c9efb0bac38e606dc0b0f13e650ec",
"reference": "96cb2a89b56c9efb0bac38e606dc0b0f13e650ec",
"shasum": ""
},
"require": {
@@ -1088,7 +1088,7 @@
],
"support": {
"issues": "https://github.com/doctrine/migrations/issues",
"source": "https://github.com/doctrine/migrations/tree/3.9.6"
"source": "https://github.com/doctrine/migrations/tree/3.9.7"
},
"funding": [
{
@@ -1104,7 +1104,7 @@
"type": "tidelift"
}
],
"time": "2026-02-11T06:46:11+00:00"
"time": "2026-04-23T19:33:20+00:00"
},
{
"name": "doctrine/orm",
@@ -1196,19 +1196,20 @@
},
{
"name": "doctrine/persistence",
"version": "4.1.1",
"version": "4.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/persistence.git",
"reference": "b9c49ad3558bb77ef973f4e173f2e9c2eca9be09"
"reference": "49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/persistence/zipball/b9c49ad3558bb77ef973f4e173f2e9c2eca9be09",
"reference": "b9c49ad3558bb77ef973f4e173f2e9c2eca9be09",
"url": "https://api.github.com/repos/doctrine/persistence/zipball/49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b",
"reference": "49ab73e0d3e2ac8d1f5ecda3dd8acd5503781e8b",
"shasum": ""
},
"require": {
"doctrine/deprecations": "^1",
"doctrine/event-manager": "^1 || ^2",
"php": "^8.1",
"psr/cache": "^1.0 || ^2.0 || ^3.0"
@@ -1219,13 +1220,13 @@
"phpstan/phpstan-phpunit": "^2",
"phpstan/phpstan-strict-rules": "^2",
"phpunit/phpunit": "^10.5.58 || ^12",
"symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0",
"symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0"
"symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0",
"symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0 || ^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Doctrine\\Persistence\\": "src/Persistence"
"Doctrine\\Persistence\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1269,7 +1270,7 @@
],
"support": {
"issues": "https://github.com/doctrine/persistence/issues",
"source": "https://github.com/doctrine/persistence/tree/4.1.1"
"source": "https://github.com/doctrine/persistence/tree/4.2.0"
},
"funding": [
{
@@ -1285,7 +1286,7 @@
"type": "tidelift"
}
],
"time": "2025-10-16T20:13:18+00:00"
"time": "2026-04-26T12:12:52+00:00"
},
{
"name": "doctrine/sql-formatter",
@@ -3657,16 +3658,16 @@
},
{
"name": "phpseclib/phpseclib",
"version": "3.0.51",
"version": "3.0.52",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "d59c94077f9c9915abb51ddb52ce85188ece1748"
"reference": "2adaefc83df2ec548558307690f376dd7d4f4fce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d59c94077f9c9915abb51ddb52ce85188ece1748",
"reference": "d59c94077f9c9915abb51ddb52ce85188ece1748",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/2adaefc83df2ec548558307690f376dd7d4f4fce",
"reference": "2adaefc83df2ec548558307690f376dd7d4f4fce",
"shasum": ""
},
"require": {
@@ -3747,7 +3748,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.51"
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.52"
},
"funding": [
{
@@ -3763,7 +3764,7 @@
"type": "tidelift"
}
],
"time": "2026-04-10T01:33:53+00:00"
"time": "2026-04-27T07:02:15+00:00"
},
{
"name": "phpstan/phpdoc-parser",
@@ -7520,16 +7521,16 @@
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.36.0",
"version": "v1.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df"
"reference": "4864388bfbd3001ce88e234fab652acd91fdc57e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/ad1b7b9092976d6c948b8a187cec9faaea9ec1df",
"reference": "ad1b7b9092976d6c948b8a187cec9faaea9ec1df",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/4864388bfbd3001ce88e234fab652acd91fdc57e",
"reference": "4864388bfbd3001ce88e234fab652acd91fdc57e",
"shasum": ""
},
"require": {
@@ -7578,7 +7579,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.36.0"
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.37.0"
},
"funding": [
{
@@ -7598,11 +7599,11 @@
"type": "tidelift"
}
],
"time": "2026-04-10T16:19:22+00:00"
"time": "2026-04-26T13:13:48+00:00"
},
{
"name": "symfony/polyfill-intl-icu",
"version": "v1.36.0",
"version": "v1.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-icu.git",
@@ -7666,7 +7667,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.36.0"
"source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.37.0"
},
"funding": [
{
@@ -7690,7 +7691,7 @@
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.36.0",
"version": "v1.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
@@ -7753,7 +7754,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.36.0"
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.37.0"
},
"funding": [
{
@@ -7777,7 +7778,7 @@
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.36.0",
"version": "v1.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
@@ -7838,7 +7839,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.36.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.37.0"
},
"funding": [
{
@@ -7862,7 +7863,7 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.36.0",
"version": "v1.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
@@ -7923,7 +7924,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.36.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.37.0"
},
"funding": [
{
@@ -7947,7 +7948,7 @@
},
{
"name": "symfony/polyfill-php83",
"version": "v1.36.0",
"version": "v1.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php83.git",
@@ -8003,7 +8004,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php83/tree/v1.36.0"
"source": "https://github.com/symfony/polyfill-php83/tree/v1.37.0"
},
"funding": [
{
@@ -8027,7 +8028,7 @@
},
{
"name": "symfony/polyfill-php84",
"version": "v1.36.0",
"version": "v1.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php84.git",
@@ -8083,7 +8084,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php84/tree/v1.36.0"
"source": "https://github.com/symfony/polyfill-php84/tree/v1.37.0"
},
"funding": [
{
@@ -8107,7 +8108,7 @@
},
{
"name": "symfony/polyfill-uuid",
"version": "v1.36.0",
"version": "v1.37.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-uuid.git",
@@ -8166,7 +8167,7 @@
"uuid"
],
"support": {
"source": "https://github.com/symfony/polyfill-uuid/tree/v1.36.0"
"source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0"
},
"funding": [
{
@@ -11740,11 +11741,11 @@
},
{
"name": "phpstan/phpstan",
"version": "2.1.51",
"version": "2.1.53",
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/dc3b523c45e714c70de2ac5113b958223b55dc59",
"reference": "dc3b523c45e714c70de2ac5113b958223b55dc59",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/ef67586798c003274797b288a68b221e4270dca7",
"reference": "ef67586798c003274797b288a68b221e4270dca7",
"shasum": ""
},
"require": {
@@ -11789,7 +11790,7 @@
"type": "github"
}
],
"time": "2026-04-21T18:22:01+00:00"
"time": "2026-04-28T16:09:00+00:00"
},
{
"name": "phpstan/phpstan-doctrine",
-484
View File
@@ -1,484 +0,0 @@
# Symfony 7.4 Upgrade Plan
**Project:** MyEP Next Booking
**Current Version:** Symfony 6.4.x (6.4.33)
**Target Version:** Symfony 7.4 (LTS)
**Date:** 2026-02-23
**Status:** Ready for Upgrade
---
## Executive Summary
**Estimated Effort: LOW**
**Risk Level: LOW**
**Status: READY FOR UPGRADE**
The MyEP Next Booking application is well-positioned for a Symfony 7.4 upgrade. The codebase follows modern Symfony best practices, uses PHP 8 features extensively, and avoids most deprecated patterns. All pre-upgrade fixes have been completed.
**Key Facts:**
- Symfony 7.4 was released on November 27, 2025
- Requires PHP 8.2.0+ (current: PHP 8.3.30)
- LTS version with bug fixes until November 2028, security fixes until November 2029
- Symfony 8.0 = Symfony 7.4 minus deprecations (same features, PHP 8.4 required)
**Pre-Upgrade Status:**
- PHP version: 8.3.30 (compatible; Symfony 7.4 requires 8.2+)
- OAuth2 Server Bundle: 1.1.0 (compatible)
- Stimulus Bundle: 2.32.0 (compatible)
- Doctrine ORM: 3.6.0 (compatible)
- All 433 tests passing
- Email validation mode: Configured (html5)
- 18 test-only deprecation warnings (cosmetic, do not affect runtime)
---
## Previous Plan Status
The previous upgrade plan (dated 2025-12-06) has been updated. All pre-upgrade tasks are now complete.
### Completed Items
| Item | Previous Status | Current Status |
|------|----------------|----------------|
| OAuth2 Server Bundle | 1.0.0 | **1.1.0 installed** |
| Stimulus Bundle | 2.31.0 | **2.32.0 installed** |
| PHP 8.2 deprecations (ParticipantDto::$touched) | Planned | **Completed** |
| Doctrine config (controller_resolver) | Planned | **Completed** |
| SecurityController null safety | Needs verification | **Completed** (uses `?->` and `??`) |
| Email validator "loose" mode deprecation | Needs fix | **Completed** (validator.yaml configured) |
| Failing test in BookingDataProcessorTest | Unrelated to upgrade | **Resolved** (test now passes) |
---
## Current State Analysis
### PHP Version Compatibility
- **Current Runtime:** PHP 8.3.30
- **Composer Platform:** PHP 8.3.30
- **Symfony 7.4 Required:** PHP 8.2.0+
- **Status:** Compatible
### Installed Dependencies
#### Core Symfony Packages (6.4.x)
All 33 Symfony packages currently at 6.4.x need version constraint updates to 7.4.*
#### Third-Party Bundles - Compatible
| Package | Installed | Symfony 7.4 Compatible |
|---------|-----------|------------------------|
| `doctrine/orm` | 3.6.0 | Yes |
| `doctrine/doctrine-bundle` | 2.18.1 | Yes |
| `doctrine/doctrine-migrations-bundle` | 3.7.0 | Yes |
| `league/oauth2-server-bundle` | 1.1.0 | Yes |
| `symfony/stimulus-bundle` | 2.32.0 | Yes |
| `symfony/webpack-encore-bundle` | 2.4.0 | Yes |
| `symfony/monolog-bundle` | 3.11.0 | Yes |
| `zenstruck/schedule-bundle` | 1.9.0 | Yes |
| `league/flysystem-bundle` | 3.6.1 | Yes |
| `league/flysystem-sftp-v3` | 3.30.0 | Yes |
| `nelexa/zip` | 4.0.2 | Yes (verify post-upgrade) |
| `spatie/crypto` | 2.1.1 | Yes |
| `easycorp/easyadmin-bundle` | 4.29.1 (^4.27) | Yes |
### Code Quality Assessment
The codebase implements modern Symfony/PHP patterns:
- All controllers use PHP 8 attributes (`#[Route]`)
- Constructor property promotion used throughout
- Strict types enforced on all files
- Typed properties and return type declarations
- Entities use PHP 8 attributes for ORM mapping
- Modern security system (AbstractLoginFormAuthenticator)
- No deprecated annotation usage
---
## Pre-Upgrade Fixes - COMPLETED
### 1. Email Validator "loose" Mode Deprecation - DONE
**Issue:** The default mode for `#[Assert\Email]` is "loose", which is deprecated in Symfony 6.2+ and removed in Symfony 7.0.
**Resolution:** Framework default configured in `config/packages/validator.yaml`:
```yaml
framework:
validation:
email_validation_mode: html5
```
All Email constraints in the codebase also explicitly use `mode: 'strict'`:
- `src/Form/Model/ParticipantDto.php` - Has `mode: 'strict'`
- `src/Form/Model/RegistrationDto.php` - Has `mode: 'strict'`
- `src/BusProNet/Model/Communication.php` - Has `mode: 'strict'`
- `src/Controller/ResetPasswordController.php` - Has `mode: 'strict'`
### 2. Test Deprecation Warnings - COSMETIC ONLY
**Issue:** 18 deprecation warnings appear during test runs.
**Cause:** `ParticipantEditDtoTest` creates a standalone validator using `Validation::createValidatorBuilder()` which bypasses the framework's `validator.yaml` configuration.
**Impact:** These warnings are cosmetic and do not affect:
- Runtime behavior (all Email constraints use explicit `mode: 'strict'`)
- Symfony 7.4 compatibility (no code changes needed)
- Test results (all 433 tests pass)
**Note:** Warnings can be silenced with `SYMFONY_DEPRECATIONS_HELPER=disabled` if desired.
---
## Required Changes
### 1. Update Composer Version Constraints
**File:** `composer.json`
#### Symfony Core Packages
Update all packages from `6.4.*` to `7.4.*`:
```json
{
"require": {
"symfony/asset": "7.4.*",
"symfony/console": "7.4.*",
"symfony/doctrine-messenger": "7.4.*",
"symfony/dom-crawler": "7.4.*",
"symfony/dotenv": "7.4.*",
"symfony/expression-language": "7.4.*",
"symfony/form": "7.4.*",
"symfony/framework-bundle": "7.4.*",
"symfony/html-sanitizer": "7.4.*",
"symfony/http-client": "7.4.*",
"symfony/intl": "7.4.*",
"symfony/lock": "7.4.*",
"symfony/mailer": "7.4.*",
"symfony/mime": "7.4.*",
"symfony/notifier": "7.4.*",
"symfony/process": "7.4.*",
"symfony/property-access": "7.4.*",
"symfony/property-info": "7.4.*",
"symfony/runtime": "7.4.*",
"symfony/security-bundle": "7.4.*",
"symfony/serializer": "7.4.*",
"symfony/string": "7.4.*",
"symfony/translation": "7.4.*",
"symfony/twig-bundle": "7.4.*",
"symfony/uid": "7.4.*",
"symfony/validator": "7.4.*",
"symfony/web-link": "7.4.*",
"symfony/yaml": "7.4.*"
}
}
```
#### Development Packages
```json
{
"require-dev": {
"symfony/browser-kit": "7.4.*",
"symfony/css-selector": "7.4.*",
"symfony/debug-bundle": "7.4.*",
"symfony/maker-bundle": "^1.0",
"symfony/phpunit-bridge": "7.4.*",
"symfony/stopwatch": "7.4.*",
"symfony/web-profiler-bundle": "7.4.*"
}
}
```
Keep `symfony/maker-bundle` at `^1.0` (compatible with Symfony 7.4).
### 2. Update Symfony Flex Configuration
**File:** `composer.json`
```json
{
"extra": {
"symfony": {
"allow-contrib": true,
"require": "7.4.*",
"docker": true
}
}
}
```
---
## Potential Breaking Changes
### 1. Symfony Core Changes (Symfony 7.0 -> 7.4)
Symfony 7.0 removed all deprecated features from 6.4. Our codebase is fully compliant:
- **Native Return Types:** Already implemented
- **Attribute-based Configuration:** Already implemented
- **Security System:** Modern authenticator pattern in use
- **Form System:** Modern approach in use
- **No Annotation Usage:** All using PHP 8 attributes
### 2. Email Validation Mode
**Breaking Change:** The default `mode` for `Email` constraint changes from `loose` to `html5` in Symfony 7.0.
**Status:** Already handled - all constraints use explicit `mode: 'strict'` and framework default is set to `html5`.
### 3. Deprecation Cleanup
Deprecations accumulated in Symfony 7.1-7.4 will need review:
- Check Symfony Profiler after upgrade for any new deprecation warnings
- Review [UPGRADE-7.0.md](https://github.com/symfony/symfony/blob/7.0/UPGRADE-7.0.md)
- Review [UPGRADE-7.4.md](https://github.com/symfony/symfony/blob/7.4/UPGRADE-7.4.md)
---
## Upgrade Procedure
### Phase 1: Preparation (15 minutes)
1. **Create Feature Branch**
```bash
git checkout -b feature/symfony-7.4-upgrade
```
2. **Backup Current State**
```bash
git tag before-symfony-7.4-upgrade
```
### Phase 2: Dependency Updates (30 minutes - 1 hour)
1. **Update composer.json**
- Update all Symfony package constraints to `7.4.*`
- Update `extra.symfony.require` to `"7.4.*"`
- Consider tightening `php` to `>=8.2` (Symfony 7.4 requires 8.2+; optional if already on 8.3)
2. **Run Composer Update**
```bash
ddev composer update
```
3. **Review Recipe Updates**
```bash
ddev composer recipes
```
Review any recipe updates from Symfony Flex and apply as needed.
4. **Clear All Caches**
```bash
ddev exec bin/console cache:clear
ddev exec bin/console cache:warmup
ddev exec "php -r 'opcache_reset();'"
```
### Phase 3: Testing & Validation (1-2 hours)
1. **Run PHPUnit Test Suite**
```bash
ddev exec ./vendor/bin/phpunit
```
Check for:
- Test failures
- Deprecation warnings
- Fatal errors
2. **Run PHP-CS-Fixer**
```bash
ddev php vendor/bin/php-cs-fixer fix --dry-run --diff
```
3. **Manual Testing - Critical Paths**
- [ ] User authentication (BPN API login)
- [ ] OAuth2 token generation (`/token` endpoint)
- [ ] OAuth2 authorization flow (`/authorize` endpoint)
- [ ] API endpoints (all `/api/*` routes)
- [ ] Booking creation flow (Steps 1-4)
- [ ] Participant form rendering and submission
- [ ] Dynamic field updates (HTMX)
- [ ] Real-time pricing calculations
- [ ] Insurance selection and filtering
- [ ] Transportation service selection
- [ ] Payment method selection
- [ ] Final booking submission to BPN API
- [ ] Booking edit functionality
- [ ] PDF/XML download functionality
- [ ] User registration
- [ ] Password reset
- [ ] Personal data management
- [ ] EasyAdmin CRUD / admin panels
4. **Check Symfony Profiler**
- Review deprecation warnings (should be minimal)
- Check performance metrics
- Verify no errors in logs
5. **Test Frontend Assets**
```bash
npm run build
```
- Verify Stimulus controllers load correctly
- Test HTMX interactions
- Verify Toastify notifications
- Check TailwindCSS compilation
6. **Verify ZIP File Functionality**
- Test any features using `nelexa/zip` (package last updated 2022)
- Verify document generation and downloads work correctly
### Phase 4: Bug Fixes (0-2 hours)
Address any issues discovered during testing:
1. **Review Error Logs**
```bash
ddev logs
```
2. **Fix Any Remaining Deprecations**
- Use Symfony Profiler to identify deprecations
- Update code to use modern alternatives
### Phase 5: Deployment (1 hour)
1. **Deploy to Staging**
```bash
ddev exec vendor/bin/dep deploy staging
```
2. **Staging Validation**
- Full regression testing
- Performance testing
3. **Production Deployment**
- Schedule maintenance window
- Deploy during low-traffic period
- Monitor error logs closely
---
## Rollback Plan
### Immediate Rollback
If critical issues are discovered:
1. **Git Revert**
```bash
git checkout master
git reset --hard before-symfony-7.4-upgrade
```
2. **Restore Dependencies**
```bash
ddev composer install
```
3. **Clear Caches**
```bash
ddev exec bin/console cache:clear
```
### Production Rollback
If issues occur in production:
```bash
ddev exec vendor/bin/dep rollback production
```
---
## Testing Checklist
### Unit Tests
- [ ] All PHPUnit tests pass (433 tests)
- [ ] No new deprecation warnings
- [ ] Code coverage maintained
### Integration Tests
- [ ] BusProNet API integration
- [ ] XML parsing and data processing
- [ ] Booking price calculations
- [ ] Insurance assignment logic
- [ ] Field handler system
### Functional Tests
- [ ] User authentication flow
- [ ] OAuth2 token generation
- [ ] API endpoints respond correctly
- [ ] Booking creation (all steps)
- [ ] Form validation
- [ ] HTMX partial updates
- [ ] Dynamic field state changes
- [ ] Real-time pricing updates
- [ ] Toast notifications
### Browser Testing
- [ ] Chrome (latest)
- [ ] Firefox (latest)
- [ ] Safari (latest)
- [ ] Mobile browsers
---
## Timeline Estimate
| Phase | Estimated Time | Notes |
|-------|---------------|-------|
| **Phase 1:** Preparation | 15 min | Branch creation |
| **Phase 2:** Dependency Updates | 30 min - 1 hour | composer.json updates, composer update |
| **Phase 3:** Testing & Validation | 1-2 hours | Automated + manual testing |
| **Phase 4:** Bug Fixes | 0-2 hours | Address any issues |
| **Phase 5:** Deployment | 1 hour | Staging deployment |
| **Total** | **2.5-6 hours** | Average: **3.5 hours** |
---
## Future Considerations: Symfony 8.0
Symfony 8.0 was released alongside 7.4 (November 2025) with identical features but:
- Requires PHP 8.4
- No deprecation layers (all deprecated code removed)
- Shorter support window (8 months)
**Recommendation:** Stay on Symfony 7.4 LTS for stability. Plan PHP 8.4 upgrade separately, then consider Symfony 8.x path.
---
## Success Criteria
- [ ] All PHPUnit tests pass (433 tests)
- [ ] No deprecation warnings in Symfony Profiler
- [ ] All critical user flows functional
- [ ] OAuth2 authentication working
- [ ] BPN API integration operational
- [ ] Booking creation flow complete
- [ ] Frontend assets compile and load
- [ ] Performance metrics comparable or better
- [ ] No errors in production logs after 24 hours
---
## Additional Resources
### Official Symfony Documentation
- [Upgrade Major Version Guide](https://symfony.com/doc/current/setup/upgrade_major.html)
- [UPGRADE-7.0.md](https://github.com/symfony/symfony/blob/7.0/UPGRADE-7.0.md)
- [UPGRADE-7.4.md](https://github.com/symfony/symfony/blob/7.4/UPGRADE-7.4.md)
- [Symfony 7.4 Release Notes](https://symfony.com/releases/7.4)
- [Preparing for Symfony 7.4 and 8.0](https://symfony.com/blog/preparing-for-symfony-7-4-and-symfony-8-0)
### Bundle-Specific Documentation
- [OAuth2 Server Bundle](https://github.com/thephpleague/oauth2-server-bundle)
- [Doctrine ORM 3.x Documentation](https://www.doctrine-project.org/projects/orm.html)
---
**Document Version:** 7.0
**Previous Version:** 6.0 (dated 2026-01-09)
**Last Updated:** 2026-02-23
**Status:** Ready for Symfony 7.4 Upgrade (updated for current project state)
-39
View File
@@ -1,39 +0,0 @@
# Contingent API Status
## Summary
The contingent API is implemented on `master`. It serves cached availability data from `HotelZimmer_*.xml` files in `var/xmlexportzimmer`, using Flysystem and the tag-aware `bpn.cache` pool. XML sync now covers both travel and contingent datasets, invalidates `xml-sync` tagged cache entries, and logs dataset transfer errors without aborting the command.
## Implemented
- OAuth-protected endpoints:
- `GET /api/contingents?hotelRef={hotelRef}&dateRef={dateRef}`
- `GET /api/contingents/rooms?hotelRef={hotelRef}&dateRef={dateRef}&dateFrom={Y-m-d}&dateTo={Y-m-d}`
- `GET /api/contingents/calendar?hotelRef={hotelRef}&dateFrom={Y-m-d}&dateTo={Y-m-d}`
- `hotelRef` and `dateRef` accept numeric IDs or business codes; date codes are sanitized before lookup.
- Parser/loader/service/controller flow is implemented via `ContingentParser`, `ContingentLoader`, `ContingentDataService`, and `ContingentController`.
- Room responses include per date + room availability, pricing, status, and `bookingUrl`.
- BelKal control-room rows override date status and set room availability to `0` for affected dates.
- Room-level contingent links and one-hop root-level file links are supported.
- `app:bpn:xml-sync` syncs travel and contingents, invalidates `xml-sync` cache tags, and refreshes travel snapshots only when travel data synced.
- `app:bpn:xml-cache-invalidate` checks both travel and contingent local XML exports.
## Config
- `.env` defines `XML_EXPORT_CONTINGENTS_PATH` and `SFTP_XML_EXPORT_CONTINGENTS_*`.
- `config/packages/flysystem.yaml` defines:
- `xml_export_contingents.storage`
- `xml_source_contingents.storage`
- `config/services.yaml` wires contingent storage, `bpn.cache`, and `APP_BASE_URL` for booking URL generation.
## Behavior Notes
- Missing contingent XML returns empty data.
- Unknown travel/date or hotel/date mismatches return `404` from the API.
- Invalid date ranges or formats return `400`.
- Dataset transfer failures are shown and logged as warnings, but `app:bpn:xml-sync` still completes with exit code `0`.
## Remaining TODOs
- Decide whether room responses still need travel metadata fields such as `summer`, `servicesIncluded`, and `servicesOptional`; these are not currently implemented.
- If the XML files grow materially or cold-cache parsing becomes slow, revisit whether `ContingentParser` should move from DOM/Crawler parsing to a streaming parser.
- Validate the deployed contingent SFTP environment variables before enabling scheduled sync in production.
## Verification
- Covered by parser, loader, data service, controller, booking URL, XML sync, and cache invalidation tests.
- Current verification command: `php bin/phpunit`.
@@ -96,6 +96,9 @@ class NewsletterSubscriptionController extends AbstractController
], $extra), Response::HTTP_BAD_REQUEST);
}
/**
* @return array<string, mixed>
*/
private function responsePayload(NewsletterSubscriptionRequestResult $result): array
{
return [
@@ -109,7 +109,7 @@ class Step4Controller extends AbstractBookingCreateController
&& $form->has('newsletterOptIn')
&& true === $form->get('newsletterOptIn')->getData();
if (true === $newsletterOptInSelected && null !== $newsletterTargetEmail) {
if (true === $newsletterOptInSelected) {
try {
$targetParticipant = $this->resolveNewsletterTargetParticipant($bookingCreateDto);
$this->doubleOptInService->requestDefaultListSubscription(