diff --git a/.appveyor.yml b/.appveyor.yml index 5077eea33d60a..3cbe5480282b1 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -17,15 +17,15 @@ init: install: - mkdir c:\php && cd c:\php - - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.1.3-Win32-VC14-x86.zip - - 7z x php-7.1.3-Win32-VC14-x86.zip -y >nul + - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php-7.2.5-Win32-VC15-x86.zip + - 7z x php-7.2.5-Win32-VC15-x86.zip -y >nul - cd ext - - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php_apcu-5.1.8-7.1-ts-vc14-x86.zip - - 7z x php_apcu-5.1.8-7.1-ts-vc14-x86.zip -y >nul + - appveyor DownloadFile https://github.com/symfony/binary-utils/releases/download/v0.1/php_apcu-5.1.17-7.2-ts-vc15-x86.zip + - 7z x php_apcu-5.1.17-7.2-ts-vc15-x86.zip -y >nul - cd .. - copy /Y php.ini-development php.ini-min - echo memory_limit=-1 >> php.ini-min - - echo serialize_precision=14 >> php.ini-min + - echo serialize_precision=-1 >> php.ini-min - echo max_execution_time=1200 >> php.ini-min - echo post_max_size=4G >> php.ini-min - echo upload_max_filesize=4G >> php.ini-min @@ -63,7 +63,10 @@ test_script: - SET SYMFONY_PHPUNIT_SKIPPED_TESTS=phpunit.skipped - copy /Y c:\php\php.ini-min c:\php\php.ini - IF %APPVEYOR_REPO_BRANCH:~-2% neq .x (rm -Rf src\Symfony\Bridge\PhpUnit) + - mv src\Symfony\Component\HttpClient\phpunit.xml.dist src\Symfony\Component\HttpClient\phpunit.xml - php phpunit src\Symfony --exclude-group tty,benchmark,intl-data || SET X=!errorlevel! + - php phpunit src\Symfony\Component\HttpClient || SET X=!errorlevel! - copy /Y c:\php\php.ini-max c:\php\php.ini - php phpunit src\Symfony --exclude-group tty,benchmark,intl-data || SET X=!errorlevel! + - php phpunit src\Symfony\Component\HttpClient || SET X=!errorlevel! - exit %X% diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0870dcfdd5cc4..b53761486bfd6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -31,6 +31,8 @@ # Messenger /src/Symfony/Bridge/Doctrine/Messenger/ @sroze /src/Symfony/Component/Messenger/ @sroze +# Notifer +/src/Symfony/Component/Notifier/ @OskarStark # OptionsResolver /src/Symfony/Component/OptionsResolver/ @yceruto # PropertyInfo diff --git a/.github/composer-config.json b/.github/composer-config.json index 752047dbb681d..01c998e5ed672 100644 --- a/.github/composer-config.json +++ b/.github/composer-config.json @@ -4,6 +4,7 @@ "preferred-install": { "symfony/form": "source", "symfony/http-kernel": "source", + "symfony/notifier": "source", "symfony/validator": "source", "*": "dist" } diff --git a/.github/patch-types.php b/.github/patch-types.php index 95e56b5984a4e..04335da560504 100644 --- a/.github/patch-types.php +++ b/.github/patch-types.php @@ -7,15 +7,6 @@ require __DIR__.'/../.phpunit/phpunit/vendor/autoload.php'; -file_put_contents(__DIR__.'/../vendor/autoload.php', preg_replace('/^return (Composer.*);/m', <<<'EOTXT' -$loader = \1; -$loader->addClassMap(['Symfony\Component\Debug\Exception\FlattenException' => \dirname(__DIR__).'/src/Symfony/Component/Debug/Exception/FlattenException.php']); - -return $loader; - -EOTXT -, file_get_contents(__DIR__.'/../vendor/autoload.php'))); - $loader = require __DIR__.'/../vendor/autoload.php'; Symfony\Component\ErrorHandler\DebugClassLoader::enable(); diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 603c05bff80d7..d8e6586e5b4b7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,17 +4,26 @@ on: push: pull_request: -jobs: +defaults: + run: + shell: bash +jobs: integration: name: Integration runs-on: Ubuntu-20.04 strategy: matrix: - php: ['7.1', '7.4'] + php: ['7.2', '7.4'] services: + postgres: + image: postgres:9.6-alpine + ports: + - 5432:5432 + env: + POSTGRES_PASSWORD: 'password' ldap: image: bitnami/openldap ports: @@ -58,18 +67,69 @@ jobs: image: rabbitmq:3.8.3 ports: - 5672:5672 + mongodb: + image: mongo + ports: + - 27017:27017 + couchbase: + image: couchbase:6.5.1 + ports: + - 8091:8091 + - 8092:8092 + - 8093:8093 + - 8094:8094 + - 11210:11210 + sqs: + image: asyncaws/testing-sqs + ports: + - 9494:9494 + zookeeper: + image: wurstmeister/zookeeper:3.4.6 + kafka: + image: wurstmeister/kafka:2.12-2.4.1 + ports: + - 9092:9092 + env: + KAFKA_AUTO_CREATE_TOPICS_ENABLE: false + KAFKA_CREATE_TOPICS: 'test-topic:1:1:compact' + KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1 + KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181' + KAFKA_ADVERTISED_PORT: 9092 steps: - name: Checkout uses: actions/checkout@v2 + - name: Install system dependencies + run: | + echo "::group::apt-get update" + sudo apt-get update + echo "::endgroup::" + + echo "::group::install tools & libraries" + sudo apt-get install librdkafka-dev + echo "::endgroup::" + + - name: Configure Couchbase + run: | + curl -s -u 'username=Administrator&password=111111' -X POST http://localhost:8091/node/controller/setupServices -d 'services=kv%2Cn1ql%2Cindex%2Cfts' + curl -s -X POST http://localhost:8091/settings/web -d 'username=Administrator&password=111111&port=SAME' + curl -s -u Administrator:111111 -X POST http://localhost:8091/pools/default/buckets -d 'ramQuotaMB=100&bucketType=ephemeral&name=cache' + curl -s -u Administrator:111111 -X POST http://localhost:8091/pools/default -d 'memoryQuota=256' + - name: Setup PHP uses: shivammathur/setup-php@v2 with: coverage: "none" - extensions: "memcached,redis,xsl,ldap" + extensions: "json,couchbase,memcached,mongodb,redis,rdkafka,xsl,ldap" ini-values: "memory_limit=-1" php-version: "${{ matrix.php }}" + tools: pecl + + - name: Display versions + run: | + php -r 'foreach (get_loaded_extensions() as $extension) echo $extension . " " . phpversion($extension) . PHP_EOL;' + php -i - name: Load fixtures uses: docker://bitnami/openldap @@ -84,9 +144,21 @@ jobs: ([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json" echo "COMPOSER_ROOT_VERSION=$(grep -m1 SYMFONY_VERSION .travis.yml | grep -o '[0-9.x]*').x-dev" >> $GITHUB_ENV + - name: Determine composer cache directory + id: composer-cache + run: echo "::set-output name=directory::$(composer config cache-dir)" + + - name: Cache composer dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.directory }} + key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ matrix.php }}-composer- + - name: Install dependencies run: | echo "::group::composer update" + composer require --dev --no-update mongodb/mongodb:@stable composer update --no-progress --ansi echo "::endgroup::" echo "::group::install phpunit" @@ -102,9 +174,14 @@ jobs: REDIS_SENTINEL_SERVICE: redis_sentinel MESSENGER_REDIS_DSN: redis://127.0.0.1:7006/messages MESSENGER_AMQP_DSN: amqp://localhost/%2f/messages + MESSENGER_SQS_DSN: "sqs://localhost:9494/messages?sslmode=disable&poll_timeout=0.01" + MESSENGER_SQS_FIFO_QUEUE_DSN: "sqs://localhost:9494/messages.fifo?sslmode=disable&poll_timeout=0.01" MEMCACHED_HOST: localhost LDAP_HOST: localhost LDAP_PORT: 3389 + MONGODB_HOST: localhost + KAFKA_BROKER: 127.0.0.1:9092 + POSTGRES_HOST: localhost - name: Run HTTP push tests if: matrix.php == '7.4' diff --git a/.php_cs.dist b/.php_cs.dist index cf005b001e380..1221b062f102d 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -33,10 +33,11 @@ return PhpCsFixer\Config::create() ->notPath('#Symfony/Bridge/PhpUnit/.*Legacy#') // file content autogenerated by `var_export` ->notPath('Symfony/Component/Translation/Tests/fixtures/resources.php') + // file content autogenerated by `VarExporter::export` + ->notPath('Symfony/Component/Serializer/Tests/Fixtures/serializer.class.metadata.php') // test template ->notPath('Symfony/Bundle/FrameworkBundle/Tests/Templating/Helper/Resources/Custom/_name_entry_label.html.php') // explicit trigger_error tests - ->notPath('Symfony/Component/Debug/Tests/DebugClassLoaderTest.php') ->notPath('Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php') ) ; diff --git a/.travis.yml b/.travis.yml index 336224a23bbbe..bcb5e9ff8f69b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,15 +14,15 @@ addons: env: global: - - SYMFONY_VERSION=4.4 - - MIN_PHP=7.1.3 + - SYMFONY_VERSION=5.2 + - MIN_PHP=7.2.5 - SYMFONY_PROCESS_PHP_TEST_BINARY=~/.phpenv/shims/php - SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE=1 matrix: include: - - php: 7.1 - env: php_extra="7.2 7.3 8.0" + - php: 7.2 + env: php_extra="7.3 8.0" - php: 7.4 env: deps=high - php: 8.0 @@ -37,13 +37,13 @@ cache: before_install: - | - # Enable Sury ppa + # Enable extra ppa sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6B05F25D762E3157 sudo add-apt-repository -y ppa:ondrej/php sudo rm /etc/apt/sources.list.d/google-chrome.list sudo rm /etc/apt/sources.list.d/mongodb-3.4.list sudo apt update - sudo apt install -y librabbitmq-dev libsodium-dev + sudo apt install -y librabbitmq-dev libsodium-dev php-uuid zlib1g-dev - | # General configuration @@ -218,7 +218,7 @@ install: - | # Install symfony/flex if [[ $deps = low ]]; then - export SYMFONY_REQUIRE='>=2.3' + export SYMFONY_REQUIRE='>=3.4' else export SYMFONY_REQUIRE=">=$SYMFONY_VERSION" fi diff --git a/CHANGELOG-4.0.md b/CHANGELOG-4.0.md deleted file mode 100644 index cba2e57482bbb..0000000000000 --- a/CHANGELOG-4.0.md +++ /dev/null @@ -1,919 +0,0 @@ -CHANGELOG for 4.0.x -=================== - -This changelog references the relevant changes (bug and security fixes) done -in 4.0 minor versions. - -To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash -To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.0.0...v4.0.1 - -* 4.0.14 (2018-08-01) - - * security #cve-2018-14774 [HttpKernel] fix trusted headers management in HttpCache and InlineFragmentRenderer (nicolas-grekas) - * security #cve-2018-14773 [HttpFoundation] Remove support for legacy and risky HTTP headers (nicolas-grekas) - * bug #28003 [HttpKernel] Fixes invalid REMOTE_ADDR in inline subrequest when configuring trusted proxy with subnet (netiul) - * bug #28007 [FrameworkBundle] fixed guard event names for transitions (destillat) - * bug #28045 [HttpFoundation] Fix Cookie::isCleared (ro0NL) - * bug #28080 [HttpFoundation] fixed using _method parameter with invalid type (Phobetor) - * bug #28052 [HttpKernel] Fix merging bindings for controllers' locators (nicolas-grekas) - -* 4.0.13 (2018-07-23) - - * bug #28005 [HttpKernel] Fixed templateExists on parse error of the template name (yceruto) - * bug #27997 Serbo-Croatian has Serbian plural rule (kylekatarnls) - * bug #26193 Fix false-positive deprecation notices for TranslationLoader and WriteCheckSessionHandler (iquito) - * bug #27941 [WebProfilerBundle] Fixed icon alignment issue using Bootstrap 4.1.2 (jmsche) - * bug #27937 [HttpFoundation] reset callback on StreamedResponse when setNotModified() is called (rubencm) - * bug #27927 [HttpFoundation] Suppress side effects in 'get' and 'has' methods of NamespacedAttributeBag (webnet-fr) - * bug #27923 [Form/Profiler] Massively reducing memory footprint of form profiling pages... (VincentChalnot) - * bug #27918 [Console] correctly return parameter's default value on "--" (seschwar) - * bug #27904 [Filesystem] fix lock file permissions (fritzmg) - * bug #27903 [Lock] fix lock file permissions (fritzmg) - * bug #27889 [Form] Replace .initialism with .text-uppercase. (vudaltsov) - * bug #27902 Fix the detection of the Process new argument (stof) - * bug #27885 [HttpFoundation] don't encode cookie name for BC (nicolas-grekas) - * bug #27782 [DI] Fix dumping ignore-on-uninitialized references to synthetic services (nicolas-grekas) - * bug #27435 [OptionResolver] resolve arrays (Doctrs) - * bug #27728 [TwigBridge] Fix missing path and separators in loader paths list on debug:twig output (yceruto) - * bug #27837 [PropertyInfo] Fix dock block lookup fallback loop (DerManoMann) - * bug #27758 [WebProfilerBundle] Prevent toolbar links color override by css (alcalyn) - * bug #27847 [Security] Fix accepting null as $uidKey in LdapUserProvider (louhde) - * bug #27834 [DI] Don't show internal service id on binding errors (nicolas-grekas) - * bug #27831 Check for Hyper terminal on all operating systems. (azjezz) - * bug #27794 Add color support for Hyper terminal . (azjezz) - * bug #27809 [HttpFoundation] Fix tests: new message for status 425 (dunglas) - * bug #27618 [PropertyInfo] added handling of nullable types in PhpDoc (oxan) - * bug #27659 [HttpKernel] Make AbstractTestSessionListener compatible with CookieClearingLogoutHandler (thewilkybarkid) - * bug #27752 [Cache] provider does not respect option maxIdLength with versioning enabled (Constantine Shtompel) - * bug #27776 [ProxyManagerBridge] Fix support of private services (bis) (nicolas-grekas) - * bug #27714 [HttpFoundation] fix session tracking counter (nicolas-grekas, dmaicher) - * bug #27747 [HttpFoundation] fix registration of session proxies (nicolas-grekas) - * bug #27722 Redesign the Debug error page in prod (javiereguiluz) - * bug #27716 [DI] fix dumping deprecated service in yaml (nicolas-grekas) - -* 4.0.12 (2018-06-25) - - * bug #27626 [TwigBundle][DX] Only add the Twig WebLinkExtension if the WebLink component is enabled (thewilkybarkid) - * bug #27701 [SecurityBundle] Dont throw if "security.http_utils" is not found (nicolas-grekas) - * bug #27690 [DI] Resolve env placeholder in logs (ro0NL) - * bug #26534 allow_extra_attributes does not throw an exception as documented (deviantintegral) - * bug #27668 [Lock] use 'r+' for fopen (fixes issue on Solaris) (fritzmg) - * bug #27669 [Filesystem] fix file lock on SunOS (fritzmg) - * bug #27662 [HttpKernel] fix handling of nested Error instances (xabbuh) - * bug #26845 [Config] Fixing GlobResource when inside phar archive (vworldat) - * bug #27382 [Form] Fix error when rendering a DateIntervalType form with exactly 0 weeks (krixon) - * bug #27309 Fix surrogate not using original request (Toflar) - * bug #27467 [HttpKernel] fix session tracking in surrogate master requests (nicolas-grekas) - * bug #27630 [Validator][Form] Remove BOM in some xlf files (gautierderuette) - * bug #27596 [Framework][Workflow] Added support for interfaces (vudaltsov) - * bug #27593 [ProxyManagerBridge] Fixed support of private services (nicolas-grekas) - * bug #27591 [VarDumper] Fix dumping ArrayObject and ArrayIterator instances (nicolas-grekas) - * bug #27581 Fix bad method call with guard authentication + session migration (weaverryan) - * bug #27576 [Cache] Fix expiry comparisons in array-based pools (nicolas-grekas) - * bug #27556 Avoiding session migration for stateless firewall UsernamePasswordJsonAuthenticationListener (weaverryan) - * bug #27452 Avoid migration on stateless firewalls (weaverryan) - * bug #27568 [DI] Deduplicate generated proxy classes (nicolas-grekas) - * bug #27326 [Serializer] deserialize from xml: Fix a collection that contains the only one element (webnet-fr) - * bug #27567 [PhpUnitBridge] Fix error on some Windows OS (Nsbx) - * bug #27357 [Lock] Remove released semaphore (jderusse) - * bug #27416 TagAwareAdapter over non-binary memcached connections corrupts memcache (Aleksey Prilipko) - * bug #27514 [Debug] Pass previous exception to FatalErrorException (pmontoya) - * bug #27516 Revert "bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen)" (nicolas-grekas) - * bug #27318 [Cache] memcache connect should not add duplicate entries on sequential calls (Aleksey Prilipko) - * bug #27389 [Serializer] Fix serializer tries to denormalize null values on nullable properties (ogizanagi) - * bug #27272 [FrameworkBundle] Change priority of AddConsoleCommandPass to TYPE_BEFORE_REMOVING (upyx) - * bug #27396 [HttpKernel] fix registering IDE links (nicolas-grekas) - * bug #26973 [HttpKernel] Set first trusted proxy as REMOTE_ADDR in InlineFragmentRenderer. (kmadejski) - * bug #27303 [Process] Consider "executable" suffixes first on Windows (sanmai) - * bug #27297 Triggering RememberMe's loginFail() when token cannot be created (weaverryan) - * bug #27344 [HttpKernel] reset kernel start time on reboot (kiler129) - * bug #27365 [Serializer] Check the value of enable_max_depth if defined (dunglas) - * bug #27358 [PhpUnitBridge] silence some stderr outputs (ostrolucky) - * bug #27366 [DI] never inline lazy services (nicolas-grekas) - -* 4.0.11 (2018-05-25) - - * bug #27364 [DI] Fix bad exception on uninitialized references to non-shared services (nicolas-grekas) - * bug #27359 [HttpFoundation] Fix perf issue during MimeTypeGuesser intialization (nicolas-grekas) - * security #cve-2018-11408 [SecurityBundle] Fail if security.http_utils cannot be configured - * security #cve-2018-11406 clear CSRF tokens when the user is logged out - * security #cve-2018-11385 migrating session for UsernamePasswordJsonAuthenticationListener - * security #cve-2018-11385 Adding session authentication strategy to Guard to avoid session fixation - * security #cve-2018-11385 Adding session strategy to ALL listeners to avoid *any* possible fixation - * security #cve-2018-11386 [HttpFoundation] Break infinite loop in PdoSessionHandler when MySQL is in loose mode - * bug #27341 [WebProfilerBundle] Fixed validator/dump trace CSS (yceruto) - * bug #27337 [FrameworkBundle] fix typo in CacheClearCommand (emilielorenzo) - -* 4.0.10 (2018-05-21) - - * bug #27264 [Validator] Use strict type in URL validator (mimol91) - * bug #27267 [DependencyInjection] resolve array env vars (jamesthomasonjr) - * bug #26781 [Form] Fix precision of MoneyToLocalizedStringTransformer's divisions on transform() (syastrebov) - * bug #27286 [Translation] Add Occitan plural rule (kylekatarnls) - * bug #27271 [DI] Allow defining bindings on ChildDefinition (nicolas-grekas) - * bug #27246 Disallow invalid characters in session.name (ostrolucky) - * bug #27287 [PropertyInfo] fix resolving parent|self type hints (nicolas-grekas) - * bug #27281 [HttpKernel] Fix dealing with self/parent in ArgumentMetadataFactory (fabpot) - * bug #24805 [Security] Fix logout (MatTheCat) - * bug #27265 [DI] Shared services should not be inlined in non-shared ones (nicolas-grekas) - * bug #27141 [Process] Suppress warnings when open_basedir is non-empty (cbj4074) - * bug #27250 [Session] limiting :key for GET_LOCK to 64 chars (oleg-andreyev) - * bug #27237 [Debug] Fix populating error_get_last() for handled silent errors (nicolas-grekas) - * bug #27232 [Cache][Lock] Fix usages of error_get_last() (nicolas-grekas) - * bug #27236 [Filesystem] Fix usages of error_get_last() (nicolas-grekas) - * bug #27191 [DI] Display previous error messages when throwing unused bindings (nicolas-grekas) - * bug #27231 [FrameworkBundle] Fix cache:clear on vagrant (nicolas-grekas) - * bug #27222 [WebProfilerBundle][Cache] Fix misses calculation when calling getItems (fsevestre) - * bug #27227 [HttpKernel] Handle NoConfigurationException "onKernelException()" (nicolas-grekas) - * bug #27152 [HttpFoundation] use brace-style regex delimiters (xabbuh) - * bug #27158 [Cache] fix logic for fetching tag versions on TagAwareAdapter (dmaicher) - * bug #27143 [Console] By default hide the short exception trace line from exception messages in Symfony's commands (yceruto) - * bug #27133 [Doctrine Bridge] fix priority for doctrine event listeners (dmaicher) - * bug #27135 [FrameworkBundle] Use the correct service id for CachePoolPruneCommand in its compiler pass (DemonTPx) - * feature #24896 Add CODE_OF_CONDUCT.md (egircys) - -* 4.0.9 (2018-04-30) - - * bug #27074 [Debug][WebProfilerBundle] Fix setting file link format (lyrixx, nicolas-grekas) - * bug #27088 ResolveBindingsPass: Don't throw error for unused service, missing parent class (weaverryan) - * bug #27086 [PHPUnitBridge] Add an implementation just for php 7.0 (greg0ire) - * bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen) - * bug #27007 [Cache] TagAwareAdapterInterface::invalidateTags() should commit deferred items (nicolas-grekas) - * bug #27067 [HttpFoundation] Fix setting session-related ini settings (e-moe) - * bug #27061 [HttpKernel] Don't clean legacy containers that are still loaded (nicolas-grekas) - * bug #27064 [VarDumper] Fix HtmlDumper classes match (ogizanagi) - * bug #27016 [Security][Guard] GuardAuthenticationProvider::authenticate cannot return null (biomedia-thomas) - * bug #26831 [Bridge/Doctrine] count(): Parameter must be an array or an object that implements Countable (gpenverne) - * bug #27044 [Security] Skip user checks if not implementing UserInterface (chalasr) - * bug #27025 [DI] Add check of internal type to ContainerBuilder::getReflectionClass (upyx) - * bug #26994 [PhpUnitBridge] Add type hints (greg0ire) - * bug #26014 [Security] Fixed being logged out on failed attempt in guard (iltar) - * bug #25348 [HttpFoundation] Send cookies using header() to fix "SameSite" ones (nicolas-grekas, cvilleger) - * bug #26910 Use new PHP7.2 functions in hasColorSupport (johnstevenson) - * bug #26999 [VarDumper] Fix dumping of SplObjectStorage (corphi) - * bug #25841 [DoctrineBridge] Fix bug when indexBy is meta key in PropertyInfo\DoctrineExtractor (insekticid) - * bug #26983 [TwigBridge] [Bootstrap 4] Fix PercentType error rendering. (alexismarquis) - * bug #26980 [TwigBundle] fix formatting arguments in plaintext format (xabbuh) - * bug #26886 Don't assume that file binary exists on *nix OS (teohhanhui) - * bug #26959 [Console] Fix PSR exception context key (scaytrase) - * bug #26899 [Routing] Fix loading multiple class annotations for invokable classes (1ed) - * bug #26643 Fix that ESI/SSI processing can turn a "private" response "public" (mpdude) - * bug #26932 [Form] Fixed trimming choice values (HeahDude) - * bug #26922 [TwigBundle] fix rendering exception stack traces (xabbuh) - * bug #26773 [HttpKernel] Make ServiceValueResolver work if controller namespace starts with a backslash in routing (mathieutu) - * bug #26870 Add d-block to bootstrap 4 alerts (Normunds) - * bug #26857 [HttpKernel] Dont create mock cookie for new sessions in tests (nicolas-grekas) - * bug #26875 [Console] Don't go past exact matches when autocompleting (nicolas-grekas) - * bug #26823 [Validator] Fix LazyLoadingMetadataFactory with PSR6Cache for non classname if tested values isn't existing class (Pascal Montoya, pmontoya) - * bug #26834 [Yaml] Throw parse error on unfinished inline map (nicolas-grekas) - -* 4.0.8 (2018-04-06) - - * bug #26802 [Security] register custom providers on ExpressionLanguage directly (dmaicher) - * bug #26794 [PhpUnitBridge] Catch deprecation error handler (cvilleger) - * bug #26788 [Security] Load the user before pre/post auth checks when needed (chalasr) - * bug #26792 [Routing] Fix throwing NoConfigurationException instead of 405 (nicolas-grekas) - * bug #26774 [SecurityBundle] Add missing argument to security.authentication.provider.simple (i3or1s, chalasr) - * bug #26763 [Finder] Remove duplicate slashes in filenames (helhum) - * bug #26758 [WebProfilerBundle][HttpKernel] Make FileLinkFormatter URL format generation lazy (nicolas-grekas) - -* 4.0.7 (2018-04-03) - - * bug #26387 [Yaml] Fix regression when trying to parse multiline (antograssiot) - * bug #26749 Add PHPDbg support to HTTP components (hkdobrev) - * bug #26609 [Console] Fix check of color support on Windows (mlocati) - * bug #26727 [HttpCache] Unlink tmp file on error (Chansig) - * bug #26675 [HttpKernel] DumpDataCollector: do not flush when a dumper is provided (ogizanagi) - * bug #26663 [TwigBridge] Fix rendering of currency by MoneyType (ro0NL) - * bug #26595 [DI] Do not suggest writing an implementation when multiple exist (chalasr) - * bug #26662 [DI] Fix hardcoded cache dir for warmups (nicolas-grekas) - * bug #26677 Support phpdbg SAPI in Debug::enable() (hkdobrev) - * bug #26600 [Routing] Fixed the importing of files using glob patterns that match multiple resources (skalpa) - * bug #26589 [Ldap] cast to string when checking empty passwords (ismail1432) - * bug #26626 [WebProfilerBundle] use the router to resolve file links (nicolas-grekas) - * bug #26634 [DI] Cleanup remainings from autoregistration (nicolas-grekas) - * bug #26635 [DI] Dont tell about autoregistration in strict autowiring mode (nicolas-grekas) - * bug #26621 [Form] no type errors with invalid submitted data types (xabbuh) - * bug #26612 [PHPunit] suite variable should be used (prisis) - * bug #26337 [Finder] Fixed leading/trailing / in filename (lyrixx) - * bug #26584 [TwigBridge] allow html5 compatible rendering of forms with null names (systemist) - * bug #24401 [Form] Change datetime to datetime-local for HTML5 datetime input (pierredup) - * bug #26513 [FrameworkBundle] Respect debug mode when warm up annotations (Strate) - * bug #26370 [Security] added userChecker to SimpleAuthenticationProvider (i3or1s) - * bug #26569 [BrowserKit] Fix cookie path handling when $domain is null (dunglas) - * bug #26273 [Security][Profiler] Display the original expression in 'Access decision log' (lyrixx) - * bug #26427 [DependencyInjection] fix regression when extending the Container class without a constructor (lsmith77) - * bug #26562 [Bridge\PhpUnit] Cannot autoload class "\Symfony\Bridge\PhpUnit\SymfonyTestsListener" (Jake Bishop) - * bug #26598 Fixes #26563 (open_basedir restriction in effect) (temperatur) - * bug #26568 [Debug] Reset previous exception handler earlier to prevent infinite loop (nicolas-grekas) - * bug #26590 Make sure form errors is valid HTML (Nyholm) - * bug #26567 [DoctrineBridge] Don't rely on ClassMetadataInfo->hasField in DoctrineOrmTypeGuesser anymore (fancyweb) - * feature #26408 Readd 'form_label_errors' block to disable errors on form labels (birkof) - * bug #26591 [TwigBridge] Make sure we always render errors. Eventhough labels are disabled (Nyholm) - * bug #26356 [FrameworkBundle] HttpCache is not longer abstract (lyrixx) - * bug #26548 [DomCrawler] Change bad wording in ChoiceFormField::untick (dunglas) - * bug #26482 [PhpUnitBridge] Ability to use different composer.json file (amcastror) - * bug #26443 [Fix][HttpFoundation] Fix the updating of timestamp in the MemcachedSessionHandler (Alessandro Loffredo) - * bug #26400 [Config] ReflectionClassResource check abstract class (andrey1s) - * bug #26433 [DomCrawler] extract(): fix a bug when the attribute list is empty (dunglas) - * bug #26041 Display the Welcome Page when there is no homepage defined (javiereguiluz) - * bug #26452 [Intl] Load locale aliases to support alias fallbacks (jakzal) - * bug #26450 [CssSelector] Fix CSS identifiers parsing - they can start with dash (jakubkulhan) - -* 4.0.6 (2018-03-05) - - * bug #26393 [DI] Skip resource tracking if disabled (chalasr) - * bug #26403 fix the handling of timestamp in the MongoDBSessionHandler (hjanuschka) - * bug #26355 [DI] Fix missing "id" normalization when dumping the container (nicolas-grekas) - * bug #26368 [WebProfilerBundle] Fix Debug toolbar breaks app (xkobal) - * bug #26369 Use fill instead of style for svg colors (rpkamp) - * bug #26358 [FrameworkBundle] Silence "Failed to remove directory" on cache:clear (nicolas-grekas) - -* 4.0.5 (2018-03-01) - - * bug #26327 [Form][WCAG] Errors sign for people that do not see colors (Nyholm) - * bug #26326 [Form][WCAG] Added role="presentation" on tables & removed bootstrap4 table (Nyholm) - * bug #26325 [Form][WCAG] Add hidden labels on date and time fields (Nyholm) - * bug #26338 [Debug] Keep previous errors of Error instances (Philipp91) - * bug #26328 [Form][WCAG] Fixed HTML errors (Nyholm) - * bug #26290 [FrameworkBundle] [Console][DX] add a warning when command is not found (Simperfit) - * bug #26318 [Routing] Fix GC control of PHP-DSL (nicolas-grekas) - * bug #26312 [Routing] Don't throw 405 when scheme requirement doesn't match (nicolas-grekas) - * bug #26275 Set controller without __invoke method from invokable class (Tobion) - * bug #26298 Fix ArrayInput::toString() for InputArgument::IS_ARRAY args (maximium) - * bug #26177 Update excluded_ajax_paths for sf4 (jenaye) - * bug #26289 [Security] Add missing use of Role (tony-tran) - * bug #26286 [Security] Add missing use for RoleInterface (tony-tran) - * bug #26265 [PropertyInfo] throw exception if docblock factory does not exist (xabbuh) - * bug #26247 [Translation] Process multiple segments within a single unit. (timewasted) - * bug #26254 fix custom radios/inputs for checkbox/radio type (mssimi) - * bug #26234 [FrameworkBundle] Add missing XML config for circular_reference_handler (dunglas) - * bug #26236 [PropertyInfo] ReflectionExtractor: give a chance to other extractors if no properties (dunglas) - * bug #26227 Add support for URL-like DSNs for the PdoSessionHandler (stof) - * bug #25557 [WebProfilerBundle] add a way to limit ajax request (Simperfit) - * bug #26088 [FrameworkBundle] Fix using annotation_reader in compiler pass to inject configured cache provider (Laizerox) - * bug #26157 [HttpKernel] Send new session cookie from AbstractTestSessionListener after session invalidation (rpkamp) - * bug #26230 [WebProfilerBundle] Fix anchor CSS (ro0NL) - * bug #26228 [HttpFoundation] Fix missing "throw" in JsonResponse (nicolas-grekas) - * bug #26211 [Console] Suppress warning from sapi_windows_vt100_support (adawolfa) - * bug #26176 Retro-fit proxy code to make it deterministic for older proxy manager implementations (lstrojny) - * bug #25787 Yaml parser regression with comments and non-strings (alexpott) - * bug #26156 Fixes #26136: Avoid emitting warning in hasParameterOption() (greg-1-anderson) - * bug #26183 [DI] Add null check for removeChild (changmin.keum) - * bug #26167 [TwigBridge] Apply some changes to support Bootstrap4-stable (mpiot, Nyholm) - * bug #26173 [Security] fix accessing request values (xabbuh) - * bug #26089 [PhpUnitBridge] Added support for PHPUnit 7 in Coverage Listener (lyrixx) - * bug #26170 [PHPUnit bridge] Avoid running the remove command without any packages (stof) - * bug #26159 created validator.tl.xlf for Form/Translations (ergiegonzaga) - * bug #26100 [Routing] Throw 405 instead of 404 when redirect is not possible (nicolas-grekas) - * bug #26119 [TwigBundle][WebProfilerBundle] Fix JS collision (ro0NL) - * bug #26040 [Process] Check PHP_BINDIR before $PATH in PhpExecutableFinder (nicolas-grekas) - * bug #26067 [YAML] Issue #26065: leading spaces in YAML multi-line string literals (tamc) - * bug #26012 Exit as late as possible (greg0ire) - * bug #26082 [Cache][WebProfiler] fix collecting cache stats with sub-requests + allow clearing calls (dmaicher) - * bug #26024 [PhpBridge] add PHPUnit 7 support to SymfonyTestsListener (shieldo) - * bug #26020 [Lock] Log already-locked errors as "notice" instead of "warning" (Simperfit) - * bug #26043 [Serialized] add context to serialize and deserialize (andrey1s) - * bug #26127 Deterministic time in cache items for reproducible builds (lstrojny) - * bug #26128 Make kernel build time optionally deterministic (lstrojny) - * bug #26117 isCsrfTokenValid() replace string by ?string (GaylordP) - * bug #26112 Env var maps to undefined constant. (dsmink) - * bug #26111 [Security] fix merge of 2.7 into 2.8 + add test case (dmaicher) - * bug #25893 [Console] Fix hasParameterOption / getParameterOption when used with multiple flags (greg-1-anderson) - * bug #25756 [TwigBundle] Register TwigBridge extensions first (fancyweb) - * bug #26051 [WebProfilerBundle] Fix sub request link (ro0NL) - * bug #25947 PhpDocExtractor::getTypes() throws fatal error when type omitted (Jared Farrish) - * bug #25940 [Form] keep the context when validating forms (xabbuh) - * bug #26057 [SecurityBundle] use libsodium to run Argon2i related tests (xabbuh) - * bug #25373 Use the PCRE_DOLLAR_ENDONLY modifier in route regexes (mpdude) - * bug #24435 [Form] Make sure errors are a part of the label on bootstrap 4 - this is a requirement for WCAG2 (Nyholm) - * bug #25762 [DependencyInjection] always call the parent class' constructor (xabbuh) - * bug #25976 [Config] Handle Service/EventSubscriberInterface in ReflectionClassResource (nicolas-grekas) - * bug #25989 [DI][Routing] Fix tracking of globbed resources (nicolas-grekas, sroze) - * bug #26009 [SecurityBundle] Allow remember-me factory creation when multiple user providers are configured. (iisisrael) - * bug #26010 [CssSelector] For AND operator, the left operand should have parentheses, not only right operand (Arnaud CHASSEUX) - * bug #26000 Fixed issue #25985 (KevinFrantz) - * bug #25996 Don't show wanna-be-private services as public in debug:container (chalasr) - * bug #25914 [HttpKernel] collect extension information as late as possible (xabbuh) - * bug #25981 [DI] Fix tracking of source class changes for lazy-proxies (nicolas-grekas) - * bug #25971 [Debug] Fix bad registration of exception handler, leading to mem leak (nicolas-grekas) - * bug #25962 [Routing] Fix trailing slash redirection for non-safe verbs (nicolas-grekas) - * bug #25948 [Form] Fixed empty data on expanded ChoiceType and FileType (HeahDude) - * bug #25978 Deterministic proxy names (lstrojny) - * bug #25972 support sapi_windows_vt100_support for php 7.2+ (jhdxr) - * bug #25744 [TwigBridge] Allow label translation to be safe (MatTheCat) - * bug #25932 Don't stop PSR-4 service discovery if a parent class is missing (derrabus) - -* 4.0.4 (2018-01-29) - - * bug #25922 [HttpFoundation] Use the correct syntax for session gc based on Pdo driver (tanasecosminromeo) - * bug #25933 Disable CSP header on exception pages only in debug (ostrolucky) - * bug #25926 [Form] Fixed Button::setParent() when already submitted (HeahDude) - * bug #25927 [Form] Fixed submitting disabled buttons (HeahDude) - * bug #25397 [Console] Provide a DX where an array could be passed (Simperfit) - * bug #25858 [DI] Fix initialization of legacy containers by delaying include_once (nicolas-grekas) - * bug #25891 [DependencyInjection] allow null values for root nodes in YAML configs (xabbuh) - * bug #24864 Have weak_vendors ignore deprecations from outside (greg0ire) - * bug #25873 [Console] Fix using finally where the catch can also fail (nicolas-grekas) - * bug #25848 [Validator] add missing parent isset and add test (Simperfit) - * bug #25869 [Process] Skip environment variables with false value in Process (francoispluchino) - * bug #25864 [Yaml] don't split lines on carriage returns when dumping (xabbuh) - * bug #25863 [Yaml] trim spaces from unquoted scalar values (xabbuh) - * bug #25861 do not conflict with egulias/email-validator 2.0+ (xabbuh) - * bug #25851 [Validator] Conflict with egulias/email-validator 2.0 (emodric) - * bug #25837 [SecurityBundle] Don't register in memory users as services (chalasr) - * bug #25835 [HttpKernel] DebugHandlersListener should always replace the existing exception handler (nicolas-grekas) - * bug #25829 [Debug] Always decorate existing exception handlers to deal with fatal errors (nicolas-grekas) - * bug #25823 [Security] Notify that symfony/expression-language is not installed if ExpressionLanguage is used (giovannialbero1992) - * bug #25824 Fixing a bug where the dump() function depended on bundle ordering (weaverryan) - * bug #25763 [OptionsResolver] Fix options resolver with array allowed types (mcg-web) - * bug #25789 Enableable ArrayNodeDefinition is disabled for empty configuration (kejwmen) - * bug #25822 [Cache] Fix handling of apcu_fetch() edgy behavior (nicolas-grekas) - * bug #25816 Problem in phar see mergerequest #25579 (betzholz) - * bug #25781 [Form] Disallow transform dates beyond the year 9999 (curry684) - * bug #25287 [Serializer] DateTimeNormalizer handling of null and empty values (returning it instead of new object) (Simperfit) - * bug #25249 [Form] Avoid button label translation when it's set to false (TeLiXj) - * bug #25127 [TwigBridge] Pass the form-check-inline in parent (Simperfit) - * bug #25812 Copied NO language files to the new NB locale (derrabus) - * bug #25753 [Console] Fix restoring exception handler (nicolas-grekas, fancyweb) - * bug #25801 [Router] Skip anonymous classes when loading annotated routes (pierredup) - * bug #25508 [FrameworkBundle] Auto-enable CSRF if the component *+ session* are loaded (nicolas-grekas) - * bug #25657 [Security] Fix fatal error on non string username (chalasr) - * bug #25791 [Routing] Make sure we only build routes once (sroze) - * bug #25799 Fixed Request::__toString ignoring cookies (Toflar) - * bug #25755 [Debug] prevent infinite loop with faulty exception handlers (nicolas-grekas) - * bug #25771 [Validator] 19 digits VISA card numbers are valid (xabbuh) - * bug #25751 [FrameworkBundle] Add the missing `enabled` session attribute (sroze) - * bug #25750 [HttpKernel] Turn bad hosts into 400 instead of 500 (nicolas-grekas) - * bug #25699 [HttpKernel] Fix session handling: decouple "save" from setting response "private" (nicolas-grekas) - * bug #25490 [Serializer] Fixed throwing exception with option JSON_PARTIAL_OUTPUT_ON_ERROR (diversantvlz) - * bug #25737 [TwigBridge] swap filter/function and package names (xabbuh) - * bug #25731 [HttpFoundation] Always call proxied handler::destroy() in StrictSessionHandler (nicolas-grekas) - * bug #25733 [HttpKernel] Fix compile error when a legacy container is fresh again (nicolas-grekas) - * bug #25709 Tweaked some styles in the profiler tables (javiereguiluz) - * bug #25719 [HttpKernel] Uses cookies to track the requests redirection (sroze) - * bug #25696 [FrameworkBundle] Fix using "annotations.cached_reader" in after-removing passes (nicolas-grekas) - * feature #25669 [Security] Fail gracefully if the security token cannot be unserialized from the session (thewilkybarkid) - * bug #25700 Run simple-phpunit with --no-suggest option (ro0NL) - -* 4.0.3 (2018-01-05) - - * bug #25685 Use triggering file to determine weak vendors if when the test is run in a separate process (alexpott) - * bug #25671 Remove randomness from dumped containers (nicolas-grekas) - * bug #25532 [HttpKernel] Disable CSP header on exception pages (ostrolucky) - * bug #25678 [WebProfilerBundle] set the var in the right scope (Jochen Mandl) - * bug #25491 [Routing] Use the default host even if context is empty (sroze) - * bug #25672 [WebServerBundle] use interface_exists instead of class_exists (kbond) - * bug #25662 Dumper shouldn't use html format for phpdbg / cli-server (jhoff) - * bug #25529 [Validator] Fix access to root object when using composite constraint (ostrolucky) - * bug #25404 [Form] Remove group options without data on debug:form command (yceruto) - * bug #25430 Fixes for Oracle in PdoSessionHandler (elislenio) - * bug #25117 [FrameworkBundle] Make cache:clear "atomic" and consistent with cache:warmup (hkdobrev) - * bug #25583 [HttpKernel] Call Response->setPrivate() instead of sending raw header() when session is started (Toflar) - * bug #25601 [TwigBundle/Brige] catch missing requirements to throw meaningful exceptions (nicolas-grekas) - * bug #25547 [DX][DependencyInjection] Suggest to write an implementation if the interface cannot be autowired (sroze) - * bug #25599 Add application/ld+json format associated to json (vincentchalamon) - * bug #25623 [HttpFoundation] Fix false-positive ConflictingHeadersException (nicolas-grekas) - * bug #25624 [WebServerBundle] Fix escaping of php binary with arguments (nicolas-grekas) - * bug #25604 Add check for SecurityBundle in createAccessDeniedException (FGM) - * bug #25591 [HttpKernel] fix cleaning legacy containers (nicolas-grekas) - * bug #25526 [WebProfilerBundle] Fix panel break when stopwatch component is not installed. (umulmrum, javiereguiluz) - * bug #25606 Updating message to inform the user how to install the component (weaverryan) - * bug #25571 [SecurityBundle] allow auto_wire for SessionAuthenticationStrategy class (xavren) - * bug #25567 [Process] Fix setting empty env vars (nicolas-grekas) - * bug #25407 [Console] Commands with an alias should not be recognized as ambiguous (Simperfit) - * bug #25523 [WebServerBundle] fix a bug where require would not require the good file because of env (Simperfit) - * bug #25559 [Process] Dont use getenv(), it returns arrays and can introduce subtle breaks accros PHP versions (nicolas-grekas) - * bug #25552 [WebProfilerBundle] Let fetch() cast URL to string (ro0NL) - * bug #25521 [Console] fix a bug when you are passing a default value and passing -n would output the index (Simperfit) - -* 4.0.2 (2017-12-15) - - * bug #25489 [FrameworkBundle] remove esi/ssi renderers if inactive (dmaicher) - * bug #25502 Fixing wrong class_exists on interface (weaverryan) - * bug #25427 Preserve percent-encoding in URLs when performing redirects in the UrlMatcher (mpdude) - * bug #25480 [FrameworkBundle] add missing validation options to XSD file (xabbuh) - * bug #25487 [Console] Fix a bug when passing a letter that could be an alias (Simperfit) - * bug #25425 When available use AnnotationRegistry::registerUniqueLoader (jrjohnson) - * bug #25474 [DI] Optimize Container::get() for perf (nicolas-grekas) - * bug #24594 [Translation] Fix InvalidArgumentException when using untranslated plural forms from .po files (BjornTwachtmann) - * bug #25233 [TwigBridge][Form] Fix hidden currency element with Bootstrap 3 theme (julienfalque) - * bug #25413 [HttpKernel] detect deprecations thrown by container initialization during tests (nicolas-grekas) - * bug #25408 [Debug] Fix catching fatal errors in case of nested error handlers (nicolas-grekas) - * bug #25330 [HttpFoundation] Support 0 bit netmask in IPv6 (`::/0`) (stephank) - * bug #25378 [VarDumper] Fixed file links leave blank pages when ide is configured (antalaron) - * bug #25410 [HttpKernel] Fix logging of post-terminate errors/exceptions (nicolas-grekas) - * bug #25409 [Bridge/Doctrine] Drop "memcache" type (nicolas-grekas) - * bug #25417 [Process] Dont rely on putenv(), it fails on ZTS PHP (nicolas-grekas) - * bug #25333 [DI] Impossible to set an environment variable and then an array as container parameter (Phantas0s) - * bug #25447 [Process] remove false-positive BC breaking exception on Windows (nicolas-grekas) - * bug #25381 [DI] Add context to service-not-found exceptions thrown by service locators (nicolas-grekas) - * bug #25438 [Yaml] empty lines don't count for indent detection (xabbuh) - * bug #25412 Extend Argon2i support check to account for sodium_compat (mbabker) - * bug #25392 [HttpFoundation] Fixed default user-agent (3.X -> 4.X) (lyrixx) - * bug #25389 [Yaml] fix some edge cases with indented blocks (xabbuh) - * bug #25396 [Form] Fix debug:form command definition (yceruto) - * bug #25398 [HttpFoundation] don't prefix cookies with "Set-Cookie:" (pableu) - * bug #25354 [DI] Fix non-string class handling in PhpDumper (nicolas-grekas, sroze) - * bug #25340 [Serializer] Unset attributes when creating child context (dunglas) - * bug #25325 [Yaml] do not evaluate PHP constant names (xabbuh) - * bug #25380 [FrameworkBundle][Cache] register system cache clearer only if it's used (xabbuh) - * bug #25323 [ExpressionLanguage] throw an SyntaxError instead of an undefined index notice (Simperfit) - * bug #25363 [HttpKernel] Disable inlining on PHP 5 (nicolas-grekas) - * bug #25364 [DependencyInjection] Prevent a loop in aliases within the `findDefinition` method (sroze) - * bug #25337 Remove Exclusive Lock That Breaks NFS Caching (brianfreytag) - -* 4.0.1 (2017-12-05) - - * bug #25304 [Bridge/PhpUnit] Prefer $_SERVER['argv'] over $argv (ricknox) - * bug #25272 [SecurityBundle] fix setLogoutOnUserChange calls for context listeners (dmaicher) - * bug #25282 [DI] Register singly-implemented interfaces when doing PSR-4 discovery (nicolas-grekas) - * bug #25274 [Security] Adding a GuardAuthenticatorHandler alias (weaverryan) - * bug #25308 [FrameworkBundle] Fix a bug where a color tag will be shown when passing an antislash (Simperfit) - * bug #25278 Fix for missing whitespace control modifier in form layout (kubawerlos) - * bug #25306 [Form][TwigBridge] Fix collision between view properties and form fields (yceruto) - * bug #25305 [Form][TwigBridge] Fix collision between view properties and form fields (yceruto) - * bug #25236 [Form][TwigBridge] Fix collision between view properties and form fields (yceruto) - * bug #25312 [DI] Fix deep-inlining of non-shared refs (nicolas-grekas) - * bug #25309 [Yaml] parse newlines in quoted multiline strings (xabbuh) - * bug #25313 [DI] Fix missing unset leading to false-positive circular ref (nicolas-grekas) - * bug #25268 [DI] turn $private to protected in dumped container, to make cache:clear BC (nicolas-grekas) - * bug #25285 [DI] Throw an exception if Expression Language is not installed (sroze) - * bug #25241 [Yaml] do not eagerly filter comment lines (xabbuh) - * bug #25284 [DI] Cast ids to string, as done on 3.4 (nicolas-grekas, sroze) - * bug #25297 [Validator] Fixed the @Valid(groups={"group"}) against null exception case (vudaltsov) - * bug #25255 [Console][DI] Fail gracefully (nicolas-grekas) - * bug #25264 [DI] Trigger deprecation when setting a to-be-private synthetic service (nicolas-grekas) - * bug #25258 [link] Prevent warnings when running link with 2.7 (dunglas) - * bug #25244 [DI] Add missing deprecation when fetching private services from ContainerBuilder (nicolas-grekas) - * bug #24750 [Validator] ExpressionValidator should use OBJECT_TO_STRING (Simperfit) - * bug #25247 [DI] Fix false-positive circular exception (nicolas-grekas) - * bug #25226 [HttpKernel] Fix issue when resetting DumpDataCollector (Pierstoval) - * bug #25230 Use a more specific file for detecting the bridge (greg0ire) - * bug #25232 [WebProfilerBundle] [TwigBundle] Fix Profiler breaking XHTML pages (tistre) - -* 4.0.0 (2017-11-30) - - * bug #25220 [HttpFoundation] Add Session::isEmpty(), fix MockFileSessionStorage to behave like the native one (nicolas-grekas) - * bug #25209 [VarDumper] Dont use empty(), it chokes on eg GMP objects (nicolas-grekas) - * bug #25200 [HttpKernel] Arrays with scalar values passed to ESI fragment renderer throw deprecation notice (Simperfit) - * bug #25201 [HttpKernel] Add a better error messages when passing a private or non-tagged controller (Simperfit) - * bug #25155 [DependencyInjection] Detect case mismatch in autowiring (Simperfit, sroze) - * bug #25217 [Dotenv] Changed preg_match flags from null to 0 (deekthesqueak) - * bug #25180 [DI] Fix circular reference when using setters (nicolas-grekas) - * bug #25204 [DI] Clear service reference graph (nicolas-grekas) - * bug #25203 [DI] Fix infinite loop in InlineServiceDefinitionsPass (nicolas-grekas) - * bug #25185 [Serializer] Do not cache attributes if `attributes` in context (sroze) - * bug #25190 [HttpKernel] Keep legacy container files for concurrent requests (nicolas-grekas) - * bug #25182 [HttpFoundation] AutExpireFlashBag should not clear new flashes (Simperfit, sroze) - * bug #25174 [Translation] modify definitions only if the do exist (xabbuh) - * bug #25179 [FrameworkBundle][Serializer] Remove YamlEncoder definition if Yaml component isn't installed (ogizanagi) - * bug #25160 [DI] Prevent a ReflectionException during cache:clear when the parent class doesn't exist (dunglas) - * bug #25163 [DI] Fix tracking of env vars in exceptions (nicolas-grekas) - * bug #25162 [HttpKernel] Read $_ENV when checking SHELL_VERBOSITY (nicolas-grekas) - * bug #25158 [DI] Remove unreachable code (GawainLynch) - * bug #25152 [Form] Don't rely on `Symfony\Component\HttpFoundation\File\File` if http-foundation isn't in FileType (issei-m) - * bug #24987 [Console] Fix global console flag when used in chain (Simperfit) - * bug #25137 Adding checks for the expression language (weaverryan) - * bug #25151 [FrameworkBundle] Automatically enable the CSRF protection if CSRF manager exists (sroze) - * bug #25043 [Yaml] added ability for substitute aliases when mapping is on single line (Michał Strzelecki, xabbuh) - -* 4.0.0-RC2 (2017-11-24) - - * bug #25146 [DI] Dont resolve envs in service ids (nicolas-grekas) - * bug #25113 [Routing] Fix "config-file-relative" annotation loader resources (nicolas-grekas, sroze) - * bug #25065 [FrameworkBundle] Update translation commands to work with default paths (yceruto) - * bug #25109 Make debug:container search command case-insensitive (jzawadzki) - * bug #25121 [FrameworkBundle] Fix AssetsInstallCommand (nicolas-grekas) - * bug #25102 [Form] Fixed ContextErrorException in FileType (chihiro-adachi) - * bug #25130 [DI] Fix handling of inlined definitions by ContainerBuilder (nicolas-grekas) - * bug #25119 [DI] Fix infinite loop when analyzing references (nicolas-grekas) - * bug #25094 [FrameworkBundle][DX] Display a nice error message if an enabled component is missing (derrabus) - * bug #25100 [SecurityBundle] providerIds is undefined error when firewall provider is not specified (karser) - * bug #25100 [SecurityBundle] providerIds is undefined error when firewall provider is not specified (karser) - * bug #25100 [SecurityBundle] providerIds is undefined error when firewall provider is not specified (karser) - * bug #25097 [Bridge\PhpUnit] Turn "preserveGlobalState" to false by default, revert "Blacklist" removal (nicolas-grekas) - -* 4.0.0-RC1 (2017-11-21) - - * bug #25077 [Bridge/Twig] Let getFlashes starts the session (MatTheCat) - * bug #25082 [HttpKernel] Disable container inlining when legacy inlining has been used (nicolas-grekas) - * bug #25022 [Filesystem] Updated Filesystem::makePathRelative (inso) - * bug #25072 [Bridge/PhpUnit] Remove trailing "\n" from ClockMock::microtime(false) (joky) - * bug #25069 [Debug] Fix undefined variable $lightTrace (nicolas-grekas) - * bug #25053 [Serializer] Fixing PropertyNormalizer supports parent properties (Christopher Hertel) - * bug #25055 [DI] Analyze setter-circular deps more precisely (nicolas-grekas) - * feature #25056 [Bridge/PhpUnit] Sync the bridge version installed in vendor/ and in phpunit clone (nicolas-grekas) - * bug #25048 Allow EnumNode name to be null (MatTheCat) - * bug #25045 [SecurityBundle] Don't trigger auto-picking notice if provider is set per listener (chalasr) - * bug #25033 [FrameworkBundle] Dont create empty bundles directory by default (ro0NL) - * bug #25037 [DI] Skip hot_path tag for deprecated services as their class might also be (nicolas-grekas) - * bug #25038 [Cache] Memcached options should ignore "lazy" (nicolas-grekas) - * bug #25014 Move deprecation under use statements (greg0ire) - * bug #25030 [Console] Fix ability to disable lazy commands (chalasr) - * bug #25032 [Bridge\PhpUnit] Disable broken auto-require mechanism of phpunit (nicolas-grekas) - * bug #25016 [HttpKernel] add type-hint for the requestType (Simperfit) - * bug #25027 [FrameworkBundle] Hide server:log command based on deps (sroze) - * bug #24991 [DependencyInjection] Single typed argument can be applied on multiple parameters (nicolas-grekas, sroze) - * bug #24983 [Validator] enter the context in which to validate (xabbuh) - * bug #24956 Fix ambiguous pattern (weltling) - * bug #24732 [DependencyInjection] Prevent service:method factory notation in PHP config (vudaltsov) - * bug #24979 [HttpKernel] remove services resetter even when it's an alias (xabbuh) - * bug #24972 [HttpKernel] Fix service arg resolver for controllers as array callables (sroze, nicolas-grekas) - * bug #24971 [FrameworkBundle] Empty event dispatcher earlier in CacheClearCommand (nicolas-grekas) - * security #24995 Validate redirect targets using the session cookie domain (nicolas-grekas) - * security #24994 Prevent bundle readers from breaking out of paths (xabbuh) - * security #24993 Ensure that submitted data are uploaded files (xabbuh) - * security #24992 Namespace generated CSRF tokens depending of the current scheme (dunglas) - * bug #24975 [DomCrawler] Type fix Crawler:: discoverNamespace() (VolCh) - * bug #24954 [DI] Fix dumping with custom base class (nicolas-grekas) - * bug #24952 [HttpFoundation] Fix session-related BC break (nicolas-grekas, sroze) - * bug #24943 [FrameworkBundle] Wire the translation.reader service instead of deprecated translation.loader in commands (ogizanagi) - -* 4.0.0-BETA4 (2017-11-12) - - * bug #24874 [TwigBridge] Fixed the .form-check-input class in the bs4 templates (vudaltsov) - * bug #24929 [Console] Fix traversable autocomplete values (ro0NL) - * feature #24860 [FrameworkBundle] Add default translations path option and convention (yceruto) - * bug #24921 [Debug] Remove false-positive deprecation from DebugClassLoader (nicolas-grekas) - * bug #24856 [FrameworkBundle] Add default mapping path for validator component in bundle-less app (yceruto) - * bug #24833 [FrameworkBundle] Add default mapping path for serializer component in bundle-less app (yceruto) - * bug #24908 [WebServerBundle] Prevent console.terminate from being fired when server:start finishes (kbond) - * bug #24888 [FrameworkBundle] Specifically inject the debug dispatcher in the collector (ogizanagi) - * bug #24909 [Intl] Update ICU data to 60.1 (jakzal) - * bug #24870 [YAML] Allow to parse custom tags when linting yaml files (pierredup) - * bug #24910 [HttpKernel][Debug] Remove noise from stack frames of deprecations (nicolas-grekas) - * bug #24906 [Bridge/ProxyManager] Remove direct reference to value holder property (nicolas-grekas) - * feature #24887 [Cache][Lock] Add RedisProxy for lazy Redis connections (nicolas-grekas) - * bug #24633 [Config] Fix cannotBeEmpty() (ro0NL) - * bug #24900 [Validator] Fix Costa Rica IBAN format (Bozhidar Hristov) - * bug #24904 [Validator] Add Belarus IBAN format (Bozhidar Hristov) - * bug #24837 [TwigBridge] [Bootstrap 4] Fix validation error design for expanded choiceType (ostrolucky) - * bug #24878 [HttpFoundation] Prevent PHP from sending Last-Modified on session start (nicolas-grekas) - * bug #24881 [WebserverBundle] fixed the bug that caused that the webserver would … (Serkan Yildiz) - * bug #24722 Replace more docblocks by type-hints (nicolas-grekas) - * bug #24850 [DI] Fix cannot bind env var (ogizanagi) - * bug #24851 [TwigBridge] Fix BC break due required twig environment (ro0NL) - -* 4.0.0-BETA3 (2017-11-05) - - * bug #24531 [HttpFoundation] Fix forward-compat of NativeSessionStorage with PHP 7.2 (sroze) - * bug #24828 [DI] Fix the "almost-circular refs" fix (nicolas-grekas) - * bug #24665 Fix dump panel hidden when closing a dump (julienfalque) - * bug #24802 [TwigBridge] [Bootstrap 4] Fix hidden errors (ostrolucky) - * bug #24816 [Serializer] Fix extra attributes when no group specified (ogizanagi) - * bug #24822 [DI] Fix "almost-circular" dependencies handling (nicolas-grekas) - * bug #24821 symfony/form auto-enables symfony/validator, even when not present (weaverryan) - * bug #24824 [FrameworkBundle][Config] fix: do not add resource checkers for no-debug (dmaicher) - * bug #24814 [Intl] Make intl-data tests pass and save language aliases again (jakzal) - * bug #24810 [Serializer] readd default argument value (xabbuh) - * bug #24809 [Config] Fix dump of config references for deprecated nodes (chalasr) - * bug #24796 [PhpUnitBridge] Fixed fatal error in CoverageListener when something goes wrong in Test::setUpBeforeClass (lyrixx) - * bug #24774 [HttpKernel] Let the storage manage the session starts (sroze) - * bug #24735 [VarDumper] fix trailling comma when dumping an exception (Simperfit) - * bug #24770 [Validator] Fix TraceableValidator is reset on data collector instantiation (ogizanagi) - * bug #24764 [HttpFoundation] add Early Hints to Reponse to fix test (Simperfit) - * bug #24759 Removes \n or space when $context/$extra are empty (kirkmadera) - * bug #24758 Throwing exception if redis and predis unavailable (aequasi) - -* 4.0.0-BETA2 (2017-10-30) - - * bug #24728 [Bridge\Twig] fix bootstrap checkbox_row to render properly & remove spaceless (arkste) - * bug #24709 [HttpKernel] Move services reset to Kernel::handle()+boot() (nicolas-grekas) - * bug #24703 [TwigBridge] Bootstrap 4 form theme fixes (vudaltsov) - * bug #24744 debug:container --types: Fix bug with non-existent classes (weaverryan) - * bug #24747 [VarDumper] HtmlDumper: fix collapsing nodes with depth < maxDepth (ogizanagi) - * bug #24743 [FrameworkBundle] Do not activate the cache if Doctrine's cache is not present (sroze) - * bug #24605 [FrameworkBundle] Do not load property_access.xml if the component isn't installed (ogizanagi) - * bug #24710 [TwigBridge] Fix template paths in profiler (ro0NL) - * bug #24706 [DependencyInjection] Add the possibility to disable assets via xml (renatomefi) - * bug #24696 Ensure DeprecationErrorHandler::collectDeprecations() is triggered (alexpott) - * bug #24711 [TwigBridge] Re-add Bootstrap 3 Checkbox Layout (arkste) - * bug #24713 [FrameworkBundle] fix CachePoolPrunerPass to use correct command service id (kbond) - * bug #24686 Fix $_ENV/$_SERVER precedence in test framework (fabpot) - * bug #24691 [HttpFoundation] Fix caching of session-enabled pages (nicolas-grekas) - * feature #24677 [HttpFoundation] Allow DateTimeImmutable in Response setters (derrabus) - * bug #24694 [Intl] Allow passing null as a locale fallback (jakzal) - * bug #24606 [HttpFoundation] Fix FileBag issue with associative arrays (enumag) - * bug #24673 [DI] Throw when a service name or an alias contains dynamic values (prevent an infinite loop) (dunglas) - * bug #24684 [Security] remove invalid deprecation notice on AbstractGuardAuthenticator::supports() (kbond) - * bug #24681 Fix isolated error handling (alexpott) - * bug #24575 Ensure that PHPUnit's error handler is still working in isolated tests (alexpott) - * bug #24597 [PhpUnitBridge] fix deprecation triggering test detection (xabbuh) - * feature #24671 [DI] Handle container.autowiring.strict_mode to opt-out from legacy autowiring (nicolas-grekas) - * bug #24660 Escape trailing \ in QuestionHelper autocompletion (kamazee) - * bug #24624 [Security] Fix missing BC layer for AbstractGuardAuthenticator::getCredentials() (chalasr) - * bug #24598 Prefer line formatter on missing cli dumper (greg0ire) - * bug #24635 [DI] Register default env var provided types (ro0NL) - * bug #24620 [FrameworkBundle][Workflow] Fix deprectation when checking workflow.registry service in dump command (Jean-Beru) - * bug #24644 [Security] Fixed auth provider authenticate() cannot return void (glye) - * bug #24642 [Routing] Fix resource miss (dunglas) - * bug #24608 Adding the Form default theme files to be warmed up in Twig's cache (weaverryan) - * bug #24626 streamed response should return $this (DQNEO) - * feature #24631 [Form] Fix FormEvents::* constant and value matching (yceruto, javiereguiluz) - * bug #24630 [WebServerBundle] Prevent commands from being registered by convention (chalasr) - * bug #24589 Username and password in basic auth are allowed to contain '.' (Richard Quadling) - * bug #24566 Fixed unsetting from loosely equal keys OrderedHashMap (maryo) - * bug #24570 [Debug] Fix same vendor detection in class loader (Jean-Beru) - * bug #24573 Fixed pathinfo calculation for requests starting with a question mark. (syzygymsu) - * bug #24565 [Serializer] YamlEncoder: throw if the Yaml component isn't installed (dunglas) - * bug #24563 [Serializer] ObjectNormalizer: throw if PropertyAccess isn't installed (dunglas) - * bug #24571 [PropertyInfo] Add support for the iterable type (dunglas) - * bug #24579 pdo session fix (mxp100) - * bug #24536 [Security] Reject remember-me token if UserCheckerInterface::checkPostAuth() fails (kbond) - -* 4.0.0-BETA1 (2017-10-19) - - * feature #24583 Adding a new debug:autowiring command (weaverryan) - * feature #24523 [HttpFoundation] Make sessions secure and lazy (nicolas-grekas) - * feature #22610 [Form] [TwigBridge] Added option to disable usage of default themes when rendering a form (emodric) - * feature #23112 [OptionsResolver] Support array of types in allowed type (pierredup) - * feature #24321 added ability to handle parent classes for PropertyNormalizer (ivoba) - * feature #24505 [HttpKernel] implement reset() in DumpDataCollector (xabbuh) - * feature #24425 [Console][HttpKernel] Handle new SHELL_VERBOSITY env var, also configures the default logger (nicolas-grekas) - * feature #24503 [MonologBridge][EventDispatcher][HttpKernel] remove deprecated features (xabbuh) - * feature #24387 [FORM] Prevent forms from extending itself as a parent (pierredup) - * feature #24484 [DI] Throw accurate failures when accessing removed services (nicolas-grekas) - * feature #24208 [Form] Display option definition from a given form type (yceruto, ogizanagi) - * feature #22228 [HttpKernel] minor: add ability to construct with headers on http exceptions (gsdevme) - * feature #24467 [Process] drop non-existent working directory support (xabbuh) - * feature #23499 [Workflow] add guard is_valid() method support (alain-flaus, lyrixx) - * feature #24364 [DependencyInjection][Filesystem][Security][SecurityBundle] remove deprecated features (xabbuh) - * feature #24441 [Bridge\Doctrine][FrameworkBundle] Remove legacy uses of ContainerAwareInterface (nicolas-grekas) - * feature #24388 [Security] Look at headers for switch_user username (chalasr) - * feature #24447 [Session] remove deprecated session handlers (Tobion) - * feature #24446 [Security] Remove GuardAuthenticatorInterface (chalasr) - * feature #23708 Added deprecation to cwd not existing Fixes #18249 (alexbowers) - * feature #24443 [Session] deprecate MemcacheSessionHandler (Tobion) - * feature #24409 [Bridge\Doctrine][FrameworkBundle] Deprecate some remaining uses of ContainerAwareTrait (nicolas-grekas) - * feature #24438 [Session][VarDumper] Deprecate accepting legacy mongo extension (Tobion) - * feature #24389 [DoctrineBridge] Deprecate dbal session handler (Tobion) - * feature #16835 [Security] Add Guard authenticator method (Amo, chalasr) - * feature #24289 [FrameworkBundle][HttpKernel] Reset profiler (derrabus) - * feature #24144 [FrameworkBundle] Expose dotenv in bin/console about (ro0NL) - * feature #24403 [FrameworkBundle][Routing] Show welcome message if no routes are configured (yceruto) - * feature #24398 [DI] Remove AutowireExceptionPass (ogizanagi) - * feature #22679 [Form] Add tel and color types (apetitpa) - * feature #23845 [Validator] Add unique entity violation cause (Ilya Vertakov) - * feature #22132 [Lock] Automaticaly release lock when user forget it (jderusse) - * feature #21751 Bootstrap4 support for Twig form theme (hiddewie, javiereguiluz) - * feature #24383 [FrameworkBundle] Don't clear app pools on cache:clear (nicolas-grekas) - * feature #24148 [Form] Hide label button when its setted to false (TeLiXj) - * feature #24380 [SecurityBundle] Remove auto picking the first provider (ogizanagi) - * feature #24378 [SecurityBundle] Deprecate auto picking the first provider (ogizanagi) - * feature #24260 [Security] Add impersonation support for stateless authentication (chalasr) - * feature #24300 [HttpKernel][FrameworkBundle] Add a minimalist default PSR-3 logger (dunglas) - * feature #21604 [Security] Argon2i Password Encoder (zanbaldwin) - * feature #24372 [DowCrawler] Default to UTF-8 when possible (nicolas-grekas) - * feature #24264 [TwigBundle] Improve the overriding of bundle templates (yceruto) - * feature #24197 [Translation] Moved PhpExtractor and PhpStringTokenParser to Translation component (Nyholm) - * feature #24362 [HttpKernel] Deprecate some compiler passes in favor of tagged iterator args (nicolas-grekas) - * feature #21027 [Asset] Provide default context (ro0NL) - * feature #22200 [DI] Reference tagged services in config (ro0NL) - * feature #24337 Adding a shortcuts for the main security functionality (weaverryan, javiereguiluz) - * feature #24358 [TwigBundle] register an identity translator as fallback (xabbuh) - * feature #24357 [Yaml] include file and line no in deprecation message (xabbuh) - * feature #24330 [FrameworkBundle] register class metadata factory alias (xabbuh) - * feature #24348 [SecurityBundle] Remove remaining ACL stuff from SecurityBundle (ogizanagi) - * feature #24349 [SecurityBundle] Add missing AclSchemaListener deprecation (ogizanagi) - * feature #24202 [Filesystem] deprecate relative paths in makePathRelative() (xabbuh) - * feature #21716 [Serializer] Add Support for `object_to_populate` in CustomNormalizer (chrisguitarguy) - * feature #21960 Remove Validator\TypeTestCase and add validator logic to base TypeTestCase (pierredup) - * feature #24338 [HttpFoundation] Removed compatibility layer for PHP <5.4 sessions (afurculita) - * feature #22113 [Lock] Include lock component in framework bundle (jderusse) - * feature #24236 [WebProfilerBundle] Render file links for twig templates (ro0NL) - * feature #21239 [Serializer] throw more specific exceptions (xabbuh) - * feature #24341 [SecurityBundle] Remove ACL related code (chalasr) - * feature #24256 CsvEncoder handling variable structures and custom header order (Oliver Hoff) - * feature #23471 [Finder] Add a method to check if any results were found (duncan3dc) - * feature #23149 [PhpUnitBridge] Added a CoverageListener to enhance the code coverage report (lyrixx) - * feature #24161 [HttpKernel] Remove bundle inheritance (fabpot) - * feature #24318 [SecurityBundle] Deprecate ACL related code (chalasr) - * feature #24335 [Security][SecurityBundle] Deprecate the HTTP digest auth (ogizanagi) - * feature #21951 [Security][Firewall] Passing the newly generated security token to the event during user switching (klandaika) - * feature #23485 [Config] extracted the xml parsing from XmlUtils::loadFile into XmlUtils::parse (Basster) - * feature #22890 [HttpKernel] Add ability to configure catching exceptions for Client (kbond) - * feature #24239 [HttpFoundation] Deprecate compatibility with PHP <5.4 sessions (afurculita) - * feature #23882 [Security] Deprecated not being logged out after user change (iltar) - * feature #24200 Added an alias for FlashBagInterface in config (tifabien) - * feature #24295 [DI][DX] Throw exception on some ContainerBuilder methods used from extensions (ogizanagi) - * feature #24253 [Yaml] support parsing files (xabbuh) - * feature #24290 Adding Definition::addError() and a compiler pass to throw errors as exceptions (weaverryan) - * feature #24301 [DI] Add AutowireRequiredMethodsPass to fix bindings for `@required` methods (nicolas-grekas) - * feature #24226 [Cache] Add ResettableInterface to allow resetting any pool's local state (nicolas-grekas) - * feature #24303 [FrameworkBundle] allow forms without translations and validator (xabbuh) - * feature #24291 [SecurityBundle] Reset the authentication token between requests (derrabus) - * feature #24280 [VarDumper] Make `dump()` a little bit more easier to use (freekmurze) - * feature #24277 [Serializer] Getter for extra attributes in ExtraAttributesException (mdeboer) - * feature #24257 [HttpKernel][DI] Enable Kernel to implement CompilerPassInterface (nicolas-grekas) - * feature #23834 [DI] Add "PHP fluent format" for configuring the container (nicolas-grekas) - * feature #24180 [Routing] Add PHP fluent DSL for configuring routes (nicolas-grekas) - * feature #24232 [Bridge\Doctrine] Add "DoctrineType::reset()" method (nicolas-grekas) - * feature #24238 [DI] Turn services and aliases private by default, with BC layer (nicolas-grekas) - * feature #24242 [Form] Remove deprecated ChoiceLoaderInterface implementation in TimezoneType (ogizanagi) - * feature #23648 [Form] Add input + regions options to TimezoneType (ro0NL) - * feature #24185 [Form] Display general forms information on debug:form (yceruto) - * feature #23747 [Serializer][FrameworkBundle] Add a DateInterval normalizer (Lctrs) - * feature #24193 [FrameworkBundle] Reset stopwatch between requests (derrabus) - * feature #24160 [HttpKernel] Deprecate bundle inheritance (fabpot) - * feature #24159 Remove the profiler.matcher configuration (fabpot) - * feature #24155 [FrameworkBundle][HttpKernel] Add DI tag for resettable services (derrabus) - * feature #23625 Feature #23583 Add current and fallback locales in WDT / Profiler (nemoneph) - * feature #24179 [TwigBundle] Add default templates directory and option to configure it (yceruto) - * feature #24176 [Translation] drop MessageSelector support in the Translator (xabbuh) - * feature #24104 Make as many services private as possible (nicolas-grekas) - * feature #18314 [Translation] added support for adding custom message formatter (aitboudad) - * feature #24158 deprecated profiler.matcher configuration (fabpot) - * feature #23728 [WebProfilerBundle] Removed the deprecated web_profiler.position option (javiereguiluz) - * feature #24131 [Console] Do not display short exception trace for common console exceptions (yceruto) - * feature #24080 Deprecated the web_profiler.position option (javiereguiluz) - * feature #24114 [SecurityBundle] Throw a meaningful exception when an undefined user provider is used inside a firewall (chalasr) - * feature #24122 [DI] rename ResolveDefinitionTemplatesPass to ResolveChildDefinitionsPass (nicolas-grekas) - * feature #23901 [DI] Allow processing env vars (nicolas-grekas) - * feature #24093 [FrameworkBundle] be able to enable workflow support explicitly (xabbuh) - * feature #24064 [TwigBridge] Show Twig's loader paths on debug:twig command (yceruto) - * feature #23978 [Cache] Use options from Memcached DSN (Bukashk0zzz) - * feature #24067 [HttpKernel] Dont register env parameter resource (ro0NL) - * feature #24075 Implemented PruneableInterface on TagAwareAdapter (Toflar) - * feature #23262 Add scalar typehints/return types (chalasr, xabbuh) - * feature #21414 [Console] Display file and line on Exception (arno14) - * feature #24068 [HttpKernel] Deprecate EnvParametersResource (ro0NL) - * feature #22542 [Lock] Check TTL expiration in lock acquisition (jderusse) - * feature #24031 [Routing] Add the possibility to define a prefix for all routes of a controller (fabpot) - * feature #24052 [DI] Remove case insensitive parameter names (ro0NL) - * feature #23967 [VarDumper] add force-collapse/expand + use it for traces (nicolas-grekas) - * feature #24033 [DI] Add ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE (nicolas-grekas) - * feature #24026 [Security] add impersonator_user to "User was reloaded" log message (gharlan) - * feature #24014 [Translator] Remove deprecated feature (maidmaid) - * feature #23603 [Cache] Add (pdo|chain) cache (adapter|simple) prune method (robfrawley) - * feature #23694 [Form] Add debug:form command (yceruto) - * feature #24028 [Yaml] mark some classes as final (xabbuh) - * feature #22543 [Lock] Expose an expiringDate and isExpired method in Lock (jderusse) - * feature #23667 [Translation] Create an TranslationReaderInterface and move TranslationLoader to TranslationComponent (Nyholm) - * feature #24024 [config] Add ability to deprecate a node (sanpii) - * feature #23668 [VarDumper] Add period caster (maidmaid) - * feature #23991 [DI] Improve psr4-based service discovery (alternative implementation) (kbond) - * feature #22382 [config] Add abbitily to deprecate a node (Nyholm, fabpot, sanpii) - * feature #23947 [Translation] Adding the ability do load in xliff2.0 (Nyholm) - * feature #23887 [Console] Allow commands to provide a default name for compile time registration (chalasr, nicolas-grekas) - * feature #23874 [DI] Case sensitive parameter names (ro0NL) - * feature #23936 Remove some sf2 references (fabpot) - * feature #23680 [Webprofiler] Added blocks that allows extension of the profiler page. (Nyholm) - * feature #23665 Create an interface for TranslationWriter (Nyholm) - * feature #23890 [Translation] Adding the ability do dump in xliff2.0 (Nyholm) - * feature #23862 [SecurityBundle] resolve class name parameter inside AddSecurityVotersPass (pjarmalavicius) - * feature #23915 [DI] Allow get available services from service locator (Koc) - * feature #23792 [HttpKernel][FrameworkBundle] Add RebootableInterface, fix and un-deprecate cache:clear with warmup (nicolas-grekas) - * feature #23227 Add support for "controller" keyword for configuring routes controllers (voronkovich) - * feature #23815 [FrameworkBundle][SecurityBundle][TwigBundle][Yaml] remove deprecated code (xabbuh) - * feature #23857 [HttpKernel] Remove convention based commands registration (chalasr) - * feature #23869 [Console] Made console command shortcuts case insensitive (thanosp) - * feature #23855 [DI] Allow dumping inline services in Yaml (nicolas-grekas) - * feature #23836 [FrameworkBundle] Catch Fatal errors in commands registration (chalasr) - * feature #23805 [HttpKernel] Deprecated commands auto-registration (GuilhemN) - * feature #23816 [Debug] Detect internal and deprecated methods (GuilhemN) - * feature #23812 [FrameworkBundle] Allow micro kernel to subscribe events easily (ogizanagi) - * feature #22187 [DependencyInjection] Support local binding (GuilhemN) - * feature #23741 [DI] Generate one file per service factory (nicolas-grekas) - * feature #23807 [Debug] Trigger a deprecation when using an internal class/trait/interface (GuilhemN) - * feature #22587 [Workflow] Add transition completed event (izzyp) - * feature #23624 [FrameworkBundle] Commands as a service (ro0NL) - * feature #21111 [Validator] add groups support to the Valid constraint (xabbuh) - * feature #20361 [Config] Enable cannotBeEmpty along with requiresAtLeastOneElement (ro0NL) - * feature #23790 [Yaml] remove legacy php/const and php/object tag support (xabbuh) - * feature #23754 [Lock] Remove Filesystem\LockHandler (jderusse) - * feature #23712 [DependencyInjection] Deprecate autowiring service auto-registration (GuilhemN) - * feature #23719 Autoconfigure instances of ArgumentValueResolverInterface (BPScott) - * feature #23706 [Webprofiler] Improve sql explain table display (mimol91) - * feature #23709 [VarDumper] Make dump() variadic (chalasr) - * feature #23724 [Lock] Deprecate Filesystem/LockHandler (jderusse) - * feature #23593 [Workflow] Adding workflow name to the announce event (Nyholm) - * feature #20496 [Form] Allow pass filter callback to delete_empty option. (Koc) - * feature #23451 [Cache] Add (filesystem|phpfiles) cache (adapter|simple) prune method and prune command (robfrawley) - * feature #23519 [TwigBundle] Commands as a service (ro0NL) - * feature #23591 [VarDumper] Add time zone caster (maidmaid) - * feature #23614 [VarDumper] Remove low PHP version and hhvm compat in interval caster (maidmaid) - * feature #22317 [Console] Make SymfonyQuestionHelper::ask optional by default (ro0NL) - * feature #23510 [Console] Add a factory command loader for standalone application with lazy-loading needs (ogizanagi) - * feature #23357 [VarDumper] Add interval caster (maidmaid) - * feature #23550 [DebugBundle] Added min_depth to Configuration (james-johnston-thumbtack) - * feature #23561 [DI] Optimize use of private and pre-defined services (nicolas-grekas) - * feature #23569 Remove last legacy codes (nicolas-grekas) - * feature #23570 [FrameworkBundle] Make RouterCacheWarmer implement ServiceSubscriberInterface (nicolas-grekas) - * feature #22783 [TwigBridge] remove deprecated features (xabbuh) - * feature #23437 [TwigBridge] deprecate TwigRenderer (Tobion) - * feature #22801 [DI] Removed deprecated setting private/pre-defined services (ro0NL) - * feature #23515 [VarDumper] Added setMinDepth to VarCloner (james-johnston-thumbtack) - * feature #23484 [DI] Remove remaining deprecated features (nicolas-grekas) - * feature #23404 [Serializer] AbstractObjectNormalizer: Allow to disable type enforcement (ogizanagi) - * feature #23380 [Process] Remove enhanced sigchild compatibility (maidmaid) - * feature #21086 [MonologBridge] Add TokenProcessor (maidmaid) - * feature #22576 [Validator] Allow to use a property path to get value to compare in comparison constraints (ogizanagi) - * feature #22689 [DoctrineBridge] Add support for doctrin/dbal v2.6 types (jvasseur) - * feature #22734 [Console] Add support for command lazy-loading (chalasr) - * feature #19034 [Security] make it possible to configure a custom access decision manager service (xabbuh) - * feature #23037 [TwigBundle] Added a RuntimeExtensionInterface to take advantage of autoconfigure (lyrixx) - * feature #22811 [DI] Remove deprecated case insensitive service ids (ro0NL) - * feature #22176 [DI] Allow imports in string format for YAML (ro0NL) - * feature #23295 [Security] Lazy load user providers (chalasr) - * feature #23440 [Routing] Add matched and default parameters to redirect responses (artursvonda, Tobion) - * feature #22804 [Debug] Removed ContextErrorException (mbabker) - * feature #22762 [Yaml] Support tagged scalars (GuilhemN) - * feature #22832 [Debug] Deprecate support for stacked errors (mbabker) - * feature #21469 [HttpFoundation] Find the original request protocol version (thewilkybarkid) - * feature #23431 [Validator] Add min/max amount of pixels to Image constraint (akeeman) - * feature #23223 Add support for microseconds in Stopwatch (javiereguiluz) - * feature #22341 [BrowserKit] Emulate back/forward browser navigation (e-moe) - * feature #22619 [FrameworkBundle][Translation] Move translation compiler pass (lepiaf) - * feature #22620 [FrameworkBundle][HttpKernel] Move httpkernel pass (lepiaf) - * feature #23402 [Ldap] Remove the RenameEntryInterface interface (maidmaid) - * feature #23337 [Component][Serializer][Normalizer] : Deal it with Has Method for the Normalizer/Denormalizer (jordscream) - * feature #23391 [Validator] Remove support of boolean value for the checkDNS option (maidmaid) - * feature #23376 [Process] Remove enhanced Windows compatibility (maidmaid) - * feature #22588 [VarDumper] Add filter in VarDumperTestTrait (maidmaid) - * feature #23288 [Yaml] deprecate the !str tag (xabbuh) - * feature #23039 [Validator] Support for parsing PHP constants in yaml loader (mimol91) - * feature #22431 [VarDumper] Add date caster (maidmaid) - * feature #23285 [Stopwatch] Add a reset method (jmgq) - * feature #23320 [WebServer] Allow * to bind all interfaces (as INADDR_ANY) (jpauli, fabpot) - * feature #23272 [FrameworkBundle] disable unusable fragment renderers (xabbuh) - * feature #23332 [Yaml] fix the displayed line number (fabpot, xabbuh) - * feature #23324 [Security] remove support for defining voters that don't implement VoterInterface. (hhamon) - * feature #23294 [Yaml][Lint] Add line numbers to JSON output. (WybrenKoelmans) - * feature #22836 [Process] remove deprecated features (xabbuh) - * feature #23286 [Yaml] remove deprecated unspecific tag behavior (xabbuh) - * feature #23026 [SecurityBundle] Add user impersonation info and exit action to the profiler (yceruto) - * feature #22863 [HttpFoundation] remove deprecated features (xabbuh) - * feature #22932 [HttpFoundation] Adds support for the immutable directive in the cache-control header (twoleds) - * feature #22554 [Profiler][Validator] Add a validator panel in profiler (ogizanagi) - * feature #22124 Shift responsibility for keeping Date header to ResponseHeaderBag (mpdude) - * feature #23122 Xml encoder optional type cast (ragboyjr) - * feature #23207 [FrameworkBundle] Allow .yaml file extension everywhere (ogizanagi) - * feature #23076 [Validator] Adds support to check specific DNS record type for URL (iisisrael) - * feature #22629 [Security] Trigger a deprecation when a voter is missing the VoterInterface (iltar) - * feature #22636 [Routing] Expose request in route conditions, if needed and possible (ro0NL) - * feature #22909 [Yaml] Deprecate using the non-specific tag (GuilhemN) - * feature #23184 [HttpFoundation] Remove obsolete ini settings for sessions (fabpot) - * feature #23042 Consistent error handling in remember me services (lstrojny) - * feature #22444 [Serializer] DateTimeNormalizer: allow to provide timezone (ogizanagi) - * feature #23143 [DI] Reference instead of inline for array-params (nicolas-grekas) - * feature #23154 [WebProfilerBundle] Sticky ajax window (ro0NL) - * feature #23161 [FrameworkBundle] Deprecate useless --no-prefix option (chalasr) - * feature #23169 [FrameworkBundle] Remove KernelTestCase deprecated code (ogizanagi) - * feature #23105 [SecurityBundle][Profiler] Give info about called security listeners in profiler (chalasr) - * feature #23148 [FrameworkBundle] drop hard dependency on the Stopwatch component (xabbuh) - * feature #23131 [FrameworkBundle] Remove dependency on Doctrine cache (fabpot) - * feature #23114 [SecurityBundle] Lazy load security listeners (chalasr) - * feature #23111 [Process] Deprecate ProcessBuilder (nicolas-grekas) - * feature #22675 [FrameworkBundle] KernelTestCase: deprecate not using KERNEL_CLASS (ogizanagi) - * feature #22917 [VarDumper] Cycle prev/next searching in HTML dumps (ro0NL) - * feature #23044 Automatically enable the routing annotation loader (GuilhemN) - * feature #22696 [PropertyInfo] Made ReflectionExtractor's prefix lists instance variables (neemzy) - * feature #23056 [WebProfilerBundle] Remove WebProfilerExtension::dumpValue() (ogizanagi) - * feature #23035 Deprecate passing a concrete service in optional cache warmers (romainneutron) - * feature #23036 Implement ServiceSubscriberInterface in optional cache warmers (romainneutron) - * feature #23046 [Form] Missing deprecated paths removal (ogizanagi) - * feature #23022 [Di] Remove closure-proxy arguments (nicolas-grekas) - * feature #22758 Remove HHVM support (fabpot) - * feature #22743 [Serializer] Remove support for deprecated signatures (dunglas) - * feature #22907 [Serializer] remove remaining deprecated features (xabbuh) - * feature #22886 [HttpKernel] remove deprecated features (xabbuh) - * feature #22906 [Console] remove remaining deprecated features (xabbuh) - * feature #22879 [Translation] remove deprecated features (xabbuh) - * feature #22880 [Routing] remove deprecated features (xabbuh) - * feature #22903 [DI] Deprecate XML services without ID (ro0NL) - * feature #22770 [Yaml] remove deprecated features (xabbuh) - * feature #22785 [ProxyManagerBridge] remove deprecated features (xabbuh) - * feature #22800 [FrameworkBundle] Remove deprecated code (ogizanagi) - * feature #22597 [Lock] Re-add the Lock component in 3.4 (jderusse) - * feature #22860 [Form] remove deprecated features (xabbuh) - * feature #22803 [DI] Deprecate Container::initialized() for privates (ro0NL) - * feature #22773 [DependencyInjection] remove deprecated autowiring_types feature (hhamon) - * feature #22809 [DI] Remove deprecated generating a dumped container without populating the method map (ro0NL) - * feature #22764 [DI] Remove deprecated dumping an uncompiled container (ro0NL) - * feature #22820 Remove PHP < 7.1.3 code (ogizanagi) - * feature #22763 [DI] Remove deprecated isFrozen() (ro0NL) - * feature #22837 [VarDumper] remove deprecated features (xabbuh) - * feature #22777 [Console] Remove deprecated console.exception event (mbabker) - * feature #22792 [PhpUnitBridge] remove deprecated features (xabbuh) - * feature #22821 [Security] remove deprecated features (xabbuh) - * feature #22750 [DependencyInjection] remove deprecated code in YamlFileLoader class (hhamon) - * feature #22828 [Finder] Deprecate FilterIterator (ogizanagi) - * feature #22791 [MonologBridge] remove deprecated features (xabbuh) - * feature #22740 [SecurityBundle][Security][Finder] Remove deprecated code paths (ogizanagi) - * feature #22823 [PropertyAccess] remove deprecated features (xabbuh) - * feature #22826 [Validator] improve strict option value deprecation (xabbuh) - * feature #22799 [Console] Remove deprecated features (chalasr) - * feature #22786 [ClassLoader][HttpKernel] Remove ClassLoader component & Kernel::loadClassCache (ogizanagi, xabbuh) - * feature #22795 [Validator] remove deprecated features (xabbuh) - * feature #22784 [DoctrineBridge] remove deprecated features (xabbuh) - * feature #22749 Remove deprecated container injections and compiler passes (chalasr) - * feature #22796 [EventDispatcher] remove deprecated features (xabbuh) - * feature #22797 [Ldap] remove deprecated features (xabbuh) - * feature #22794 [ExpressionLanguage] remove deprecated features (xabbuh) - * feature #22779 [BC Break] Removed BC layers for ControllerResolver::getArguments() (iltar) - * feature #22782 [Debug][VarDumper] Remove the symfony_debug C extension (nicolas-grekas) - * feature #22771 [Workflow] Removed deprecated features (lyrixx) - * feature #22741 [Serializer] Remove deprecated DoctrineCache support (dunglas) - * feature #22733 Bump minimum version to PHP 7.1 for Symfony 4 (fabpot, dunglas, nicolas-grekas) - diff --git a/CHANGELOG-4.1.md b/CHANGELOG-4.1.md deleted file mode 100644 index 3a013e2504087..0000000000000 --- a/CHANGELOG-4.1.md +++ /dev/null @@ -1,586 +0,0 @@ -CHANGELOG for 4.1.x -=================== - -This changelog references the relevant changes (bug and security fixes) done -in 4.1 minor versions. - -To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash -To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.1.0...v4.1.1 - -* 4.1.10 (2019-01-06) - - * bug #29494 [HttpFoundation] Fix request uri when it starts with double slashes (alquerci) - * bug #29697 [DI] Fixed wrong factory method in exception (Wojciech Gorczyca) - * bug #29679 [HttpKernel] Correctly Render Signed URIs Containing Fragments (zanbaldwin) - * bug #29754 Ensure final input of CommandTester works with default (Firehed) - * bug #29695 [Form] Do not ignore the choice groups for caching (vudaltsov) - * bug #29738 [Intl] handle null date and time types (xabbuh) - * bug #29708 [FrameworkBundle] access the container getting it from the kernel (xabbuh) - * bug #29704 [FrameworkBundle] improve errors in tests missing the BrowserKit component (xabbuh) - * bug #29617 [Console] Add specific replacement for help text in single command applications (codedmonkey) - * bug #29714 [Event Dispatcher] fixed 29703: TraceableEventDispatcher reset() callStack to null (mlievertz) - * bug #29597 [DI] fix reporting bindings on overriden services as unused (nicolas-grekas) - * bug #29639 [Yaml] detect circular references (xabbuh) - * bug #29626 [Routing] fix trailing slash redirections involving a trailing var (nicolas-grekas) - * bug #29411 [EventDispatcher] Revers event tracing order (ro0NL) - * bug #29533 Fixed public directory when configured in composer.json (alexander-schranz) - * bug #29619 [Console] OutputFormatter: move strtolower to createStyleFromString (ogizanagi) - * bug #29621 [Security] Prefer clone() over unserialize(serialize()) for user refreshment (chalasr) - * bug #29542 [Routing] fix dumping same-path routes with placeholders (nicolas-grekas) - * bug #29587 [Debug] ignore underscore vs backslash namespaces in DebugClassLoader (nicolas-grekas) - * bug #29584 [FrameworkBundle] fix describing routes with no controllers (nicolas-grekas) - * bug #29582 [DI] move RegisterServiceSubscribersPass before DecoratorServicePass (kbond) - * bug #29527 [TwigBridge][Form] Prevent multiple rendering of form collection prototypes (Shoplifter) - * bug #29571 [Yaml] ensures that the mb_internal_encoding is reset to its initial value (Jörn Lang) - * bug #29513 [Hackday][Serializer] Deserialization ignores argument type hint from phpdoc for array in constructor argument (karser) - * bug #29323 [Security] defer log message in guard authenticator (eschultz-magix) - * bug #29531 [Validator] Added IBAN format for Vatican City State (raulfraile) - * bug #29501 [Form] filter out invalid language values (xabbuh) - * bug #29307 [Form] Filter arrays out of scalar form types (nicolas-grekas) - * bug #29500 [Form] filter out invalid Intl values (xabbuh) - * bug #29499 [Validator] Fixed grouped composite constraints (HeahDude) - -* 4.1.9 (2018-12-06) - - * security #cve-2018-19790 [Security\Http] detect bad redirect targets using backslashes (xabbuh) - * security #cve-2018-19789 [Form] Filter file uploads out of regular form types (nicolas-grekas) - * bug #29436 [Cache] Fixed Memcached adapter doClear()to call flush() (raitocz) - * bug #29441 [Routing] ignore trailing slash for non-GET requests (nicolas-grekas) - * bug #29444 [Workflow] Fixed BC break for Workflow metadata (lyrixx) - * bug #29432 [DI] dont inline when lazy edges are found (nicolas-grekas) - * bug #29413 [Serializer] fixed DateTimeNormalizer to maintain microseconds when a different timezone required (rvitaliy) - * bug #29424 [Routing] fix taking verb into account when redirecting (nicolas-grekas) - * bug #29414 [DI] Fix dumping expressions accessing single-use private services (chalasr) - * bug #29375 [Validator] Allow `ConstraintViolation::__toString()` to expose codes that are not null or emtpy strings (phansys) - * bug #29376 [EventDispatcher] Fix eventListener wrapper loop in TraceableEventDispatcher (jderusse) - * bug #29386 undeprecate the single-colon notation for controllers (fbourigault) - * bug #29393 [DI] fix edge case in InlineServiceDefinitionsPass (nicolas-grekas) - * bug #29380 [Routing] fix greediness of trailing slash (nicolas-grekas) - * bug #29343 [Form] Handle all case variants of "nan" when parsing a number (mwhudson, xabbuh) - * bug #29373 [Routing] fix trailing slash redirection (nicolas-grekas) - * bug #29355 [PropertyAccess] calculate cache keys for property setters depending on the value (xabbuh) - * bug #29369 [DI] fix combinatorial explosion when analyzing the service graph (nicolas-grekas) - * bug #29349 [Debug] workaround opcache bug mutating "$this" !?! (nicolas-grekas) - -* 4.1.8 (2018-11-26) - - * bug #29318 [Console] Move back root exception to stack trace in verbose mode (chalasr) - * bug #29332 [PropertyAccess] make cache keys encoding bijective (nicolas-grekas) - * bug #29298 [Routing] fix trailing slash redirection when using RedirectableUrlMatcher (nicolas-grekas) - * bug #29297 [Routing] fix trailing slash redirection when using RedirectableUrlMatcher (nicolas-grekas) - * bug #29313 [PropertyAccessor] fix encoding of cache keys (nicolas-grekas) - * bug #28917 [DoctrineBridge] catch errors while converting to db values in data collector (alekitto) - * bug #29317 [WebProfiler] Detect non-file paths in file viewer (ro0NL) - * bug #29305 [EventDispatcher] Unwrap wrapped listeners internally (ro0NL) - * bug #27314 [DoctrineBridge] fix case sensitivity issue in RememberMe\DoctrineTokenProvider (PF4Public) - * bug #29310 [MonologBridge] Return empty list for unknown requests (ro0NL) - * bug #29308 [Translation] Use XLIFF source rather than resname when there's no target (thewilkybarkid) - * bug #26244 [BrowserKit] fixed BC Break for HTTP_HOST header (brizzz) - * bug #28147 [DomCrawler] exclude fields inside "template" tags (Gorjunov) - * bug #29222 [Dotenv] properly parse backslashes in unquoted env vars (xabbuh) - * bug #29256 [HttpFoundation] Fixed absolute Request URI with default port (thomasbisignani) - * bug #29274 [Routing] Remove duplicate schemes and methods for invokable controllers (claudusd) - * bug #29271 [HttpFoundation] Fix trailing space for mime-type with parameters (Sascha Dens) - * bug #29243 [Cache] fix optimizing Psr6Cache for AdapterInterface pools (nicolas-grekas) - * bug #29247 [DI] fix taking lazy services into account when dumping the container (nicolas-grekas) - * bug #29249 [Form] Fixed empty data for compound date interval (HeahDude) - * bug #29265 [Bridge/PhpUnit] Use composer to download phpunit (nicolas-grekas) - * bug #28769 [FrameworkBundle] deal with explicitly enabled workflow nodes (xabbuh) - * bug #29223 [Validator] Added the missing constraints instance checks (thomasbisignani) - * bug #28966 [PropertyAccessor] Fix unable to write to singular property using setter while plural adder/remover exist (karser) - * bug #29182 [Form] Fixed empty data for compound date types (HeahDude) - * bug #29191 [Routing] generate(null) should throw an exception (nicolas-grekas) - * bug #29185 [Form] Fixed keeping hash of equal \DateTimeInterface on submit (HeahDude) - * bug #29141 [Workflow] Fixed bug of buildTransitionBlockerList when many transition are enabled (Tetragramat, lyrixx) - * bug #29137 [Workflow][FrameworkBundle] fixed guard event names for transitions (destillat, lyrixx) - * bug #28731 [Form] invalidate forms on transformation failures (xabbuh) - * bug #29152 [Config] Unset key during normalization (ro0NL) - * bug #29165 [DI] align IniFileLoader to PHP bugfix #76965 (nicolas-grekas) - * bug #29115 Change button_widget class to btn-primary (neFAST) - * bug #29131 [Dotenv] dont use getenv() to read SYMFONY_DOTENV_VARS (nicolas-grekas) - * bug #29057 [HttpFoundation] replace any preexisting Content-Type headers (nicolas-grekas) - * bug #29076 [Serializer] Allow null values when denormalizing with constructor missing data (danut007ro) - * bug #29104 [DI] fix dumping inlined services (nicolas-grekas) - * bug #29054 [VarDumper] fix dump of closures created from callables (nicolas-grekas) - * bug #29102 [DI] fix GraphvizDumper ignoring inline definitions (nicolas-grekas) - * bug #29107 [DI] dont track classes/interfaces used to compute autowiring error messages (nicolas-grekas) - -* 4.1.7 (2018-11-03) - - * bug #28820 [DependencyInjection] Fix tags on multiple decorated service (Soner Sayakci) - * bug #29020 Fix ini_get() for boolean values (deguif) - * bug #28955 [Messenger] send using the routing_key for AMQP transport (nicolas-grekas) - * bug #28960 also clean away the NO_AUTO_CACHE_CONTROL_HEADER if we have no session (dbu) - * feature #28893 [TwigBundle] Fix usage of TwigBundle without FrameworkBundle (tgalopin) - * bug #28889 [Serializer] Reduce class discriminator overhead (fbourigault) - * bug #28861 [DependencyInjection] Skip empty proxy code (olvlvl) - * bug #28801 Convert InsufficientAuthenticationException to HttpException with 401 status code (vincentchalamon) - * bug #28840 add missing double-quotes to extra_fields output message (danielkay) - * bug #28838 [DI] Default undefined env to empty string during compile (ro0NL) - * bug #28863 [Process] Allow to pass non-string arguments to Process (vudaltsov) - * bug #28712 [Form] reverse transform RFC 3339 formatted dates (xabbuh) - * bug #28813 Fix for race condition in console output stream write (rudolfratusinski) - * bug #27772 [Console] Fixes multiselect choice question defaults in non-interactive mode (veewee) - * bug #28835 [FrameworkBundle] Setting missing default paths under BC layer (yceruto) - * bug #28760 [DI] fix dumping inline services again (nicolas-grekas) - * bug #28689 [Process] fix locking of pipe files on Windows (nicolas-grekas) - * bug #28704 [Form] fix multi-digit seconds fraction handling (xabbuh) - * bug #28793 [SecurityBundle] do not override custom access decision configs (xabbuh) - * bug #28783 [FrameworkBundle] add missing cache prefix seed attribute to XSD (xabbuh) - * bug #28072 [Security] Do not deauthenticate user when the first refreshed user has changed (gpekz) - * bug #28735 [FWBundle] Automatically enable PropertyInfo when using Flex (dunglas) - * bug #28751 [FrameworkBundle] Register messenger before the profiler (sroze) - -* 4.1.6 (2018-10-03) - - * bug #28604 [Finder] fixed root directory access for ftp/sftp wrapper (DerDu) - * bug #28688 [FWBundle] Throw if PropertyInfo is enabled, but the component isn't installed (dunglas) - * bug #28638 [Console] Fix clearing sections containing questions (chalasr) - * bug #28690 [FrameworkBundle] dont suggest hidden services in debug:container and debug:autow commands (nicolas-grekas) - * bug #28648 [PHPUnitBridge] Fix ClockMock microtime() format (acasademont) - * bug #28678 [DI] fix dumping setters before their inlined instances (nicolas-grekas) - * bug #28672 [DI] fix error in dumped container (nicolas-grekas) - * bug #28664 [Console] Don't return early as this bypasses the auto exit feature (duncan3dc) - -* 4.1.5 (2018-09-30) - - * bug #28636 [HttpFoundation] X-Accel-Mapping does not use HTTP key=value syntax (c960657) - * bug #28376 [TwigBundle] Fixed caching of templates in src/Resources//views on cache warmup (yceruto) - * bug #28565 [HttpFoundation][Security] forward locale and format to subrequests (nicolas-grekas) - * bug #28561 [Cache] prevent getting older entries when the version key is evicted (nicolas-grekas) - * bug #28562 [HttpFoundation] fix hidding warnings from session handlers (nicolas-grekas) - * bug #28545 [Console] Send the right exit code to console.terminate listeners (mpdude) - * bug #28553 [Debug] Fix false-positive "MicroKernelTrait::loadRoutes()" method is considered internal" (nicolas-grekas) - * bug #28466 [Form] fail reverse transforming invalid RFC 3339 dates (xabbuh) - * bug #28540 [Intl] parse numbers terminated with decimal separator (xabbuh) - * bug #28548 [Console] Fixed boxed table style with colspan (ro0NL) - * bug #28433 [HttpFoundation] Allow reuse of Session between requests if ID did not change (tgalopin) - * bug #28508 [Form] forward false label option to nested types (xabbuh) - * bug #28471 [MonologBridge] Re-add option option to ignore empty context and extra data (mpdude) - * bug #28464 [Form] forward the invalid_message option in date types (xabbuh) - * bug #28524 [PhpUnitBridge] fix disabling DeprecationErrorHandler using phpunit.xml file (soerenbernstein) - * bug #28512 [DI] fix infinite loop involving self-references in decorated services (nicolas-grekas) - * bug #28507 [DI] fix dumping lazy services (nicolas-grekas) - * bug #28469 [Form][TwigBridge] fix not displaying labels when value is false (xabbuh) - * bug #28495 [PhpUnitBridge] Implement startTest rather than startTestSuite (greg0ire) - * bug #28480 [DI] Detect circular references with ChildDefinition parent (Seb33300) - * bug #28497 [VarDumper] Fix global dump function return value for PHP7 (patrickcarlohickman) - * bug #28499 [Ldap] Use shut up operator on connection errors at ldap_start_tls (Andras Debreczeni) - * bug #28372 [Form] Fix DateTimeType html5 input format (franzwilding, mcfedr) - * bug #28396 [Intl] Blacklist Eurozone and United Nations in Region Data Generator (gregurco) - * bug #28418 [FrameworkBundle] Register the messenger data collector only when the profiler is enabled (pierredup) - * bug #28393 [Console] fixed corrupt error output for unknown multibyte short option (downace) - * bug #28411 [Debug] fix detecting overriden final/internal methods implemented using traits (nicolas-grekas) - * bug #28404 [Controller][ServiceValueResolver] Making method access case insensitive (nicoweb) - * bug #28401 [Console] Fix SymfonyQuestionHelper::askQuestion() with choice value as default (chalasr) - * bug #28388 [DI] configure inlined services before injecting them when dumping the container (nicolas-grekas) - * bug #28377 fix fopen flags (SpacePossum) - * bug #27764 [TwigBundle] Fixed caching of templates in default path on cache warmup (yceruto) - * bug #28366 [DI] Fix dumping some complex service graphs (nicolas-grekas) - * bug #27970 [FileValidator] Format file size in validation message according to binaryFormat option (jfredon) - * bug #28029 [TwigBundle] remove cache warmers when Twig cache is disabled (xabbuh) - * bug #28322 [Workflow] Make sure we do not run the next transition on an updated state (Nyholm) - * bug #28344 [HttpKernel][FrameworkBundle] Fix escaping of serialized payloads passed to test clients (nicolas-grekas) - * bug #28183 [WebProfilerBundle] fix wrong url when base path is the index (ismail1432) - * bug #28334 [FWB][Messenger] Revert "Move commands-specifics to a compiler pass in FWB" (sroze) - * bug #28328 [Messenger][FrameworkBundle] Move commands-specifics to a compiler pass in FWB (sroze) - -* 4.1.4 (2018-08-28) - - * bug #28278 [HttpFoundation] Fix unprepared BinaryFileResponse sends empty file (wackymole) - * bug #28284 [PhpUnitBridge] keep compat with composer 1.0 (nicolas-grekas) - * bug #28251 [HttpFoundation] Allow RedisCluster class for RedisSessionHandler (michaelperrin) - * bug #28241 [HttpKernel] fix forwarding trusted headers as server parameters (nicolas-grekas) - * bug #28220 [PropertyAccess] fix type error handling when writing values (xabbuh) - * bug #28249 [Cache] enable Memcached::OPT_TCP_NODELAY to fix perf of misses (nicolas-grekas) - * bug #28252 [DoctrineBridge] support __toString as documented for UniqueEntityValidator (dmaicher) - * bug #28216 [FrameworkBundle] `message_bus` alias public (sroze) - * bug #28113 [Form] Add help texts for checkboxes in horizontal bootstrap 4 forms (apfelbox) - * bug #28100 [Security] Call AccessListener after LogoutListener (chalasr) - * bug #28174 Remove the HTML5 validation from the profiler URL search form (Soullivaneuh) - * bug #28159 [DI] Fix autowire inner service (hason) - * bug #28060 [DI] Fix false-positive circular ref leading to wrong exceptions or infinite loops at runtime (nicolas-grekas) - * bug #28144 [HttpFoundation] fix false-positive ConflictingHeadersException (nicolas-grekas) - * bug #28152 [Translation] fix perf of lint:xliff command (nicolas-grekas) - * bug #28115 [Form] Remove extra .form-group wrapper around file widget in bootstrap 4 (MrMitch) - * bug #28120 [Routing] Fixed scheme redirecting for root path (twoleds) - * bug #28112 Fix CSS property typo (AhmedAbdulrahman) - * bug #28012 [PropertyInfo] Allow nested collections (jderusse) - * bug #28055 [PropertyInfo] Allow nested collections (jderusse) - * bug #28083 Remove the Expires header when calling Response::expire() (javiereguiluz) - -* 4.1.3 (2018-08-01) - - * security #cve-2018-14774 [HttpKernel] fix trusted headers management in HttpCache and InlineFragmentRenderer (nicolas-grekas) - * security #cve-2018-14773 [HttpFoundation] Remove support for legacy and risky HTTP headers (nicolas-grekas) - * bug #28003 [HttpKernel] Fixes invalid REMOTE_ADDR in inline subrequest when configuring trusted proxy with subnet (netiul) - * bug #28007 [FrameworkBundle] fixed guard event names for transitions (destillat) - * bug #28045 [HttpFoundation] Fix Cookie::isCleared (ro0NL) - * bug #28080 [HttpFoundation] fixed using _method parameter with invalid type (Phobetor) - * bug #28059 [Messenger] Fix error message on undefined message class for non-subscriber handler (chalasr) - * bug #28052 [HttpKernel] Fix merging bindings for controllers' locators (nicolas-grekas) - * bug #28014 [Messenger] Fix chaining senders with their aliases (sroze) - -* 4.1.2 (2018-07-23) - - * bug #28005 [HttpKernel] Fixed templateExists on parse error of the template name (yceruto) - * bug #28013 [Messenger] Add missing typehint on chain sender (sroze) - * bug #27997 Serbo-Croatian has Serbian plural rule (kylekatarnls) - * bug #26193 Fix false-positive deprecation notices for TranslationLoader and WriteCheckSessionHandler (iquito) - * bug #27827 [Serializer] Supports nested abstract items (sroze) - * bug #27958 [Form] Remaining changes for bootstrap 4 file fields (apfelbox) - * bug #27919 [Form] Improve rendering of `file` field in bootstrap 4 (apfelbox) - * bug #27941 [WebProfilerBundle] Fixed icon alignment issue using Bootstrap 4.1.2 (jmsche) - * bug #27937 [HttpFoundation] reset callback on StreamedResponse when setNotModified() is called (rubencm) - * bug #27927 [HttpFoundation] Suppress side effects in 'get' and 'has' methods of NamespacedAttributeBag (webnet-fr) - * bug #27913 [EventDispatcher] Clear orphaned events on reset (acasademont) - * bug #27923 [Form/Profiler] Massively reducing memory footprint of form profiling pages... (VincentChalnot) - * bug #27918 [Console] correctly return parameter's default value on "--" (seschwar) - * bug #27826 [Serializer] Fix serialization of items with groups across entities and discrimination map (sroze) - * bug #27904 [Filesystem] fix lock file permissions (fritzmg) - * bug #27903 [Lock] fix lock file permissions (fritzmg) - * bug #27889 [Form] Replace .initialism with .text-uppercase. (vudaltsov) - * bug #27902 Fix the detection of the Process new argument (stof) - * bug #27885 [HttpFoundation] don't encode cookie name for BC (nicolas-grekas) - * bug #27782 [DI] Fix dumping ignore-on-uninitialized references to synthetic services (nicolas-grekas) - * bug #27435 [OptionResolver] resolve arrays (Doctrs) - * bug #27728 [TwigBridge] Fix missing path and separators in loader paths list on debug:twig output (yceruto) - * bug #27837 [PropertyInfo] Fix dock block lookup fallback loop (DerManoMann) - * bug #27848 [Workflow] Fixed BC break (lyrixx) - * bug #27758 [WebProfilerBundle] Prevent toolbar links color override by css (alcalyn) - * bug #27847 [Security] Fix accepting null as $uidKey in LdapUserProvider (louhde) - * bug #27820 [Messenger] Fix a bug when having more than one named handler per message subscriber (sroze) - * bug #27834 [DI] Don't show internal service id on binding errors (nicolas-grekas) - * bug #27831 Check for Hyper terminal on all operating systems. (azjezz) - * bug #27794 Add color support for Hyper terminal . (azjezz) - * bug #27809 [HttpFoundation] Fix tests: new message for status 425 (dunglas) - * bug #27618 [PropertyInfo] added handling of nullable types in PhpDoc (oxan) - * bug #27659 [HttpKernel] Make AbstractTestSessionListener compatible with CookieClearingLogoutHandler (thewilkybarkid) - * bug #27752 [Cache] provider does not respect option maxIdLength with versioning enabled (Constantine Shtompel) - * bug #27773 [Serializer] Class discriminator and serialization groups (sroze) - * bug #27710 [DependencyInjection] fix handling of empty DI extension configs (xabbuh) - * bug #27776 [ProxyManagerBridge] Fix support of private services (bis) (nicolas-grekas) - * bug #27714 [HttpFoundation] fix session tracking counter (nicolas-grekas, dmaicher) - * bug #27727 [Routing] Disallow object usage inside Route (paxal) - * bug #27736 [Routing] fix too much greediness in host-matching regex (nicolas-grekas) - * bug #27747 [HttpFoundation] fix registration of session proxies (nicolas-grekas) - * bug #27754 [HttpFoundation] missing namespace for RedisProxy (Bonfante) - * bug #27722 Redesign the Debug error page in prod (javiereguiluz) - * bug #27716 [DI] fix dumping deprecated service in yaml (nicolas-grekas) - -* 4.1.1 (2018-06-25) - - * bug #27626 [TwigBundle][DX] Only add the Twig WebLinkExtension if the WebLink component is enabled (thewilkybarkid) - * bug #27702 [TwigBundle] bump lowest deps to fix issue with "double-colon" controller service refs (nicolas-grekas) - * bug #27701 [SecurityBundle] Dont throw if "security.http_utils" is not found (nicolas-grekas) - * bug #27690 [DI] Resolve env placeholder in logs (ro0NL) - * bug #27687 [HttpKernel] fix argument's error messages in ServiceValueResolver (nicolas-grekas) - * bug #27614 [VarDumper] Fix dumping by splitting Server/Connection out of Dumper/ServerDumper (nicolas-grekas) - * bug #27681 [DI] Avoid leaking unused env placeholders (ro0NL) - * bug #26534 allow_extra_attributes does not throw an exception as documented (deviantintegral) - * bug #27664 [FrameworkBundle] Ignore keepQueryParams attribute when generating route redirect (vudaltsov) - * bug #27668 [Lock] use 'r+' for fopen (fixes issue on Solaris) (fritzmg) - * bug #27669 [Filesystem] fix file lock on SunOS (fritzmg) - * bug #27662 [HttpKernel] fix handling of nested Error instances (xabbuh) - * bug #27651 [Messenger] Fixed MessengerPass::guessHandledClasses return type (massimilianobraglia) - * bug #26845 [Config] Fixing GlobResource when inside phar archive (vworldat) - * bug #27382 [Form] Fix error when rendering a DateIntervalType form with exactly 0 weeks (krixon) - * bug #27309 Fix surrogate not using original request (Toflar) - * bug #27467 [HttpKernel] fix session tracking in surrogate master requests (nicolas-grekas) - * bug #27632 [HttpFoundation] Ensure RedisSessionHandler::updateTimestamp returns a boolean (MatTheCat) - * bug #27630 [Validator][Form] Remove BOM in some xlf files (gautierderuette) - * bug #27596 [Framework][Workflow] Added support for interfaces (vudaltsov) - * bug #27593 [ProxyManagerBridge] Fixed support of private services (nicolas-grekas) - * bug #27591 [VarDumper] Fix dumping ArrayObject and ArrayIterator instances (nicolas-grekas) - * bug #27528 [FrameworkBundle] give access to non-shared services when using test.service_container (nicolas-grekas) - * bug #27584 Avoid calling eval when there is no script embedded in the toolbar (stof) - * bug #27581 Fix bad method call with guard authentication + session migration (weaverryan) - * bug #27576 [Cache] Fix expiry comparisons in array-based pools (nicolas-grekas) - * bug #27566 [FrameworkBundle] fix for allowing single colon controller notation (dmaicher) - * bug #27556 Avoiding session migration for stateless firewall UsernamePasswordJsonAuthenticationListener (weaverryan) - * bug #27452 Avoid migration on stateless firewalls (weaverryan) - * bug #27568 [DI] Deduplicate generated proxy classes (nicolas-grekas) - * bug #27511 [Routing] fix matching host patterns, utf8 prefixes and non-capturing groups (nicolas-grekas) - * bug #27326 [Serializer] deserialize from xml: Fix a collection that contains the only one element (webnet-fr) - * bug #27562 [HttpKernel] Log/Collect exceptions at prio 0 (ro0NL) - * bug #27567 [PhpUnitBridge] Fix error on some Windows OS (Nsbx) - * bug #27357 [Lock] Remove released semaphore (jderusse) - * bug #27416 TagAwareAdapter over non-binary memcached connections corrupts memcache (Aleksey Prilipko) - * bug #27514 [Debug] Pass previous exception to FatalErrorException (pmontoya) - * bug #27516 Revert "bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen)" (nicolas-grekas) - * bug #27501 [FrameworkBundle] Fix test-container on kernel reboot, revert to returning the real container from Client::getContainer() (nicolas-grekas) - * bug #27472 [DI] Ignore missing tree root nodes on validate (ro0NL) - * bug #27458 [WebProfilerBundle] fixed getSession when no session has been set deprecation warnings (GregOriol) - * bug #27318 [Cache] memcache connect should not add duplicate entries on sequential calls (Aleksey Prilipko) - * bug #27498 [Routing] Don't reorder past variable-length placeholders (nanocom, nicolas-grekas) - * bug #27496 [DebugBundle] DebugBundle::registerCommands should be noop (ogizanagi) - * bug #27485 [BrowserKit] Fix a BC break in Client affecting Panthère (dunglas) - * bug #27470 [DI] Remove default env type check on validate (ro0NL) - * bug #27454 [FrameworkBundle][TwigBridge] Fix BC break from strong dependency on CSRF token storage (tgalopin) - * bug #27389 [Serializer] Fix serializer tries to denormalize null values on nullable properties (ogizanagi) - * bug #27272 [FrameworkBundle] Change priority of AddConsoleCommandPass to TYPE_BEFORE_REMOVING (upyx) - * bug #27396 [HttpKernel] fix registering IDE links (nicolas-grekas) - * bug #26973 [HttpKernel] Set first trusted proxy as REMOTE_ADDR in InlineFragmentRenderer. (kmadejski) - * bug #27303 [Process] Consider "executable" suffixes first on Windows (sanmai) - * bug #27297 Triggering RememberMe's loginFail() when token cannot be created (weaverryan) - -* 4.1.0 (2018-05-30) - - * bug #27420 Revert "feature #26702 Mark ExceptionInterfaces throwable (ostrolucky)" (nicolas-grekas) - * bug #27415 Insert correct parameter_bag service in AbstractController (curry684) - -* 4.1.0-BETA3 (2018-05-26) - - * bug #27388 [Routing] Account for greediness when merging route patterns (nicolas-grekas) - * bug #27344 [HttpKernel] reset kernel start time on reboot (kiler129) - * bug #27365 [Serializer] Check the value of enable_max_depth if defined (dunglas) - * bug #27358 [PhpUnitBridge] silence some stderr outputs (ostrolucky) - * bug #27366 [DI] never inline lazy services (nicolas-grekas) - * bug #27352 Remove reference to the test container after kernel shutdown (stof) - * bug #27350 [HttpKernel] fix deprecation in AbstractTestSessionListener (alekitto) - * bug #27367 [FrameworkBundle] cleanup generated test container (nicolas-grekas) - * bug #27379 [FrameworkBundle] Fix using test.service_container when Client is rebooted (nicolas-grekas) - * bug #27364 [DI] Fix bad exception on uninitialized references to non-shared services (nicolas-grekas) - * bug #27359 [HttpFoundation] Fix perf issue during MimeTypeGuesser intialization (nicolas-grekas) - * security #cve-2018-11408 [SecurityBundle] Fail if security.http_utils cannot be configured - * security #cve-2018-11406 clear CSRF tokens when the user is logged out - * security #cve-2018-11385 migrating session for UsernamePasswordJsonAuthenticationListener - * security #cve-2018-11385 migrating session for UsernamePasswordJsonAuthenticationListener - * security #cve-2018-11385 Adding session authentication strategy to Guard to avoid session fixation - * security #cve-2018-11385 Adding session strategy to ALL listeners to avoid *any* possible fixation - * security #cve-2018-11386 [HttpFoundation] Break infinite loop in PdoSessionHandler when MySQL is in loose mode - * bug #27341 [WebProfilerBundle] Fixed validator/dump trace CSS (yceruto) - * bug #27337 [FrameworkBundle] fix typo in CacheClearCommand (emilielorenzo) - * bug #27292 [Serializer] Fix and improve constraintViolationListNormalizer's RFC7807 compliance (dunglas) - -* 4.1.0-BETA2 (2018-05-21) - - * bug #27312 Supress deprecation notices thrown when getting private servies from container in tests (arderyp) - * feature #27275 [Messenger] Allow to scope handlers per bus (ogizanagi, sroze) - * bug #27264 [Validator] Use strict type in URL validator (mimol91) - * bug #27267 [DependencyInjection] resolve array env vars (jamesthomasonjr) - * bug #26781 [Form] Fix precision of MoneyToLocalizedStringTransformer's divisions on transform() (syastrebov) - * bug #27270 [Routing] Fix adding name prefix to canonical route names (ismail1432) - * bug #27286 [Translation] Add Occitan plural rule (kylekatarnls) - * bug #27271 [DI] Allow defining bindings on ChildDefinition (nicolas-grekas) - * bug #27246 Disallow invalid characters in session.name (ostrolucky) - * feature #27230 [Messenger] Select alternatives on missing receiver arg or typo (yceruto) - * bug #27287 [PropertyInfo] fix resolving parent|self type hints (nicolas-grekas) - * bug #27281 [HttpKernel] Fix dealing with self/parent in ArgumentMetadataFactory (fabpot) - * bug #24805 [Security] Fix logout (MatTheCat) - * bug #27265 [DI] Shared services should not be inlined in non-shared ones (nicolas-grekas) - * bug #27141 [Process] Suppress warnings when open_basedir is non-empty (cbj4074) - * bug #27250 [Session] limiting :key for GET_LOCK to 64 chars (oleg-andreyev) - * feature #27128 [Messenger] Middleware factories support in config (ogizanagi) - * bug #27214 [HttpKernel] Fix services are no longer injected into __invoke controllers method (ogizanagi) - * bug #27237 [Debug] Fix populating error_get_last() for handled silent errors (nicolas-grekas) - * bug #27232 [Cache][Lock] Fix usages of error_get_last() (nicolas-grekas) - * bug #27236 [Filesystem] Fix usages of error_get_last() (nicolas-grekas) - * feature #27202 [Messenger] Improve the profiler panel (ogizanagi) - * bug #27191 [DI] Display previous error messages when throwing unused bindings (nicolas-grekas) - * bug #27231 [FrameworkBundle] Fix cache:clear on vagrant (nicolas-grekas) - * bug #27222 [WebProfilerBundle][Cache] Fix misses calculation when calling getItems (fsevestre) - * bug #27227 [HttpKernel] Handle NoConfigurationException "onKernelException()" (nicolas-grekas) - * feature #27034 [Messenger][DX] Uses custom method names for handlers (sroze) - * bug #27228 [Messenger] Remove autoconfiguration for Sender/ReceiverInterface (kbond) - * bug #27229 [Messenger] Rename tag attribute "name" by "alias" (yceruto) - * bug #27224 [Messenger] Make sure default receiver name is set before command configuration (yceruto) - * feature #27225 [Messenger] Autoconfiguring TransportFactoryInterface classes (yceruto) - * bug #27220 [Messenger] Fix new AMQP Transport test with Envelope & fix contract (ogizanagi) - * bug #27184 [Messenger] Fix return senders based on the message parents/interfaces (yceruto) - * feature #27182 [Messenger] Re-introduce wrapped message configuration (with fix) (sroze, ogizanagi) - * bug #27209 [Workflow] add is deprecated since Symfony 4.1. Use addWorkflow() instead (xkobal) - * feature #26803 [Messenger] Add debug:messenger CLI command (ro0NL, sroze) - * bug #27189 [Profiler] Fix dump makes toolbar disappear (ogizanagi) - * bug #27199 [Messenger] Fix default bus name (ogizanagi) - * bug #27198 [Messenger] Fix the transport factory after moving it (sroze) - * bug #27197 [Messenger] Fix AMQP Transport factory & TransportFactoryInterface (ogizanagi) - * bug #27196 [Messenger] Fix AMQP Transport (yceruto) - -* 4.1.0-BETA1 (2018-05-07) - - * feature #26945 [Messenger] Support configuring messages when dispatching (ogizanagi) - * feature #27168 [HttpKernel] Add Kernel::getAnnotatedClassesToCompile() (nicolas-grekas) - * feature #27170 Show the deprecations tab by default in the logger panel (javiereguiluz) - * feature #27130 [Messenger] Add a new time limit receiver (sdelicata) - * feature #27104 [DX] Redirect to proper Symfony version documentation (noniagriconomie) - * feature #27105 [Serializer] Add ->hasCacheableSupportsMethod() to CacheableSupportsMethodInterface (nicolas-grekas) - * feature #24896 Add CODE_OF_CONDUCT.md (egircys) - * feature #27092 [Workflow] "clear()" instead of "reset()" (nicolas-grekas) - * feature #26655 [WebProfilerBundle] Make WDT follow ajax requests if header set (jeffreymb) - * feature #27049 [Serializer] Cache the normalizer to use when possible (dunglas, nicolas-grekas) - * feature #27062 [SecurityBundle] Register a `UserProviderInterface` alias if one provider only (sroze) - * feature #27065 [DI][Routing] Allow invokable objects to be used as PHP-DSL loaders (aurimasniekis) - * feature #26975 [Messenger] Add a memory limit option for `ConsumeMessagesCommand` (sdelicata) - * feature #26864 [Messenger] Define multiple buses from the `framework.messenger.buses` configuration (sroze) - * feature #27017 [Serializer] Allow to access to the context and various other infos in callbacks and max depth handler (dunglas) - * feature #26832 [MonologBridge] Added WebSubscriberProcessor to ease processor configuration (lyrixx) - * feature #24699 [HttpFoundation] Add HeaderUtils class (c960657) - * feature #26791 [BrowserKit] Bypass Header Informations (cfjulien) - * feature #26825 [Form] Add choice_translation_locale option for Intl choice types (yceruto, fabpot) - * feature #26921 [DI][FrameworkBundle] Hide service ids that start with a dot (nicolas-grekas) - * feature #23659 [HttpKernel] LoggerDataCollector: splitting logs on different sub-requests (vtsykun) - * feature #26768 [DI] Allow autoconfigured calls in PHP (Gary PEGEOT, GaryPEGEOT) - * feature #26833 [HttpKernel] Added support for timings in ArgumentValueResolvers (iltar) - * feature #26770 Do not normalize array keys in twig globals (lstrojny) - * feature #26787 [Security] Make security.providers optional (MatTheCat) - * feature #26970 [VarDumper] Add dd() helper == dump() + exit() (nicolas-grekas) - * feature #26941 [Messenger] Allow to configure the transport (sroze) - * feature #26632 [Messenger] Add AMQP adapter (sroze) - * feature #26863 [Console] Support iterable in SymfonyStyle::write/writeln (ogizanagi) - * feature #26847 [Console] add support for iterable in output (Tobion) - * feature #26660 [SecurityBundle] allow using custom function inside allow_if expressions (dmaicher) - * feature #26096 [HttpFoundation] Added a migrating session handler (rossmotley) - * feature #26528 [Debug] Support any Throwable object in FlattenException (derrabus) - * feature #26811 [PhpUnitBridge] Search for other SYMFONY_* env vars in phpunit.xml then phpunit.xml.dist (lyrixx) - * feature #26800 [PhpUnitBridge] Search for SYMFONY_PHPUNIT_REMOVE env var in phpunit.xml then phpunit.xml.dist (lyrixx) - * feature #26684 [Messenger] Remove the Doctrine middleware configuration from the FrameworkBundle (sroze) - * feature #21856 [LDAP] Allow adding and removing values to/from multi-valued attributes (jean-gui) - * feature #26767 [Form] ability to set rounding strategy for MoneyType (syastrebov) - * feature #23707 [Monolog Bridge][DX] Add a Monolog activation strategy for ignoring specific HTTP codes (simshaun, fabpot) - * feature #26685 [Messenger] Add a `MessageHandlerInterface` (multiple messages + auto-configuration) (sroze) - * feature #26648 [Messenger] Added a middleware that validates messages (Nyholm) - * feature #26475 [HttpFoundation] split FileException into specialized ones about upload handling (fmata) - * feature #26702 Mark ExceptionInterfaces throwable (ostrolucky) - * feature #26656 [Workflow][Registry] Added a new 'all' method (alexpozzi, lyrixx) - * feature #26693 [Console] Add box-double table style (maidmaid) - * feature #26698 [Console] Use UTF-8 bullet for listing (ro0NL) - * feature #26682 Improved the lint:xliff command (javiereguiluz) - * feature #26681 Allow to easily ask Symfony not to set a response to private automatically (Toflar) - * feature #26627 [DI] Add runtime service exceptions to improve the error message when controller arguments cannot be injected (nicolas-grekas) - * feature #26504 [FrameworkBundle] framework.php_errors.log now accept a log level (Simperfit) - * feature #26498 Allow "json:" env var processor to accept null value (mcfedr) - * feature #25928 [DI] Allow binary values in parameters. (bburnichon) - * feature #26647 [Messenger] Add a middleware that wraps all handlers in one Doctrine transaction. (Nyholm) - * feature #26668 [WebProfilerBundle] Live duration of AJAX request (ostrolucky) - * feature #26650 [Messenger] Clone messages to show in profiler (Nyholm) - * feature #26281 [FrameworkBundle] keep query in redirect (Simperfit) - * feature #26665 Improved the Ajax profiler panel when there are exceptions (javiereguiluz) - * feature #26654 [VarDumper] Provide binary, allowing to start a server at any time (ogizanagi) - * feature #26332 Add a data_help method in Form (mpiot, Nyholm) - * feature #26671 More compact display of vendor code in exception pages (javiereguiluz) - * feature #26502 [Form] Add Bootstrap 4 style for field FileType (zenmate) - * feature #23888 [DI] Validate env vars in config (ro0NL) - * feature #26658 Adding support to bind scalar values to controller arguments (weaverryan) - * feature #26651 [Workflow] Added a TransitionException (andrewtch, lyrixx) - * feature #23831 [VarDumper] Introduce a new way to collect dumps through a server dumper (ogizanagi, nicolas-grekas) - * feature #26220 [HttpFoundation] Use parse_str() for query strings normalization (nicolas-grekas) - * feature #24411 [Messenger] Add a new Messenger component (sroze) - * feature #22150 [Serializer] Added a ConstraintViolationListNormalizer (lyrixx) - * feature #26639 [SecurityBundle] Added an alias from RoleHierarchyInterface to security.role_hierarchy (lyrixx) - * feature #26636 [DI] deprecate TypedReference::canBeAutoregistered() and getRequiringClass() (nicolas-grekas) - * feature #26445 [Serializer] Ignore comments when decoding XML (q0rban) - * feature #26284 [Routing] allow no-slash root on imported routes (nicolas-grekas) - * feature #26092 [Workflow] Add a MetadataStore to fetch some metadata (lyrixx) - * feature #26121 [FrameworkBundle] feature: add the ability to search a route (Simperfit) - * feature #25197 [FrameworkBundle][TwigBridge] make csrf_token() usable without forms (xabbuh) - * feature #25631 [DI] Service decoration: autowire the inner service (dunglas) - * feature #26076 [Workflow] Add transition blockers (d-ph, lyrixx) - * feature #24363 [Console] Modify console output and print multiple modifyable sections (pierredup) - * feature #26381 Transform both switchToXHR() and removeXhr() to xmlHttpRequest() (Simperfit) - * feature #26449 Make ProgressBar::setMaxSteps public (ostrolucky) - * feature #26308 [Config] Introduce BuilderAwareInterface (ro0NL) - * feature #26518 [Routing] Allow inline definition of requirements and defaults (nicolas-grekas) - * feature #26143 [Routing] Implement i18n routing (frankdejonge, nicolas-grekas) - * feature #26564 [HttpFoundation] deprecate call to Request::getSession() when Request::hasSession() returns false (fmata) - * feature #26408 Readd 'form_label_errors' block to disable errors on form labels (birkof) - * feature #25456 [Console] Make pretty the `box` style table (maidmaid) - * feature #26499 [FrameworkBundle] Allow fetching private services from test clients (nicolas-grekas) - * feature #26509 [BrowserKit] Avoid nullable values in some Client's methods (ossinkine) - * feature #26288 [FrameworkBundle] show the unregistered command warning at the end of the list command (Simperfit) - * feature #26520 Added some HTML5 features to the Symfony Profiler (javiereguiluz) - * feature #26398 [WebProfilerBundle] Display the missing translation panel by default (javiereguiluz) - * feature #23409 [Security] AuthenticationUtils::getLastUsername() return type inconsistency (vudaltsov) - * feature #26439 [Console] [DX] Fix command description/help display (noniagriconomie) - * feature #26372 Revert "feature #24763 [Process] Allow writing portable "prepared" command lines (Simperfit)" (nicolas-grekas) - * feature #26223 [FrameworkBundle] Add command to delete an item from a cache pool (pierredup) - * feature #26341 Autoconfigure service locator tag (apfelbox) - * feature #26330 [FORM] Fix HTML errors. (Nyholm) - * feature #26334 [SecurityBundle] Deprecate switch_user.stateless config node (chalasr) - * feature #26304 [Routing] support scheme requirement without redirectable dumped matcher (Tobion) - * feature #26283 [Routing] Redirect from trailing slash to no-slash when possible (nicolas-grekas) - * feature #25732 [Console] Add option to automatically run suggested command if there is only 1 alternative (pierredup) - * feature #26085 Deprecate bundle:controller:action and service:method notation (Tobion) - * feature #26175 [Security] Add configuration for Argon2i encryption (CoalaJoe) - * feature #26075 [Validator] Deprecate use of `Locale` validation constraint without setting "canonicalize" option to `true` (phansys) - * feature #26218 [MonologBridge] Allow to change level format in ConsoleFormatter (ostrolucky) - * feature #26232 [Lock] Add a TTL to refresh lock (jderusse) - * feature #26108 [Serializer] Add a MaxDepth handler (dunglas) - * feature #24778 [BrowserKit] add a way to switch to ajax for one request (Simperfit) - * feature #25605 [PropertyInfo] Added support for extracting type from constructor (lyrixx) - * feature #24763 [Process] Allow writing portable "prepared" command lines (Simperfit) - * feature #25218 [Serializer] add a constructor arguement to return csv always as collection (Simperfit) - * feature #25369 [Serializer] add a context key to return always as collection for XmlEncoder (Simperfit) - * feature #26213 [FrameworkBundle] Add support to 307/308 HTTP status codes in RedirectController (ZipoKing) - * feature #26149 Added support for name on the unit node (Nyholm) - * feature #24308 [Validator] support protocolless urls validation (MyDigitalLife) - * feature #26059 [Routing] Match 77.7x faster by compiling routes in one regexp (nicolas-grekas) - * feature #22447 [WebProfilerBundle] Imply forward request by a new X-Previous-Debug-Token header (ro0NL) - * feature #26152 [Intl] Add polyfill for Locale::canonicalize() (nicolas-grekas) - * feature #26073 [DoctrineBridge] Add support for datetime immutable types in doctrine type guesser (jvasseur) - * feature #26079 [Workflow] Remove constraints on transition/place name + Updated Dumper (lyrixx) - * feature #23617 [PropertyInfo] Add hassers for accessors prefixes (sebdec) - * feature #25997 Always show all deprecations except legacy ones when not weak (greg0ire) - * feature #25582 [Form] Support \DateTimeImmutable (vudaltsov) - * feature #24705 [Workflow] Add PlantUML dumper to workflow:dump command (Plopix) - * feature #24508 [Serializer] Fix security issue on CsvEncoder about CSV injection (welcoMattic) - * feature #25772 [Security] The AuthenticationException should implements Security's ExceptionInterface (sroze) - * feature #25164 [WebProfilerBundle] Improve controller linking (ro0NL) - * feature #22353 [Validator] Add `canonicalize` option for `Locale` validator (phansys) - * feature #26036 Added support for getting default values in Accept headers (javiereguiluz) - * feature #25780 [TwigBundle] Deprecating "false" in favor of "kernel.debug" as default value of "strict_variable" (yceruto) - * feature #23508 Deprecated the AdvancedUserInterface (iltar) - * feature #24781 [HttpFoundation] RedisSessionHandler (dkarlovi) - * feature #26028 Unwrap errors in FlattenException (derrabus) - * feature #25892 Adding an array adapter (weaverryan) - * feature #24894 [FrameworkBundle] add a notice when passing a routerInterface without warmupInterface in RouterCacheWarmer (Simperfit) - * feature #24632 [DependencyInjection] Anonymous services in PHP DSL (unkind) - * feature #25836 [HttpKernel] Make session-related services extra-lazy (nicolas-grekas) - * feature #25775 Introduce signaled process specific exception class (Soullivaneuh) - * feature #22253 [Config] allow changing the path separator (bburnichon) - * feature #25493 [Serializer] `default_constructor_arguments` context option for denormalization (Nek-) - * feature #25839 [SecurityBundle] Deprecate in_memory.user abstract service (chalasr) - * feature #24392 Display orphaned events in profiler (kejwmen) - * feature #25275 [DI] Allow for invokable event listeners (ro0NL) - * feature #25627 [DI] Add a simple CSV env var processor (dunglas) - * feature #25092 [Security] #25091 add target user to SwitchUserListener (jwmickey) - * feature #24777 [TwigBundle] Added priority to twig extensions (Brunty) - * feature #25710 [FrameworkBundle] add cache.app.simple psr simple cache (dmaicher) - * feature #25669 [Security] Fail gracefully if the security token cannot be unserialized from the session (thewilkybarkid) - * feature #25504 [Validator] Add option to pass custom values to Expression validator (ostrolucky) - * feature #25701 [FrameworkBundle] add autowiring aliases for TranslationReaderInterface, ExtractorInterface & TranslationWriterInterface (Dennis Langen) - * feature #25516 [Validator] Deprecated "checkDNS" option in Url constraint (ro0NL) - * feature #25588 Move SecurityUserValueResolver to security-http (chalasr) - * feature #25629 [Process] Make `PhpExecutableFinder` look for the `PHP_BINARY` env var (nicolas-grekas) - * feature #25562 allow autowire for http_utils class (do-see) - * feature #25478 [FrameworkBundle] add email_validation_mode option (xabbuh) - * feature #25366 [HttpKernel] Decouple exception logging from rendering (ro0NL) - * feature #25450 [PropertyAccess] add more information to NoSuchPropertyException Message (Simperfit) - * feature #25148 Pr/workflow name as graph label (shdev) - * feature #25324 [HttpFoundation] Incorrect documentation and method name for UploadedFile::getClientSize() (Simperfit) - * feature #24738 [FrameworkBundle][Routing] Use a PSR-11 container in FrameworkBundle Router (ogizanagi) - * feature #25439 Add ControllerTrait::getParameter() (chalasr) - * feature #25332 [VarDumper] Allow VarDumperTestTrait expectation to be non-scalar (romainneutron) - * feature #25301 [Console] Add box style table (maidmaid) - * feature #25415 [FrameworkBundle] Add atom editor to ide config (lexcast) - * feature #24442 [Validator] Html5 Email Validation (PurpleBooth) - * feature #25288 [DI][FrameworkBundle] Add PSR-11 "ContainerBag" to access parameters as-a-service (nicolas-grekas, sroze) - * feature #25290 [FrameworkBundle] debug:autowiring: don't list FQCN when they are aliased (nicolas-grekas) - * feature #24375 [Serializer] Serialize and deserialize from abstract classes (sroze) - * feature #25346 [DoctrineBridge] DoctrineDataCollector comments the non runnable part of the query (Simperfit) - * feature #24216 added clean option to assets install command (robinlehrmann) - * feature #25142 [Process] Create a "isTtySupported" static method (nesk) - * feature #24751 [Workflow] Introduce a Workflow interface (Simperfit) - * feature #25293 [Routing] Parse PHP constants in YAML routing files (ostrolucky) - * feature #25295 [Translation] Parse PHP constants in YAML translation files (ostrolucky) - * feature #25294 [Serializer] Parse PHP constants in YAML mappings (ostrolucky) - * feature #24637 [FrameworkBundle] Improve the DX of TemplateController when using SF 4 (dunglas) - * feature #25178 [Routing] Allow to set name prefixes from the configuration (sroze) - * feature #25237 [VarDumper] add a GMP caster in order to cast GMP resources into string or integer (Simperfit) - * feature #25166 [WebProfilerBundle] Expose dotenv variables (ro0NL) - * feature #24785 [Profiler][Translation] Logging false by default and desactivated when using the profiler (Simperfit) - * feature #24826 [FrameworkBundle] Allow to pass a logger instance to the Router (ogizanagi) - * feature #24937 [DependencyInjection] Added support for variadics in named arguments (PabloKowalczyk) - * feature #24819 [Console] add setInputs to ApplicationTester and share some code (Simperfit) - * feature #25131 [SecurityBundle][Security][Translation] trigger some deprecations for legacy methods (xabbuh) - diff --git a/CHANGELOG-4.2.md b/CHANGELOG-4.2.md deleted file mode 100644 index 40e3209d1d568..0000000000000 --- a/CHANGELOG-4.2.md +++ /dev/null @@ -1,668 +0,0 @@ -CHANGELOG for 4.2.x -=================== - -This changelog references the relevant changes (bug and security fixes) done -in 4.2 minor versions. - -To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash -To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.2.0...v4.2.1 - -* 4.2.10 (2019-06-26) - - * bug #31972 Add missing rendering of form help block. (alexsegura) - * bug #32137 [HttpFoundation] fix accessing session bags (xabbuh) - * bug #32164 [EventDispatcher] collect called listeners information only once (xabbuh) - * bug #32173 [FrameworkBundle] Fix calling Client::getProfile() before sending a request (dunglas) - * bug #32163 [DoctrineBridge] Fix type error (norkunas) - * bug #32170 [Security/Core] Don't use ParagonIE_Sodium_Compat (nicolas-grekas) - * bug #32094 [Validator] Use LogicException for missing Property Access Component in comparison constraints (Lctrs) - * bug #32123 [Form] fix translation domain (xabbuh) - * bug #32116 [FrameworkBundle] tag the FileType service as a form type (xabbuh) - * bug #32090 [Debug] workaround BC break in PHP 7.3 (nicolas-grekas) - * bug #32076 [Lock] Fix PDO prune not called (jderusse) - * bug #32071 Fix expired lock not cleaned (jderusse) - * bug #32057 [HttpFoundation] Fix SA/phpdoc JsonResponse (ro0NL) - * bug #32025 SimpleCacheAdapter fails to cache any item if a namespace is used (moufmouf) - * bug #32037 [Form] validate composite constraints in all groups (xabbuh) - * bug #32007 [Serializer] Handle true and false appropriately in CSV encoder (battye) - * bug #32000 [Routing] fix absolute url generation when scheme is not known (Tobion) - * bug #32024 [VarDumper] fix dumping objects that implement __debugInfo() (nicolas-grekas) - * bug #31962 Fix reporting unsilenced deprecations from insulated tests (nicolas-grekas) - * bug #31925 [Form] fix usage of legacy TranslatorInterface (nicolas-grekas) - * bug #31908 [Validator] fix deprecation layer of ValidatorBuilder (nicolas-grekas) - * bug #31894 Fix wrong requirements for ocramius/proxy-manager in root composer.json (henrikvolmer) - * bug #31865 [Form] Fix wrong DateTime on outdated ICU library (aweelex) - * bug #31879 [Cache] Pass arg to get callback everywhere (fancyweb) - * bug #31863 [HttpFoundation] Fixed case-sensitive handling of cache-control header in RedirectResponse constructor (Ivo) - * bug #31869 Fix json-encoding when JSON_THROW_ON_ERROR is used (nicolas-grekas) - * bug #31868 [HttpKernel] Fix handling non-catchable fatal errors (nicolas-grekas) - * bug #31860 [HttpFoundation] work around PHP 7.3 bug related to json_encode() (nicolas-grekas) - * bug #31407 [Security] added support for updated "distinguished name" format in x509 authentication (Robert Kopera) - * bug #31786 [Translation] Fixed case sensitivity of lint:xliff command (javiereguiluz) - * bug #31757 [DomCrawler] Fix type error with null Form::$currentUri (chalasr) - * bug #31654 [HttpFoundation] Do not set X-Accel-Redirect for paths outside of X-Accel-Mapping (vilius-g) - -* 4.2.9 (2019-05-28) - - * bug #31584 [Workflow] Do not trigger extra guards (lyrixx) - * bug #31632 [Messenger] Use "real" memory usage to honor --memory-limit (chalasr) - * bug #31599 [Translation] Fixed issue with new vs old TranslatorInterface in TranslationDataCollector (althaus) - * bug #31349 [WebProfilerBundle] Use absolute URL for profiler links (Alumbrados) - * bug #31541 [DI] fix using bindings with locators of service subscribers (nicolas-grekas) - * bug #31568 [Process] Fix infinite waiting for stopped process (mshavliuk) - * bug #31551 [ProxyManager] isProxyCandidate() does not take into account interfaces (andrerom) - * bug #31335 [Doctrine] Respect parent class contract in ContainerAwareEventManager (Koc) - * bug #31421 [Routing][AnnotationClassLoader] fix utf-8 encoding in default route name (przemyslaw-bogusz) - * bug #31510 Use the current working dir as default first arg in 'link' binary (lyrixx) - * bug #31524 [HttpFoundation] prevent deprecation when filesize matches error code (xabbuh) - * bug #31535 [Debug] Wrap call to require_once in a try/catch (lyrixx) - * bug #31477 [PropertyAccess] Add missing property to PropertyAccessor (vudaltsov) - * bug #31479 [Cache] fix saving unrelated keys in recursive callback calls (nicolas-grekas) - * bug #31438 [Serializer] Fix denormalization of object with variadic constructor typed argument (ajgarlag) - * bug #31445 [Messenger] Making cache rebuild correctly when message subscribers change (weaverryan) - * bug #31442 [Validator] Fix finding translator parent definition in compiler pass (deguif) - * bug #31475 [HttpFoundation] Allow set 'None' on samesite cookie flag (markitosgv) - * bug #31456 Remove deprecated usage of some Twig features (fabpot) - * bug #31207 [Routing] Fixed unexpected 404 NoConfigurationException (yceruto) - * bug #31261 [Console] Commands with an alias should not be recognized as ambiguous when using register (Simperfit) - * bug #31371 [DI] Removes number of elements information in debug mode (jschaedl) - * bug #31418 [FrameworkBundle] clarify the possible class/interface of the cache (xabbuh) - * bug #31411 [Intl] Fix root fallback locale (ro0NL) - * bug #31377 [Console] Fix auto-complete for ChoiceQuestion (multi-select answers) (battye) - * bug #31380 [WebProfilerBundle] Don't filter submitted IP values (javiereguiluz) - -* 4.2.8 (2019-05-01) - - * bug #31338 Revert "bug #30620 [FrameworkBundle][HttpFoundation] make session service resettable (dmaicher)" (nicolas-grekas) - * bug #31326 fix ConsoleFormatter - call to a member function format() on string (keksa) - * bug #31331 [Workflow] Fixed dumping when many transition with same name exist (lyrixx) - * bug #31302 [FramworkBundle] mark any env vars found in the ide setting as used (nicolas-grekas) - * bug #31290 [TwigBundle] Use the apply tag instead of the filter tag (greg0ire) - * bug #31275 [Translator] Preserve default domain when extracting strings from php files (Stadly) - * bug #31240 Fix url matcher edge cases with trailing slash (arjenm) - * bug #31201 [Form] resolve class name parameters (xabbuh) - * bug #31213 [WebProfilerBundle] Intercept redirections only for HTML format (javiereguiluz) - * bug #31210 [PhpUnitBridge] fix reading phpunit.xml on bootstrap (nicolas-grekas) - * bug #31023 [Routing] Fix route URL generation in CLI context (X-Coder264) - * bug #31117 [FrameworkBundle] fix math depth handler configuration (Raulnet) - * bug #31182 [Routing] fix trailing slash matching with empty-matching trailing vars (nicolas-grekas) - * bug #31167 [Routing] fix matching trailing vars with defaults (nicolas-grekas) - * bug #31164 [Validator] fix LegacyTranslatorProxy (nicolas-grekas) - * bug #31156 [FrameworkBundle] call method with Translator component only (xabbuh) - -* 4.2.7 (2019-04-17) - - * bug #31107 [Routing] fix trailing slash redirection with non-greedy trailing vars (nicolas-grekas) - * bug #31108 [FrameworkBundle] decorate the ValidatorBuilder's translator with LegacyTranslatorProxy (nicolas-grekas) - * bug #31121 [HttpKernel] Fix get session when the request stack is empty (yceruto) - * bug #31084 [HttpFoundation] Make MimeTypeExtensionGuesser case insensitive (vermeirentony) - * bug #31142 Revert "bug #30423 [Security] Rework firewall's access denied rule (dimabory)" (chalasr) - * security #cve-2019-10910 [DI] Check service IDs are valid (nicolas-grekas) - * security #cve-2019-10909 [FrameworkBundle][Form] Fix XSS issues in the form theme of the PHP templating engine (stof) - * security #cve-2019-10912 [Cache][PHPUnit Bridge] Prevent destructors with side-effects from being unserialized (nicolas-grekas) - * security #cve-2019-10911 [Security] Add a separator in the remember me cookie hash (pborreli) - * security #cve-2019-10913 [HttpFoundation] reject invalid method override (nicolas-grekas) - -* 4.2.6 (2019-04-16) - - * bug #31088 [DI] fix removing non-shared definition while inlining them (nicolas-grekas) - * bug #29944 [DI] Overriding services autowired by name under _defaults bind not working (przemyslaw-bogusz, renanbr) - * bug #30993 [FrameworkBundle] Fix for Controller DEPRECATED when using composer --optimized (aweelex) - * bug #31076 [HttpKernel] Fixed LoggerDataCollector crashing on empty file (althaus) - * bug #31071 property normalizer should also pass format and context to isAllowedAttribute (dbu) - * bug #31059 Show more accurate message in profiler when missing stopwatch (linaori) - * bug #31026 [Serializer] Add default object class resolver (jdecool) - * bug #31031 [Serializer] MetadataAwareNameConverter: Do not assume that property names are strings (soyuka) - * bug #31043 [VarExporter] support PHP7.4 __serialize & __unserialize (nicolas-grekas) - * bug #30423 [Security] Rework firewall's access denied rule (dimabory) - * bug #31020 [VarExporter] fix exporting classes with private constructors (nicolas-grekas) - * bug #31012 [Process] Fix missing $extraDirs when open_basedir returns (arsonik) - * bug #30852 [Console] fix buildTableRows when Colspan is use with content too long (Raulnet) - * bug #30950 [Serializer] Also validate callbacks when given in the normalizer context (dbu) - * bug #30907 [Serializer] Respect ignored attributes in cache key of normalizer (dbu) - * bug #30085 Fix TestRunner compatibility to PhpUnit 8 (alexander-schranz) - * bug #30999 Fix dark themed componnents (ro0NL) - * bug #30977 [serializer] prevent mixup in normalizer of the object to populate (dbu) - * bug #30976 [Debug] Fixed error handling when an error is already handled when another error is already handled (5) (lyrixx) - * bug #30979 Fix the configurability of CoreExtension deps in standalone usage (stof) - * bug #30918 [Cache] fix using ProxyAdapter inside TagAwareAdapter (dmaicher) - * bug #30961 [Form] fix translating file validation error message (xabbuh) - * bug #30951 Handle case where no translations were found (greg0ire) - * bug #29800 [Validator] Only traverse arrays that are cascaded into (corphi) - * bug #30921 [Translator] Warm up the translations cache in dev (tgalopin) - * bug #30922 [TwigBridge] fix horizontal spacing of inlined Bootstrap forms (xabbuh) - * bug #30860 [Profiler] Fix dark theme elements color (dFayet) - * bug #30895 [Form] turn failed file uploads into form errors (xabbuh) - * bug #30919 [Translator] Fix wrong dump for PO files (deguif) - * bug #30889 [DependencyInjection] Fix a wrong error when using a factory (Simperfit) - * bug #30911 [Console] Fix table trailing backslash (maidmaid) - * bug #30903 [Messenger] Uses the `SerializerStamp` when deserializing the envelope (sroze) - * bug #30879 [Form] Php doc fixes and cs + optimizations (Jules Pietri) - * bug #30883 [Console] Fix stty not reset when aborting in QuestionHelper::autocomplete() (Simperfit) - * bug #30878 [Console] Fix inconsistent result for choice questions in non-interactive mode (chalasr) - * bug #30825 [Routing] Fix: annotation loader ignores method's default values (voronkovich) - -* 4.2.5 (2019-04-02) - - * bug #30660 [Bridge][Twig] DebugCommand - fix escaping and filter (SpacePossum) - * bug #30784 [Translator] Add resource path to exception message for schema valida… (jschaedl) - * bug #30720 Fix getSetMethodNormalizer to correctly ignore the attributes specified in "ignored_attributes" (Emmanuel BORGES) - * bug #30749 [Serializer] Added check of constuctor modifiers to AbstractNormalizer (NekaKawaii) - * bug #30776 [Routing] Fix routes annotation loading with glob pattern (snoob) - * bug #30773 [DependencyInjection] Fix hardcoded hotPathTagName (jderusse) - * bug #30737 [Validator] Improve constraint default option check (vudaltsov) - * bug #30736 [Validator] Fix annotation default for @Count and @Length (vudaltsov) - * bug #30621 [Cache] Ensure key exists before checking array value (jrjohnson) - * bug #30711 [Serializer] Use object class resolver when extracting attributes (joelwurtz) - * bug #30641 [FrameworkBundle] properly describe service definitions without class (xabbuh) - * bug #30620 [FrameworkBundle][HttpFoundation] make session service resettable (dmaicher) - * bug #30648 Debug finalized config in debug:config (ro0NL) - * bug #30640 [Phpunit] fixed support for PHP 5.3 (fabpot) - * bug #30616 Fix case when multiple loaders are providing paths for the same namespace (yceruto) - * bug #30595 Do not validate child constraints if form has no validation groups (maryo) - * bug #30440 [TwigBridge] Fix DebugCommand when chain loader is involved (yceruto) - * bug #30479 Check if Client exists when test.client does not exist, to provide clearer exception message (SerkanYildiz) - * bug #30597 [Form] Added ResetInterface to CachingFactoryDecorator (HeahDude) - * bug #30593 Fixed usage of TranslatorInterface in form extension (fixes #30591) (althaus) - * feature #30584 [Intl] Add compile binary (ro0NL) - * bug #30487 Fix Cache error while using anonymous class (Emmanuel BORGES) - * bug #30576 [Cache] fix LockRegistry (nicolas-grekas) - * bug #30548 Correct language code for ukrainian language (stanleyk) - * bug #30518 [Cache] Fix perf when using RedisCluster by reducing roundtrips to the servers (nicolas-grekas) - * bug #30515 [Cache] Only delete one key at a time when on Predis + Cluster (andrerom) - * bug #30511 [Process] fix using argument $php of new PhpProcess() (nicolas-grekas) - * bug #30507 [Routing] Fixed XML options resolution (Jules Pietri) - * bug #30506 [TwigBridge] remove deprecation triggered when using Twig 2.7 (nicolas-grekas) - * bug #30496 [PHPUnit-Bridge] override some Composer environment variables (nicoweb) - * bug #30505 [TwigBridge] Remove usages of the spaceless tag (nicolas-grekas) - * bug #30466 [Messenger] Make 'headers' key optional for encoded messages (yceruto) - * bug #30474 compatibility with phpunit8 (garak) - * bug #30497 [HttpKernel] Change default log level for output streams (yceruto) - * bug #30498 [translation] Update defaut format from yml to yaml (GaryPEGEOT) - * bug #30490 Don't resolve the Deprecation error handler mode until a deprecation is triggered (Emmanuel BORGES) - * bug #30396 [Form] Avoid a form type extension appears many times in debug:form (markitosgv) - * bug #30361 [PropertyInfo] Fix undefined variable fromConstructor when passing context to getTypes (mantis) - * bug #30361 [PropertyInfo] Fix undefined variable fromConstructor when passing context to getTypes (mantis, OskarStark) - * bug #30410 [Monolog] Really reset logger when calling logger::reset() (lyrixx) - * bug #30437 [Debug] detect annotations before blank docblock lines (xabbuh) - * bug #30417 Autoconfig: don't automatically tag decorators (dunglas) - * bug #30392 [PropertyAccess] Fixed PropertyPathBuilder remove that fails to reset internal indexes (GregOriol) - -* 4.2.4 (2019-03-03) - - * bug #30383 [WebProfilerBundle] toolbar: invisible route name in Firefox (inmarelibero) - * bug #26532 [HttpKernel] Correctly merging cache directives in HttpCache/ResponseCacheStrategy (aschempp) - * bug #30363 Fixed the DebugClassLoader compatibility with eval()'d code on Darwin (skalpa) - * bug #30329 [Form] IntegerType: reject submitted non-integer numbers (xabbuh) - * bug #30331 [Cache] fix warming up cache.system and apcu (nicolas-grekas) - * bug #30347 [Security] Change FormAuthenticator if condition (PReimers) - * bug #30354 [Console] handles multi-byte characters in autocomplete (jls-esokia) - * bug #30351 Fix getItems() performance issue with RedisCluster (php-redis) (andrerom) - * bug #30350 [VarDumper] Keep a ref to objects to ensure their handle cannot be reused while cloning (nicolas-grekas) - * bug #30327 [HttpKernel] Fix possible infinite loop of exceptions (enumag) - * bug #27601 [Routing] fix URL generation with look-around requirements (nasimnabavi) - * bug #30277 [Console] Prevent ArgvInput::getFirstArgument() from returning an option value (chalasr) - * bug #29981 [Security] Complain about an empty decision strategy (corphi) - * bug #29822 [EventDispatcher] Fix unknown priority (ro0NL) - * bug #30324 [Validator] Fixed duplicate UUID (ralfkuehnel) - * bug #30265 [Form] do not validate non-submitted form fields in PATCH requests (xabbuh) - * bug #30313 Avoid mutating the Finder when building the iterator (stof) - * bug #30294 [FrameworkBundle] Fix Descriptor throwing on non existent parent (GuilhemN) - * bug #30271 [Console] Fix command testing with missing user inputs (chalasr) - * bug #30278 Remove unnecessary ProgressBar stdout writes (fixes flickering) (ostrolucky) - * bug #30274 [VarDumper] fix serializing Stub instances (nicolas-grekas) - * bug #30273 [Validator] Added missing use statement for UnexpectedTypeException (devrck) - * bug #30247 Don't resolve the Deprecation error handler mode until a deprecation is triggered (ossinkine) - * bug #30264 [Debug][ErrorHandler] Preserve next error handler (fancyweb) - * bug #30245 fix lost namespace in eval (fizzka) - * bug #30090 [FrameworkBundle] add constraint validators before optimizations (xabbuh) - * feature #30126 [Form] forward valid numeric values to transform() (xabbuh) - * bug #30122 [Security] fix switch user without having current token (Antoine Lamirault) - * bug #30136 use PropertyAccessorInterface instead of PropertyAccessor (nick-zh) - * bug #30124 Fix KernelTestCase compatibility for PhpUnit 8 (bis) (nicolas-grekas) - * bug #30061 [Form] render integer types with grouping as text input (xabbuh) - * bug #30063 [Form] don't lose int precision with not needed type casts (xabbuh) - * bug #30076 [Form] ignore _method forms in NativeRequestHandler (xabbuh) - * bug #30084 Fix KernelTestCase compatibility for PhpUnit 8 (alexander-schranz) - * bug #30093 [DependencyInjection] add $lazyLoad context to the generated code for lazy non-shared service by PhpDumper (XuruDragon) - * bug #30102 [Workflow] Graphviz dumper escape not always a string (Korbeil) - * bug #29884 [Form] CsrfValidationListener marks the token as invalid if it is not a string (umpirsky) - * bug #30058 [Routing] fix perf issue when dumping large number of routes (nicolas-grekas) - * bug #30062 [Form] do not overwrite the constraint being evaluated (xabbuh) - * bug #30074 Fix wrong value in file id attribute for Xliff 2.0 (deguif) - * bug #30078 [Messenger] Fix DataCollector template (ottaviano) - * bug #30087 [PhpUnitBridge] fix PHP 5.3 compat (nicolas-grekas) - -* 4.2.3 (2019-02-03) - - * bug #30050 [Cache] fix pruning pdo cache for vendors that throw on execute (bendavies) - * bug #30046 [DI] Fix dumping Doctrine-like service graphs (nicolas-grekas) - * bug #30028 [Form] fix some docblocks and type checks (xabbuh) - * bug #30037 Disable Twig in the profiler menu when Twig is not used (javiereguiluz) - * bug #30026 [VarDumper] dont implement Serializable in Stub (nicolas-grekas) - * bug #30034 [Config] ensure moving away from Serializable wont break cache:clear (nicolas-grekas) - * bug #29532 [Messenger] fixed RabbitMQ arguments not passed as integer values (thePanz) - * bug #30013 [Routing] dont redirect routes with greedy trailing vars with no explicit slash (nicolas-grekas) - * bug #30006 [Security] don't do nested calls to serialize() (nicolas-grekas, Renan) - * bug #30007 [FrameworkBundle] Support use of hyphen in asset package name (damaya, XuruDragon) - * bug #30004 Fix format strings for deprecation notices (TysonAndre) - * bug #29984 [VarDumper] Fixed search bar (ro0NL) - * bug #29764 [HttpFoundation] Check file exists before unlink (adam-mospan) - * bug #29783 [HttpFoundation] MemcachedSessionHandler::close() must close connection (grachevko) - * bug #29794 Always pass $key to NullAdapter->createCacheItem (TysonAndre) - * bug #29844 [Console] Fixed #29835: ConfirmationQuestion with default true for answer '0' (mrthehud) - * bug #29869 [Debug][ErrorHandler] Preserve our error handler when a logger sets another one (fancyweb) - * bug #29900 [Cache] PDO-based cache pool table autocreation does not work (errogaht) - * bug #29926 [Form] Changed UrlType input type to text when default_protocol is not null (MatTheCat) - * bug #29961 [Translation] Concatenated translation messages (Stadly) - * bug #29847 [Cache] fix used variable name (xabbuh) - * bug #29920 [Debug][DebugClassLoader] Match more cases for final, deprecated and internal classes / methods extends (fancyweb) - * bug #29922 Avoid dots in generated class names (derrabus) - * bug #29863 [Security] Do not mix password_*() API with libsodium one (chalasr) - * bug #29894 [DependencyInjection] the string "0" is a valid service identifier (xabbuh) - * bug #29885 Update MimeType extensions (fabpot) - * bug #29875 [TwigBridge] fix compatibility with Twig >= 2.6.1 (xabbuh) - * bug #29873 [Debug] remove return type hint for PHP 5 compatibility (xabbuh) - * bug #29837 Fix SwiftMailerHandler to support Monolog's latest reset functionality (Seldaek) - * bug #29853 Revert "bug #29597 [DI] fix reporting bindings on overriden services as unused" (mmarynich) - * bug #29833 [DebugClassLoader] expose proxyfied findFile() method (fancyweb) - -* 4.2.2 (2019-01-06) - - * bug #29494 [HttpFoundation] Fix request uri when it starts with double slashes (alquerci) - * bug #29697 [DI] Fixed wrong factory method in exception (Wojciech Gorczyca) - * bug #29679 [HttpKernel] Correctly Render Signed URIs Containing Fragments (zanbaldwin) - * bug #29754 Ensure final input of CommandTester works with default (Firehed) - * bug #29695 [Form] Do not ignore the choice groups for caching (vudaltsov) - * bug #29738 [Intl] handle null date and time types (xabbuh) - * bug #29708 [FrameworkBundle] access the container getting it from the kernel (xabbuh) - * bug #29676 [HttpFoundation] Fix erasing cookies issue (eiannone) - * bug #29741 [VarExporter] fix exporting array indexes (xabbuh) - * bug #29704 [FrameworkBundle] improve errors in tests missing the BrowserKit component (xabbuh) - * bug #29721 [SecurityBundle] Fix traceable voters (ro0NL) - * bug #29617 [Console] Add specific replacement for help text in single command applications (codedmonkey) - * bug #29714 [Event Dispatcher] fixed 29703: TraceableEventDispatcher reset() callStack to null (mlievertz) - * bug #29597 [DI] fix reporting bindings on overriden services as unused (nicolas-grekas) - * bug #29639 [Yaml] detect circular references (xabbuh) - * bug #29644 [Cache] fix bad optim (nicolas-grekas) - * bug #29648 [Cache] fix Simple\Psr6Cache proxying of metadata (nicolas-grekas) - * bug #29569 [FrameworkBundle] decouple debug:autowiring from phpdocumentor/reflection-docblock (SerkanYildiz) - * bug #29546 [DI] map snake-case ids of service subscribers to camel-case autowiring aliases (nicolas-grekas) - * bug #29409 Fix env fallback to an unresolved variable (jderusse) - * bug #29626 [Routing] fix trailing slash redirections involving a trailing var (nicolas-grekas) - * bug #29411 [EventDispatcher] Revers event tracing order (ro0NL) - * bug #29533 Fixed public directory when configured in composer.json (alexander-schranz) - * bug #29619 [Console] OutputFormatter: move strtolower to createStyleFromString (ogizanagi) - * bug #29621 [Security] Prefer clone() over unserialize(serialize()) for user refreshment (chalasr) - * bug #29591 [Cache] Fix undefined variable in ArrayTrait (eXtreme) - * bug #29558 [Messenger] Restore message handlers laziness (chalasr) - * bug #29589 [VarExporter] dont call userland code with uninitialized objects (nicolas-grekas) - * bug #29542 [Routing] fix dumping same-path routes with placeholders (nicolas-grekas) - * bug #29587 [Debug] ignore underscore vs backslash namespaces in DebugClassLoader (nicolas-grekas) - * bug #29584 [FrameworkBundle] fix describing routes with no controllers (nicolas-grekas) - * bug #29582 [DI] move RegisterServiceSubscribersPass before DecoratorServicePass (kbond) - * bug #29527 [TwigBridge][Form] Prevent multiple rendering of form collection prototypes (Shoplifter) - * bug #29571 [Yaml] ensures that the mb_internal_encoding is reset to its initial value (Jörn Lang) - * bug #29513 [Hackday][Serializer] Deserialization ignores argument type hint from phpdoc for array in constructor argument (karser) - * bug #29323 [Security] defer log message in guard authenticator (eschultz-magix) - * bug #29539 [WebProfilerBundle][TwigBundle] CSS fixes (ro0NL) - * bug #29543 [Cache] Don't erase processed redis dsn (chalasr) - * bug #29531 [Validator] Added IBAN format for Vatican City State (raulfraile) - * bug #29501 [Form] filter out invalid language values (xabbuh) - * bug #29307 [Form] Filter arrays out of scalar form types (nicolas-grekas) - * bug #29500 [Form] filter out invalid Intl values (xabbuh) - * bug #29499 [Validator] Fixed grouped composite constraints (HeahDude) - -* 4.2.1 (2018-12-06) - - * security #cve-2018-19790 [Security\Http] detect bad redirect targets using backslashes (xabbuh) - * security #cve-2018-19789 [Form] Filter file uploads out of regular form types (nicolas-grekas) - * bug #29481 [TwigBridge] Deprecating legacy Twig paths in DebugCommand and simplifications (yceruto) - * bug #29436 [Cache] Fixed Memcached adapter doClear()to call flush() (raitocz) - * bug #29482 Fixes sprintf(): Too few arguments in MessageFormatter::choiceFormat (stephanedelprat) - * bug #29461 [Contracts] extract LocaleAwareInterface out of TranslatorInterface (nicolas-grekas) - * bug #29446 [VarExporter] fix dumping private properties from abstract classes (nicolas-grekas) - * bug #29441 [Routing] ignore trailing slash for non-GET requests (nicolas-grekas) - * bug #29445 [FrameworkBundle] Fix empty output for debug:autowiring when reflection-docblock is not installed (chalasr) - * bug #29444 [Workflow] Fixed BC break for Workflow metadata (lyrixx) - * bug #29432 [DI] dont inline when lazy edges are found (nicolas-grekas) - * bug #29413 [Serializer] fixed DateTimeNormalizer to maintain microseconds when a different timezone required (rvitaliy) - * bug #29424 [Routing] fix taking verb into account when redirecting (nicolas-grekas) - * bug #29418 [VarExporter] fix dumping protected property from abstract classes (nicolas-grekas) - * bug #29414 [DI] Fix dumping expressions accessing single-use private services (chalasr) - * bug #28853 [LDAP] Add TIMEOUT Option to LDAP Connection Options (lmatte7) - * bug #29399 [FrameworkBundle] define doctrine as default_pdo_provider only if the package is installed (nicolas-grekas) - * bug #29375 [Validator] Allow `ConstraintViolation::__toString()` to expose codes that are not null or emtpy strings (phansys) - * bug #29376 [EventDispatcher] Fix eventListener wrapper loop in TraceableEventDispatcher (jderusse) - * bug #29386 undeprecate the single-colon notation for controllers (fbourigault) - * bug #29393 [DI] fix edge case in InlineServiceDefinitionsPass (nicolas-grekas) - * bug #29394 [Config] fix path exclusion during glob discovery (nicolas-grekas) - * bug #29395 [FrameworkBundle][Messenger] Restore check for messenger serializer default id (ogizanagi) - * bug #29380 [Routing] fix greediness of trailing slash (nicolas-grekas) - -* 4.2.0 (2018-11-30) - - * bug #29343 [Form] Handle all case variants of "nan" when parsing a number (mwhudson, xabbuh) - * bug #29373 [Routing] fix trailing slash redirection (nicolas-grekas) - * bug #29355 [PropertyAccess] calculate cache keys for property setters depending on the value (xabbuh) - * bug #29369 [DI] fix combinatorial explosion when analyzing the service graph (nicolas-grekas) - * bug #29349 [Debug] workaround opcache bug mutating "$this" !?! (nicolas-grekas) - * bug #29344 Fixes sprintf(): Too few arguments in Translator (stephanedelprat) - * bug #29318 [Console] Move back root exception to stack trace in verbose mode (chalasr) - -* 4.2.0-RC1 (2018-11-26) - - * bug #29332 [PropertyAccess] make cache keys encoding bijective (nicolas-grekas) - * bug #29298 [Routing] fix trailing slash redirection when using RedirectableUrlMatcher (nicolas-grekas) - * bug #29297 [Routing] fix trailing slash redirection when using RedirectableUrlMatcher (nicolas-grekas) - * bug #29313 [PropertyAccessor] fix encoding of cache keys (nicolas-grekas) - * bug #29328 [HttpKernel] handle anonymous classes when generating the dumped container class name (nicolas-grekas) - * bug #28917 [DoctrineBridge] catch errors while converting to db values in data collector (alekitto) - * bug #29317 [WebProfiler] Detect non-file paths in file viewer (ro0NL) - * bug #29305 [EventDispatcher] Unwrap wrapped listeners internally (ro0NL) - * bug #29302 [Contracts][Cache] allow retrieving metadata of cached items (nicolas-grekas) - * bug #29315 [DI] fix copying expression providers when analyzing the service graph (nicolas-grekas) - * bug #27314 [DoctrineBridge] fix case sensitivity issue in RememberMe\DoctrineTokenProvider (PF4Public) - * bug #29310 [MonologBridge] Return empty list for unknown requests (ro0NL) - * bug #29316 [VarDumper] Fix ClassStub ellipsis (ro0NL) - * bug #29300 [Translation] fix dumping catalogues cache (nicolas-grekas) - * bug #29308 [Translation] Use XLIFF source rather than resname when there's no target (thewilkybarkid) - * bug #26244 [BrowserKit] fixed BC Break for HTTP_HOST header (brizzz) - * bug #28147 [DomCrawler] exclude fields inside "template" tags (Gorjunov) - * bug #29260 [Lock] Fixed PdoStore::putOffExpiration(), PdoStore::getHashedKey() (PavelPrischepa) - * bug #29222 [Dotenv] properly parse backslashes in unquoted env vars (xabbuh) - * bug #29256 [HttpFoundation] Fixed absolute Request URI with default port (thomasbisignani) - * bug #29274 [Routing] Remove duplicate schemes and methods for invokable controllers (claudusd) - * bug #29285 [HttpKernel][WebProfilerBundle] Getting the cached client mime type instead of guessing it again (yceruto) - * bug #29271 [HttpFoundation] Fix trailing space for mime-type with parameters (Sascha Dens) - * feature #29167 [Messenger] Add a trait for synchronous query & command buses (ogizanagi) - * bug #29243 [Cache] fix optimizing Psr6Cache for AdapterInterface pools (nicolas-grekas) - * bug #29247 [DI] fix taking lazy services into account when dumping the container (nicolas-grekas) - * bug #29249 [Form] Fixed empty data for compound date interval (HeahDude) - * bug #29265 [Bridge/PhpUnit] Use composer to download phpunit (nicolas-grekas) - * bug #28769 [FrameworkBundle] deal with explicitly enabled workflow nodes (xabbuh) - -* 4.2.0-BETA2 (2018-11-16) - - * bug #29190 [Debug][HttpKernel] remove frames added by DebugClassLoader in stack traces (nicolas-grekas) - * bug #29233 [FrameworkBundle] metadata_update_threshold default value must be an int (dunglas) - * bug #29226 [Messenger] Improved message when handler class does not exist (neeckeloo) - * bug #29223 [Validator] Added the missing constraints instance checks (thomasbisignani) - * bug #28966 [PropertyAccessor] Fix unable to write to singular property using setter while plural adder/remover exist (karser) - * bug #29182 [Form] Fixed empty data for compound date types (HeahDude) - * bug #29224 [SecurityBundle] Fix remember-me cookie framework inheritance when session is disabled (fbourigault) - * bug #29220 [Translation] make intl+icu format seamless by handling it in MessageCatalogue (nicolas-grekas) - * feature #29166 [Messenger] Add handled & sent stamps (ogizanagi) - * bug #29209 [VarExporter] fix handling of __sleep() (nicolas-grekas) - * bug #29196 [Messenger] Fix collecting messages (ro0NL) - * bug #29205 [Dotenv] skip loading "local" env twice (nicolas-grekas) - * bug #29204 [FrameworkBundle][WebServerBundle] Revert deprecation of --env and --no-debug console options (chalasr) - * bug #29191 [Routing] generate(null) should throw an exception (nicolas-grekas) - * bug #29199 [FrameworkBundle] conflict with Dotenv <4.2 to simplify recipes (nicolas-grekas) - * bug #29197 Revert "bug #29154 [FrameworkBundle] Define APP_ENV/APP_DEBUG from argv via Application::bootstrapEnv() (nicolas-grekas) - * bug #29185 [Form] Fixed keeping hash of equal \DateTimeInterface on submit (HeahDude) - * bug #29183 [HttpKernel] Fix collecting uploaded files (ro0NL) - * bug #29141 [Workflow] Fixed bug of buildTransitionBlockerList when many transition are enabled (Tetragramat, lyrixx) - * bug #29137 [Workflow][FrameworkBundle] fixed guard event names for transitions (destillat, lyrixx) - * bug #29184 [WebProfilerBundle] Fix theme settings (ro0NL) - * feature #29159 [Messenger] collect all stamps added on Envelope as collections (nicolas-grekas) - * bug #29171 [Dotenv] load .env.dist when it exists and .env is not found (nicolas-grekas) - * bug #28731 [Form] invalidate forms on transformation failures (xabbuh) - * bug #29152 [Config] Unset key during normalization (ro0NL) - * bug #29165 [DI] align IniFileLoader to PHP bugfix #76965 (nicolas-grekas) - * bug #29154 [FrameworkBundle] Define APP_ENV/APP_DEBUG from argv via Application::bootstrapEnv() (chalasr) - * bug #29129 [Dotenv] add loadEnv(), a smoother alternative to loadForEnv() (nicolas-grekas) - * bug #29113 [Routing] fix dumping conditions that use the request (nicolas-grekas) - * bug #29115 Change button_widget class to btn-primary (neFAST) - * bug #29131 [Dotenv] dont use getenv() to read SYMFONY_DOTENV_VARS (nicolas-grekas) - * bug #29057 [HttpFoundation] replace any preexisting Content-Type headers (nicolas-grekas) - * bug #29076 [Serializer] Allow null values when denormalizing with constructor missing data (danut007ro) - * bug #29128 [FrameworkBundle] Cleaning translation commands and fix a bug for --all option (yceruto) - * bug #29104 [DI] fix dumping inlined services (nicolas-grekas) - * bug #29054 [VarDumper] fix dump of closures created from callables (nicolas-grekas) - * bug #29102 [DI] fix GraphvizDumper ignoring inline definitions (nicolas-grekas) - * bug #29090 LoggingTranslator should implement Symfony\Contracts\Translation\TranslatorInterface (desmax) - * bug #29095 [TwigBridge] require the needed symfony/contracts package (xabbuh) - * bug #29107 [DI] dont track classes/interfaces used to compute autowiring error messages (nicolas-grekas) - * bug #29094 Add samesite attribute to session cookie after session migration (rpkamp) - * bug #29080 [FrameworkBundle] fix deps (ro0NL) - -* 4.2.0-BETA1 (2018-11-03) - - * feature #28622 [VarDumper] add caster for Memcached (jschaedl) - * feature #29042 [DI] use filter_var() instead of XmlUtils::phpize() in EnvVarProcessor (nicolas-grekas) - * feature #29047 Revert "[HttpFoundation] Adds getAcceptableFormats() method for Request" (Tobion) - * feature #29046 [Bridge/Doctrine] remove workarounds from the past (nicolas-grekas) - * feature #29022 [Cache] allow to skip saving the computed value when using CacheInterface::get() (nicolas-grekas) - * feature #29010 [Messenger] make senders and handlers subscribing to parent interfaces receive *all* matching messages, wildcard included (nicolas-grekas) - * feature #29006 [Messenger] make TraceableMiddleware decorate a StackInterface instead of each middleware to free the callstack from noisy frames (nicolas-grekas) - * feature #28970 [FrameworkBundle] make debug:autowiring list useful services and their description (nicolas-grekas) - * feature #28952 [Translation] allow using the ICU message format using domains with the "+intl-icu" suffix (nicolas-grekas) - * feature #27914 [Security][SecurityBundle] Add voter individual decisions to profiler (l-vo) - * feature #28985 [Messenger] Move MiddlewareTestCase in Test ns (ogizanagi) - * feature #28892 [FrameworkBundle] Deprecate support for legacy directories in Translation comands (chalasr) - * feature #28854 [VarDumper] Scroll into view when searching (ro0NL) - * feature #28997 [FrameworkBundle] Deprecating support for legacy translations directory (yceruto) - * feature #28983 [Messenger] make dispatch(), handle() and send() methods return Envelope (nicolas-grekas) - * feature #28533 [DotEnv] Add a new loadForEnv() method mimicking Ruby's dotenv behavior (dunglas) - * feature #28943 [Messenger] Add `StackInterface`, allowing to unstack the call stack (nicolas-grekas) - * feature #28860 [Form] Deprecate TimezoneType regions option (ro0NL) - * feature #28945 [Messenger] remove AllowNoHandlerMiddleware in favor of a constructor argument on HandleMessageMiddleware (nicolas-grekas) - * feature #28947 [Messenger] remove classifying sub-namespaces in favor of semantic ones (nicolas-grekas) - * feature #27917 [Validator] catch any UnexpectedValueException on validation (xabbuh) - * feature #28875 [FWBundle] Add a new method AbstractController::addLink() (dunglas) - * feature #28934 [WebProfilerBundle] Add channel log filter (ro0NL) - * feature #28939 [WebProfilerBundle] Remove application name (ro0NL) - * feature #28709 [Serializer] Refactor and uniformize the config by introducing a default context (dunglas) - * feature #28914 [Messenger] make Envelope first class citizen for middleware handlers (nicolas-grekas) - * feature #28909 [Messenger] made dispatch() and handle() return void (nicolas-grekas) - * feature #28936 [WebProfilerBundle] Replay referer URL (ro0NL) - * feature #28893 [TwigBundle] Fix usage of TwigBundle without FrameworkBundle (tgalopin) - * feature #28891 [TwigBundle] Deprecating support for legacy templates directories (yceruto) - * feature #28911 [Messenger] rename "envelope items" and move them in the "Stamp" namespace (nicolas-grekas) - * feature #27043 [Form][TwigBridge] Add help_attr (mpiot) - * feature #28810 [HttpKernel] Deprecate usage of getRootDir() and kernel.root_dir (fabpot) - * feature #28809 [HttpKernel] Deprecate the Kernel name (fabpot) - * feature #28807 [HttpFoundation] Make ResponseHeaderBag::makeDisposition static (fabpot) - * feature #28842 [Validator] Deprecate checkMX and checkHost on Email validator (fabpot) - * feature #28833 [Intl] Blacklist invalid languages (ro0NL) - * feature #28815 YamlEncoder handle yml format (kevin-biig) - * feature #27742 [Process] Add feature "wait until callback" to process class (Nek-) - * feature #28713 [Cache] added support for connecting to Redis clusters via DSN (nicolas-grekas) - * feature #24263 Filter logs by level (ro0NL) - * feature #24151 Display the log context in the debug pages (javiereguiluz) - * feature #26261 [Validator] Improvement: provide file basename for constr. violation messages in FileValidator. (TheCelavi) - * feature #26324 [Form] allow additional http methods in form configuration (alekitto) - * feature #26771 [Filesystem] Fix mirroring a directory with a relative path and a custom iterator (fxbt) - * feature #27291 [OptionsResolver] Added support for nesting options definition (yceruto) - * feature #27261 [VarDumper] Allow to use a light theme out of the box (ogizanagi) - * feature #27967 [Finder] Added a way to inverse a previous sorting (lyrixx) - * feature #28061 [Security] add port in access_control (roukmoute) - * feature #28476 Added different protocols to be allowed as asset base_url (alexander-schranz) - * feature #27770 [FrameworkBundle] Moving Cache-related CompilerPass to Cache component (Korbeil) - * feature #28738 [OptionsResolver] Passing Options argument to deprecation closure (yceruto) - * feature #28718 [Cache] add CacheInterface::delete() + improve CacheTrait (nicolas-grekas) - * feature #24530 [Form] simplify the form type extension registration (xabbuh) - * feature #28586 [WebServerBundle] Added ability to display the current hostname address if available when binding to 0.0.0.0 (respinoza) - * feature #28763 [WebProfilerBundle] Extract server parameters into their own tab (fabpot) - * feature #28375 [Translator] Deprecated transChoice and moved it away from contracts (Nyholm, nicolas-grekas) - * feature #28745 [WebServerBundle] Deprecate relying on --env in server:start and server:run (chalasr) - * feature #28505 [Serialized] allow configuring the serialized name of properties through metadata (fbourigault) - * feature #28669 [Serializer] Object class resolver (alanpoulain) - * feature #28653 [FrameworkBundle] Deprecate the "--env" and "--no-debug" console options (chalasr) - * feature #28693 [Security] Deprecate simple_preauth and simple_form in favor of Guard (chalasr) - * feature #28626 [Translation] marked getFallbackLocales() as internal (boscho87) - * feature #28571 [DependencyInjection] Improve ServiceLocatorTagPass service matching (codedmonkey) - * feature #28644 [Validator] Pre-check constraint validator dependencies (ro0NL) - * feature #28661 [Serializer] Add an option to skip null values (dunglas) - * feature #28679 [FrameworkBundle] Add vscode editor to ide config (lexcast) - * feature #28656 When a CSRF occures on a Form submit add a cause on the FormError object (gmponos) - * feature #28588 [Cache] add "setCallbackWrapper()" on adapters implementing CacheInterface for more flexibility (nicolas-grekas) - * feature #28598 [Cache] support configuring multiple Memcached servers in one DSN (nicolas-grekas) - * feature #28447 [HttpFoundation] make cookies auto-secure when passing them $secure=null + plan to make it and samesite=lax the defaults in 5.0 (nicolas-grekas) - * feature #28446 [SecurityBundle] make remember-me cookies auto-secure + inherit their default config from framework.session.cookie_* (nicolas-grekas) - * feature #28417 [VarExporter] add Instantiator::instantiate() to create+populate objects without calling their constructor nor any other methods (nicolas-grekas) - * feature #27819 [Serializer] deprecated normalizers and encoders who dont implement the base interfaces (rodnaph) - * feature #28572 Make it clear that the profiler is for dev only (fabpot) - * feature #28536 Favor LogicException for missing classes & functions (ro0NL) - * feature #28569 [Form] deprecate precision in IntegerToLocalizedStringTransformer (xabbuh) - * feature #28570 [Form] deprecate the unused scale option (xabbuh) - * feature #28566 [VarDumper] add casters for IntlDateFormatter and IntlCalendar (jschaedl) - * feature #28559 [VarDumper] add caster for IntlTimeZone (jschaedl) - * feature #28449 [DependencyInjection] improved message when alias service is not found (xabbuh) - * feature #27434 [Console] Add support for error ouput in the CommandTester (cdekok) - * feature #28555 [VarDumper] add caster for NumberFormatter (jschaedl) - * feature #28538 [Lock] Wrap release exception (jderusse) - * feature #28551 [VarDumper] add caster for MessageFormatter (nicolas-grekas) - * feature #28329 [Debug] Trigger a deprecation for new parameters not defined in sub classes (GuilhemN) - * feature #27920 Add Zookeeper data store for Lock Component (Ganesh Chandrasekaran) - * feature #28317 [VarDumper] Allow dd() to be called without arguments (SjorsO) - * feature #28424 [Ldap] Add verbose ext-ldap error if present for easier debugging (scaytrase) - * feature #28521 [Yaml] Added support for multiple files or directories in LintCommand (yceruto) - * feature #28522 [Translation] Added support for multiple files or directories in XliffLintCommand (yceruto) - * feature #28523 [FrameworkBundle] Register an identity translator as fallback (yceruto) - * feature #28473 [Validator] Check the BIC country with symfony/intl (sylfabre) - * feature #28487 [FrameworkBundle] Ignore backslashes in service ids when using debug:container and debug:autowiring (respinoza) - * feature #28412 [PhpUnitBridge] enable DebugClassLoader by default (nicolas-grekas) - * feature #28416 [FrameworkBundle] bind "ContainerInterface $parameterBag" arguments to the "parameter_bag" service (nicolas-grekas) - * feature #28316 Trigger deprecation notices when inherited class calls parent method but misses adding new arguments (kevinjhappy) - * feature #28373 [Console] Support max column width in Table (ro0NL) - * feature #28422 [VarExporter] throw component-specific exceptions (nicolas-grekas) - * feature #28415 [FrameworkBundle] Deprecate ContainerAwareCommand (chalasr) - * feature #28419 [Messenger] Change AmqpExt classes constructor signature (fabpot) - * feature #28405 [Messenger] Uses a messenger serializer, not an individual encoder/decoder (sroze) - * feature #28298 [WebServerBundle] Add support for Xdebug's Profiler (maidmaid) - * feature #28399 [Messenger] Add a SenderLocator decoupled from ContainerInterface (fabpot) - * feature #27321 [Messenger][Profiler] Trace middleware execution (ogizanagi) - * feature #28400 [Messenger] Add a simple serializer (fabpot) - * feature #28397 [Messenger] Change exceptions to use component's one (fabpot) - * feature #28387 [HttpKernel][Profiler] Add arg value resolver category in performances panel (ogizanagi) - * feature #25015 [Validator] Deprecate validating DateTimeInterface in Date|Time|DateTime constraints (ro0NL) - * feature #28394 [Messenger] Add interfaces to be type-hinted even when not using a Container (fabpot) - * feature #27981 [TwigBridge] Added template "name" argument to debug:twig command to find their paths (yceruto) - * feature #28207 [DI] leverage Contracts\Service (nicolas-grekas) - * feature #22225 [Console] Support formatted text cutting (ro0NL) - * feature #28206 [Contracts] Add traits+interfaces from the DI component (nicolas-grekas) - * feature #27456 [LOCK] Add a PdoStore (jderusse) - * feature #24297 Feature/doctrine type guesser simple json array support (iluuu1994) - * feature #26859 [Dotenv] add a flag to allow env vars override (fmata) - * feature #26997 [PropertyInfo] Add an extractor to guess if a property is initializable (dunglas) - * feature #27667 [Form][OptionsResolver] Show deprecated options definition on debug:form command (yceruto) - * feature #27021 [Serializer] Allow to access extra infos in name converters (dunglas) - * feature #26923 [FrameworkBundle] Allow user to specify folder for flock (MaksSlesarenko) - * feature #25125 [VarDumper] New env var to select the dump format (dunglas) - * feature #28117 [FrameworkBundle] add class description to debug:container command (gimler) - * feature #28270 [Messenger] Uses Symfony Serializer by default for envelope items (sroze) - * feature #27935 [FrameworkBundle] [Command] TranslationUpdate change default output to xlf (Alexis BOYER) - * feature #28168 Add SameSite cookies to FrameWorkBundle (rpkamp) - * feature #28303 [Process] Add relative path support for PHP_BINARY env var of PhpExecutableFinder (maidmaid) - * feature #28096 [Contracts] Add Cache contract to extend PSR-6 with tag invalidation, callback-based computation and stampede protection (nicolas-grekas) - * feature #27399 [Translation] Added intl message formatter. (aitboudad, Nyholm) - * feature #28315 [DI] Trigger exception when using '@id' name in parent option (Seb33300) - * feature #28210 [Contracts] Add Translation\TranslatorInterface + decouple symfony/validator from symfony/translation (nicolas-grekas) - * feature #28331 [FrameworkBundle] Don't populate fallback cache on warmup (nicolas-grekas) - * feature #28264 [VarDumper] make RedisCaster handle RedisCluster and dump all options on all drivers (nicolas-grekas) - * feature #28289 [Serializer] Add support for ignoring comments while XML encoding (maidmaid) - * feature #28294 [Messenger] Remove the "obscure" message subscriber configuration (sroze) - * feature #28271 [Messenger] Allow interfaces to be type-hinted as well (sroze) - * feature #28190 [Messenger] Add a --bus option to the messenger:consume-messages command (chalasr, sroze) - * feature #28275 [Messenger] Only subscribe to a given bus from the MessageSubscriber (sroze) - * feature #28243 [FrameworkBundle] Deprecate `Symfony\Bundle\FrameworkBundle\Controller\Controller` (sroze) - * feature #28070 [Translator] Use ICU parent locales as fallback locales (thewilkybarkid) - * feature #28231 [VarExporter] a new component to serialize values to plain PHP code (nicolas-grekas) - * feature #28244 [FrameworkBundle] Added new "auto" mode for `framework.session.cookie_secure` to turn it on when https is used (nicolas-grekas) - * feature #28277 [Serializer] AbstractObjectNormalizer improve performance (martiis) - * feature #28247 [Messenger] Don't make EnvelopeItemInterface extend Serializable (nicolas-grekas) - * feature #27926 [Serializer] XmlEncoder doesn't ignore PI nodes while encoding (maidmaid) - * feature #27890 Mock date() in ClockMock (Dominic Tubach) - * feature #28218 Improve support for anonymous classes (nicolas-grekas) - * feature #28221 [DomCrawler] Add a way to filter direct children (Einenlum) - * feature #28234 [DI] Allow autowiring by type + parameter name (nicolas-grekas) - * feature #28156 [Serializer] Fix the XML comments encoding (maidmaid) - * feature #28069 [Validator] New `DivisibleBy` constraint for testing divisibility (colinodell) - * feature #28176 [DI] [FrameworkBundle] Add LoggerAwareInterface to auto configuration (GaryPEGEOT) - * feature #27957 [Routing] Add fallback to cultureless locale for internationalized routes (fancyweb) - * feature #28027 [Config] Rename FileLoaderLoadException to LoaderLoadException (ProgMiner) - * feature #28085 [Config] show proposals when unsupported option is provided (fmata) - * feature #27806 [DI] Allow autoconfiguring bindings (nicolas-grekas) - * feature #21002 [Form] Added options for separate date/time labels in DateTimeType. (mktcode) - * feature #27763 [WebProfilerBundle] Append new ajax request to the end of the list (BoShurik) - * feature #28035 [DomCrawler] Allow using non-absolute base URIs (javiereguiluz) - * feature #28106 [Yaml] save preg_match() calls when possible (xabbuh) - * feature #27678 Allow to configure some options of the profiler interface (javiereguiluz) - * feature #27943 [Security] Deprecate returning stringish objects from Security::getUser (ro0NL) - * feature #27956 Added types and tweaked PHPdoc of clickLink() and submitForm() methods (javiereguiluz) - * feature #27976 [Security] Remember me: allow to set the samesite cookie flag (dunglas) - * feature #27978 [WebProfilerBundle] Show relative path of the template and improving panel view (yceruto) - * feature #27891 [Finder] Allow arrays as parameters of some methods for better fluent experience and code readability (jfredon) - * feature #27829 [DoctrineBridge] Inject the entity manager instead of the class metadata factory in DoctrineExtractor (dunglas) - * feature #27093 Add symfony/contracts: a set of abstractions extracted out of the Symfony components (nicolas-grekas) - * feature #27807 Added new methods submitForm and clickLink to Client class (nowiko) - * feature #27879 [Routing] deprecate non string requirement names (xabbuh) - * feature #26933 [Console] Add title table (maidmaid) - * feature #27697 [ProxyManagerBridge][DI] allow proxifying interfaces with "lazy: Some\ProxifiedInterface" (nicolas-grekas) - * feature #27645 [Cache] Add `MarshallerInterface` allowing to change the serializer, providing a default one that automatically uses igbinary when available (nicolas-grekas) - * feature #27694 [FrameworkBundle][Cache] Allow configuring PDO-based cache pools, with table auto-creation on first use (nicolas-grekas) - * feature #27774 [FrameworkBundle] allow turning routes to utf8 mode by default (nicolas-grekas) - * feature #27821 [Process][Console] deprecated defining commands as strings (nicolas-grekas) - * feature #27320 [Messenger] Activation middleware decorator (ogizanagi) - * feature #27519 [HttpKernel][FrameworkBundle] Turn HTTP exceptions to HTTP status codes by default (nicolas-grekas) - * feature #27020 [Serializer] Allow to access to the format and context in circular ref handler (dunglas) - * feature #27783 [DI] Add ServiceLocatorArgument to generate array-based locators optimized for OPcache shared memory (nicolas-grekas) - * feature #27850 [Security] Allow passing null as $filter in LdapUserProvider to get the default filter (louhde) - * feature #27650 [SecurityBundle] Add json login ldap (Rudy Onfroy) - * feature #27798 [Security] Use AuthenticationTrustResolver in SimplePreAuthenticationListener (nicolas-grekas) - * feature #27801 [MonologBridge] Add ProcessorInterface, enabling autoconfiguration of monolog processors (nicolas-grekas) - * feature #27503 [Serializer] Allow to pass a single value for the groups opt (dunglas) - * feature #27715 [Serializer] Deprecate CsvEncoder as_collection false default value (ogizanagi) - * feature #27768 [VarDumper] display the signature of callables (nicolas-grekas) - * feature #27766 [VarDumper] show proxified class on hover (nicolas-grekas) - * feature #27675 [DoctrineBridge] always load event listeners lazy via ServiceLocator (dmaicher) - * feature #27499 Improved an error message related to controllers (javiereguiluz) - * feature #26300 [PropertyInfo] Implement "Collection" types in PhpDocExtractor (popy-dev) - * feature #26946 [WebProfilerBundle] Display uploaded files in the profiler (javiereguiluz) - * feature #27476 [Config] deprecate tree builders without root nodes (xabbuh) - * feature #27586 [PropertyAccess] Add Property Path to Exception Message (rodnaph) - * feature #27699 Redesigned the default error page in production (javiereguiluz) - * feature #27655 [Translation] Added support for translation files with other filename patterns (javiereguiluz) - * feature #27580 [Form] Add ability to clear form errors (colinodell) - * feature #27247 [Form] Deprecate `searchAndRenderBlock` returning empty string (ostrolucky) - * feature #27646 [Cache] added support for phpredis 4 `compression` and `tcp_keepalive` options (nicolas-grekas) - * feature #27605 [DX] Log potential redirect loops caused by forced HTTPS (colinodell) - * feature #27653 [Translation] Improved the performance of the lint:xliff command (javiereguiluz) - * feature #27421 CacheWarmerAggregate handle deprecations logs (ScullWM) - * feature #27611 [FrameworkBundle][SecurityBundle] Moved security expression providers pass logic to SecurityBundle (HeahDude) - * feature #27277 [OptionsResolver] Introduce ability to deprecate options, allowed types and values (yceruto) - * feature #26919 [TwigBridge] Added bundle name suggestion on wrongly overrided templates paths (pmontoya, Pascal Montoya) - * feature #26486 [HttpFoundation] Adds getAcceptableFormats() method for Request (AndreiIgna) - * feature #27535 [TwigBundle] Enhance the twig not found exception (behnoushnorouzi) - * feature #27551 [FrameworkBundle] show public/private for aliases in debug:container command (OskarStark) - * feature #27543 [Cache] serialize objects using native arrays when possible (nicolas-grekas) - * feature #27563 [Cache] Improve perf of array-based pools (nicolas-grekas) - * feature #27604 [Cache] Prevent stampede at warmup using flock() (nicolas-grekas) - * feature #27315 [TwigBundle] add exception chain breadcrumbs navigation (kiler129) - * feature #27031 [Cache] Use sub-second accuracy for internal expiry calculations (nicolas-grekas) - * feature #27549 [Cache] Unconditionally use PhpFilesAdapter for system pools (nicolas-grekas) - * feature #27009 [Cache] Add stampede protection via probabilistic early expiration (nicolas-grekas) - * feature #27471 [DI] Improve performance of removing/inlining passes (nicolas-grekas) - * feature #27462 [FrameworkBundle] Deprecate auto-injection of the container in AbstractController instances (nicolas-grekas) - * feature #27077 [DependencyInjection] add ServiceSubscriberTrait (kbond) - * feature #27398 [Cache] Remove TaggableCacheInterface, alias cache.app.taggable to CacheInterface (nicolas-grekas) - * feature #27343 [Messenger][Profiler] Show dispatch caller (ogizanagi) - * feature #27429 [PropertyInfo] Auto-enable PropertyInfo component (sroze) - * feature #27430 [PropertyInfo] Add an alias to the property info type extractor (sroze) - * feature #27417 [WebProfilerBundle] Make Twig bundle an explicit dependency (fabpot) - * feature #27024 [Finder] added "use natural sort" option (vyshkant) - * feature #26934 [FrameworkBundle] Allow configuring taggable cache pools (nicolas-grekas) - * feature #26981 No more support for custom anon/remember tokens based on FQCN (Iltar van der Berg) - * feature #27336 [Security][SecurityBundle] FirewallMap/FirewallContext deprecations (chalasr) - * feature #27157 [DI] Select specific key from an array resolved env var (bobvandevijver) - * feature #27165 [DI] Allow binding by type+name (nicolas-grekas) - * feature #26929 [Cache] Add [Taggable]CacheInterface, the easiest way to use a cache (nicolas-grekas) - * feature #27305 [Security/Core] Add "is_granted()" to security expressions, deprecate "has_role()" (nicolas-grekas) - * feature #27069 [LDAP] Add "applyOperations" method to EntryManager (mablae) - * feature #27118 [BrowserKit] Adds support for meta refresh (jhedstrom) - * feature #27268 [DI] fine tune dumped factories (nicolas-grekas) - * feature #27075 [DI][DX] Allow exclude to be an array of patterns (magnetik) - * feature #27138 [HttpKernel] Better exception page when the controller returns nothing (lyrixx) - diff --git a/CHANGELOG-4.3.md b/CHANGELOG-4.3.md deleted file mode 100644 index 9c95e7e327a31..0000000000000 --- a/CHANGELOG-4.3.md +++ /dev/null @@ -1,848 +0,0 @@ -CHANGELOG for 4.3.x -=================== - -This changelog references the relevant changes (bug and security fixes) done -in 4.3 minor versions. - -To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash -To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.3.0...v4.3.1 - -* 4.3.10 (2020-01-21) - - * bug #35364 [Yaml] Throw on unquoted exclamation mark (fancyweb) - * bug #35065 [Security] Use supportsClass in addition to UnsupportedUserException (linaori) - * bug #35343 [Security] Fix RememberMe with null password (jderusse) - * bug #34223 [DI] Suggest typed argument when binding fails with untyped argument (gudfar) - * bug #35324 [HttpClient] Fix strict parsing of response status codes (Armando-Walmeric) - * bug #35318 [Yaml] fix PHP const mapping keys using the inline notation (xabbuh) - * bug #35304 [HttpKernel] Fix that no-cache MUST revalidate with the origin (mpdude) - * bug #35299 Avoid `stale-if-error` in FrameworkBundle's HttpCache if kernel.debug = true (mpdude) - * bug #35151 [DI] deferred exceptions in ResolveParameterPlaceHoldersPass (Islam93) - * bug #35278 [EventDispatcher] expand listener in place (xabbuh) - * bug #35254 [PHPUnit-Bridge] Fail-fast in simple-phpunit if one of the passthru() commands fails (mpdude) - * bug #35261 [Routing] Fix using a custom matcher & generator dumper class (fancyweb) - * bug #34643 [Dotenv] Fixed infinite loop with missing quote followed by quoted value (naitsirch) - * bug #35239 [Security\Http] Prevent canceled remember-me cookie from being accepted (chalasr) - * bug #35267 [Debug] fix ClassNotFoundFatalErrorHandler (nicolas-grekas) - * bug #35193 [TwigBridge] button_widget now has its title attr translated even if its label = null or false (stephen-lewis) - * bug #35219 [PhpUnitBridge] When using phpenv + phpenv-composer plugin, composer executable is wrapped into a bash script (oleg-andreyev) - * bug #35150 [Messenger] Added check if json_encode succeeded (toooni) - * bug #35170 [FrameworkBundle][TranslationUpdateCommand] Do not output positive feedback on stderr (fancyweb) - * bug #35223 [HttpClient] Don't read from the network faster than the CPU can deal with (nicolas-grekas) - * bug #35214 [DI] DecoratorServicePass should keep container.service_locator on the decorated definition (malarzm) - * bug #35210 [HttpClient] NativeHttpClient should not send >1.1 protocol version (nicolas-grekas) - * bug #33672 [Mailer] Remove line breaks in email attachment content (Stuart Fyfe) - * bug #35101 [Routing] Fix i18n routing when the url contains the locale (fancyweb) - * bug #35124 [TwigBridge][Form] Added missing help messages in form themes (cmen) - * bug #35168 [HttpClient] fix capturing SSL certificates with NativeHttpClient (nicolas-grekas) - * bug #35134 [PropertyInfo] Fix BC issue in phpDoc Reflection library (jaapio) - * bug #35173 [Mailer][MailchimpBridge] Fix missing attachments when sending via Mandrill API (vilius-g) - * bug #35172 [Mailer][MailchimpBridge] Fix incorrect sender address when sender has name (vilius-g) - * bug #35125 [Translator] fix performance issue in MessageCatalogue and catalogue operations (ArtemBrovko) - * bug #35120 [HttpClient] fix scheduling pending NativeResponse (nicolas-grekas) - * bug #35117 [Cache] do not overwrite variable value (xabbuh) - * bug #35113 [VarDumper] Fix "Undefined index: argv" when using CliContextProvider (xepozz) - * bug #35103 [Translation] Use `locale_parse` for computing fallback locales (alanpoulain) - * bug #35094 [Console] Fix filtering out identical alternatives when there is a command loader (fancyweb) - * bug #35039 [DI] skip looking for config class when the extension class is anonymous (nicolas-grekas) - * bug #35049 [ProxyManager] fix generating proxies for root-namespaced classes (nicolas-grekas) - * bug #35022 [Dotenv] FIX missing getenv (mccullagh) - * bug #35025 [HttpClient][Psr18Client] Remove Psr18ExceptionTrait (fancyweb) - * bug #35014 [HttpClient] make pushed responses retry-able (nicolas-grekas) - * bug #35010 [VarDumper] ignore failing __debugInfo() (nicolas-grekas) - * bug #34998 [DI] fix auto-binding service providers to their service subscribers (nicolas-grekas) - * bug #33670 [DI] Service locators can't be decorated (malarzm) - * bug #35000 [Console][SymfonyQuestionHelper] Handle multibytes question choices keys and custom prompt (fancyweb) - * bug #34996 Fix displaying anonymous classes on PHP 7.4 (nicolas-grekas) - * bug #29839 [Validator] fix comparisons with null values at property paths (xabbuh) - * bug #34900 [DoctrineBridge] Fixed submitting invalid ids when using queries with limit (HeahDude) - * bug #34791 [Serializer] Skip uninitialized (PHP 7.4) properties in PropertyNormalizer and ObjectNormalizer (vudaltsov) - * bug #34956 [Messenger][AMQP] Use delivery_mode=2 by default (lyrixx) - * bug #34915 [FrameworkBundle] Fix invalid Windows path normalization in TemplateNameParser (mvorisek) - * bug #34981 stop using deprecated Doctrine persistence classes (xabbuh) - * bug #34904 [Validator][ConstraintValidator] Safe fail on invalid timezones (fancyweb) - * bug #34955 Require doctrine/persistence ^1.3 (nicolas-grekas) - * bug #34923 [DI] Fix support for immutable setters in CallTrait (Lctrs) - * bug #34918 [Translation] fix memoryleak in PhpFileLoader (nicolas-grekas) - * bug #34920 [Routing] fix memoryleak when loading compiled routes (nicolas-grekas) - * bug #34787 [Cache] Propagate expiry when syncing items in ChainAdapter (trvrnrth) - * bug #34896 [Cache] fix memory leak when using PhpFilesAdapter (nicolas-grekas) - * bug #34438 [HttpFoundation] Use `Cache-Control: must-revalidate` only if explicit lifetime has been given (mpdude) - * bug #34449 [Yaml] Implement multiline string as scalar block for tagged values (natepage) - * bug #34601 [MonologBridge] Fix debug processor datetime type (mRoca) - * bug #34842 [ExpressionLanguage] Process division by zero (tigr1991) - * bug #34902 [PropertyAccess] forward caught exception (xabbuh) - * bug #34888 [TwigBundle] add tags before processing them (xabbuh) - * bug #34762 [Config] never try loading failed classes twice with ClassExistenceResource (nicolas-grekas) - * bug #34839 [Cache] fix memory leak when using PhpArrayAdapter (nicolas-grekas) - * bug #34812 [Yaml] fix parsing negative octal numbers (xabbuh) - * bug #34854 [Messenger] gracefully handle missing event dispatchers (xabbuh) - * bug #34788 [SecurityBundle] Properly escape regex in AddSessionDomainConstraintPass (fancyweb) - * bug #34755 [FrameworkBundle] resolve service locators in `debug:*` commands (nicolas-grekas) - * bug #34832 [Validator] Allow underscore character "_" in URL username and password (romainneutron) - * bug #34776 [DI] fix resolving bindings for named TypedReference (nicolas-grekas) - * bug #34738 [SecurityBundle] Passwords are not encoded when algorithm set to "true" (nieuwenhuisen) - * bug #34779 [Security] do not validate passwords when the hash is null (xabbuh) - * bug #34757 [DI] Fix making the container path-independent when the app is in /app (nicolas-grekas) - -* 4.3.9 (2019-12-01) - - * bug #34649 more robust initialization from request (dbu) - * bug #34671 [Security] Fix clearing remember-me cookie after deauthentication (chalasr) - * bug #34711 Fix the translation commands when a template contains a syntax error (fabpot) - * bug #34560 [Config][ReflectionClassResource] Handle parameters with undefined constant as their default values (fancyweb) - * bug #34695 [Config] don't break on virtual stack frames in ClassExistenceResource (nicolas-grekas) - * bug #34716 [DependencyInjection] fix dumping number-like string parameters (xabbuh) - * bug #34558 [Console] Fix autocomplete multibyte input support (fancyweb) - * bug #34130 [Console] Fix commands description with numeric namespaces (fancyweb) - * bug #34677 [EventDispatcher] Better error reporting when arguments to dispatch() are swapped (rimas-kudelis) - * bug #33573 [TwigBridge] Add row_attr to all form themes (fancyweb) - * bug #34019 [Serializer] CsvEncoder::NO_HEADERS_KEY ignored when used in constructor (Dario Savella) - * bug #34083 [Form] Keep preferred_choices order for choice groups (vilius-g) - * bug #34091 [Debug] work around failing chdir() on Darwin (mary2501) - * bug #34305 [PhpUnitBridge] Read configuration CLI directive (ro0NL) - * bug #34490 [Serializer] Fix MetadataAwareNameConverter usage with string group (antograssiot) - * bug #34632 [Console] Fix trying to access array offset on value of type int (Tavafi) - * bug #34669 [HttpClient] turn exception into log when the request has no content-type (nicolas-grekas) - * bug #34636 [VarDumper] notice on potential undefined index (sylvainmetayer) - * bug #34668 [Cache] Make sure we get the correct number of values from redis::mget() (thePanz) - * bug #34569 [Workflow] Apply the same logic of precedence between the apply() and the buildTransitionBlockerList() method (lyrixx) - * bug #34533 [Monolog Bridge] Fixed accessing static property as non static. (Sander-Toonen) - * bug #34546 [Serializer] Add DateTimeZoneNormalizer into Dependency Injection (jewome62) - * bug #34547 [Messenger] Error when specified default bus is not among the configured (vudaltsov) - * bug #34551 [Security] SwitchUser is broken when the User Provider always returns a valid user (tucksaun) - * bug #34385 Avoid empty "If-Modified-Since" header in validation request (mpdude) - * bug #34458 [Validator] ConstraintValidatorTestCase: add missing return value to mocked validate method calls (ogizanagi) - * bug #34451 [DependencyInjection] Fix dumping multiple deprecated aliases (shyim) - * bug #34448 [Form] allow button names to start with uppercase letter (xabbuh) - * bug #34419 [Cache] Disable igbinary on PHP >= 7.4 (nicolas-grekas) - * bug #34366 [HttpFoundation] Allow redirecting to URLs that contain a semicolon (JayBizzle) - * bug #34397 [FrameworkBundle] Remove project dir from Translator cache vary scanned directories (fancyweb) - * bug #34408 [Cache] catch exceptions when using PDO directly (xabbuh) - * bug #34410 [HttpFoundation] Fix MySQL column type definition. (jbroutier) - * bug #34398 [Config] fix id-generation for GlobResource (nicolas-grekas) - * bug #34396 [Finder] Allow ssh2 stream wrapper for sftp (damienalexandre) - * bug #34383 [DI] Use reproducible entropy to generate env placeholders (nicolas-grekas) - * bug #34381 [WebProfilerBundle] Require symfony/twig-bundle (fancyweb) - -* 4.3.8 (2019-11-13) - - * bug #34344 [Console] Constant STDOUT might be undefined (nicolas-grekas) - * security #cve-2019-18886 [Security\Core] throw AccessDeniedException when switch user fails (nicolas-grekas) - * security #cve-2019-18888 [Mime] fix guessing mime-types of files with leading dash (nicolas-grekas) - * security #cve-2019-11325 [VarExporter] fix exporting some strings (nicolas-grekas) - * security #cve-2019-18889 [Cache] forbid serializing AbstractAdapter and TagAwareAdapter instances (nicolas-grekas) - * security #cve-2019-18888 [HttpFoundation] fix guessing mime-types of files with leading dash (nicolas-grekas) - * security #cve-2019-18887 [HttpKernel] Use constant time comparison in UriSigner (stof) - -* 4.3.7 (2019-11-11) - - * bug #34294 [Workflow] Fix error when we use ValueObject for the marking property (FabienSalles) - * bug #34297 [DI] fix locators with numeric keys (nicolas-grekas) - * bug #34282 [DI] Dont cache classes with missing parents (nicolas-grekas) - * bug #34287 [HttpClient] Fix a crash when calling CurlHttpClient::__destruct() (dunglas) - * bug #34129 [FrameworkBundle][Translation] Invalidate cached catalogues when the scanned directories change (fancyweb) - * bug #34246 [Serializer] Use context to compute MetadataAwareNameConverter cache (antograssiot) - * bug #34251 [HttpClient] expose only gzip when doing transparent compression (nicolas-grekas) - * bug #34244 [Inflector] add support for 'species' (jeffreymoelands) - * bug #34085 [Console] Detect dimensions using mode CON if vt100 is supported (rtek) - * bug #34199 [HttpClient] Retry safe requests using HTTP/1.1 when HTTP/2 fails (nicolas-grekas) - * bug #34192 [Routing] Fix URL generator instantiation (X-Coder264, HypeMC) - * bug #34134 [Messenger] fix retry of messages losing the routing key and properties (Tobion) - * bug #34181 [Stopwatch] Fixed bug in getDuration when counting multiple ongoing periods (TimoBakx) - * bug #34165 [PropertyInfo] Fixed type extraction for nullable collections of non-nullable elements (happyproff) - * bug #34179 [Stopwatch] Fixed a bug in StopwatchEvent::getStartTime (TimoBakx) - * bug #34203 [FrameworkBundle] [HttpKernel] fixed correct EOL and EOM month (erics86) - * bug #34035 [Serializer] Fix property name usage for denormalization (antograssiot) - -* 4.3.6 (2019-11-01) - - * bug #34198 [HttpClient] Fix perf issue when doing thousands of requests with curl (nicolas-grekas) - * bug #33998 [Config] Disable default alphabet sorting in glob function due of unstable sort (hurricane-voronin) - * bug #34144 [Serializer] Improve messages for unexpected resources values (fancyweb) - * bug #34186 [HttpClient] always return the empty string when the response cannot have a body (nicolas-grekas) - * bug #34167 [HttpFoundation] Allow to not pass a parameter to Request::isMethodSafe() (dunglas) - * bug #33828 [DoctrineBridge] Auto-validation must work if no regex are passed (dunglas) - * bug #34080 [SecurityBundle] correct types for default arguments for firewall configs (shieldo) - * bug #34152 [Workflow] Made the configuration more robust for the 'property' key (lyrixx) - * bug #34154 [HttpClient] fix handling of 3xx with no Location header - ignore Content-Length when no body is expected (nicolas-grekas) - * bug #34140 [Security/Core] make NativePasswordEncoder use sodium to validate passwords when possible (nicolas-grekas) - * bug #33999 [Form] Make sure to collect child forms created on *_SET_DATA events (yceruto) - * bug #34090 [WebProfilerBundle] Improve display in Email panel for dark theme (antograssiot) - * bug #34116 [HttpClient] ignore the body of responses to HEAD requests (nicolas-grekas) - * bug #32456 [Messenger] use database platform to convert correctly the DateTime (roukmoute) - * bug #34107 [Messenger] prevent infinite redelivery loops and blocked queues (Tobion) - * bug #32341 [Messenger] Show exceptions after multiple retries (TimoBakx) - * bug #34082 Revert "[Messenger] Fix exception message of failed message is dropped (Tobion) - * bug #34021 [TwigBridge] do not render errors for checkboxes twice (xabbuh) - * bug #34017 [Messenger] Fix ignored options in redis transport (chalasr) - * bug #34041 [HttpKernel] fix wrong removal of the just generated container dir (nicolas-grekas) - * bug #34024 [Routing] fix route loading with wildcard, but dir or file is empty (gseidel) - * bug #34023 [Dotenv] allow LF in single-quoted strings (nicolas-grekas) - * bug #33818 [Yaml] Throw exception for tagged invalid inline elements (gharlan) - * bug #33994 [Mailer] Fix Mandrill Transport API payload for named addresses (Michaël Perrin) - * bug #33985 [HttpClient] workaround curl_multi_select() issue (nicolas-grekas) - * bug #33948 [PropertyInfo] Respect property name case when guessing from public method name (antograssiot) - * bug #33962 [Cache] fixed TagAwareAdapter returning invalid cache (v-m-i) - * bug #33958 [DI] Add extra type check to php dumper (gquemener) - * bug #33965 [HttpFoundation] Add plus character `+` to legal mime subtype (ilzrv) - * bug #32943 [Dotenv] search variable values in ENV first then env file (soufianZantar) - * bug #33943 [VarDumper] fix resetting the "bold" state in CliDumper (nicolas-grekas) - * bug #33936 [HttpClient] Missing argument in method_exists (detinkin) - * bug #33937 [Cache] ignore unserialization failures in AbstractTagAwareAdapter::doDelete() (nicolas-grekas) - * bug #33935 [HttpClient] send `Accept: */*` by default, fix removing it when needed (nicolas-grekas) - * bug #33922 [Cache] remove implicit dependency on symfony/filesystem (nicolas-grekas) - * bug #33927 Allow to set SameSite config to 'none' (ihmels) - * bug #33930 [Cache] clean tags folder on invalidation (nicolas-grekas) - * bug #33919 [VarDumper] fix array key error for class SymfonyCaster (zcodes) - * bug #33885 [Form][DateTimeImmutableToDateTimeTransformer] Preserve microseconds and use \DateTime::createFromImmutable() when available (fancyweb) - * bug #33900 [HttpKernel] Fix to populate $dotenvVars in data collector when not using putenv() (mynameisbogdan) - -* 4.3.5 (2019-10-07) - - * bug #33742 [Crawler] document $default as string|null (nicolas-grekas) - * bug #32308 [Messenger] DoctrineTransport: ensure auto setup is only done once (bendavies) - * bug #33871 [HttpClient] bugfix exploding values of headers (michaljusiega) - * bug #33834 [Validator] Fix ValidValidator group cascading usage (fancyweb) - * bug #33863 [Routing] gracefully handle docref_root ini setting (nicolas-grekas) - * bug #33846 [Cache] give 100ms before starting the expiration countdown (nicolas-grekas) - * bug #33853 [HttpClient] fix "no_proxy" option ignored in NativeHttpClient (Harry-Dunne) - * bug #33841 [VarDumper] fix dumping uninitialized SplFileInfo (nicolas-grekas) - * bug #33842 [Cache] fix logger usage in CacheTrait::doGet() (nicolas-grekas) - * bug #33835 [Workflow] Fixed BC break on WorkflowInterface (lyrixx) - * bug #33799 [Security]: Don't let falsy usernames slip through impersonation (j4nr6n) - * bug #33814 [HttpFoundation] Check if data passed to SessionBagProxy::initialize is an array (mynameisbogdan) - * bug #33744 [DI] Add CSV env var processor tests / support PHP 7.4 (ro0NL) - * bug #33805 [FrameworkBundle] Fix wrong returned status code in ConfigDebugCommand (jschaedl) - * bug #33781 [AnnotationCacheWarmer] add RedirectController to annotation cache (jenschude) - * bug #33777 Fix the :only-of-type pseudo class selector (jakzal) - * bug #32051 [Serializer] Add CsvEncoder tests for PHP 7.4 (ro0NL) - * feature #33776 Copy phpunit.xsd to a predictable path (julienfalque) - * bug #33759 [Security/Http] fix parsing X509 emailAddress (nicolas-grekas) - * bug #33733 [Serializer] fix denormalization of string-arrays with only one element (mkrauser) - * bug #33754 [Cache] fix known tag versions ttl check (SwenVanZanten) - * bug #33646 [HttpFoundation] allow additinal characters in not raw cookies (marie) - * bug #33748 [Console] Do not include hidden commands in suggested alternatives (m-vo) - * bug #33625 [DependencyInjection] Fix wrong exception when service is synthetic (k0d3r1s) - * bug #32979 [Messenger] return empty envelopes when RetryableException occurs (surikman) - * bug #32522 [Validator] Accept underscores in the URL validator, as the URL will load (battye) - * bug #32437 Fix toolbar load when GET params are present in "_wdt" route (Molkobain) - * bug #32925 [Translation] Collect original locale in case of fallback translation (digilist) - * bug #33691 [HttpClient] fix race condition when reading response with informational status (nicolas-grekas) - * bug #33727 [HttpClient] workaround bad Content-Length sent by old libcurl (nicolas-grekas) - * bug #31198 [FrameworkBundle] Fix framework bundle lock configuration not working as expected (HypeMC) - * bug #33719 [Cache] dont override native Memcached options (nicolas-grekas) - * bug #33703 [Cache] fail gracefully when locking is not supported (nicolas-grekas) - * bug #33713 Fix exceptions (PDOException) error code type (fruty) - * bug #32335 [Form] Names for buttons should start with lowercase (mcfedr) - * bug #33706 [Mailer][Messenger] ensure legacy event dispatcher compatibility (xabbuh) - * bug #33688 Add missing row_attr option to FormType (mcsky) - * bug #33693 [Security] use LegacyEventDispatcherProxy (dmaicher) - * bug #33675 [PhpUnit] Fix usleep mock return value (fabpot) - * bug #33652 [Cache] skip igbinary on PHP 7.4.0 (nicolas-grekas) - * bug #33643 [HttpClient] fix throwing HTTP exceptions when the 1st chunk is emitted (nicolas-grekas) - * bug #33618 fix tests depending on other components' tests (xabbuh) - * bug #33626 [PropertyInfo] ensure compatibility with type resolver 0.5 (xabbuh) - * bug #33620 [Twig] Fix Twig config extra keys (fabpot) - * bug #33600 [Messenger] Fix exception message of failed message is dropped on retry (tienvx) - * bug #33601 [HttpClient] Add default value for Accept header (numerogeek) - * bug #33340 [Finder] Adjust regex to correctly match comments in gitignore contents (Jeroeny) - * bug #33588 [PropertyInfo] ensure compatibility with type resolver 0.5 (xabbuh) - * bug #33575 [WebProfilerBundle] Fix time panel legend buttons (fancyweb) - * bug #33571 [Inflector] add support 'see' to 'ee' for singularize 'fees' to 'fee' (maxhelias) - * bug #32763 [Console] Get dimensions from stty on windows if possible (rtek) - * bug #33570 Fixed cache pools affecting each other due to an overwritten seed variable (roed) - * bug #33517 [Yaml] properly catch legacy tag syntax usages (xabbuh) - * bug #33546 [DependencyInjection] Accept existing interfaces as valid named args (fancyweb) - * bug #33547 [HttpClient] Re-enable Server Push support (dunglas) - * bug #33521 Fixed incompatibility between ServiceSubscriberTrait and classes with protected $container property (a-menshchikov) - * bug #33518 [Yaml] don't dump a scalar tag value on its own line (xabbuh) - * bug #33505 [HttpClient] fallbackto CURLMOPT_MAXCONNECTS when CURLMOPT_MAX_HOST_CONNECTIONS is not available (nicolas-grekas) - * bug #32818 [HttpKernel] Fix getFileLinkFormat() to avoid returning the wrong URL in Profiler (Arman-Hosseini) - * bug #33487 [HttpKernel] Fix Apache mod_expires Session Cache-Control issue (pbowyer) - * bug #33469 [FrameworkBundle] Fixed suggested package for missing server:dump command (lyrixx) - * bug #31964 [Router] routing cache crash when using generator_class (dFayet) - * bug #33481 [Messenger] fix empty amqp body returned as false (Tobion) - * bug #33387 [Mailer] maintain sender/recipient name in SMTP envelopes (xabbuh) - * bug #33449 Fix gmail relay (Beno!t POLASZEK) - * bug #33391 [HttpClient] fix support for 103 Early Hints and other informational status codes (nicolas-grekas) - * bug #33444 [HttpClient] improve handling of HTTP/2 PUSH, disable it by default (nicolas-grekas) - * bug #33435 [Validator] Only handle numeric values in DivisibleBy (fancyweb) - * bug #33437 Fix #33427 (sylfabre) - * bug #33439 [Validator] Sync string to date behavior and throw a better exception (fancyweb) - * bug #33436 [DI] fix support for "!tagged_locator foo" (nicolas-grekas) - * bug #32903 [PHPUnit Bridge] Avoid registering listener twice (alexpott) - * bug #33432 [Mailer] Fix Mailgun support when a response is not JSON as expected (fabpot) - * bug #33402 [Finder] Prevent unintentional file locks in Windows (jspringe) - * bug #33376 [Mailer] Remove the default dispatcher in AbstractTransport (fabpot) - * bug #33357 [FrameworkBundle] Fix about command not showing .env vars (brentybh) - * bug #33396 Fix #33395 PHP 5.3 compatibility (kylekatarnls) - * bug #33363 [Routing] fix static route reordering when a previous dynamic route conflicts (nicolas-grekas) - * bug #33385 [Console] allow Command::getName() to return null (nicolas-grekas) - * bug #33353 Return null as Expire header if it was set to null (danrot) - * bug #33382 [ProxyManager] remove ProxiedMethodReturnExpression polyfill (nicolas-grekas) - * bug #33377 [Yaml] fix dumping not inlined scalar tag values (xabbuh) - -* 4.3.4 (2019-08-26) - - * bug #33335 [DependencyInjection] Fixed the `getServiceIds` implementation to always return aliases (pdommelen) - * bug #33298 [Messenger] Stop worker when it should stop (tienvx) - * bug #33292 [VarExporter] fix support for PHP 7.4 (nicolas-grekas) - * bug #33282 [HttpKernel] Do not extend the new SF 4.3 ControllerEvent so we can make it final (Tobion) - * bug #33278 [FrameworkBundle] Fix BrowserKit assertions to make them compatible with Panther (dunglas) - * bug #33216 [Mime] Trim and remove line breaks from NamedAddress name arg (maldoinc) - * bug #33124 [Config] Add handling for ignored keys in ArrayNode::mergeValues. (Alexandre Parent) - * bug #33244 [Router] Fix TraceableUrlMatcher behaviour with trailing slash (Xavier Leune) - * bug #33232 Fix handling for session parameters (vkhramtsov) - * bug #32497 [Messenger] DispatchAfterCurrentBusMiddleware does not cancel messages from delayed handlers (Nyholm, BastienClement) - * bug #33127 [Messenger] make delay exchange and queues durable like the normal ones by default (Tobion) - * bug #33210 [Mailer] Don't duplicate addresses in Sendgrid Transport (pierredup) - * bug #33172 [Console] fixed a PHP notice when there is no function in the stack trace of an Exception (fabpot) - * bug #33157 Fix getMaxFilesize() returning zero (ausi) - * bug #33139 [Intl] Cleanup unused language aliases entry (ro0NL) - * bug #33126 [SecurityBundle] display the correct class name on the deprecated notice (maxhelias) - * bug #33093 [EventDispatcher] wrong Request class (maxhelias) - * bug #33092 [DependencyInjection] Improve an exception message (fabpot) - * bug #32541 [HttpKernel] trim the leading backslash in the controller init (Simperfit, fabpot) - * bug #32455 [HttpFoundation] Clear invalid session cookie (Toflar) - * bug #33066 [Serializer] Fix negative DateInterval (jderusse) - * bug #33045 Make HttpClientTestCase compatible with PHPUnit8 (jderusse) - * bug #33033 [Lock] consistently throw NotSupportException (xabbuh) - * bug #33022 [HttpClient] Remove CURLOPT_CONNECTTIMEOUT_MS curl opt (lyrixx) - * bug #32516 [FrameworkBundle][Config] Ignore exceptions thrown during reflection classes autoload (fancyweb) - * bug #33010 [TwigBridge] pass translation parameters to the trans filter (xabbuh) - * bug #32981 Fix tests/code for php 7.4 (jderusse) - * bug #32986 [Mime] fixed wrong mimetype (rjwebdev) - * bug #32992 [ProxyManagerBridge] Polyfill for unmaintained version (jderusse) - * bug #32989 [HttpClient] Declare `$active` first to prevent weird issue (Kocal) - * bug #32999 Added correct plural for box -> boxes (cinamo) - * bug #32933 [PhpUnitBridge] fixed PHPUnit 8.3 compatibility: method handleError was renamed to __invoke (karser) - * bug #32947 [Intl] Support DateTimeInterface in IntlDateFormatter::format (pierredup) - * bug #32919 [Intl] Order alpha2 to alpha3 mapping + phpdoc fixes (ro0NL) - * bug #32792 [Messenger] Fix incompatibility with FrameworkBundle <4.3.1 (chalasr) - * bug #32836 [Messenger] Removed named parameters and replaced with `?` placeholders for sqlsrv compatibility (David Legatt) - * bug #32838 [FrameworkBundle] Detect indirect env vars in routing (ro0NL) - * bug #32918 [Intl] Order alpha2 to alpha3 mapping (ro0NL) - * bug #32902 [PhpUnitBridge] Allow sutFqcnResolver to return array (VincentLanglet) - * bug #32814 Create mailBody with only attachments part present (srsbiz) - * bug #32682 [HttpFoundation] Revert getClientIp @return docblock (ossinkine) - * bug #32910 [Yaml] PHP-8: Uncaught TypeError: abs() expects parameter 1 to be int or float, string given (Aleksandr Dankovtsev) - * bug #32870 #32853 Check if $this->parameters is array. (ABGEO07) - * bug #32899 [Mailer] fix wrong error message when connection closes unexpectedly (fabpot) - * bug #32895 [Mailer] Fix error not being thrown properly (fabpot) - * bug #32868 [PhpUnitBridge] Allow symfony/phpunit-bridge > 4.2 to be installed with phpunit 4.8 (jderusse) - * bug #32823 [HttpClient] Preserve the case of headers when sending them (nicolas-grekas) - * bug #32767 [Yaml] fix comment in multi line value (soufianZantar) - * bug #32790 [HttpFoundation] Fix `getMaxFilesize` (bennyborn) - * bug #32796 [Cache] fix warning on PHP 7.4 (jpauli) - * bug #32806 [Console] fix warning on PHP 7.4 (rez1dent3) - * bug #32809 Don't add object-value of static properties in the signature of container metadata-cache (arjenm) - * bug #32708 Recompile container when translations directory changes (pierredup) - * bug #32722 [DependencyInjection] Fix bindings and tagged_locator (deguif) - * bug #32802 Make sure trace_level is always defined (dbu) - * bug #30096 [DI] Fix dumping Doctrine-like service graphs (bis) (weaverryan, nicolas-grekas) - * bug #32799 [HttpKernel] do not stopwatch sections when profiler is disabled (Tobion) - * bug #32631 [Messenger] expire delay queue and fix auto_setup logic (Tobion) - * bug #32641 [Messenger] Retrieve table default options from the SchemaManager (vincenttouzet) - -* 4.3.3 (2019-07-28) - - * bug #32726 [Messenger] Fix redis last error not cleared between calls (chalasr) - * bug #32760 [HttpKernel] clarify error handler restoring process (xabbuh) - * bug #32730 [Inflector] Fix pluralizing words ending with "son" (norkunas) - * bug #32715 [DI] fix perf issue with lazy autowire error messages (nicolas-grekas) - * bug #32503 Fix multiSelect ChoiceQuestion when answers have spaces (IceMaD) - * bug #32688 [Yaml] fix inline handling when dumping tagged values (xabbuh) - * bug #32710 [Security/Core] align defaults for sodium with PHP 7.4 (nicolas-grekas) - * bug #32644 [WebProfileBundle] Avoid getting right to left style (Arman-Hosseini) - * bug #32689 [HttpClient] rewind stream when using Psr18Client (nicolas-grekas) - * bug #32700 [Messenger] Flatten collection of stamps collected by the traceable middleware (ogizanagi) - * bug #32699 [HttpClient] fix canceling responses in a streaming loop (nicolas-grekas) - * bug #32679 [Intl] relax some date parser patterns (xabbuh) - * bug #31303 [VarDumper] Use \ReflectionReference for determining if a key is a reference (php >= 7.4) (dorumd, nicolas-grekas) - * bug #32485 [Validator] Added support for validation of giga values (kernig) - * bug #32567 [Messenger] pass transport name to factory (Tobion) - * bug #32568 [Messenger] Fix UnrecoverableExceptionInterface handling (LanaiGrunt) - * bug #32604 Properly handle optional tag attributes for !tagged_iterator (apfelbox) - * bug #32571 [HttpClient] fix debug output added to stderr at shutdown (nicolas-grekas) - * bug #32443 [PHPUnitBridge] Mute deprecations triggered from phpunit (greg0ire) - * bug #32572 Bump minimum version of symfony/phpunit-bridge (fancyweb) - * bug #32438 [Serializer] XmlEncoder: don't cast padded strings (ogizanagi) - * bug #32579 [Config] Do not use absolute path when computing the vendor freshness (lyrixx) - * bug #32563 Container*::getServiceIds() should return strings (mathroc) - * bug #32553 [Mailer] Allow register mailer configuration in xml format (Koc) - * bug #32442 Adding missing event_dispatcher wiring for messenger.middleware.send_message (weaverryan) - * bug #32466 [Config] Fix for signatures of typed properties (tvandervorm) - * bug #32501 [FrameworkBundle] Fix descriptor of routes described as callable array (ribeiropaulor) - * bug #32500 [Debug][DebugClassLoader] Include found files instead of requiring them (fancyweb) - * bug #32464 [WebProfilerBundle] Fix Twig 1.x compatibility (yceruto) - * bug #31620 [FrameworkBundle] Inform the user when save_path will be ignored (gnat42) - * bug #32096 Don't assume port 0 for X-Forwarded-Port (alexbowers, xabbuh) - * bug #31820 [SecurityBundle] Fix profiler dump for non-invokable security listeners (chalasr) - * bug #32392 [Messenger] Doctrine Transport: Support setting auto_setup from DSN (bendavies) - * bug #31267 [Translator] Load plurals from mo files properly (Stadly) - * bug #31266 [Translator] Load plurals from po files properly (Stadly) - * bug #32383 [Serializer] AbstractObjectNormalizer ignores the property types of discriminated classes (sandergo90) - * bug #32413 [Messenger] fix publishing headers set on AmqpStamp (Tobion) - * bug #32421 [EventDispatcher] Add tag kernel.rest on 'debug.event_dispatcher' service (lyrixx) - * bug #32398 [Messenger] Removes deprecated call to ReflectionType::__toString() on MessengerPass (brunowowk) - * bug #32379 [SecurityBundle] conditionally register services (xabbuh) - * bug #32380 [Messenger] fix broken key normalization (Tobion) - * bug #32363 [FrameworkBundle] reset cache pools between requests (nicolas-grekas) - * bug #32365 [DI] fix processing of regular parameter bags by MergeExtensionConfigurationPass (nicolas-grekas) - * bug #32187 [PHPUnit] Fixed composer error on Windows (misterx) - * bug #32299 [Lock] Stores must implement `putOffExpiration` (jderusse) - * bug #32302 [Mime] Remove @internal annotations for the serialize methods (francoispluchino) - * bug #32334 [Messenger] Fix authentication for redis transport (alexander-schranz) - * bug #32309 Fixing validation for messenger transports retry_strategy service key (weaverryan) - * bug #32331 [Workflow] only decorate when an event dispatcher was passed (xabbuh) - * bug #32236 [Cache] work aroung PHP memory leak (nicolas-grekas) - * bug #32206 Catch JsonException and rethrow in JsonEncode (phil-davis) - * bug #32211 [Mailer] Fix error message when connecting to a stream raises an error before connect() (fabpot) - * bug #32210 [Mailer] Fix timeout type hint (fabpot) - * bug #32199 [EventDispatcher] improve error messages in the event dispatcher (xabbuh) - * bug #32200 [Security/Core] work around sodium_compat issue (nicolas-grekas) - -* 4.3.2 (2019-06-26) - - * bug #31954 [PhpunitBridge] Read environment variable from superglobals (greg0ire) - * bug #32131 [Mailgun Mailer] fixed issue when using html body (alOneh) - * bug #31730 [PhpUnitBridge] More accurate grouping (greg0ire) - * bug #31966 [Messenger] Doctrine Connection find and findAll now correctly decode headers (TimoBakx) - * bug #31972 Add missing rendering of form help block. (alexsegura) - * bug #32141 [HttpClient] fix dealing with 1xx informational responses (nicolas-grekas) - * bug #32138 [Filesystem] fix mirroring directory into parent directory (xabbuh) - * bug #32137 [HttpFoundation] fix accessing session bags (xabbuh) - * bug #32147 [HttpClient] fix timing measurements with NativeHttpClient (nicolas-grekas) - * bug #32165 revert #30525 due to performance penalty (bendavies) - * bug #32164 [EventDispatcher] collect called listeners information only once (xabbuh) - * bug #32173 [FrameworkBundle] Fix calling Client::getProfile() before sending a request (dunglas) - * bug #32163 [DoctrineBridge] Fix type error (norkunas) - * bug #32154 [Messenger] fix retrying handlers using DoctrineTransactionMiddleware (Tobion) - * bug #32169 [Security/Core] require libsodium >= 1.0.14 (nicolas-grekas) - * bug #32170 [Security/Core] Don't use ParagonIE_Sodium_Compat (nicolas-grekas) - * bug #32156 [Workflow] re-add workflow.definition tag to workflow services (nikossvnk) - * bug #32053 [Messenger] No need for retry to require SentStamp (Tobion) - * bug #32083 [HttpClient] fixing passing debug info to progress callback (nicolas-grekas) - * bug #32129 [DebugBundle] fix register ReflectionCaster::unsetClosureFileInfo caster in var cloner service (alekitto) - * bug #32027 [Messenger] Remove DispatchAfterCurrentBusStamp when message is put on internal queue (Nyholm) - * bug #32125 [Form] accept floats for input="string" in NumberType (xabbuh) - * bug #32094 [Validator] Use LogicException for missing Property Access Component in comparison constraints (Lctrs) - * bug #32136 [FrameworkBundle] sync `require-dev` and `conflict` constraints (xabbuh) - * bug #32123 [Form] fix translation domain (xabbuh) - * bug #32115 [SecurityBundle] don't validate IP addresses from env var placeholders (xabbuh) - * bug #32116 [FrameworkBundle] tag the FileType service as a form type (xabbuh) - * bug #32109 [Messenger] fix delay exchange recreation after disconnect (Tobion) - * bug #32090 [Debug] workaround BC break in PHP 7.3 (nicolas-grekas) - * bug #32076 [Lock] Fix PDO prune not called (jderusse) - * bug #32071 Fix expired lock not cleaned (jderusse) - * bug #32052 [Messenger] fix AMQP delay queue to be per exchange (Tobion) - * bug #32065 [HttpClient] throw DecodingExceptionInterface when toArray() fails because of content-type error (nicolas-grekas) - * bug #32057 [HttpFoundation] Fix SA/phpdoc JsonResponse (ro0NL) - * bug #32040 [DI] Show the right class autowired when providing a non-existing class (Simperfit) - * bug #32035 [Messenger] fix delay delivery for non-fanout exchanges (Tobion) - * bug #32025 SimpleCacheAdapter fails to cache any item if a namespace is used (moufmouf) - * bug #32022 [HttpClient] Don't use CurlHttpClient on Windows when curl.cainfo is not set (nicolas-grekas) - * bug #32037 [Form] validate composite constraints in all groups (xabbuh) - * bug #32007 [Serializer] Handle true and false appropriately in CSV encoder (battye) - * bug #32036 [Messenger] improve logs (Tobion) - * bug #31998 Parameterize Mailgun's region (jderusse) - * bug #32000 [Routing] fix absolute url generation when scheme is not known (Tobion) - * bug #32012 Add statement to fileLink to ignore href code when no fileLink. (bmxmale) - * bug #32024 [VarDumper] fix dumping objects that implement __debugInfo() (nicolas-grekas) - * bug #32014 Do not log or call the proxy function when the locale is the same (gmponos) - * bug #32011 [HttpClient] fix closing debug stream prematurely (nicolas-grekas) - * bug #32017 [Contracts] add missing required dependencies (mbessolov) - * bug #31992 Fix sender/recipients in SMTP Envelope (fabpot) - * bug #31999 [PhpunitBridge] Restore php 5.5 compat (greg0ire) - * bug #31991 [EventDispatcher] collect called listeners information only once (xabbuh) - * bug #31988 [TwigBridge] add back possibility to use form themes without translations (xabbuh) - * bug #31982 [HttpClient] fix Psr18Client handling of non-200 response codes (nicolas-grekas) - * bug #31953 [DoctrineBridge] fix handling nested embeddables (xabbuh) - * bug #31962 Fix reporting unsilenced deprecations from insulated tests (nicolas-grekas) - * bug #31936 PropertyInfoLoader should not try to add validation to non-existent property (weaverryan) - * bug #31923 [Serializer] Fix DataUriNormalizer deprecation (MIME type guesser is optional) (ogizanagi) - * bug #31928 [FrameworkBundle] avoid service id conflicts with Swiftmailer (xabbuh) - * bug #31925 [Form] fix usage of legacy TranslatorInterface (nicolas-grekas) - * bug #31908 [Validator] fix deprecation layer of ValidatorBuilder (nicolas-grekas) - -* 4.3.1 (2019-06-06) - - * bug #31894 Fix wrong requirements for ocramius/proxy-manager in root composer.json (henrikvolmer) - * bug #31865 [Form] Fix wrong DateTime on outdated ICU library (aweelex) - * bug #31893 [HttpKernel] fix link to source generation (nicolas-grekas) - * bug #31880 [FrameworkBundle] fix BC-breaking property in WebTestAssertionsTrait (nicolas-grekas) - * bug #31881 [FramworkBundle][HttpKernel] fix KernelBrowser BC layer (nicolas-grekas) - * bug #31879 [Cache] Pass arg to get callback everywhere (fancyweb) - * bug #31874 [Doctrine Bridge] Check field type before adding Length constraint (belinde) - * bug #31872 [Messenger] Add missing runtime check for ext redis version (chalasr) - * bug #31864 [Cache] Fixed undefined variable in ArrayTrait (eXtreme) - * bug #31863 [HttpFoundation] Fixed case-sensitive handling of cache-control header in RedirectResponse constructor (Ivo) - * bug #31850 [HttpClient] add $response->cancel() (nicolas-grekas) - * bug #31871 [HttpClient] revert bad logic around JSON_THROW_ON_ERROR (nicolas-grekas) - * bug #31869 Fix json-encoding when JSON_THROW_ON_ERROR is used (nicolas-grekas) - * bug #31868 [HttpKernel] Fix handling non-catchable fatal errors (nicolas-grekas) - * bug #31834 [HttpClient] Don't throw InvalidArgumentException on bad Location header (nicolas-grekas) - * bug #31846 [Mailer] Set default crypto method (bpolaszek) - * bug #31849 [Console] Add check for Konsole/Yakuake to disable hyperlinks (belinde) - * bug #31854 Rename the Symfony Mailer service implementation to avoid conflict with SwitMailer (tgalopin) - * bug #31856 [VarDumper] fix dumping the cloner itself (nicolas-grekas) - * bug #31861 [HttpClient] work around PHP 7.3 bug related to json_encode() (nicolas-grekas) - * bug #31860 [HttpFoundation] work around PHP 7.3 bug related to json_encode() (nicolas-grekas) - * bug #31852 [Form] add missing symfony/service-contracts dependency (nicolas-grekas) - * bug #31836 [DoctrineBridge] do not process private properties from parent class (xabbuh) - * bug #31790 [Messenger] set amqp content_type based on serialization format (Tobion) - * bug #31832 [HttpClient] fix unregistering the debug buffer when using curl (nicolas-grekas) - * bug #31407 [Security] added support for updated "distinguished name" format in x509 authentication (Robert Kopera) - * bug #31774 [Mailer] Fix the possibility to set a From header from MessageListener (fabpot) - * bug #31811 [DoctrineBridge] don't add embedded properties to wrapping class metadata (xabbuh) - * bug #31786 [Translation] Fixed case sensitivity of lint:xliff command (javiereguiluz) - * bug #31815 [Translator] Collect locale details earlier in the process (pierredup) - * bug #31761 [TwigBridge] suggest Translation Component when TranslationExtension is used (nicolas-grekas) - * bug #31748 [Messenger] Inject RoutableMessageBus instead of bus locator (chalasr) - * bug #31763 [Security\Core] Make SodiumPasswordEncoder validate BCrypt-ed passwords (nicolas-grekas) - * bug #31744 [Validator] Fix TimezoneValidator default option (ro0NL) - * bug #31749 [DoctrineBridge][Validator] do not enable validator auto mapping by default (xabbuh) - * bug #31757 [DomCrawler] Fix type error with null Form::$currentUri (chalasr) - * bug #31721 [PHPUnitBridge] Use a more appropriate group when deprecating mode (greg0ire) - -* 4.3.0 (2019-05-30) - - * bug #31654 [HttpFoundation] Do not set X-Accel-Redirect for paths outside of X-Accel-Mapping (vilius-g) - -* 4.3.0-RC1 (2019-05-28) - - * bug #31650 Create an abstract HTTP transport and extend it in all HTTP transports (bocharsky-bw) - * feature #31641 [HttpClient] make $response->getInfo('debug') return extended logs about the HTTP transaction (nicolas-grekas) - * feature #31571 [Contracts] split in one package per sub-contracts (nicolas-grekas) - * bug #31625 [Messenger] Disable the SchemaAssetsFilter when setup the transport (vincenttouzet) - * bug #31621 [Messenger] Fix missing auto_setup for RedisTransport (chalasr) - * bug #31584 [Workflow] Do not trigger extra guards (lyrixx) - * bug #31632 [Messenger] Use "real" memory usage to honor --memory-limit (chalasr) - * bug #31610 [HttpClient] fix handling exceptions thrown before first mock chunk (nicolas-grekas) - * bug #31615 Allow WrappedListener to describe uncallable listeners (derrabus) - * bug #31599 [Translation] Fixed issue with new vs old TranslatorInterface in TranslationDataCollector (althaus) - * bug #31565 [Mime][HttpFoundation] Added mime type audio/x-hx-aac-adts (ifaridjalilov) - * bug #31591 [FrameworkBundle] fix named autowiring aliases for TagAwareCacheInterface (nicolas-grekas) - * bug #31590 [Cache] improve logged messages (nicolas-grekas) - * bug #31586 [HttpClient] display proper error message on TransportException when curl is used (nicolas-grekas) - * bug #31349 [WebProfilerBundle] Use absolute URL for profiler links (Alumbrados) - * bug #31541 [DI] fix using bindings with locators of service subscribers (nicolas-grekas) - * bug #31568 [Process] Fix infinite waiting for stopped process (mshavliuk) - -* 4.3.0-BETA2 (2019-05-22) - - * bug #31569 [HttpClient] Only use CURLMOPT_MAX_HOST_CONNECTIONS & CURL_VERSION_HTTP2 if defined (GawainLynch) - * bug #31566 [Security] fixed a fatal error when upgrading from 4.2 (fabpot) - * bug #31219 [HttpClient] Allow arrays as query parameters (sleepyboy) - * bug #31482 [Messenger][DoctrineBridge] Throws UnrecoverableMessageHandlingException when passed invalid entity manager name (Koc) - * feature #31471 [Messenger] Add "non sendable" stamps (weaverryan) - * bug #31545 [Messenger] Fix redis Connection::get() should be non blocking by default (chalasr) - * bug #31537 [Workflow] use method marking store (noniagriconomie) - * bug #31551 [ProxyManager] isProxyCandidate() does not take into account interfaces (andrerom) - * bug #31542 [HttpClient] add missing argument check (nicolas-grekas) - * bug #31544 [Messenger] Fix undefined index on read timeout (chalasr) - * bug #31335 [Doctrine] Respect parent class contract in ContainerAwareEventManager (Koc) - * bug #31421 [Routing][AnnotationClassLoader] fix utf-8 encoding in default route name (przemyslaw-bogusz) - * bug #31493 [EventDispatcher] Removed "callable" type hint from WrappedListener constructor (wskorodecki) - * bug #31502 [WebProfilerBundle][Form] The form data collector return serialized data (Simperfit) - * bug #31510 Use the current working dir as default first arg in 'link' binary (lyrixx) - * bug #31524 [HttpFoundation] prevent deprecation when filesize matches error code (xabbuh) - * bug #31535 [Debug] Wrap call to require_once in a try/catch (lyrixx) - * feature #31030 [Serializer] Deprecate calling createChildContext without the format parameter (dbu) - * bug #31459 Fix the interface incompatibility of EventDispatchers (keulinho) - * bug #31463 [DI] default to service id - *not* FQCN - when building tagged locators (nicolas-grekas) - * feature #31294 [Form] Add intl/choice_translation_locale option to TimezoneType (ro0NL) - * feature #31452 [FrameworkBundle] Add cache configuration for PropertyInfo (alanpoulain) - * feature #31486 [Doctrine][PropertyInfo] Detect if the ID is writeable (dunglas) - * bug #31481 [Validator] Autovalidation: skip readonly props (dunglas) - * bug #31480 Update dependencies in the main component (DavidPrevot) - * bug #31477 [PropertyAccess] Add missing property to PropertyAccessor (vudaltsov) - * bug #31479 [Cache] fix saving unrelated keys in recursive callback calls (nicolas-grekas) - * bug #30930 [FrameworkBundle] Fixed issue when a parameter contains a '' (lyrixx) - * bug #31438 [Serializer] Fix denormalization of object with variadic constructor typed argument (ajgarlag) - * bug #31445 [Messenger] Making cache rebuild correctly when message subscribers change (weaverryan) - * bug #31442 [Validator] Fix finding translator parent definition in compiler pass (deguif) - * bug #31475 [HttpFoundation] Allow set 'None' on samesite cookie flag (markitosgv) - * feature #31454 [Messenger] remove send_and_handle which can be achieved with SyncTransport (Tobion) - * bug #31425 [Messenger] On failure retry, make message appear received from original sender (weaverryan) - * bug #31472 [Messenger] Fix routable message bus default bus (weaverryan) - * bug #31465 [Serializer] Fix BC break: DEPTH_KEY_PATTERN must be public (dunglas) - * bug #31458 [TwigBundle] Fix Mailer integration in Twig (fabpot) - * bug #31456 Remove deprecated usage of some Twig features (fabpot) - * bug #31207 [Routing] Fixed unexpected 404 NoConfigurationException (yceruto) - * bug #31261 [Console] Commands with an alias should not be recognized as ambiguous when using register (Simperfit) - * bug #31371 [DI] Removes number of elements information in debug mode (jschaedl) - * bug #31418 [FrameworkBundle] clarify the possible class/interface of the cache (xabbuh) - -* 4.3.0-BETA1 (2019-05-09) - - * feature #31249 [Translator] Set sources when extracting strings from php files (Stadly) - * feature #31365 [Intl] Made countries ISO 3166 compliant + exclude Zzzz script code (ro0NL) - * feature #31060 [Validator] Make API endpoint for NotCompromisedPasswordValidator configurable (xelan) - * feature #31353 [FrameworkBundle] Show injected services for iterator and array arguments (jschaedl) - * feature #31350 [Intl] Rename Regions to Countries (ro0NL) - * feature #31364 [Bridge/PhpUnit] Extract all the code but shebang from bin/simple-phpunit (JustBlackBird) - * feature #30985 [Form] Keep preferred choices order in ChoiceType (vudaltsov) - * feature #31288 [Messenger] RoutableMessageBus route to default bus (dirk39) - * feature #31292 [Validator] Allow intl timezones (ro0NL) - * feature #30970 [Messenger] Adding failure transport support (weaverryan) - * feature #31318 [Intl] Compile localized timezone offset name (ro0NL) - * feature #31248 [Translator] Add sources when dumping qt files (Stadly) - * feature #31280 [WebServerBundle] Change the default pidfile location to cache directory (jschaedl) - * feature #31293 [Form] Remove default option grouping in TimezoneType (ro0NL) - * feature #31262 [Intl] Update timezones to ICU 64.2 + compile zone to country mapping (ro0NL) - * feature #31295 [Intl] Add timezone offset utilities (ro0NL) - * feature #30958 [Messenger] Allows to register handlers on a specific transport (sroze) - * feature #31061 [BridgeDoctrineMessenger] Doctrine ping connection middleware (insidestyles) - * feature #31282 [Messenger] Add WorkerStoppedEvent (chalasr) - * feature #31138 [Security] Dispatch an event when "logout user on change" steps in (Simperfit) - * feature #31242 Update LoggingTranslator to log the change of a locale (gmponos) - * feature #30917 [Messenger] Add a redis stream transport (soyuka, alexander-schranz) - * feature #31195 [Form] Add intltimezone input to TimezoneType (ro0NL) - * feature #31134 [Routing] do not encode comma in query and fragment (Tobion) - * feature #31220 [TwigBridge] bootstrap4 file_widget: allow setting label attributes declared in label_attr (AngelFQC) - * feature #31204 [Messenger] ease testing and allow forking the middleware stack (nicolas-grekas) - * feature #30370 [Cache] Add optimized FileSystem & Redis TagAware Adapters (andrerom) - * feature #28831 [Intl] Add Timezones (ro0NL) - * feature #31170 [Security] deprecate BCryptPasswordEncoder in favor of NativePasswordEncoder (nicolas-grekas) - * feature #31140 [Security] Add NativePasswordEncoder (nicolas-grekas) - * feature #31130 [VarDumper] add caster for WeakReference instances of PHP 7.4 (nicolas-grekas) - * feature #31082 [Form] Show all option normalizers on debug:form command (yceruto) - * feature #30957 [Messenger] Remove base64_encode & use addslashes (weaverryan) - * feature #30717 [Serializer] Use name converter when normalizing constraint violation list (norkunas) - * feature #28846 [Intl] Simplify API (ro0NL) - * feature #31093 [PhpUnitBridge] ClockMock does not mock gmdate() (Simperfit) - * feature #29211 [PhpUnitBridge] Url encoded deprecations helper config (greg0ire) - * feature #31062 [Dotenv] Deprecate useage of "putenv" (Nyholm) - * feature #31021 [Cache] Added command for list all available cache pools (Nyholm) - * feature #31027 [Config] Deprecate TreeBuilder::root (gharlan) - * feature #31019 [Security] Replace Argon2*PasswordEncoder by SodiumPasswordEncoder (chalasr) - * feature #30997 [Console] Add callback support to Console\Question autocompleter (Mikkel Paulson) - * feature #30959 [FrameworkBundle] [TwigBundle] Move the hinclude key away from templating (Simperfit) - * feature #30968 [Security] Add Argon2idPasswordEncoder (chalasr) - * feature #30963 [Serializer] Experimental for ObjectListExtractor (joelwurtz) - * feature #30933 [Routing][ObjectRouteLoader] Allow invokable route loader services (fancyweb) - * feature #30897 [DIC] Add a `require` env var processor (mpdude) - * feature #30964 [HttpKernel] Add a "short" trace header format, make header configurable (mpdude) - * feature #29935 [DI] Fix bad error message for unused bind under _defaults (przemyslaw-bogusz) - * feature #30962 [DoctrineBridge] Deprecated implicit optimization in DoctrineChoiceLoader (HeahDude) - * feature #30862 [Routing] UrlHelper to get absolute URL for a path (vudaltsov) - * feature #30607 [Serializer] Add Support of recursive denormalization on object_to_populate (jewome62) - * feature #30429 [Form] group_by as callback returns array (antonch1989) - * feature #30887 [FrameworkBundle] fix search in debug autowiring (sez-open) - * feature #30935 Use env variable to create anytype of lock store (jderusse) - * feature #30932 [Validator] Add an option to disable NotCompromisedPasswordValidator (lyrixx) - * feature #30909 [Translator] Add comments when dumping po files (deguif) - * feature #30913 [Messenger] Uses an `AmqpStamp` to provide flags and attributes (sroze) - * feature #30900 [Validator] add new `Timezone` validation constraint (phansys) - * feature #30915 [Serializer] Add datetimezone normalizer (jewome62) - * feature #28937 Improve Translator caching (rpkamp) - * feature #30904 [Serializer] provide new ObjectPropertyListExtractorInterface (dmaicher) - * feature #30902 [Workflow] The TransitionEvent is able to modify the context (lyrixx) - * feature #30908 [Workflow] Added workflow_transition_blockers twig function (lyrixx) - * feature #30893 Add "input" option to NumberType (fancyweb, Bernhard Schussek) - * feature #30898 [Validator] Wire NotCompromisedPassword in FrameworkBundle and handle non UTF-8 password (tgalopin) - * feature #30890 [Workflow] Changed initial_places to initial_marking, added property (HeahDude, lyrixx) - * feature #30906 [symfony/HttpKernel] Throws an error when the generated class name is invalid. (drupol) - * feature #30892 [DomCrawler] Improve Crawler HTML5 parser need detection (tgalopin) - * feature #30901 Renamed NotPwned to NotCompromisedPassword (javiereguiluz) - * feature #30020 [Messenger] Ensure message is handled only once per handler (keulinho, sroze) - * feature #30545 #30536 PropertyAccessor->getValue disable exception (dimabory) - * feature #30008 [messenger] Adds a stamp to provide a routing key on message publishing (G15N, sroze) - * feature #29097 [Messenger] Add a "in-memory://" transport (GaryPEGEOT, sroze) - * feature #30537 [HttpClient] logger integration (antonch1989, nicolas-grekas) - * feature #30853 [Twig] Remove TemplatedEmail::template() (fabpot) - * feature #30757 [Messenger] Adding MessageCountAwareInterface to get transport message count (weaverryan) - * feature #28929 [HttpKernel][Framework] Locale aware services (neghmurken) - * feature #29306 [DomCrawler] Optionally use html5-php to parse HTML (tgalopin) - * feature #30255 [DependencyInjection] Invokable Factory Services (zanbaldwin) - * feature #30843 [HttpClient] Add ScopingHttpClient::forBaseUri() + tweak MockHttpClient (nicolas-grekas) - * feature #30844 [Cache] add logs on early-recomputation and locking (nicolas-grekas) - * feature #30520 [RouterDebugCommand] add link to Controllers (nicoweb) - * feature #30212 [DI] Add support for "wither" methods - for greater immutable services (nicolas-grekas) - * feature #30674 [FrameworkBundle] change the way http clients are configured by leveraging ScopingHttpClient (nicolas-grekas) - * feature #29312 [EventDispatcher] Split events across requests (ro0NL) - * feature #30827 [TwigBridge] Add template file link to debug:twig command (yceruto) - * feature #30826 [Form] Add file links for described classes in debug:form command (yceruto) - * feature #30813 New PHPUnit assertions for the WebTestCase (Pierstoval, fabpot) - * feature #27738 [Validator] Add a HaveIBeenPwned password validator (dunglas) - * feature #30690 Changing messenger bus id from 'message_bus' to 'messenger.default_bus' (THERAGE Kévin) - * feature #30810 [Inflector] remove "internal" marker from the component (nicolas-grekas) - * feature #26890 [Inflector] Support pluralization in the inflector (mbabker) - * feature #28637 [Validator] add number constraints (jschaedl) - * feature #30754 [Messenger] New messenger:stop-workers Command (weaverryan) - * feature #30707 [Messenger][DX] Allow stamps to be passed directly to MessageBusInterface::dispatch() (weaverryan) - * feature #29007 [Messenger] Add a Doctrine transport (vincenttouzet) - * feature #30628 Making the serializer configurable by transport (weaverryan) - * feature #30569 [FrameworkBundle][HttpKernel] Provide intuitive error message when a controller fails because it's not registered as a service (moynzzz) - * feature #26484 [Validator] String normalization options for string-based validators (renan-taranto) - * feature #30320 [Form][TwigBridge] Add row_attr to form theme (alexander-schranz) - * feature #30371 [OptionsResolver] Add a new method addNormalizer and normalization hierarchy (yceruto) - * feature #27735 [Validator][DoctrineBridge][FWBundle] Automatic data validation (dunglas) - * feature #30758 [PropertyAccess] Allow Can Accessor in Property Access (ragboyjr) - * feature #30116 [Filesystem] Fix mirroring a directory into itself or in his child with realpath checks (Fleuv, XuruDragon) - * feature #28879 [Debug] Mimic __toString php behavior in FlattenException (Deltachaos) - * feature #29495 [Ldap] Implement pagination (kevans91) - * feature #29448 [Ldap] Entry move support (kevans91) - * feature #30741 Add the Mailer component (fabpot) - * feature #30780 Fix some exception previous type hints (fabpot) - * feature #30729 [HttpKernel] change $previous argument for HttpException to \Throwable (sGy1980de) - * feature #30744 [Finder] Throw a dedicated exception for non-existing directory (xelan) - * feature #30759 [Messenger] Adding the "sync" transport to call handlers synchronously (weaverryan) - * feature #30772 [Contracts][EventDispatcher] move the Event class to symfony/contracts (nicolas-grekas) - * feature #30708 [Messenger] ReceiverInterface::handle() to get() & Worker with prioritized transports (weaverryan) - * feature #27648 [Lock] Added MongoDBStore (Joe Bennett) - * feature #30752 [HttpClient] use "nyholm/psr7" by default in Psr18Client (nicolas-grekas) - * feature #30671 Add optional parameter `prefetching` for AMQP connection (fbouchery) - * feature #25707 [DI] ServiceProviderInterface, implementation for ServiceLocator (kejwmen) - * feature #30606 [Validator] allow brackets in the optional query string (Emmanuel BORGES) - * feature #29476 [Messenger] Add a command to setup transports (vincenttouzet) - * feature #30719 [Mime] Add BodyRendererInterface (fabpot) - * feature #30664 [Finder] Get filename without extension (antonch1989) - * feature #30645 Alias for each assets package (gpenverne) - * feature #30706 [PropertyInfo] Add possibility to extract private and protected properties in reflection extractor (joelwurtz) - * feature #27808 [DI] Deprecate non-string default envs (ro0NL) - * feature #30691 [Contracts][EventDispatcher] add EventDispatcherInterface to symfony/contracts and use it where possible (nicolas-grekas) - * feature #20978 [Form] TransformationFailedException: Support specifying message to display (ogizanagi) - * feature #30676 Avoid dispatching SendMessageToTransportsEvent on redeliver (weaverryan) - * feature #26555 [Validator] Add constraint on unique elements collection(Assert\Unique) (zenmate, nicolas-grekas) - * feature #27684 [FrameworkBundle] Debug container environment variables (ro0NL) - * feature #30666 [Form][Console] Use dumper (ro0NL) - * feature #30559 [HttpClient] Parse common API error formats for better exception messages (dunglas) - * feature #28898 [Console] Add dumper (ro0NL) - * feature #30629 [HttpClient] added CachingHttpClient (fabpot) - * feature #30602 [BrowserKit] Add support for HttpClient (fabpot, THERAGE Kévin) - * feature #30651 Allow user to set the project dir (tdutrion) - * feature #30654 [HttpClient] Add a ScopingHttpClient (XuruDragon) - * feature #30388 [Security] undeprecate the RoleHierarchyInterface (xabbuh) - * feature #30652 Fixing a bug where messenger:consume could send message to wrong bus (weaverryan) - * feature #30650 Dispatching two events when a message is sent & handled (weaverryan) - * feature #30557 [Messenger] Worker events + global retry functionality (weaverryan) - * feature #30468 [Workflow] Added support for many inital places (lyrixx) - * feature #30448 [Finder] Ignore paths from .gitignore #26714 (amaabdou) - * feature #30625 [HttpKernel] add RealHttpKernel: handle requests with HttpClientInterface (fabpot) - * feature #30508 [Routing] Exposed "utf8" option, defaults "locale" and "format" in configuration (Jules Pietri) - * feature #28920 [EventDispatcher] swap arguments of dispatch() to allow registering events by FQCN (nicolas-grekas) - * feature #30605 [Cache] added DSN support for rediss in AbstractAdapter and RedisTrait (alex-vasilchenko-md) - * feature #30604 [HttpClient] add MockHttpClient (nicolas-grekas) - * feature #21035 [FrameworkBundle] Deprecate the Templating component integration (dunglas, fabpot) - * feature #30567 [HttpClient] exceptions carry response (antonch1989) - * feature #28849 [Messenger] Support for handling messages after current bus is finished (Nyholm) - * feature #29538 [Workflow] Add colors to workflow dumps (alexislefebvre) - * feature #28975 [DI] Add an url EnvProcessor (jderusse) - * feature #30419 [FrameworkBundle] Add integration of http-client component (Ioni14, nicoweb) - * feature #30583 [Messenger] Display a nice error when connection fail (lyrixx) - * feature #30450 [Profiler] Render the performance graph with SVG (Tom32i) - * feature #29130 [Serializer] Normalize constraint violation parameters (ogizanagi) - * feature #28330 [MonologBridge] Add monolog processors adding route and command info (trakos) - * feature #30339 [Monolog] Disable DebugLogger in CLI (lyrixx) - * feature #30584 [Intl] Add compile binary (ro0NL) - * feature #30579 Using AMQP auto-setup in all cases, not just in debug (weaverryan) - * feature #30348 [DependencyInjection] Add ability to define an index for service in an injected service locator argument (XuruDragon, nicolas-grekas) - * feature #30469 Create a hyperlink to interfaces/classes that can be autowired (SerkanYildiz) - * feature #30334 [DI] add ReverseContainer: a locator that turns services back to their ids (nicolas-grekas) - * feature #30539 [Messenger] deprecate LoggingMiddleware in favor of providing a logger to SendMessageMiddleware (nicolas-grekas) - * feature #30556 [HttpClient] Allow to pass user/pw as an array (dunglas) - * feature #30547 [HttpClient] Add new bearer option (dunglas) - * feature #29303 [Messenger] add welcome notice when running the command (nicolas-grekas) - * feature #30541 [BrowserKit] Rename Client to Browser (fabpot) - * feature #30504 [DI] replace "nullable" env processor by improving the "default" one (nicolas-grekas) - * feature #30499 [HttpClient] add ResponseInterface::toArray() (nicolas-grekas) - * feature #30472 [Translation] Add XLIFF 1 source to metadata to differentiate from attr (ostrolucky) - * feature #30484 [Mime] added Headers::toArray() (fabpot) - * feature #30482 [Mime] Fix support for date form parts (fabpot) - * feature #30385 [SecurityBundle] Validate the IPs configured in access_control (javiereguiluz) - * feature #30413 [HttpClient][Contracts] introduce component and related contracts (nicolas-grekas) - * feature #30377 [Validator] add MIR card scheme (antonch1989) - * feature #29146 [Workflow] Added a context to `Workflow::apply()` (lyrixx) - * feature #30433 [Form] Allow to disable and customize PercentType symbol (Ken Stanley, OskarStark) - * feature #30408 [HttpKernel] Better exception page when the invokable controller returns nothing (dimabory) - * feature #30325 [HttpKernel] Prevent search engines from indexing dev applications (GaryPEGEOT) - * feature #30390 [FrameworkBundle] Fix UrlGenerator::generate to return an empty string instead of null (Emmanuel BORGES) - * feature #30375 [Messenger] Added transport agnostic exception (nikossvnk, lolmx) - * feature #29254 [FrameworkBundle] Added the condition routing option to the debug router command (soufianZantar) - * feature #30286 Drop more usages of Serializable (nicolas-grekas) - * feature #30379 [FrameworkBundle][Routing] allow boolean container parameters for routes (dmaicher) - * feature #29661 [Filesystem] Support resources and deprecate using arrays in dumpFile() and appendToFile() (thewilkybarkid) - * feature #30358 [Form] be able to specify the input format for times (xabbuh) - * feature #30416 Mime messages (fabpot) - * feature #22048 [Security] deprecate the Role and SwitchUserRole classes (xabbuh) - * feature #30345 [Monolog] Added a way to configure the ConsoleFormatter from the ConsoleHandler (lyrixx) - * feature #30357 [TwigBridge] rename parent_form() to form_parent() (xabbuh) - * feature #30257 [DependencyInjection] Allow to choose an index for tagged collection (deguif, XuruDragon) - * feature #30311 [VarDumper] Implement DsCaster (enumag) - * feature #27570 [PropertyInfo] Added support for extract type from default value (tsantos84) - * feature #28919 [DX][WebProfilerBundle] Add Pretty Print functionality for Request Content (SamFleming) - * feature #28723 [Form] deprecate custom formats with HTML5 widgets (xabbuh) - * feature #29865 [Console] Added suggestions for missing packages (przemyslaw-bogusz) - * feature #30301 [VarDumper] add link to source next to class names (nicolas-grekas) - * feature #30225 publish message with custom queue options : flags | attributes (fedor.f, insidestyles) - * feature #30249 [Routing] deprecate some router options (Tobion) - * feature #30267 [Form] add option to render NumberType as type="number" (xabbuh) - * feature #28969 [Form] deprecate using invalid names for buttons (xabbuh) - * feature #29887 [Form] Add input_format option to DateType and DateTimeType (fancyweb) - * feature #30051 Drop \Serializable implementations (renanbr) - * feature #30236 Add element to ghost in Exception (przemyslaw-bogusz) - * feature #30120 [FrameworkBundle][Translation] Added support for PHP files with trans() in translation commands (yceruto) - * feature #28812 [Form] add a convenience method to get the parent form in Twig templates (xabbuh) - * feature #29121 [FrameworkBundle][Translation] Add support for Translator paths, Twig paths and Translator aware services paths in commands (yceruto) - * feature #28477 [Validator] Add new json Validator (zairigimad) - * feature #30126 [Form] forward valid numeric values to transform() (xabbuh) - * feature #28635 [Form] Add label_translation_parameters, help_translation_parameters and attr_translation_parameters options to base form type (webnet-fr) - * feature #29767 Nullable environment variable processor (bpolaszek) - * feature #30111 [SecurityBundle] Deprecate the normalization of the cookie names (javiereguiluz) - * feature #30027 [FrameworkBundle] Add sid_length and sid_bits_per_character session ini options in session configuration (XuruDragon) - * feature #30075 [DependencyInjection] Added information about deprecated aliases in debug:autowiring (XuruDragon) - * feature #30024 [Debug] Display more details in the simple error page of Debug (javiereguiluz) - * feature #30052 [Security] Replace serialization API (renanbr) - * feature #27898 [Yaml] Fixed invalid Parser behavior (guiguiboy) - * feature #29753 [Console] Add an iterate method to the ProgressBar class (jvasseur) - * feature #29999 [PropertyAccess] speed up accessing object properties (xabbuh) - * feature #29641 [Validator] NotBlank: add a new option to allow null values (dunglas) - * feature #28721 [Form] deprecate some options for single_text widgets (xabbuh) - * feature #29936 [Mime] Add a set of default content-types for some extensions (fabpot) - * feature #28865 [Routing] allow using compiled matchers and generators without dumping PHP code (nicolas-grekas) - * feature #29236 [Cache] deprecate all PSR-16 adapters, provide Psr16Cache instead (nicolas-grekas) - * feature #29958 introducing native php serialize() support for Messenger transport (weaverryan, xabbuh) - * feature #29861 [Form][TwigBridge] Add help_html (mpiot) - * feature #29968 [DI] Added support for deprecating aliases (j92, Renan) - * feature #29850 [FrameworkBundle] xliff-version option to translation update command (andrewwro) - * feature #29896 [Mime] Add the component (fabpot) - * feature #29862 Add block prefix to csrf token field (alexander-schranz) - * feature #29881 [BrowserKit] Various changes to the Response class (fabpot) - * feature #29813 [FrameworkBundle] Remove ControllerTrait::isFormValid() (lyrixx) - * feature #29148 Load original file metadata when loading Xliff 1.2 files (eternoendless) - * feature #29840 [FrameworkBundle] pass project dir into the assets install command (xabbuh) - * feature #29821 [VarDumper] add caster for OpenSSL X.509 resources (nicolas-grekas) - * feature #29781 [DI] Add trim env processor (ogizanagi) - * feature #28902 [Debug] Detect virtual methods using @method (ro0NL) - * feature #29780 [Profiler] Still show locale and fallback locale even if no trans used (ogizanagi) - * feature #29680 [Form] Add new block_prefix option for an easy form theming (yceruto) - * feature #29528 [DebugBundle] Added 'theme' option to change the color of dump() when rendered inside templates (dem3trio) - * feature #24576 [FrameworkBundle] Added `ControllerTrait::isFormValid` (lyrixx) - * feature #29483 [HttpKernel] Set the default locale early (thewilkybarkid) - * feature #29186 [HttpKernel] Increase priority of AddRequestFormatsListener (thewilkybarkid) - * feature #29658 [Validator] Choices constraint improvement (nikophil) - * feature #29283 [Serializer] CsvEncoder no header option (encode / decode) (redecs) - * feature #29718 [PHPUnit bridge] Bump php version of PHPUnit-bridge (gmponos) - * feature #29599 [Routing] Allow force-generation of trailing parameters using eg "/exports/news.{!_format}" (zavulon) - * feature #29613 [VarDumper] Use hyperlinks in CliDescriptor (ogizanagi) - * feature #28581 [DomCrawler] return empty string on `Crawler::text()` and `Crawler::html()` instead of an exception (respinoza) - * feature #29286 [WebProfilerBundle] Enable translation filters (ro0NL) - * feature #29517 [Hackday][Messenger] Add an alias for transport.symfony_serializer so SerializerInterface can be autowired (karser) - * feature #29108 [DI] compute autowiring error messages lazily (nicolas-grekas) - * feature #29235 [VarDumper] add support for links in CliDumper (nicolas-grekas) - * feature #29541 [FrameworkBundle] Stop calling Kernel::boot() twice in cli (chalasr) - * feature #28931 [PhpUnitBridge] Added ClassExistsMock (ro0NL) - * feature #29504 [Validator] Add support for UATP card validation (raulfraile) - * feature #29168 [Console] Add hyperlinks support (ostrolucky) - * feature #29439 [PhpUnitBridge] install PHPUnit 7 on PHP 7.1 and fix requir. for PHPUnit 6 (gregurco) - * feature #29452 [Form] Shortcut debug:form for partial type name (ro0NL) - * feature #28954 [Debug] Mark ErrorHandler and ExceptionHandler classes as final (fancyweb) - * feature #28479 [Validator] Checking a BIC along with an IBAN (sylfabre) - * feature #28858 [DI] Deprecated using env vars with cannotBeEmpty() (ro0NL) - * feature #28976 [DI] Add a "default" EnvProcessor (jderusse) - * feature #29127 [DomCrawler] Added return of element name in `extract()` method (andrey-helldar) - * feature #29145 [Workflow] Trigger `entered` event for subject entering in the Workflow for the first time (lyrixx) - diff --git a/CHANGELOG-4.4.md b/CHANGELOG-4.4.md deleted file mode 100644 index 3a2f916e7fc34..0000000000000 --- a/CHANGELOG-4.4.md +++ /dev/null @@ -1,1166 +0,0 @@ -CHANGELOG for 4.4.x -=================== - -This changelog references the relevant changes (bug and security fixes) done -in 4.4 minor versions. - -To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash -To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.4.0...v4.4.1 - -* 4.4.21 (2021-03-29) - - * bug #40598 [Form] error if the input string couldn't be parsed as a date (xabbuh) - * bug #40587 [HttpClient] fix using stream_copy_to_stream() with responses cast to php streams (nicolas-grekas) - * bug #40510 [Form] IntegerType: Always use en for IntegerToLocalizedStringTransformer (Warxcell) - * bug #40593 Uses the correct assignment action for console options depending if they are short or long (topikito) - * bug #40535 [HttpKernel] ConfigDataCollector to return known data without the need of a Kernel (topikito) - * bug #40552 [Translation] Fix update existing key with existing +int-icu domain (Alexis) - * bug #40537 [Security] Handle properly 'auto' option for remember me cookie security (fliespl) - * bug #40506 [Validator] Avoid triggering the autoloader for user-input values (Seldaek) - * bug #40538 [HttpClient] remove using $http_response_header (nicolas-grekas) - * bug #40508 [PhpUnitBridge] fix reporting deprecations from DebugClassLoader (nicolas-grekas) - * bug #40348 [Console] Fix line wrapping for decorated text in block output (grasmash) - * bug #40499 [Inflector][String] Fixed pluralize "coupon" (Nyholm) - * bug #40494 [PhpUnitBridge] fix compat with symfony/debug (nicolas-grekas) - * bug #40453 [VarDumper] Adds support for ReflectionUnionType to VarDumper (Michael Nelson, michaeldnelson) - * bug #40460 Correctly clear lines for multi-line progress bar messages (grasmash) - * bug #40450 [Console] ProgressBar clears too many lines on update (danepowell) - * bug #40178 [FrameworkBundle] Exclude unreadable files when executing About command (michaljusiega) - * bug #40472 [Bridge\Twig] Add 'form-control-range' for range input type (Oviglo) - * bug #39866 [Mime] Escape commas in address names (YaFou) - * bug #40373 Check if templating engine supports given view (fritzmg) - * bug #39992 [Security] Refresh original user in SwitchUserListener (AndrolGenhald) - * bug #40446 [TwigBridge] Fix "Serialization of 'Closure'" error when rendering an TemplatedEmail (jderusse) - * bug #40425 [DoctrineBridge] Fix eventListener initialization when eventSubscriber constructor dispatch an event (jderusse) - * bug #40313 [FrameworkBundle] Fix PropertyAccess definition when not in debug (PedroTroller) - * bug #40417 [Form] clear unchecked choice radio boxes even if clear missing is set to false (xabbuh) - * bug #40388 [ErrorHandler] Added missing type annotations to FlattenException (derrabus) - * bug #40407 [TwigBridge] Allow version 3 of the Twig extra packages (derrabus) - * bug #39685 [Mailer][Mime][TwigBridge][Validator] Allow egulias/email-validator 3.x (derrabus) - * bug #40398 [FrameworkBundle] : Fix method name compare in ResolveControllerNameSubscriber (glensc) - * bug #39733 [TwigBridge] Render email once (jderusse) - * bug #40386 [DependencyInjection][Security] Backport psr/container 1.1/2.0 compatibility (derrabus) - -* 4.4.20 (2021-03-04) - - * bug #40318 [Translation] deal with indented heredoc/nowdoc tokens (xabbuh) - * bug #40350 [DependencyInjection] fix parsing calls of methods named "method" (xabbuh) - * bug #40316 [Serializer] zero parts can be omitted in date interval input (xabbuh) - * bug #40239 MockResponse total_time should not be simulated when provided (Pierrick VIGNAND) - * bug #40299 [Cache] Add server-commands support for Predis Replication Environments (DemigodCode) - * bug #40231 [HttpKernel] Configure `session.cookie_secure` earlier (tamcy) - * bug #40283 [Translation] Make `name` attribute optional in xliff2 (MarieMinasyan) - * bug #39599 [Cache] Fix Redis TLS scheme `rediss` for Redis connection (misaert) - * bug #40244 [Routing] fix conflict with param named class in attribute (nlhommet) - * bug #40273 [Cache] fix setting items' metadata on commit() (nicolas-grekas) - * bug #40258 [Form] Ignoring invalid forms from delete_empty behavior in CollectionType (yceruto) - * bug #40162 [Intl] fix Locale::getFallback() throwing exception on long $locale (AmirHo3ein13) - * bug #40208 [PropertyInfo] fix resolving self to name of the analyzed class (xabbuh) - * bug #40209 [WebLink] Escape double quotes in attributes values (fancyweb) - * bug #40192 [Console] fix QuestionHelper::getHiddenResponse() not working with space in project directory name (Yendric) - * bug #40175 [PropertyInfo]  use the right context for properties defined in traits (xabbuh) - * bug #40172 [Translation] Allow using dashes in locale when linting Xliff files (localheinz) - * bug #40187 [Console] Fix PHP 8.1 null error for preg_match flag (kylekatarnls) - * bug #39659 [Form] keep valid submitted choices when additional choices are submitted (xabbuh) - * bug #40188 [HttpFoundation] Fix PHP 8.1 null values (kylekatarnls) - * bug #40167 [DependencyInjection] Definition::removeMethodCall should remove all matching calls (ruudk) - * bug #40160 [PropertyInfo] fix extracting mixed type-hinted property types (xabbuh) - * bug #40040 [Finder] Use a lazyIterator to close files descriptors when no longer used (jderusse) - * bug #40135 [FrameworkBundle] Fix freshness checks with boolean parameters on routes (HypeMC) - * bug #40138 [FrameworkBundle] fix registering "annotations.cache" on the "container.hot_path" (nicolas-grekas) - * bug #40116 [FrameworkBundle][Translator] scan directories for translations sequentially (xabbuh) - * bug #40104 [HttpKernel] [Kernel] Silence failed deprecations logs writes (fancyweb) - * bug #40098 [DependencyInjection] fix tracking of changes to vendor/ dirs (nicolas-grekas) - * bug #39980 [Mailer][Mime] Update inline part names with newly generated ContentId (ddegentesh) - * bug #40043 [HttpFoundation] Setting `REQUEST_TIME_FLOAT` when constructing a Request object (ctasada) - * bug #40050 [FrameworkBundle][Translator] Fixed updating catalogue metadata from Intl domain (yceruto) - * bug #40089 [SecurityBundle] role_names variable instead of roles (wickedOne) - * bug #40042 [Doctrine] Restore priority for EventSubscribers (jderusse) - * bug #40066 [ErrorHandler] fix parsing return types in DebugClassLoader (nicolas-grekas) - * bug #40065 [ErrorHandler] fix handling messages with null bytes from anonymous classes (nicolas-grekas) - * bug #40067 [PhpUnitBridge] fix reporting deprecations when they come from DebugClassLoader (nicolas-grekas) - * bug #40060 fix validator when we have false returned by the current element of the iterator (FabienSalles) - * bug #40062 [Mime] Fix case-sensitive handling of header names (piku235) - * bug #40023 [Finder]  use proper keys to not override appended files (xabbuh) - * bug #40019 [ErrorHandler] Fix strpos error when trying to call a method without a name (Deuchnord) - * bug #40004 [Serializer] Prevent access to private properties without getters (julienfalque) - -* 4.4.19 (2021-01-27) - - * bug #38900 [Serializer] Exclude non-initialized properties accessed with getters (BoShurik) - * bug #39887 [Translator] fix handling plural for floating numbers (kylekatarnls) - * bug #39967 [Messenger] fix redis messenger options with dsn (Kleinast) - * bug #39970 [Messenger] Fix transporting non-UTF8 payloads by encoding them using base 64 (nicolas-grekas) - * bug #39909 [PhpUnitBridge] Allow relative path to composer cache (jderusse) - * bug #39944 [HttpKernel] Configure the ErrorHandler even when it is overriden (nicolas-grekas) - * bug #39932 [Console] [Command] Fix Closure code binding when it is a static anonymous function (fancyweb) - * bug #39880 [DoctrineBridge] Add username to UserNameNotFoundException (qurben) - * bug #39633 [HttpFoundation] Drop int return type from parseFilesize() (LukeTowers) - * bug #39889 [HttpClient] Add check for constant in Curl client (pierredup) - * bug #39886 [HttpFoundation] Revert #38614 and add assert to avoid regressions (BafS) - * bug #39858 Fix problem when SYMFONY_PHPUNIT_VERSION is empty string value (alexander-schranz) - * bug #39861 [DependencyInjection] Skip deprecated definitions in CheckTypeDeclarationsPass (chalasr) - * bug #39862 [Security] Replace message data in JSON security error response (wouterj) - * bug #39667 [DoctrineBridge] Take into account that indexBy="person_id" could be a db column name, for a referenced entity (victormacko) - * bug #39799 [DoctrineBridge] Fix circular loop with EntityManager (jderusse) - * bug #39821 [DependencyInjection] Don't trigger notice for deprecated aliases pointing to deprecated definitions (chalasr) - * bug #39816 [HttpFoundation] use atomic writes in MockFileSessionStorage (nicolas-grekas) - * bug #39735 [Serializer] Rename normalize param (VincentLanglet) - * bug #39797 Dont allow unserializing classes with a destructor (jderusse) - * bug #39743 [Mailer] Fix missing BCC recipients in SES bridge (jderusse) - * bug #39764 [Config]  fix handling float-like key attribute values (xabbuh) - * bug #39787 [Yaml] a colon followed by spaces exclusively separates mapping keys and values (xabbuh) - * bug #39788 [Cache] fix possible collision when writing tmp file in filesystem adapter (nicolas-grekas) - * bug #39794 Dont allow unserializing classes with a destructor - 4.4 (jderusse) - * bug #39747 [DependencyInjection] Support PHP 8 builtin types in CheckTypeDeclarationsPass (derrabus) - * bug #39738 [VarDumper] fix mutating $GLOBALS while cloning it (nicolas-grekas) - * bug #39746 [DependencyInjection] Fix InvalidParameterTypeException for function parameters (derrabus) - * bug #39681 [HttpFoundation] parse cookie values containing the equal sign (xabbuh) - * bug #39716 [DependencyInjection] do not break when loading schemas from network paths on Windows (xabbuh) - * bug #39703 [Finder] apply the sort callback on the whole search result (xabbuh) - * bug #39717 [TwigBridge] Remove full head content in HTML to text converter (pupaxxo) - * bug #39708 [WebProfilerBundle] take query and request parameters into account when matching routes (xabbuh) - * bug #39683 [Yaml] keep trailing newlines when dumping multi-line strings (xabbuh) - * bug #39670 [Form] disable error bubbling by default when inherit_data is configured (xabbuh) - * bug #39686 [Lock] Fix config merging in lock (jderusse) - * bug #39668 [Yaml] do not dump extra trailing newlines for multiline blocks (xabbuh) - * bug #39653 [Form] fix passing null $pattern to IntlDateFormatter (nicolas-grekas) - * bug #39598 [Messenger] Fix stopwach usage if it has been reset (lyrixx) - * bug #39631 [VarDumper] Fix display of nullable union return types (derrabus) - * bug #39629 [VarDumper] fixed displaying "mixed" as "?mixed" (nicolas-grekas) - * bug #39597 [Mailer] Handle failure when sending DATA (jderusse) - * bug #39610 [ProxyManagerBridge] fix PHP notice, switch to "friendsofphp/proxy-manager-lts" (nicolas-grekas) - -* 4.4.18 (2020-12-18) - - * bug #39531 [Mailer] Fix parsing Dsn with empty user/password (OskarStark) - * bug #39518 [Ldap] Incorrect determination of RelativeDistinguishedName for the "move" operation (astepin) - * bug #39476 [Lock] Prevent store exception break combined store (dzubchik) - * bug #39433 [Cache] fix setting "read_timeout" when using Redis (nicolas-grekas) - * bug #39420 [Cache] Prevent notice on case matching metadata trick (bastnic) - * bug #39203 [DI] Fix not working if only "default_index_method" used (malteschlueter) - * bug #39142 [Config] Stop treating multiline resources as globs (michaelKaefer) - * bug #39341 [Form] Fixed StringUtil::trim() to trim ZERO WIDTH SPACE (U+200B) and SOFT HYPHEN (U+00AD) (pmishev) - * bug #39334 [Config][TwigBundle] Fixed syntax error in config (Nyholm) - * bug #39196 [DI] Fix Xdebug 3.0 detection (vertexvaar) - * bug #39226 [PhpUnitBridge] Fix disabling DeprecationErrorHandler from PHPUnit configuration file (fancyweb) - * bug #39357 [FrameworkBundle] fix preserving some special chars in the query string (nicolas-grekas) - * bug #39271 [HttpFoundation] Fix TypeError: Argument 1 passed to JsonResponse::setJson() must be of the type string, object given (sidz) - * bug #39251 [DependencyInjection] Fix container linter for union types (derrabus) - * bug #39336 [Config] YamlReferenceDumper: No default value required for VariableNode with array example (Nyholm) - * bug #39333 [Form] do not apply the Valid constraint on scalar form data (lchrusciel, xabbuh) - * bug #39331 [PhpUnitBridge] Fixed PHPunit 9.5 compatibility (wouterj) - * bug #39220 [HttpKernel] Fix bug with whitespace in Kernel::stripComments() (ausi) - * bug #39252 [Mime] Leverage PHP 8's detection of CSV files (derrabus) - * bug #39313 [FrameworkBundle] TextDescriptor::formatControllerLink checked method… (fjogeleit) - * bug #39286 [HttpClient] throw clearer error when no scheme is provided (BackEndTea) - * bug #39267 [Yaml] fix lexing backslashes in single quoted strings (xabbuh) - * bug #39151 [DependencyInjection] Fixed incorrect report for private services if required service does not exist (Islam93) - * bug #39274 [Yaml] fix lexing mapping values with trailing whitespaces (xabbuh) - * bug #39270 [Inflector] Fix Notice when argument is empty string (moldman) - * bug #39247 [Security] remove return type definition in order to avoid type juggling (adeptofvoltron) - * bug #39223 [Console] Re-enable hyperlinks in Konsole/Yakuake (OndraM) - * bug #39241 [Yaml] fix lexing inline sequences/mappings with trailing whitespaces (Nyholm, xabbuh) - * bug #39243 [Filesystem] File existence check before calling unlink method (gechetspr) - -* 4.4.17 (2020-11-29) - - * bug #39166 [Messenger] Fix mssql compatibility for doctrine transport. (bill moll) - * bug #39211 [HttpClient] fix binding to network interfaces (nicolas-grekas) - * bug #39129 [DependencyInjection] Fix circular in DI with lazy + byContruct loop (jderusse) - * bug #39068 [DependencyInjection][Translator] Silent deprecation triggered by libxml_disable_entity_loader (jderusse) - * bug #39119 [Form] prevent duplicated error message for file upload limits (xabbuh) - * bug #39099 [Form] ignore the pattern attribute for textareas (xabbuh) - * bug #39154 [Yaml] fix lexing strings containing escaped quotation characters (xabbuh) - * bug #38597 [PhpUnitBridge] Fix qualification of deprecations triggered by the debug class loader (fancyweb) - * bug #39160 [Console] Use a partial buffer in SymfonyStyle (jderusse) - * bug #39168 [Console] Fix console closing tag (jderusse) - * bug #39155 [VarDumper] fix casting resources turned into objects on PHP 8 (nicolas-grekas) - * bug #39115 [HttpClient] don't fallback to HTTP/1.1 when HTTP/2 streams break (nicolas-grekas) - * bug #33763 [Yaml] fix lexing nested sequences/mappings (xabbuh) - * bug #39083 [Dotenv] Check if method inheritEnvironmentVariables exists (Chi-teck) - * bug #39094 [Ldap] Fix undefined variable $con (derrabus) - * bug #39091 [Config] Recheck glob brace support after GlobResource was serialized (wouterj) - * bug #39092 Fix critical extension when reseting paged control (jderusse) - * bug #38614 [HttpFoundation] Fix for virtualhosts based on URL path (mvorisek) - * bug #38387 [Validator] prevent hash collisions caused by reused object hashes (fancyweb, xabbuh) - * bug #38999 [DependencyInjection] autoconfigure behavior describing tags on decorators (xabbuh) - * bug #39058 [DependencyInjection] Fix circular detection with multiple paths (jderusse) - * bug #39059 [Filesystem] fix cleaning up tmp files when dumpFile() fails (nicolas-grekas) - * bug #38628 [DoctrineBridge] indexBy could reference to association columns (juanmiguelbesada) - * bug #39021 [DependencyInjection] Optimize circular collection by removing flattening (jderusse) - * bug #39031 [Ldap] Fix pagination (jderusse) - * bug #39038 [DoctrineBridge] also reset id readers (xabbuh) - * bug #39025 [DoctrineBridge] Fix DBAL deprecations in middlewares (derrabus) - * bug #38991 [Console] Fix ANSI when stdErr is not a tty (jderusse) - * bug #38980 [DependencyInjection] Fix circular reference with Factory + Lazy Iterrator (jderusse) - * bug #38971 [PhpUnitBridge] fix replaying skipped tests (nicolas-grekas) - * bug #38910 [HttpKernel] Fix session initialized several times (jderusse) - * bug #38882 [DependencyInjection] Improve performances in CircualReference detection (jderusse) - * bug #38950 [Process] Dont test TTY if there is no TTY support (Nyholm) - * bug #38921 [PHPUnitBridge] Fixed crash on Windows with PHP 8 (villfa) - * bug #38869 [SecurityBundle] inject only compatible token storage implementations for usage tracking (xabbuh) - * bug #38894 [HttpKernel] Remove Symfony 3 compatibility code (derrabus) - * bug #38895 [PhpUnitBridge] Fix wrong check for exporter in ConstraintTrait (alcaeus) - * bug #38879 [Cache] Fixed expiry could be int in ChainAdapter due to race conditions (phamviet) - * bug #38856 [Cache] Add missing use statement (fabpot) - -* 4.4.16 (2020-10-28) - - * bug #38713 [DI] Fix Preloader exception when preloading a class with an unknown parent/interface (rgeraads) - * bug #38647 [HttpClient] relax auth bearer format requirements (xabbuh) - * bug #38699 [DependencyInjection] Preload classes with union types correctly (derrabus) - * bug #38669 [Serializer] fix decoding float XML attributes starting with 0 (Marcin Kruk) - * bug #38680 [PhpUnitBridge] Support new expect methods in test case polyfill (alcaeus) - * bug #38681 [PHPUnitBridge] Support PHPUnit 8 and PHPUnit 9 in constraint compatibility trait (alcaeus) - * bug #38679 [PhpUnitBridge] Add missing exporter function for PHPUnit 7 (alcaeus) - * bug #38595 [TwigBridge] do not translate null placeholders or titles (xabbuh) - * bug #38635 [Cache] Use correct expiry in ChainAdapter (Nyholm) - * bug #38652 [Filesystem] Check if failed unlink was caused by permission denied (Nyholm) - * bug #38645 [PropertyAccess] forward the caught exception (xabbuh) - * bug #38604 [DoctrineBridge] indexBy does not refer to attributes, but to column names (xabbuh) - * bug #38606 [WebProfilerBundle] Hide debug toolbar in print view (jt2k) - * bug #38582 [DI] Fix Reflection file name with eval()\'d code (maxime-aknin) - * bug #38516 [HttpFoundation] Fix Range Requests (BattleRattle) - * bug #38553 [Lock] Reset Key lifetime time before we acquire it (Nyholm) - * bug #38551 Remove content-type check on toArray methods (jderusse) - * bug #38544 [DI] fix dumping env vars (nicolas-grekas) - * bug #38530 [HttpClient] fix reading the body after a ClientException (nicolas-grekas) - * bug #38510 [PropertyInfo] Support for the mixed type (derrabus) - * bug #38493 [HttpClient] Fix CurlHttpClient memory leak (HypeMC) - * bug #38456 [Cache] skip igbinary < 3.1.6 (nicolas-grekas) - * bug #38392 [Ldap] Bypass the use of `ldap_control_paged_result` on PHP >= 7.3 (lucasaba) - * bug #38444 [PhpUnitBridge] fix running parallel tests with phpunit 9 (nicolas-grekas) - * bug #38442 [VarDumper] fix truncating big arrays (nicolas-grekas) - * bug #38433 [Mime] Fix serialization of RawMessage (gilbertsoft) - -* 4.4.15 (2020-10-04) - - * bug #36291 [Lock] Fix StoreFactory to accept same DSN syntax as AbstractAdapter (Jontsa) - * bug #38390 [Serializer][Minor] Fix circular reference exception message (bad limit displayed) (l-vo) - * bug #38388 [HttpClient] Always "buffer" empty responses (nicolas-grekas) - * bug #38380 [Form] propagate validation groups to subforms (johanderuijter, xabbuh) - * bug #38377 Ignore more deprecations for Mockery mocks (fancyweb) - * bug #38375 [HttpClient] fix using proxies with NativeHttpClient (nicolas-grekas) - * bug #38372 [Routing] fix using !important and defaults/reqs in inline route definitions (nicolas-grekas) - * bug #38373 [ErrorHandler][DebugClassLoader] Do not check Mockery mocks classes (fancyweb) - * bug #38368 [HttpClient] Fix using https with proxies (bohanyang) - * bug #38350 [TwigBundle] Only remove kernel exception listener if twig is used (dmolineus) - * bug #38360 [BrowserKit] Cookie expiration at current timestamp (iquito) - * bug #38358 [Messenger] Fix redis connection error message (alexander-schranz) - * bug #38343 Revert "bug #38063 [FrameworkBundle] generate preload.php in src/ to make opcache.preload predictable" (nicolas-grekas) - * bug #38336 [PhpUnitBridge] Fixed class_alias() for PHPUnit\Framework\Error\Error (stevegrunwell) - -* 4.4.14 (2020-09-27) - - * bug #38248 [HttpClient] Allow bearer token with colon (stephanvierkant) - * bug #37837 [Form] Fix custom formats deprecation with HTML5 widgets (fancyweb) - * bug #38285 [Contracts][Translation] Optional Intl dependency (ro0NL) - * bug #38283 [Translator] Optional Intl dependency (ro0NL) - * bug #38271 [ErrorHandler] Escape JSON encoded log context (ro0NL) - * bug #38284 [Cache][Lock][Messenger] fix compatibility with Doctrine DBAL 3 (xabbuh) - * bug #38228 [Yaml Parser] Fix edge cases when parsing multiple documents (digilist) - * bug #38229 [Yaml] fix parsing comments not prefixed by a space (xabbuh) - * bug #38127 [Translator] Make sure a null locale is handled properly (jschaedl) - * bug #38221 [Cache] Allow cache tags to be objects implementing __toString() (lstrojny) - * bug #38212 [HttpKernel] Do not override max_redirects option in HttpClientKernel (dmolineus) - * bug #38215 [HttpClient] Support for CURLOPT_LOCALPORT (derrabus) - * bug #38202 [FrameworkBundle] Fix xsd definition which prevent to add more than one workflow metadata (l-vo) - * bug #38166 [Console] work around disabled putenv() (SenTisso) - * bug #38173 [HttpClient][HttpClientTrait] don't calculate alternatives if option is auth_ntlm (ybenhssaien) - * bug #38169 [PhpUnitBridge] Internal classes are not legacy (derrabus) - * bug #38156 [Cache] fix ProxyAdapter not persisting items with infinite expiration (dmaicher) - * bug #38148 [HttpClient] fail properly when the server replies with HTTP/0.9 (nicolas-grekas) - * bug #38131 [Validator] allow consumers to mock all methods (xabbuh) - * bug #38139 [DI] dump OS-indepent paths in the compiled container (nicolas-grekas) - * bug #38126 [Cache] Limit cache version character range (lstrojny) - * bug #38142 [FrameworkBundle] adopt src/.preload.php (nicolas-grekas) - * bug #38108 [Cache] Fix key encoding issue in Memcached adapter (lstrojny) - * bug #38122 [HttpClient] Fix Array to string conversion notice when parsing JSON error body with non-scalar detail property (emarref) - * bug #37097 DateTime validator support for trailing data (stefankleff) - * bug #38116 [Console] Silence warnings on sapi_windows_cp_set() call (chalasr) - * bug #38114 [Console] guard $argv + $token against null, preventing unnecessary exceptions (bilogic) - * bug #38094 [PhpUnitBridge] Skip internal classes in CoverageListenerTrait (sanmai) - * bug #38101 [VarExporter] unserialize() might throw an Exception on php 8 (derrabus) - * bug #38100 [ErrorHandler] Parse "x not found" errors correctly on php 8 (derrabus) - * bug #38099 Prevent parsing invalid octal digits as octal numbers (julienfalque) - * bug #38095 [Mailer] Remove unnecessary check for existing request (jschaedl) - * bug #38091 [DI] fix ContainerBuilder on PHP8 (nicolas-grekas) - * bug #38086 [HttpClient] with "bindto" with NativeHttpClient (nicolas-grekas) - * bug #38063 [FrameworkBundle] generate preload.php in src/ to make opcache.preload predictable (nicolas-grekas) - * bug #38080 [Console] Make sure $maxAttempts is an int or null (derrabus) - * bug #38075 esmtp error not being thrown properly (Anton Zagorskii) - * bug #38040 [Yaml Parser] fixed Parser to skip comments when inlining sequences (korve) - * bug #38073 [VarDumper] Fix caster for invalid SplFileInfo objects on php 8 (derrabus) - * bug #38071 [PhpUnitBridge] Adjust output parsing of CoverageListenerTrait for PHPUnit 9.3 (sanmai, derrabus) - * bug #38062 [DI] fix generating preload file when cache_dir is outside project_dir (nicolas-grekas) - * bug #38059 [Cache] Fix CacheCollectorPass with decorated cache pools (shyim) - * bug #38054 [PhpUnitBridge] CoverageListenerTrait update for PHPUnit 8.5/9.x (sanmai) - * bug #38049 [Debug] Parse "x not found" errors correctly on php 8 (derrabus) - * bug #38041 [PropertyInfo] Fix typed collections in PHP 7.4 (ndench) - * bug #37959 [PhpunitBridge] Fix deprecation type detection (when several autoload files are used) (l-vo) - -* 4.4.13 (2020-09-02) - - * security #cve-2020-15094 Remove headers with internal meaning from HttpClient responses (mpdude) - * bug #38024 [Console] Fix undefined index for inconsistent command name definition (chalasr) - * bug #38023 [DI] fix inlining of non-shared services (nicolas-grekas) - * bug #38020 [PhpUnitBridge] swallow deprecations (xabbuh) - * bug #38010 [Cache] Psr16Cache does not handle Proxy cache items (alex-dev) - * bug #37937 [Serializer] fixed fix encoding of cache keys with anonymous classes (michaelzangerle) - -* 4.4.12 (2020-08-31) - - * bug #37966 [HttpClient][MockHttpClient][DX] Throw when the response factory callable does not return a valid response (fancyweb) - * bug #37971 [PropertyInfo] Backport support for typed properties (PHP 7.4) (dunglas) - * bug #37970 [PhpUnitBridge] Polyfill new phpunit 9.1 assertions (phpfour) - * bug #37960 [PhpUnit] Add polyfill for assertMatchesRegularExpression() (dunglas) - * bug #37949 [Yaml] fix more numeric cases changing in PHP 8 (xabbuh) - * bug #37921 [Yaml] account for is_numeric() behavior changes in PHP 8 (xabbuh) - * bug #37912 [ExpressionLanguage] fix passing arguments to call_user_func_array() on PHP 8 (xabbuh) - * bug #37907 [Messenger] stop using the deprecated schema synchronizer API (xabbuh) - * bug #37900 [Mailer] Fixed mandrill api header structure (wulff) - * bug #37888 [Mailer] Reorder headers used to determine Sender (cvmiert) - * bug #37872 [Sendgrid-Mailer] Fixed envelope recipients on sendgridApiTransport (arendjantetteroo) - * bug #37860 [Serializer][ClassDiscriminatorMapping] Fix getMappedObjectType() when a discriminator child extends another one (fancyweb) - * bug #37853 [Validator] ensure that the validator is a mock object for backwards-compatibility (xabbuh) - * bug #36340 [Serializer] Fix configuration of the cache key (dunglas) - * bug #36810 [Messenger] Do not stack retry stamp (jderusse) - * bug #37849 [FrameworkBundle] Add missing mailer transports in xsd (l-vo) - * bug #37586 [ErrorHandler][DebugClassLoader] Add mixed and static return types support (fancyweb) - * bug #37845 [Serializer] Fix variadic support when using type hints (fabpot) - * bug #37841 [VarDumper] Backport handler lock when using VAR_DUMPER_FORMAT (ogizanagi) - * bug #37725 [Form] Fix Guess phpdoc return type (franmomu) - * bug #37771 Use PHPUnit 9.3 on php 8 (derrabus) - * bug #36140 [Validator] Add BC layer for notInRangeMessage when min and max are set (l-vo) - * bug #35843 [Validator] Add target guards for Composite nested constraints (ogizanagi) - * bug #37803 Fix for issue #37681 (Rav) - * bug #37744 [Yaml] Fix for #36624; Allow PHP constant as first key in block (jnye) - * bug #37767 [Form] fix mapping errors from unmapped forms (xabbuh) - * bug #37731 [Console] Table: support cells with newlines after a cell with colspan >= 2 (GMTA) - * bug #37791 Fix redis connect with empty password (alexander-schranz) - * bug #37790 Fix deprecated libxml_disable_entity_loader (fabpot) - * bug #37763 Fix deprecated libxml_disable_entity_loader (jderusse) - * bug #37774 [Console] Make sure we pass a numeric array of arguments to call_user_func_array() (derrabus) - * bug #37729 [FrameworkBundle] fail properly when the required service is not defined (xabbuh) - * bug #37701 [Serializer] Fix that it will never reach DOMNode (TNAJanssen) - * bug #37671 [Cache] fix saving no-expiry items with ArrayAdapter (philipp-kolesnikov) - * bug #37102 [WebProfilerBundle] Fix error with custom function and web profiler routing tab (JakeFr) - * bug #37560 [Finder] Fix GitIgnore parser when dealing with (sub)directories and take order of lines into account (Jeroeny) - * bug #37700 [VarDumper] Improve previous fix on light array coloration (l-vo) - * bug #37705 [Mailer] Added the missing reset tag to mailer.logger_message_listener (vudaltsov) - * bug #37697 [Messenger] reduce column length for MySQL 5.6 compatibility (xabbuh) - -* 4.4.11 (2020-07-24) - - * bug #37590 Allows RedisClusterProxy instance in Lock RedisStore (jderusse) - * bug #37583 [Mime] Fix EmailHeaderSame to make use of decoded value (evertharmeling) - * bug #37569 [Messenger] Allow same middleware to be used multiple times with different arguments (HypeMC) - * bug #37624 [Cache] Connect to RedisCluster with password auth (mforbak) - * bug #37635 [Cache] fix catching auth errors (nicolas-grekas) - * bug #37628 [Serializer] Support multiple levels of discriminator mapping (jeroennoten) - * bug #37572 [FrameworkBundle] set default session.handler alias if handler_id is not provided (Youssef BENHSSAIEN) - * bug #37607 Fix checks for phpunit releases on Composer 2 (colinodell) - * bug #37594 Use hexadecimal numerals instead of hexadecimals in strings to repres… (arekzb) - * bug #37576 [WebProfilerBundle] modified url generation to use absolute urls (smatyas) - * bug #36888 [Mailer] Fix mandrill raw http request setting from email/name (JohJohan) - * bug #37527 [Mailer] Fix reply-to functionality in the SendgridApiTransport (jt2k) - * bug #37581 [Mime] Fix compat with HTTP requests (fabpot) - * bug #37580 [Mime] Keep Sender full address when used by non-SMTP transports (fabpot) - * bug #37511 [DependencyInjection][Config] Use several placeholder unique prefixes for dynamic placeholder values (fancyweb) - * bug #37562 [Cache] Use the default expiry when saving (not when creating) items (philipp-kolesnikov) - * bug #37563 Fix DBAL deprecation (nicolas-grekas) - * bug #37521 [Form] Fix ChoiceType translation domain (VincentLanglet) - * bug #37550 [OptionsResolver] Fix force prepend normalizer (hason) - * bug #37520 [Form] silently ignore uninitialized properties when mapping data to forms (ph-fritsche) - * bug #37526 [Cache][Config] ensure compatibility with PHP 8 stack traces (xabbuh) - * bug #37513 [PhpUnitBridge] ExcludeList usage for PHPUnit 9.4 (gennadigennadigennadi) - * bug #37461 [Process] Fix Permission Denied error when writing sf_proc_00 lock files on Windows (JasonStephensTAMU) - * bug #37505 [Form] fix handling null as empty data (xabbuh) - * bug #37385 [Console] Fixes question input encoding on Windows (YaFou) - * bug #37491 [HttpClient] Fix promise behavior in HttplugClient (brentybh) - * bug #37469 [Console] always use stty when possible to ask hidden questions (nicolas-grekas) - * bug #37486 [HttpClient] fix parsing response headers in CurlResponse (nicolas-grekas) - * bug #37484 [HttpClient][CurlHttpClient] Fix http_version option usage (fancyweb) - * bug #37447 [Validator] fix validating lazy properties that evaluate to null (xabbuh) - * bug #37464 [ErrorHandler] fix throwing from __toString() (nicolas-grekas) - * bug #37449 [Translation] Fix caching of parent locales file in translator (jvasseur) - * bug #37418 [PhpUnitBridge] Fix compatibility with phpunit 9.3 (Gennadi Janzen) - * bug #37441 [DoctrineBridge] work around Connection::ping() deprecation (nicolas-grekas) - * bug #37291 [MimeType] Duplicated MimeType due to PHP Bug (juanmrad) - * bug #37429 [DI] fix parsing of argument type=binary in xml (Tobion) - * bug #37425 [Form] fix guessing form types for DateTime types (xabbuh) - * bug #37392 [Validator] fix handling typed properties as constraint options (xabbuh) - * bug #37358 Directly use the driverConnection executeUpdate method (TristanPouliquen) - * bug #37389 [HttpFondation] Change file extension of "audio/mpeg" from "mpga" to "mp3" (YaFou) - * bug #37379 [HttpClient] Support for cURL handler objects (derrabus) - * bug #37383 [VarDumper] Support for cURL handler objects (derrabus) - * bug #37395 add .body wrapper element (Nemo64) - * bug #37400 [HttpClient] unset activity list when creating CurlResponse (nicolas-grekas) - * bug #36304 Check whether path is file in DataPart::fromPath() (freiondrej) - * bug #37345 [Form] collect all transformation failures (xabbuh) - * bug #37362 [SecurityBundle] Drop cache.security_expression_language service if invalid (chalasr) - * bug #37353 [DI] disable preload.php on the CLI (nicolas-grekas) - * bug #37268 [Messenger] Fix precedence of DSN options for 4.4 (jderusse) - * bug #37341 Fix support for PHP8 union types (nicolas-grekas) - * bug #37271 [FrameworkBundle] preserve dots in query-string when redirecting (nicolas-grekas) - * bug #37340 Fix support for PHP8 union types (nicolas-grekas) - * bug #37275 [DI] tighten detection of local dirs to prevent false positives (nicolas-grekas) - * bug #37090 [PhpUnitBridge] Streamline ansi/no-ansi of composer according to phpunit --colors option (kick-the-bucket) - * bug #36230 [VarDumper] Fix CliDumper coloration on light arrays (l-vo) - * bug #37270 [FrameworkBundle] preserve dots in query-string when redirecting (nicolas-grekas) - * bug #37319 [HttpClient] Convert CurlHttpClient::handlePush() to instance method (mpesari) - * bug #37342 [Cache] fix compat with DBAL v3 (nicolas-grekas) - * bug #37286 [Console] Reset question validator attempts only for actual stdin (bis) (nicolas-grekas) - * bug #37160 Reset question validator attempts only for actual stdin (ostrolucky) - * bug #36975 [PropertyInfo] Make PhpDocExtractor compatible with phpDocumentor v5 (DerManoMann) - -* 4.4.10 (2020-06-12) - - * bug #37227 [DependencyInjection][CheckTypeDeclarationsPass] Handle unresolved parameters pointing to environment variables (fancyweb) - * bug #37103 [Form] switch the context when validating nested forms (xabbuh) - * bug #37182 [HttpKernel] Fix regression where Store does not return response body correctly (mpdude) - * bug #37193 [DependencyInjection][CheckTypeDeclarationsPass] Always resolve parameters (fancyweb) - * bug #37191 [HttpClient] fix offset computation for data chunks (nicolas-grekas) - * bug #37177 [Ldap] fix refreshUser() ignoring extra_fields (arkste) - * bug #37181 [Mailer] Remove an internal annot (fabpot) - * bug #36913 [FrameworkBundle] fix type annotation on ControllerTrait::addFlash() (ThomasLandauer) - * bug #37162 [Mailer] added the reply-to addresses to the API SES transport request. (ribeiropaulor) - * bug #37167 [Mime] use fromString when creating a new Address (fabpot) - * bug #37169 [Cache] fix forward compatibility with Doctrine DBAL 3 (xabbuh) - * bug #37159 [Mailer] Fixed generator bug when creating multiple transports using Transport::fromDsn (atailouloute) - * bug #37048 [HttpClient] fix monitoring timeouts when other streams are active (nicolas-grekas) - * bug #37085 [Form] properly cascade validation to child forms (xabbuh) - * bug #37095 [PhpUnitBridge] Fix undefined index when output of "composer show" cannot be parsed (nicolas-grekas) - * bug #37092 [PhpUnitBridge] fix undefined var on version 3.4 (nicolas-grekas) - * bug #37065 [HttpClient] Throw JsonException instead of TransportException on empty response in Response::toArray() (jeroennoten) - * bug #37077 [WebProfilerBundle] Move ajax clear event listener initialization on loadToolbar (Bruno BOUTAREL) - * bug #37049 [Serializer] take into account the context when preserving empty array objects (xabbuh) - -* 4.4.9 (2020-05-31) - - * bug #37008 [Security] Fixed AbstractToken::hasUserChanged() (wouterj) - * bug #36894 [Validator] never directly validate Existence (Required/Optional) constraints (xabbuh) - * bug #37007 [Console] Fix QuestionHelper::disableStty() (chalasr) - * bug #36865 [Form] validate subforms in all validation groups (xabbuh) - * bug #36907 Fixes sprintf(): Too few arguments in form transformer (pedrocasado) - * bug #36868 [Validator] Use Mime component to determine mime type for file validator (pierredup) - * bug #37000 Add meaningful message when using ProcessHelper and Process is not installed (l-vo) - * bug #36995 [TwigBridge] fix fallback html-to-txt body converter (nicolas-grekas) - * bug #36993 [ErrorHandler] fix setting $trace to null in FatalError (nicolas-grekas) - * bug #36987 Handle fetch mode deprecation of DBAL 2.11. (derrabus) - * bug #36974 [Security] Fixed handling of CSRF logout error (wouterj) - * bug #36947 [Mime] Allow email message to have "To", "Cc", or "Bcc" header to be valid (Ernest Hymel) - * bug #36914 Parse and render anonymous classes correctly on php 8 (derrabus) - * bug #36921 [OptionsResolver][Serializer] Remove calls to deprecated ReflectionParameter::getClass() (derrabus) - * bug #36920 [VarDumper] fix PHP 8 support (nicolas-grekas) - * bug #36917 [Cache] Accessing undefined constants raises an Error in php8 (derrabus) - * bug #36891 Address deprecation of ReflectionType::getClass() (derrabus) - * bug #36899 [VarDumper] ReflectionFunction::isDisabled() is deprecated (derrabus) - * bug #36905 [Validator] Catch expected ValueError (derrabus) - * bug #36915 [DomCrawler] Catch expected ValueError (derrabus) - * bug #36908 [Cache][HttpClient] Made method signatures compatible with their corresponding traits (derrabus) - * bug #36906 [DomCrawler] Catch expected ValueError (derrabus) - * bug #36904 [PropertyAccess] Parse php 8 TypeErrors correctly (derrabus) - * bug #36839 [BrowserKit] Raw body with custom Content-Type header (azhurb) - * bug #36896 [Config] Removed implicit cast of ReflectionProperty to string (derrabus) - * bug #35944 [Security/Core] Fix wrong roles comparison (thlbaut) - * bug #36882 [PhpUnitBridge] fix installing under PHP >= 8 (nicolas-grekas) - * bug #36833 [HttpKernel] Fix that the `Store` would not save responses with the X-Content-Digest header present (mpdude) - * bug #36867 [PhpUnitBridge] fix bad detection of unsilenced deprecations (nicolas-grekas) - * bug #36862 [Security] Unserialize $parentData, if needed, to avoid errors (rfaivre) - * bug #36855 [HttpKernel] Fix error logger when stderr is redirected to /dev/null (fabpot) - * bug #36838 [HttpKernel] Bring back the debug toolbar (derrabus) - * bug #36592 [BrowserKit] Allow Referer set by history to be overridden (Slamdunk) - * bug #36823 [HttpClient] fix PHP warning + accept status code >= 600 (nicolas-grekas) - * bug #36824 [Security/Core] fix compat of `NativePasswordEncoder` with pre-PHP74 values of `PASSWORD_*` consts (nicolas-grekas) - * bug #36811 [DependencyInjection] Fix register event listeners compiler pass (X-Coder264) - * bug #36789 Change priority of KernelEvents::RESPONSE subscriber (marcw) - * bug #36794 [Serializer] fix issue with PHP 8 (nicolas-grekas) - * bug #36786 [WebProfiler] Remove 'none' when appending CSP tokens (ndench) - * bug #36743 [Yaml] Fix escaped quotes in quoted multi-line string (ossinkine) - * bug #36777 [TwigBundle] FormExtension does not have a constructor anymore since sf 4.0 (Tobion) - * bug #36716 [Mime] handle passing custom mime types as string (mcneely) - * bug #36747 Queue name is a required parameter (theravel) - * bug #36751 [Mime] fix bad method call on `EmailAddressContains` (Kocal) - * bug #36696 [Console] don't check tty on stdin, it breaks with "data lost during stream conversion" (nicolas-grekas) - * bug #36569 [PhpUnitBridge] Mark parent class also covered in CoverageListener (lyrixx) - * bug #36690 [Yaml] prevent notice for invalid octal numbers on PHP 7.4 (xabbuh) - * bug #36590 [Console] Default hidden question to 1 attempt for non-tty session (ostrolucky) - * bug #36497 [Filesystem] Handle paths on different drives (crishoj) - * bug #36678 [WebProfiler] Do not add src-elem CSP directives if they do not exist (ndench) - * bug #36501 [DX] Show the ParseException message in all YAML file loaders (fancyweb) - * bug #36683 [Yaml] fix parse error when unindented collections contain a comment (wdiesveld) - * bug #36672 [Validator] Skip validation when email is an empty object (acrobat) - * bug #36673 [PhpUnitBridge] fix PHP 5.3 compat again (nicolas-grekas) - * bug #36505 [Translation] Fix for translation:update command updating ICU messages (artemoliynyk) - * bug #36627 [Validator] fix lazy property usage. (bendavies) - * bug #36601 [Serializer] do not transform empty \Traversable to Array (soyuka) - * bug #36606 [Cache] Fixed not supported Redis eviction policies (SerheyDolgushev) - * bug #36625 [PhpUnitBridge] fix compat with PHP 5.3 (nicolas-grekas) - -* 4.4.8 (2020-04-28) - - * bug #36536 [Cache] Allow invalidateTags calls to be traced by data collector (l-vo) - * bug #36566 [PhpUnitBridge] Use COMPOSER_BINARY env var if available (fancyweb) - * bug #36560 [YAML] escape DEL(\x7f) (sdkawata) - * bug #36539 [PhpUnitBridge] fix compatibility with phpunit 9 (garak) - * bug #36555 [Cache] skip APCu in chains when the backend is disabled (nicolas-grekas) - * bug #36523 [Form] apply automatically step=1 for datetime-local input (ottaviano) - * bug #36519 [FrameworkBundle] debug:autowiring: Fix wrong display when using class_alias (weaverryan) - * bug #36454 [DependencyInjection][ServiceSubscriber] Support late aliases (fancyweb) - * bug #36498 [Security/Core] fix escape for username in LdapBindAuthenticationProvider.php (stoccc) - * bug #36506 [FrameworkBundle] Fix session.attribute_bag service definition (fancyweb) - * bug #36500 [Routing][PrefixTrait] Add the _locale requirement (fancyweb) - * bug #36457 [Cache] CacheItem with tag is never a hit after expired (alexander-schranz, nicolas-grekas) - * bug #36490 [HttpFoundation] workaround PHP bug in the session module (nicolas-grekas) - * bug #36483 [SecurityBundle] fix accepting env vars in remember-me configurations (zek) - * bug #36343 [Form] Fixed handling groups sequence validation (HeahDude) - * bug #36460 [Cache] Avoid memory leak in TraceableAdapter::reset() (lyrixx) - * bug #36467 Mailer from sender fixes (fabpot) - * bug #36408 [PhpUnitBridge] add PolyfillTestCaseTrait::expectExceptionMessageMatches to provide FC with recent phpunit versions (soyuka) - * bug #36447 Remove return type for Twig function workflow_metadata() (gisostallenberg) - * bug #36449 [Messenger] Make sure redis transports are initialized correctly (Seldaek) - * bug #36411 [Form] RepeatedType should always have inner types mapped (biozshock) - * bug #36441 [DI] fix loading defaults when using the PHP-DSL (nicolas-grekas) - * bug #36434 [HttpKernel] silence E_NOTICE triggered since PHP 7.4 (xabbuh) - * bug #36365 [Validator] Fixed default group for nested composite constraints (HeahDude) - * bug #36422 [HttpClient] fix HTTP/2 support on non-SSL connections - CurlHttpClient only (nicolas-grekas) - * bug #36417 Force ping after transport exception (oesteve) - * bug #35591 [Validator] do not merge constraints within interfaces (greedyivan) - * bug #36377 [HttpClient] Fix scoped client without query option configuration (X-Coder264) - * bug #36387 [DI] fix detecting short service syntax in yaml (nicolas-grekas) - * bug #36392 [DI] add missing property declarations in InlineServiceConfigurator (nicolas-grekas) - * bug #36400 Allowing empty secrets to be set (weaverryan) - * bug #36380 [Process] Fixed input/output error on PHP 7.4 (mbardelmeijer) - * bug #36376 [Workflow] Use a strict comparison when retrieving raw marking in MarkingStore (lyrixx) - * bug #36375 [Workflow] Use a strict comparison when retrieving raw marking in MarkingStore (lyrixx) - * bug #36305 [PropertyInfo][ReflectionExtractor] Check the array mutator prefixes last when the property is singular (fancyweb) - * bug #35656 [HttpFoundation] Fixed session migration with custom cookie lifetime (Guite) - * bug #36342 [HttpKernel][FrameworkBundle] fix compat with Debug component (nicolas-grekas) - * bug #36315 [WebProfilerBundle] Support for Content Security Policy style-src-elem and script-src-elem in WebProfiler (ampaze) - * bug #36286 [Validator] Allow URL-encoded special characters in basic auth part of URLs (cweiske) - * bug #36335 [Security] Track session usage whenever a new token is set (wouterj) - * bug #36332 [Serializer] Fix unitialized properties (from PHP 7.4.2) when serializing context for the cache key (alanpoulain) - * bug #36337 [MonologBridge] Fix $level type (fancyweb) - * bug #36223 [Security][Http][SwitchUserListener] Ignore all non existent username protection errors (fancyweb) - * bug #36239 [HttpKernel][LoggerDataCollector] Prevent keys collisions in the sanitized logs processing (fancyweb) - * bug #36245 [Validator] Fixed calling getters before resolving groups (HeahDude) - * bug #36265 Fix the reporting of deprecations in twig:lint (stof) - * bug #36283 [Security] forward multiple attributes voting flag (xabbuh) - -* 4.4.7 (2020-03-30) - - * security #cve-2020-5255 [HttpFoundation] Do not set the default Content-Type based on the Accept header (yceruto) - * security #cve-2020-5275 [Security] Fix access_control behavior with unanimous decision strategy (chalasr) - * bug #36262 [DI] fix generating TypedReference from PriorityTaggedServiceTrait (nicolas-grekas) - * bug #36252 [Security/Http] Allow setting cookie security settings for delete_cookies (wouterj) - * bug #36261 [FrameworkBundle] revert to legacy wiring of the session when circular refs are detected (nicolas-grekas) - * bug #36259 [DomCrawler] Fix BC break in assertions breaking Panther (dunglas) - * bug #36181 [BrowserKit] fixed missing post request parameters in file uploads (codebay) - * bug #36216 [Validator] Assert Valid with many groups (phucwan91) - * bug #36222 [Console] Fix OutputStream for PHP 7.4 (guillbdx) - -* 4.4.6 (2020-03-27) - - * bug #36169 [HttpKernel] fix locking for PHP 7.4+ (nicolas-grekas) - * bug #36175 [Security/Http] Remember me: allow to set the samesite cookie flag (dunglas) - * bug #36173 [Http Foundation] Fix clear cookie samesite (guillbdx) - * bug #36176 [Security] Check if firewall is stateless before checking for session/previous session (koenreiniers) - * bug #36149 [Form] Support customized intl php.ini settings (jorrit) - * bug #36172 [Debug] fix for PHP 7.3.16+/7.4.4+ (nicolas-grekas) - * bug #36151 [Security] Fixed hardcoded value of SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE (lyrixx) - * bug #36141 Prevent warning in proc_open() (BenMorel) - * bug #36143 [FrameworkBundle] Fix Router Cache (guillbdx) - * bug #36103 [DI] fix preloading script generation (nicolas-grekas) - * bug #36118 [Security/Http] don't require the session to be started when tracking its id (nicolas-grekas) - * bug #36108 [DI] Fix CheckTypeDeclarationPass (guillbdx) - * bug #36121 [VarDumper] fix side-effect by not using mt_rand() (nicolas-grekas) - * bug #36073 [PropertyAccess][DX] Improved errors when reading uninitialized properties (HeahDude) - * bug #36063 [FrameworkBundle] start session on flashbag injection (William Arslett) - * bug #36031 [Console] Fallback to default answers when unable to read input (ostrolucky) - * bug #36083 [DI][Form] Fixed test suite (TimeType changes & unresolved merge conflict) (wouterj) - * bug #36026 [Mime] Fix boundary header (guillbdx) - * bug #36020 [Form] ignore microseconds submitted by Edge (xabbuh) - * bug #36038 [HttpClient] disable debug log with curl 7.64.0 (nicolas-grekas) - * bug #36041 fix import from config file using type: glob (Tobion) - * bug #35987 [DoctrineBridge][DoctrineExtractor] Fix wrong guessed type for "json" type (fancyweb) - * bug #35949 [DI] Fix container lint command when a synthetic service is used in an expression (HypeMC) - * bug #36023 [HttpClient] fix requests to hosts that idn_to_ascii() cannot handle (nicolas-grekas) - * bug #35938 [Form] Handle false as empty value on expanded choices (fancyweb) - * bug #36030 [SecurityBundle] Minor fix in LDAP config tree builder (HeahDude) - * bug #35993 Remove int return type from FlattenException::getCode (wucdbm) - * bug #36004 [Yaml] fix dumping strings containing CRs (xabbuh) - * bug #35982 [DI] Fix XmlFileLoader bad error message (przemyslaw-bogusz) - * bug #35957 [DI] ignore extra tags added by autoconfiguration in PriorityTaggedServiceTrait (nicolas-grekas) - * bug #35937 Revert "bug symfony#28179 [DomCrawler] Skip disabled fields processing in Form" (dmaicher) - * bug #35928 [Routing] Prevent localized routes _locale default & requirement from being overridden (fancyweb) - * bug #35912 [FrameworkBundle] register only existing transport factories (xabbuh) - * bug #35899 [DomCrawler] prevent deprecation being triggered from assertion (xabbuh) - * bug #35910 [SecurityBundle] Minor fixes in configuration tree builder (HeahDude) - -* 4.4.5 (2020-02-29) - - * bug #35781 [Form] NumberToLocalizedStringTransformer return int if scale = 0 (VincentLanglet) - * bug #35846 [Serializer] prevent method calls on null values (xabbuh) - * bug #35897 [FrameworkBundle] add missing Messenger options to XML schema definition (xabbuh) - * bug #35870 [ErrorHandler] fix parsing static return type on interface method annotation (alekitto) - * bug #35839 [Security] Allow switching to another user when already switched (chalasr) - * bug #35851 [DoctrineBridge] Use new Types::* constants and support new json types (fancyweb) - * bug #35716 [PhpUnitBridge] Fix compatibility to PHPUnit 9 (Benjamin) - * bug #35803 [Cache] Fix versioned namespace atomic clears (trvrnrth) - * bug #35817 [DoctrineBridge] Use new Types::* constants and support new json type (fancyweb) - * bug #35832 [Debug][ErrorHandler] improved deprecation notices for methods new args and return type (HeahDude) - * bug #35827 [BrowserKit] Nested file array prevents uploading file (afilina) - * bug #35707 [ExpressionLanguage] Fixed collisions of character operators with object properties (Andrej-in-ua) - * bug #35794 [DoctrineBridge][DoctrineExtractor] Fix indexBy with custom and some core types (fancyweb) - * bug #35787 [PhpUnitBridge] Use trait instead of extending deprecated class (marcello-moenkemeyer) - * bug #35792 [Security] Prevent TypeError in case RememberMetoken has no attached user (nikophil) - * bug #35735 [Routing] Add locale requirement for localized routes (mtarld) - * bug #35772 [Config] don't throw on missing excluded paths (nicolas-grekas) - * bug #35774 [Ldap] force default network timeout (nicolas-grekas) - * bug #35702 [VarDumper] fixed DateCaster not displaying additional fields (Makdessi Alex) - * bug #35722 [HttpKernel] Set previous exception when rethrown from controller resolver (danut007ro) - * bug #35714 [HttpClient] Correctly remove trace level options for HttpCache (aschempp) - * bug #35718 [HttpKernel] fix registering DebugHandlersListener regardless of the PHP_SAPI (nicolas-grekas) - * bug #35728 Add missing autoload calls (greg0ire) - * bug #35693 [Finder] Fix unix root dir issue (chr-hertel) - * bug #35709 [HttpFoundation] fix not sending Content-Type header for 204 responses (Tobion) - * bug #35710 [ErrorHandler] silence warning when zend.assertions=-1 (nicolas-grekas) - * bug #35676 [Console] Handle zero row count in appendRow() for Table (Adam Prickett) - * bug #35696 [Console] Don't load same-namespace alternatives on exact match (chalasr) - * bug #35674 [HttpClient] fix getting response content after its destructor throwed an HttpExceptionInterface (nicolas-grekas) - * bug #35672 [HttpClient] fix HttpClientDataCollector when handling canceled responses (thematchless) - * bug #35641 [Process] throw when PhpProcess::fromShellCommandLine() is used (Guikingone) - * bug #35645 [ErrorHandler] Never throw on warnings triggered by assert() and set assert.exception=1 in Debug::enable() (nicolas-grekas) - * bug #35633 [Mailer] Do not ping the SMTP server before sending every message (micheh) - * bug #33897 [Console] Consider STDIN interactive (ostrolucky) - * bug #35605 [HttpFoundation][FrameworkBundle] fix support for samesite in session cookies (fabpot) - * bug #35609 [DoctrineBridge] Fixed submitting ids with query limit or offset (HeahDude) - * bug #35597 [PHPunit bridge] Provide current file as file path (greg0ire) - * bug #33960 [DI] Unknown env prefix not recognized as such (ro0NL) - * bug #35342 [DI] Fix support for multiple tags for locators and iterators (Alexandre Parent) - * bug #33820 [PhpUnitBridge] Fix some errors when using serialized deprecations (l-vo) - * bug #35553 Fix HTTP client config handling (julienfalque) - * bug #35588 [ErrorHandler] Escape variable in Exception template (jderusse) - * bug #35583 Add missing use statements (fabpot) - * bug #35582 Missing use statement 4.4 (fabpot) - * bug #34123 [Form] Fix handling of empty_data's \Closure value in Date/Time form types (yceruto) - * bug #35537 [Config][XmlReferenceDumper] Prevent potential \TypeError (fancyweb) - * bug #35227 [Mailer] Fix broken mandrill http send for recipients with names (vilius-g) - * bug #35430 [Translation] prefer intl domain when adding messages to catalogue (Guite) - * bug #35497 Fail on empty password verification (without warning on any implementation) (Stefan Kruppa) - * bug #35546 [Validator] check for __get method existence if property is uninitialized (alekitto) - * bug #35332 [Yaml][Inline] Fail properly on empty object tag and empty const tag (fancyweb) - * bug #35489 [PhpUnitBridge] Fix running skipped tests expecting only deprecations (chalasr) - * bug #35161 [FrameworkBundle] Check non-null type for numeric type (Arman-Hosseini) - * bug #34059 [DomCrawler] Skip disabled fields processing in Form (sbogx) - * bug #34114 [Console] SymonfyStyle - Check value isset to avoid PHP notice (leevigraham) - * bug #35557 [Config] dont catch instances of Error (nicolas-grekas) - * bug #35562 [HttpClient] fix HttpClientDataCollector when handling canceled responses (nicolas-grekas) - -* 4.4.4 (2020-01-31) - - * bug #35530 [HttpClient] Fix regex bearer (noniagriconomie) - * bug #35532 [Validator] fix access to uninitialized property when getting value (greedyivan) - * bug #35486 [Translator] Default value for 'sort' option in translation:update should be 'asc' (versgui) - * bug #35305 [HttpKernel] Fix stale-if-error behavior, add tests (mpdude) - * bug #34808 [PhpUnitBridge] Properly handle phpunit arguments for configuration file (biozshock) - * bug #35517 [Intl] Provide more locale translations (ro0NL) - * bug #35518 [Mailer] Fix STARTTLS support for Postmark and Mandrill (fabpot) - * bug #35480 [Messenger] Check for all serialization exceptions during message dec… (Patrick Berenschot) - * bug #35502 [Messenger] Fix bug when using single route with XML config (Nyholm) - * bug #35438 [SecurityBundle] fix ldap_bind service arguments (Ioni14) - * bug #35429 [DI] CheckTypeDeclarationsPass now checks if value is type of parameter type (pfazzi) - * bug #35464 [ErrorHandler] Add debug argument to decide whether debug page is shown or not (yceruto) - * bug #35423 Fixes a runtime error when accessing the cache panel (DamienHarper) - * bug #35428 [Cache] fix checking for igbinary availability (nicolas-grekas) - * bug #35424 [HttpKernel] Check if lock can be released (sjadema) - -* 4.4.3 (2020-01-21) - - * bug #35364 [Yaml] Throw on unquoted exclamation mark (fancyweb) - * bug #35065 [Security] Use supportsClass in addition to UnsupportedUserException (linaori) - * bug #35351 Revert #34797 "Fixed translations file dumper behavior" and fix #34713 (yceruto) - * bug #35355 [DI] Fix EnvVar not loaded when Loader requires an env var (jderusse) - * bug #35343 [Security] Fix RememberMe with null password (jderusse) - * bug #34223 [DI] Suggest typed argument when binding fails with untyped argument (gudfar) - * bug #35323 [FrameworkBundle] Set booted flag to false when test kernel is unset (thiagocordeiro) - * bug #35324 [HttpClient] Fix strict parsing of response status codes (Armando-Walmeric) - * bug #35318 [Yaml] fix PHP const mapping keys using the inline notation (xabbuh) - * bug #35306 [FrameworkBundle] Make sure one can use fragments.hinclude_default_template (Nyholm) - * bug #35304 [HttpKernel] Fix that no-cache MUST revalidate with the origin (mpdude) - * bug #35299 Avoid `stale-if-error` in FrameworkBundle's HttpCache if kernel.debug = true (mpdude) - * bug #35240 [SecurityBundle] Fix collecting traceable listeners info on lazy firewalls (chalasr) - * bug #35151 [DI] deferred exceptions in ResolveParameterPlaceHoldersPass (Islam93) - * bug #35290 [Filesystem][FilesystemCommonTrait] Use a dedicated directory when there are no namespace (fancyweb) - * bug #35099 [FrameworkBundle] Do not throw exception on value generate key (jderusse) - * bug #35278 [EventDispatcher] expand listener in place (xabbuh) - * bug #35269 [HttpKernel][FileLocator] Fix deprecation message (fancyweb) - * bug #35254 [PHPUnit-Bridge] Fail-fast in simple-phpunit if one of the passthru() commands fails (mpdude) - * bug #35261 [Routing] Fix using a custom matcher & generator dumper class (fancyweb) - * bug #34643 [Dotenv] Fixed infinite loop with missing quote followed by quoted value (naitsirch) - * bug #35239 [Security\Http] Prevent canceled remember-me cookie from being accepted (chalasr) - * bug #35267 [Debug] fix ClassNotFoundFatalErrorHandler (nicolas-grekas) - * bug #35252 [Serializer] Fix cache in MetadataAwareNameConverter (bastnic) - * bug #35200 [TwigBridge] do not render preferred choices as selected (xabbuh) - * bug #35243 [HttpKernel] release lock explicitly (nicolas-grekas) - * bug #35193 [TwigBridge] button_widget now has its title attr translated even if its label = null or false (stephen-lewis) - * bug #35219 [PhpUnitBridge] When using phpenv + phpenv-composer plugin, composer executable is wrapped into a bash script (oleg-andreyev) - * bug #35150 [Messenger] Added check if json_encode succeeded (toooni) - * bug #35137 [Messenger] Added check if json_encode succeeded (toooni) - * bug #35170 [FrameworkBundle][TranslationUpdateCommand] Do not output positive feedback on stderr (fancyweb) - * bug #35245 [HttpClient] fix exception in case of PSR17 discovery failure (nicolas-grekas) - * bug #35244 [Cache] fix processing chain adapter based cache pool (xabbuh) - * bug #35247 [FrameworkBundle][ContainerLintCommand] Only skip .errored. services (fancyweb) - * bug #35225 [DependencyInjection] Handle ServiceClosureArgument for callable in container linting (shieldo) - * bug #35223 [HttpClient] Don't read from the network faster than the CPU can deal with (nicolas-grekas) - * bug #35214 [DI] DecoratorServicePass should keep container.service_locator on the decorated definition (malarzm) - * bug #35209 [HttpClient] fix support for non-blocking resource streams (nicolas-grekas) - * bug #35210 [HttpClient] NativeHttpClient should not send >1.1 protocol version (nicolas-grekas) - * bug #35162 [Mailer] Make sure you can pass custom headers to Mailgun (Nyholm) - * bug #33672 [Mailer] Remove line breaks in email attachment content (Stuart Fyfe) - * bug #35101 [Routing] Fix i18n routing when the url contains the locale (fancyweb) - * bug #35124 [TwigBridge][Form] Added missing help messages in form themes (cmen) - * bug #35195 [HttpClient] fix casting responses to PHP streams (nicolas-grekas) - * bug #35168 [HttpClient] fix capturing SSL certificates with NativeHttpClient (nicolas-grekas) - * bug #35134 [PropertyInfo] Fix BC issue in phpDoc Reflection library (jaapio) - * bug #35184 [Mailer] Payload sent to Sendgrid doesn't include names (versgui) - * bug #35173 [Mailer][MailchimpBridge] Fix missing attachments when sending via Mandrill API (vilius-g) - * bug #35172 [Mailer][MailchimpBridge] Fix incorrect sender address when sender has name (vilius-g) - * bug #35125 [Translator] fix performance issue in MessageCatalogue and catalogue operations (ArtemBrovko) - * bug #35120 [HttpClient] fix scheduling pending NativeResponse (nicolas-grekas) - * bug #35117 [Cache] do not overwrite variable value (xabbuh) - * bug #35113 [VarDumper] Fix "Undefined index: argv" when using CliContextProvider (xepozz) - * bug #34673 Migrate server:log command away from WebServerBundle (jderusse) - * bug #35103 [Translation] Use `locale_parse` for computing fallback locales (alanpoulain) - * bug #35060 [Security] Fix missing defaults for auto-migrating encoders (chalasr) - * bug #35067 [DependencyInjection][CheckTypeDeclarationsPass] Handle \Closure for callable (fancyweb) - * bug #35094 [Console] Fix filtering out identical alternatives when there is a command loader (fancyweb) - -* 4.4.2 (2019-12-19) - - * bug #35051 [DependencyInjection] Fix binding tagged services to containers (nicolas-grekas) - * bug #35039 [DI] skip looking for config class when the extension class is anonymous (nicolas-grekas) - * bug #35049 [ProxyManager] fix generating proxies for root-namespaced classes (nicolas-grekas) - * bug #35022 [Dotenv] FIX missing getenv (mccullagh) - * bug #35023 [HttpKernel] ignore failures generated by opcache.restrict_api (nicolas-grekas) - * bug #35024 [HttpFoundation] fix pdo session handler for sqlsrv (azjezz) - * bug #35025 [HttpClient][Psr18Client] Remove Psr18ExceptionTrait (fancyweb) - * bug #35015 [Config] fix perf of glob discovery when GLOB_BRACE is not available (nicolas-grekas) - * bug #35014 [HttpClient] make pushed responses retry-able (nicolas-grekas) - * bug #35010 [VarDumper] ignore failing __debugInfo() (nicolas-grekas) - * bug #34998 [DI] fix auto-binding service providers to their service subscribers (nicolas-grekas) - * bug #34954 [Mailer] Fixed undefined index when sending via Mandrill API (wulff) - * bug #33670 [DI] Service locators can't be decorated (malarzm) - * bug #35000 [Console][SymfonyQuestionHelper] Handle multibytes question choices keys and custom prompt (fancyweb) - * bug #35005 [HttpClient] force HTTP/1.1 when NTLM auth is used (nicolas-grekas) - * bug #34707 [Validation][FrameworkBundle] Allow EnableAutoMapping to work without auto-mapping namespaces (ogizanagi) - * bug #34996 Fix displaying anonymous classes on PHP 7.4 (nicolas-grekas) - * bug #29839 [Validator] fix comparisons with null values at property paths (xabbuh) - * bug #34900 [DoctrineBridge] Fixed submitting invalid ids when using queries with limit (HeahDude) - * bug #34791 [Serializer] Skip uninitialized (PHP 7.4) properties in PropertyNormalizer and ObjectNormalizer (vudaltsov) - * bug #34956 [Messenger][AMQP] Use delivery_mode=2 by default (lyrixx) - * bug #34915 [FrameworkBundle] Fix invalid Windows path normalization in TemplateNameParser (mvorisek) - * bug #34981 stop using deprecated Doctrine persistence classes (xabbuh) - * bug #34904 [Validator][ConstraintValidator] Safe fail on invalid timezones (fancyweb) - * bug #34935 [FrameworkBundle][DependencyInjection] Skip removed ids in the lint container command and its associated pass (fancyweb) - * bug #34957 [Security] Revert "AbstractAuthenticationListener.php error instead info" (larzuk91) - * bug #34922 [FrameworkBundle][Secrets] Hook configured local dotenv file (fancyweb) - * bug #34967 [HttpFoundation] fix redis multi host dsn not recognized (Jan Christoph Beyer) - * bug #34963 [Lock] fix constructor argument type declaration (xabbuh) - * bug #34955 Require doctrine/persistence ^1.3 (nicolas-grekas) - * bug #34923 [DI] Fix support for immutable setters in CallTrait (Lctrs) - * bug #34878 [TwigBundle] fix broken FilesystemLoader::exists() with Twig 3 (dpesch) - * bug #34921 [HttpFoundation] Removed "Content-Type" from the preferred format guessing mechanism (yceruto) - * bug #34886 [HttpKernel] fix triggering deprecation in file locator (xabbuh) - * bug #34918 [Translation] fix memoryleak in PhpFileLoader (nicolas-grekas) - * bug #34920 [Routing] fix memoryleak when loading compiled routes (nicolas-grekas) - * bug #34787 [Cache] Propagate expiry when syncing items in ChainAdapter (trvrnrth) - * bug #34694 [Validator] Fix auto-mapping constraints should not be validated (ogizanagi) - * bug #34848 [Process] change the syntax of portable command lines (nicolas-grekas) - * bug #34862 [FrameworkBundle][ContainerLintCommand] Reinitialize bundles when the container is reprepared (fancyweb) - * bug #34896 [Cache] fix memory leak when using PhpFilesAdapter (nicolas-grekas) - * bug #34438 [HttpFoundation] Use `Cache-Control: must-revalidate` only if explicit lifetime has been given (mpdude) - * bug #34449 [Yaml] Implement multiline string as scalar block for tagged values (natepage) - * bug #34601 [MonologBridge] Fix debug processor datetime type (mRoca) - * bug #34842 [ExpressionLanguage] Process division by zero (tigr1991) - * bug #34902 [PropertyAccess] forward caught exception (xabbuh) - * bug #34903 Fixing bad order of operations with null coalescing operator (weaverryan) - * bug #34888 [TwigBundle] add tags before processing them (xabbuh) - * bug #34760 [Mailer] Fix SMTP Authentication when using STARTTLS (DjLeChuck) - * bug #34762 [Config] never try loading failed classes twice with ClassExistenceResource (nicolas-grekas) - * bug #34783 [DependencyInjection] Handle env var placeholders in CheckTypeDeclarationsPass (fancyweb) - * bug #34839 [Cache] fix memory leak when using PhpArrayAdapter (nicolas-grekas) - * bug #34812 [Yaml] fix parsing negative octal numbers (xabbuh) - * bug #34854 [Messenger] gracefully handle missing event dispatchers (xabbuh) - * bug #34802 [Security] Check UserInterface::getPassword is not null before calling needsRehash (dbrekelmans) - * bug #34788 [SecurityBundle] Properly escape regex in AddSessionDomainConstraintPass (fancyweb) - * bug #34859 [SecurityBundle] Fix TokenStorage::reset not called in stateless firewall (jderusse) - * bug #34827 [HttpFoundation] get currently session.gc_maxlifetime if ttl doesnt exists (rafaeltovar) - * bug #34755 [FrameworkBundle] resolve service locators in `debug:*` commands (nicolas-grekas) - * bug #34832 [Validator] Allow underscore character "_" in URL username and password (romainneutron) - * bug #34811 [TwigBridge] Update bootstrap_4_layout.html.twig missing switch-custom label (sabruss) - * bug #34820 [FrameworkBundle][SodiumVault] Create secrets directory only when it is used (fancyweb) - * bug #34776 [DI] fix resolving bindings for named TypedReference (nicolas-grekas) - * bug #34794 [DependencyInjection] Resolve expressions in CheckTypeDeclarationsPass (fancyweb) - * bug #34797 [Translation] Fix FileDumper behavior (yceruto) - * bug #34738 [SecurityBundle] Passwords are not encoded when algorithm set to "true" (nieuwenhuisen) - * bug #34759 [SecurityBundle] Fix switch_user provider configuration handling (fancyweb) - * bug #34779 [Security] do not validate passwords when the hash is null (xabbuh) - * bug #34786 [SecurityBundle] Use config variable in AnonymousFactory (martijnboers) - * bug #34784 [FrameworkBundle] Set the parameter bag as resolved in ContainerLintCommand (fancyweb) - * bug #34763 [Security/Core] Fix checking for SHA256/SHA512 passwords (David Brooks) - * bug #34757 [DI] Fix making the container path-independent when the app is in /app (nicolas-grekas) - -* 4.4.1 (2019-12-01) - - * bug #34732 [DependencyInjection][Xml] Fix the attribute 'tag' is not allowed in 'bind' tag (tienvx) - * bug #34729 [DI] auto-register singly implemented interfaces by default (nicolas-grekas) - * bug #34728 [DI] fix overriding existing services with aliases for singly-implemented interfaces (nicolas-grekas) - * bug #34649 more robust initialization from request (dbu) - * bug #34715 [TwigBundle] remove service when base class is missing (xabbuh) - * bug #34600 [DoctrineBridge] do not depend on the QueryBuilder from the ORM (xabbuh) - * bug #34627 [Security/Http] call auth listeners/guards eagerly when they "support" the request (nicolas-grekas) - * bug #34671 [Security] Fix clearing remember-me cookie after deauthentication (chalasr) - * bug #34711 Fix the translation commands when a template contains a syntax error (fabpot) - * bug #34032 [Mime] Fixing multidimensional array structure with FormDataPart (jvahldick) - * bug #34560 [Config][ReflectionClassResource] Handle parameters with undefined constant as their default values (fancyweb) - * bug #34695 [Config] don't break on virtual stack frames in ClassExistenceResource (nicolas-grekas) - * bug #34716 [DependencyInjection] fix dumping number-like string parameters (xabbuh) - * bug #34558 [Console] Fix autocomplete multibyte input support (fancyweb) - * bug #34130 [Console] Fix commands description with numeric namespaces (fancyweb) - * bug #34562 [DI] Skip unknown method calls for factories in check types pass (fancyweb) - * bug #34677 [EventDispatcher] Better error reporting when arguments to dispatch() are swapped (rimas-kudelis) - * bug #33573 [TwigBridge] Add row_attr to all form themes (fancyweb) - * bug #34019 [Serializer] CsvEncoder::NO_HEADERS_KEY ignored when used in constructor (Dario Savella) - * bug #34083 [Form] Keep preferred_choices order for choice groups (vilius-g) - * bug #34091 [Debug] work around failing chdir() on Darwin (mary2501) - * bug #34305 [PhpUnitBridge] Read configuration CLI directive (ro0NL) - * bug #34490 [Serializer] Fix MetadataAwareNameConverter usage with string group (antograssiot) - * bug #34632 [Console] Fix trying to access array offset on value of type int (Tavafi) - * bug #34669 [HttpClient] turn exception into log when the request has no content-type (nicolas-grekas) - * bug #34662 [HttpKernel] Support typehint to deprecated FlattenException in controller (andrew-demb) - * bug #34619 Restores preview mode support for Html and Serializer error renderers (yceruto) - * bug #34636 [VarDumper] notice on potential undefined index (sylvainmetayer) - * bug #34668 [Cache] Make sure we get the correct number of values from redis::mget() (thePanz) - * bug #34621 [Routing] Continue supporting single colon in object route loaders (fancyweb) - * bug #34554 [HttpClient] Fix early cleanup of pushed HTTP/2 responses (lyrixx) - * bug #34607 [HttpKernel] Ability to define multiple kernel.reset tags (rmikalkenas) - * bug #34599 [Mailer][Mailchimp Bridge] Throwing undefined index _id when setting message id (monteiro) - * bug #34569 [Workflow] Apply the same logic of precedence between the apply() and the buildTransitionBlockerList() method (lyrixx) - * bug #34580 [HttpKernel] Don't cache "not-fresh" state (nicolas-grekas) - * bug #34577 [FrameworkBundle][Cache] Don't deep-merge cache pools configuration (alxndrbauer) - * bug #34515 [DependencyInjection] definitions are valid objects (xabbuh) - * bug #34536 [SecurityBundle] Don't require a user provider for the anonymous listener (chalasr) - * bug #34533 [Monolog Bridge] Fixed accessing static property as non static. (Sander-Toonen) - * bug #34502 [FrameworkBundle][ContainerLint] Keep "removing" compiler passes (fancyweb) - * bug #34552 [Dotenv] don't fail when referenced env var does not exist (xabbuh) - * bug #34546 [Serializer] Add DateTimeZoneNormalizer into Dependency Injection (jewome62) - * bug #34547 [Messenger] Error when specified default bus is not among the configured (vudaltsov) - * bug #34513 [Validator] remove return type declaration from __sleep() (xabbuh) - * bug #34551 [Security] SwitchUser is broken when the User Provider always returns a valid user (tucksaun) - * bug #34385 Avoid empty "If-Modified-Since" header in validation request (mpdude) - * bug #34458 [Validator] ConstraintValidatorTestCase: add missing return value to mocked validate method calls (ogizanagi) - * bug #34516 [HttpKernel] drop return type declaration (xabbuh) - * bug #34474 [Messenger] Ignore stamps in in-memory transport (tienvx) - -* 4.4.0 (2019-11-21) - - * bug #34464 [Form] group constraints when calling the validator (nicolas-grekas) - * bug #34451 [DependencyInjection] Fix dumping multiple deprecated aliases (shyim) - * bug #34448 [Form] allow button names to start with uppercase letter (xabbuh) - * bug #34428 [Security] Fix best encoder not wired using migrate_from (chalasr) - -* 4.4.0-RC1 (2019-11-17) - - * bug #34419 [Cache] Disable igbinary on PHP >= 7.4 (nicolas-grekas) - * bug #34347 [Messenger] Perform no deep merging of bus middleware (vudaltsov) - * bug #34366 [HttpFoundation] Allow redirecting to URLs that contain a semicolon (JayBizzle) - * feature #34405 [HttpFoundation] Added possibility to configure expiration time in redis session handler (mantulo) - * bug #34397 [FrameworkBundle] Remove project dir from Translator cache vary scanned directories (fancyweb) - * bug #34384 [DoctrineBridge] Improve queries parameters display in Profiler (fancyweb) - * bug #34408 [Cache] catch exceptions when using PDO directly (xabbuh) - * bug #34411 [HttpKernel] Flatten "exception" controller argument if not typed (chalasr) - * bug #34410 [HttpFoundation] Fix MySQL column type definition. (jbroutier) - * bug #34403 [Cache] Redis Tag Aware warn on wrong eviction policy (andrerom) - * bug #34400 [HttpKernel] collect bundle classes, not paths (nicolas-grekas) - * bug #34398 [Config] fix id-generation for GlobResource (nicolas-grekas) - * bug #34404 [HttpClient] fix HttpClientDataCollector (nicolas-grekas) - * bug #34396 [Finder] Allow ssh2 stream wrapper for sftp (damienalexandre) - * bug #34383 [DI] Use reproducible entropy to generate env placeholders (nicolas-grekas) - * bug #34389 [WebProfilerBundle] add FrameworkBundle requirement (xabbuh) - * bug #34381 [WebProfilerBundle] Require symfony/twig-bundle (fancyweb) - * bug #34358 [Security] always check the token on non-lazy firewalls (nicolas-grekas, lyrixx) - * bug #34390 [FrameworkBundle] fix wiring of httplug client (nicolas-grekas) - * bug #34369 [FrameworkBundle] Disallow WebProfilerBundle < 4.4 (derrabus) - * bug #34370 [DI] fix detecting singly implemented interfaces (nicolas-grekas) - -* 4.4.0-BETA2 (2019-11-13) - - * bug #34344 [Console] Constant STDOUT might be undefined (nicolas-grekas) - * security #cve-2019-18886 [Security\Core] throw AccessDeniedException when switch user fails (nicolas-grekas) - * security #cve-2019-18888 [Mime] fix guessing mime-types of files with leading dash (nicolas-grekas) - * security #cve-2019-11325 [VarExporter] fix exporting some strings (nicolas-grekas) - * security #cve-2019-18889 [Cache] forbid serializing AbstractAdapter and TagAwareAdapter instances (nicolas-grekas) - * security #cve-2019-18888 [HttpFoundation] fix guessing mime-types of files with leading dash (nicolas-grekas) - * security #cve-2019-18887 [HttpKernel] Use constant time comparison in UriSigner (stof) - -* 4.4.0-BETA1 (2019-11-12) - - * feature #34333 Revert "feature #34329 [ExpressionLanguage] add XOR operator (ottaviano)" (nicolas-grekas) - * feature #34332 Allow \Throwable $previous everywhere (fancyweb) - * feature #34329 [ExpressionLanguage] add XOR operator (ottaviano) - * feature #34312 [ErrorHandler] merge and remove the ErrorRenderer component (nicolas-grekas, yceruto) - * feature #34309 [HttpKernel] make ExceptionEvent able to propagate any throwable (nicolas-grekas) - * feature #34139 [Security] Add migrating encoder configuration (chalasr) - * feature #32194 [HttpFoundation] Add a way to anonymize IPs (Seldaek) - * feature #34252 [Console] Add support for NO_COLOR env var (Seldaek) - * feature #34295 [DI][FrameworkBundle] add EnvVarLoaderInterface - remove SecretEnvVarProcessor (nicolas-grekas) - * feature #31310 [DependencyInjection] Added option `ignore_errors: not_found` for imported config files (pulzarraider) - * feature #34216 [HttpClient] allow arbitrary JSON values in requests (pschultz) - * feature #31977 Add handling for delayed message to redis transport (alexander-schranz) - * feature #34217 [Messenger] use events consistently in worker (Tobion) - * feature #33065 Deprecate things that prevent \Throwable from bubbling down (fancyweb) - * feature #34184 [VarDumper] display the method we're in when dumping stack traces (nicolas-grekas) - * feature #33732 [Console] Rename some methods related to redraw frequency (javiereguiluz) - * feature #31587 [Routing][Config] Allow patterns of resources to be excluded from config loading (tristanbes) - * feature #32256 [DI] Add compiler pass and command to check that services wiring matches type declarations (alcalyn, GuilhemN, nicolas-grekas) - * feature #32061 Add new Form WeekType (dFayet) - * feature #33954 Form theme: support Bootstrap 4 custom switches (romaricdrigon) - * feature #33854 [DI] Add ability to choose behavior of decorations on non existent decorated services (mtarld) - * feature #34185 [Messenger] extract worker logic to listener and get rid of SendersLocatorInterface::getSenderByAlias (Tobion) - * feature #34156 Adding DoctrineClearEntityManagerWorkerSubscriber to reset EM in worker (weaverryan) - * feature #34133 [Cache] add DeflateMarshaller - remove phpredis compression (nicolas-grekas) - * feature #34177 [HttpFoundation][FrameworkBundle] allow configuring the session handler with a DSN (nicolas-grekas) - * feature #32107 [Validator] Add AutoMapping constraint to enable or disable auto-validation (dunglas) - * feature #34170 Re-allow to use "tagged" in service definitions (dunglas) - * feature #34043 [Lock] Add missing lock connection string in FrameworkExtension (jderusse) - * feature #34057 [Lock][Cache] Allows URL DSN in PDO adapters (jderusse) - * feature #34151 [DomCrawler] normalizeWhitespace should be true by default (dunglas) - * feature #34020 [Security] Allow to stick to a specific password hashing algorithm (chalasr) - * feature #34131 [FrameworkBundle] Remove suffix convention when using env vars to override secrets from the vault (nicolas-grekas) - * feature #34051 [HttpClient] allow option "buffer" to be a stream resource (nicolas-grekas) - * feature #34028 [ExpressionLanguage][Lexer] Exponential format for number (tigr1991) - * feature #34069 [Messenger] Removing "sync" transport and replacing it with config trick (weaverryan) - * feature #34014 [DI] made the `env(base64:...)` processor able to decode base64url (nicolas-grekas) - * feature #34044 [HttpClient] Add a canceled state to the ResponseInterface (Toflar) - * feature #33997 [FrameworkBundle] Add `secrets:*` commands and `env(secret:...)` processor to deal with secrets seamlessly (Tobion, jderusse, nicolas-grekas) - * feature #34013 [DI] add `LazyString` for lazy computation of string values injected into services (nicolas-grekas) - * feature #33961 [TwigBridge] Add show-deprecations option to the lint:twig command (yceruto) - * feature #33973 [HttpClient] add HttpClient::createForBaseUri() (nicolas-grekas) - * feature #33980 [HttpClient] try using php-http/discovery when nyholm/psr7 is not installed (nicolas-grekas) - * feature #33967 [Mailer] Add Message-Id to SentMessage when sending an email (fabpot) - * feature #33896 [Serializer][CSV] Add context options to handle BOM (malarzm) - * feature #33883 [Mailer] added ReplyTo option for PostmarkApiTransport (pierregaste) - * feature #33053 [ErrorHandler] Rework fatal errors (fancyweb) - * feature #33939 [Cache] add TagAwareMarshaller to optimize data storage when using AbstractTagAwareAdapter (nicolas-grekas) - * feature #33941 Keeping backward compatibility with legacy FlattenException usage (yceruto) - * feature #33851 [EventDispatcher] Allow to omit the event name when registering listeners (derrabus) - * feature #33461 [Cache] Improve RedisTagAwareAdapter invalidation logic & requirements (andrerom) - * feature #33779 [DI] enable improved syntax for defining method calls in Yaml (nicolas-grekas) - * feature #33743 [HttpClient] Async HTTPlug client (Nyholm) - * feature #33856 [Messenger] Allow to configure the db index on Redis transport (chalasr) - * feature #33881 [VarDumper] Added a support for casting Ramsey/Uuid (lyrixx) - * feature #33861 [CssSelector] Support *:only-of-type (jakzal) - * feature #33793 [EventDispatcher] A compiler pass for aliased userland events (derrabus) - * feature #33791 [Form] Added CountryType option for using alpha3 country codes (creiner) - * feature #33628 [DependencyInjection] added Ability to define a priority method for tagged service (lyrixx) - * feature #33775 [Console] Add deprecation message for non-int statusCode (jschaedl) - * feature #33783 [WebProfilerBundle] Try to display the most useful panel by default (fancyweb) - * feature #33701 [HttpKernel] wrap compilation of the container in an opportunistic lock (nicolas-grekas) - * feature #33789 [Serializer] Deprecate the XmlEncoder::TYPE_CASE_ATTRIBUTES constant (pierredup) - * feature #33776 Copy phpunit.xsd to a predictable path (julienfalque) - * feature #31446 [VarDumper] Output the location of calls to dump() (ktherage) - * feature #33412 [Console] Do not leak hidden console commands (m-vo) - * feature #33676 [Security] add "anonymous: lazy" mode to firewalls (nicolas-grekas) - * feature #32440 [DomCrawler] add a normalizeWhitespace argument to text() method (Simperfit) - * feature #33148 [Intl] Excludes locale from language codes (split localized language names) (ro0NL) - * feature #31202 [FrameworkBundle] WebTestCase KernelBrowser::getContainer null return type (Simperfit) - * feature #33038 [ErrorHandler] Forward \Throwable (fancyweb) - * feature #33574 [Http][DI] Replace REMOTE_ADDR in trusted proxies with the current REMOTE_ADDR (mcfedr) - * feature #33113 [Messenger][DX] Display real handler if handler is wrapped (DavidBadura) - * feature #33128 [FrameworkBundle] Sort tagged services (krome162504) - * feature #33658 [Yaml] fix parsing inline YAML spanning multiple lines (xabbuh) - * feature #33698 [HttpKernel] compress files generated by the profiler (nicolas-grekas) - * feature #33317 [Messenger] Added support for `from_transport` attribute on `messenger.message_handler` tag (ruudk) - * feature #33584 [Security] Deprecate isGranted()/decide() on more than one attribute (wouterj) - * feature #33663 [Security] Make stateful firewalls turn responses private only when needed (nicolas-grekas) - * feature #33609 [Form][SubmitType] Add "validate" option (fancyweb) - * feature #33621 Revert "feature #33507 [WebProfiler] Deprecated intercept_redirects in 4.4 (dorumd)" (lyrixx) - * feature #33605 [Twig] Add NotificationEmail (fabpot) - * feature #33623 [DependencyInjection] Allow binding iterable and tagged services (lyrixx) - * feature #33507 [WebProfiler] Deprecated intercept_redirects in 4.4 (dorumd) - * feature #33579 Adding .gitattributes to remove Tests directory from "dist" (Nyholm) - * feature #33562 [Mailer] rename SmtpEnvelope to Envelope (xabbuh) - * feature #33565 [Mailer] Rename an exception class (fabpot) - * feature #33516 [Cache] Added reserved characters constant for CacheItem (andyexeter) - * feature #33503 [SecurityBundle] Move Anonymous DI integration to new AnonymousFactory (wouterj) - * feature #33535 [WebProfilerBundle] Assign automatic colors to custom Stopwatch categories (javiereguiluz) - * feature #32565 [HttpClient] Allow enabling buffering conditionally with a Closure (rjwebdev) - * feature #32032 [DI] generate preload.php file for PHP 7.4 in cache folder (nicolas-grekas) - * feature #33117 [FrameworkBundle] Added --sort option for TranslationUpdateCommand (k0d3r1s) - * feature #32832 [Serializer] Allow multi-dimenstion object array in AbstractObjectNormalizer (alediator) - * feature #33189 New welcome page on startup for 4.4 LTS & 5.0 (yceruto) - * feature #33295 [OptionsResolver] Display full nested option hierarchy in exceptions (fancyweb) - * feature #33486 [VarDumper] Display fully qualified title (pavinthan, nicolas-grekas) - * feature #33496 Deprecated not passing dash symbol (-) to STDIN commands (yceruto) - * feature #32742 [Console] Added support for definition list and horizontal table (lyrixx) - * feature #33494 [Mailer] Change DSN syntax (fabpot) - * feature #33471 [Mailer] Check email validity before opening an SMTP connection (fabpot) - * feature #31177 #21571 Comparing roles to detected that users has changed (oleg-andreyev) - * feature #33459 [Validator] Deprecated CacheInterface in favor of PSR-6 (derrabus) - * feature #33271 Added new ErrorController + Preview and enabling there the error renderer mechanism (yceruto) - * feature #33454 [Mailer] Improve an exception when trying to send a RawMessage without an Envelope (fabpot) - * feature #33327 [ErrorHandler] Registering basic exception handler for late failures (yceruto) - * feature #33446 [TwigBridge] lint all templates from configured Twig paths if no argument was provided (yceruto) - * feature #33409 [Mailer] Add support for multiple mailers (fabpot) - * feature #33424 [Mailer] Change the DSN semantics (fabpot) - * feature #33319 Allow configuring class names through methods instead of class parameters in Doctrine extensions (alcaeus) - * feature #33283 [ErrorHandler] make DebugClassLoader able to add return type declarations (nicolas-grekas) - * feature #33323 [TwigBridge] Throw an exception when one uses email as a context variable in a TemplatedEmail (fabpot) - * feature #33308 [SecurityGuard] Deprecate returning non-boolean values from checkCredentials() (derrabus) - * feature #33217 [FrameworkBundle][DX] Improving the redirect config when using RedirectController (yceruto) - * feature #33015 [HttpClient] Added TraceableHttpClient and WebProfiler panel (jeremyFreeAgent) - * feature #33091 [Mime] Add Address::fromString (gisostallenberg) - * feature #33144 [DomCrawler] Added Crawler::matches(), ::closest(), ::outerHtml() (lyrixx) - * feature #33152 Mark all dispatched event classes as final (Tobion) - * feature #33258 [HttpKernel] deprecate global dir to load resources from (Tobion) - * feature #33272 [Translation] deprecate support for null locales (xabbuh) - * feature #33269 [TwigBridge] Mark all classes extending twig as @final (fabpot) - * feature #33270 [Mime] Remove NamedAddress (fabpot) - * feature #33169 [HttpFoundation] Precalculate session expiry timestamp (azjezz) - * feature #33237 [Mailer] Remove the auth mode DSN option and support in the eSMTP transport (fabpot) - * feature #33233 [Mailer] Simplify the way TLS/SSL/STARTTLS work (fabpot) - * feature #32360 [Monolog] Added ElasticsearchLogstashHandler (lyrixx) - * feature #32489 [Messenger] Allow exchange type headers binding (CedrickOka) - * feature #32783 [Messenger] InMemoryTransport handle acknowledged and rejected messages (tienvx) - * feature #33155 [ErrorHandler] Added call() method utility to turns any PHP error into \ErrorException (yceruto) - * feature #33203 [Mailer] Add support for the queued flag in the EmailCount assertion (fabpot) - * feature #30323 [ErrorHandler] trigger deprecation in DebugClassLoader when child class misses a return type (fancyweb, nicolas-grekas) - * feature #33137 [DI] deprecate support for non-object services (nicolas-grekas) - * feature #32845 [HttpKernel][FrameworkBundle] Add alternative convention for bundle directories (yceruto) - * feature #32548 [Translation] XliffLintCommand: allow .xliff file extension (codegain) - * feature #28363 [Serializer] Encode empty objects as objects, not arrays (mcfedr) - * feature #33122 [WebLink] implement PSR-13 directly (nicolas-grekas) - * feature #33078 Add compatibility trait for PHPUnit constraint classes (alcaeus) - * feature #32988 [Intl] Support ISO 3166-1 Alpha-3 country codes (terjebraten-certua) - * feature #32598 [FrameworkBundle][Routing] Private service route loaders (fancyweb) - * feature #32486 [DoctrineBridge] Invokable event listeners (fancyweb) - * feature #31083 [Validator] Allow objects implementing __toString() to be used as violation messages (mdlutz24) - * feature #32122 [HttpFoundation] deprecate HeaderBag::get() returning an array and add all($key) instead (Simperfit) - * feature #32807 [HttpClient] add "max_duration" option (fancyweb) - * feature #31546 [Dotenv] Use default value when referenced variable is not set (j92) - * feature #32930 [Mailer][Mime] Add PHPUnit constraints and assertions for the Mailer (fabpot) - * feature #32912 [Mailer] Add support for the profiler (fabpot) - * feature #32940 [PhpUnitBridge] Add polyfill for PhpUnit namespace (jderusse) - * feature #31843 [Security] add support for opportunistic password migrations (nicolas-grekas) - * feature #32824 [Ldap] Add security LdapUser and provider (chalasr) - * feature #32922 [PhpUnitBridge] make the bridge act as a polyfill for newest PHPUnit features (nicolas-grekas) - * feature #32927 [Mailer] Add message events logger (fabpot) - * feature #32916 [Mailer] Add a name to the transports (fabpot) - * feature #32917 [Mime] Add AbstractPart::asDebugString() (fabpot) - * feature #32543 [FrameworkBundle] add config translator cache_dir (Raulnet) - * feature #32669 [Yaml] Add flag to dump NULL as ~ (OskarStark) - * feature #32896 [Mailer] added debug info to TransportExceptionInterface (fabpot) - * feature #32817 [DoctrineBridge] Deprecate RegistryInterface (Koc) - * feature #32504 [ErrorRenderer] Add DebugCommand for easy debugging and testing (yceruto) - * feature #32581 [DI] Allow dumping the container in one file instead of many files (nicolas-grekas) - * feature #32762 [Form][DX] derive default timezone from reference_date option when possible (yceruto) - * feature #32745 [Messenger][Profiler] Attempt to give more useful source info when using HandleTrait (ogizanagi) - * feature #32680 [Messenger][Profiler] Collect the stamps at the end of dispatch (ogizanagi) - * feature #32683 [VarDumper] added support for Imagine/Image (lyrixx) - * feature #32749 [Mailer] Make transport factory test case public (Koc) - * feature #32718 [Form] use a reference date to handle times during DST (xabbuh) - * feature #32637 [ErrorHandler] Decouple from ErrorRenderer component (yceruto) - * feature #32609 [Mailer][DX][RFC] Rename mailer bridge transport classes (Koc) - * feature #32587 [Form][Validator] Generate accept attribute with file constraint and mime types option (Coosos) - * feature #32658 [Form] repeat preferred choices in list of all choices (Seb33300, xabbuh) - * feature #32698 [WebProfilerBundle] mark all classes as internal (Tobion) - * feature #32695 [WebProfilerBundle] Decoupling TwigBundle and using the new ErrorRenderer mechanism (yceruto) - * feature #31398 [TwigBundle] Deprecating error templates for non-html formats and using ErrorRenderer as fallback (yceruto) - * feature #32582 [Routing] Deprecate ServiceRouterLoader and ObjectRouteLoader in favor of ContainerLoader and ObjectLoader (fancyweb) - * feature #32661 [ErrorRenderer] Improving the exception page provided by HtmlErrorRenderer (yceruto) - * feature #32332 [DI] Move non removing compiler passes to after removing passes (alexpott) - * feature #32475 [Process] Deprecate Process::inheritEnvironmentVariables() (ogizanagi) - * feature #32583 [Mailer] Logger vs debug mailer (fabpot) - * feature #32471 Add a new ErrorHandler component (mirror of the Debug component) (yceruto) - * feature #32463 [VarDumper] Allow to configure VarDumperTestTrait casters & flags (ogizanagi) - * feature #31946 [Mailer] Extract transport factory and allow create custom transports (Koc) - * feature #31194 [PropertyAccess] Improve errors when trying to find a writable property (pierredup) - * feature #32435 [Validator] Add a new constraint message when there is both min and max (Lctrs) - * feature #32470 Rename ErrorCatcher to ErrorRenderer (rendering part only) (yceruto) - * feature #32462 [WebProfilerBundle] Deprecating templateExists method (yceruto) - * feature #32446 [Lock] rename and deprecate Factory into LockFactory (Simperfit) - * feature #31975 Dynamic bundle assets (garak) - * feature #32429 [VarDumper] Let browsers trigger their own search on double CMD/CTRL + F (ogizanagi) - * feature #32198 [Lock] Split "StoreInterface" into multiple interfaces with less responsability (Simperfit) - * feature #31511 [Validator] Allow to use property paths to get limits in range constraint (Lctrs) - * feature #32424 [Console] don't redraw progress bar more than every 100ms by default (nicolas-grekas) - * feature #32418 [Console] Added Application::reset() (lyrixx) - * feature #31217 [WebserverBundle] Deprecate the bundle in favor of symfony local server (Simperfit) - * feature #31554 [SECURITY] AbstractAuthenticationListener.php error instead info. Rebase of #28462 (berezuev) - * feature #32284 [Cache] Add argument $prefix to AdapterInterface::clear() (nicolas-grekas) - * feature #32423 [ServerBundle] Display all logs by default (lyrixx) - * feature #26339 [Console] Add ProgressBar::preventRedrawFasterThan() and forceRedrawSlowerThan() methods (ostrolucky) - * feature #31269 [Translator] Dump native plural formats to po files (Stadly) - * feature #31560 [Ldap][Security] LdapBindAuthenticationProvider does not bind before search query (Simperfit) - * feature #31626 [Console] allow answer to be trimmed by adding a flag (Simperfit) - * feature #31876 [WebProfilerBundle] Add clear button to ajax tab (Matts) - * feature #32415 [Translation] deprecate passing a null locale (Simperfit) - * feature #32290 [HttpClient] Add $response->toStream() to cast responses to regular PHP streams (nicolas-grekas) - * feature #32402 [Intl] Exclude root language (ro0NL) - * feature #32295 [FrameworkBundle] Add autowiring alias for PSR-14 (nicolas-grekas) - * feature #32390 [DependencyInjection] Deprecated passing Parameter instances as class name to Definition (derrabus) - * feature #32106 [FrameworkBundle] Use default_locale as default value for translator.fallbacks (dunglas) - * feature #32294 [FrameworkBundle] Allow creating chained cache pools by providing several adapters (nicolas-grekas) - * feature #32207 [FrameworkBundle] Allow to use the BrowserKit assertions with Panther and API Platform's test client (dunglas) - * feature #32344 [HttpFoundation][HttpKernel] Improving the request/response format autodetection (yceruto) - * feature #32231 [HttpClient] Add support for NTLM authentication (nicolas-grekas) - * feature #32265 [Validator] deprecate non-string constraint violation codes (xabbuh) - * feature #31528 [Validator] Add a Length::$allowEmptyString option to reject empty strings (ogizanagi) - * feature #32081 [WIP][Mailer] Overwrite envelope sender and recipients from config (Devristo) - * feature #32255 [HttpFoundation] Drop support for ApacheRequest (lyrixx) - * feature #31825 [Messenger] Added support for auto trimming of redis streams (Toflar) - * feature #32277 Remove @experimental annotations (fabpot) - * feature #30981 [Mime] S/MIME Support (sstok) - * feature #32180 [Lock] add an InvalidTTLException to be more accurate (Simperfit) - * feature #32241 [PropertyAccess] Deprecate null as allowed value for defaultLifetime argument in createCache method (jschaedl) - * feature #32221 [ErrorCatcher] Make IDEs and static analysis tools happy (fabpot) - * feature #32227 Rename the ErrorHandler component to ErrorCatcher (fabpot) - * feature #31065 Add ErrorHandler component (yceruto) - * feature #32126 [Process] Allow writing portable "prepared" command lines (Simperfit) - * feature #31532 [Ldap] Add users extraFields in ldap component (Simperfit) - * feature #32104 Add autowiring for HTTPlug (nicolas-grekas) - * feature #32130 [Form] deprecate int/float for string input in NumberType (xabbuh) - * feature #31547 [Ldap] Add exception for mapping ldap errors (Simperfit) - * feature #31764 [FrameworkBundle] add attribute stamps (walidboughdiri) - * feature #32059 [PhpUnitBridge] Bump PHPUnit 7+8 (ro0NL) - * feature #32041 [Validator] Deprecate unused arg in ExpressionValidator (ogizanagi) - * feature #31287 [Config] Introduce find method in ArrayNodeDefinition to ease configuration tree manipulation (jschaedl) - * feature #31959 [DomCrawler][Feature][DX] Add Form::getName() method (JustBlackBird) - * feature #32026 [VarDumper] caster for HttpClient's response dumps all info (nicolas-grekas) - * feature #31976 [HttpClient] add HttplugClient for compat with libs that need httplug v1 or v2 (nicolas-grekas) - * feature #31956 [Mailer] Changed EventDispatcherInterface dependency from Component to Contracts (Koc) - * feature #31980 [HttpClient] make Psr18Client implement relevant PSR-17 factories (nicolas-grekas) - * feature #31919 [WebProfilerBundle] Select default theme based on user preferences (javiereguiluz) - * feature #31451 [FrameworkBundle] Allow dots in translation domains (jschaedl) - * feature #31321 [DI] deprecates tag !tagged in favor of !tagged_iterator (jschaedl) - * feature #31658 [HTTP Foundation] Deprecate passing argument to method Request::isMethodSafe() (dFayet) - * feature #31597 [Security] add MigratingPasswordEncoder (nicolas-grekas) - * feature #31351 [Validator] Improve TypeValidator to handle array of types (jschaedl) - * feature #31526 [Validator] Add compared value path to violation parameters (ogizanagi) - * feature #31514 Add exception as HTML comment to beginning and end of `exception_full.html.twig` (ruudk) - * feature #31739 [FrameworkBundle] Add missing BC layer for deprecated ControllerNameParser injections (chalasr) - * feature #31831 [HttpClient] add $response->cancel() (nicolas-grekas) - * feature #31334 [Messenger] Add clear Entity Manager middleware (Koc) - * feature #31594 [Security] add PasswordEncoderInterface::needsRehash() (nicolas-grekas) - * feature #31821 [FrameworkBundle][TwigBundle] Add missing deprecations for PHP templating layer (yceruto) - * feature #31509 [Monolog] Setup the LoggerProcessor after all other processor (lyrixx) - * feature #31785 [Messenger] Deprecate passing a bus locator to ConsumeMessagesCommand's constructor (chalasr) - * feature #31700 [MonologBridge] RouteProcessor class is now final to ease the the removal of deprecated event (Simperfit) - * feature #31732 [HttpKernel] Make DebugHandlersListener internal (chalasr) - * feature #31539 [HttpKernel] Add lts config (noniagriconomie) - * feature #31437 [Cache] Add Redis Sentinel support (StephenClouse) - * feature #31543 [DI] deprecate short callables in yaml (nicolas-grekas) - diff --git a/CHANGELOG-5.0.md b/CHANGELOG-5.0.md new file mode 100644 index 0000000000000..1836adff61c2d --- /dev/null +++ b/CHANGELOG-5.0.md @@ -0,0 +1,791 @@ +CHANGELOG for 5.0.x +=================== + +This changelog references the relevant changes (bug and security fixes) done +in 5.0 minor versions. + +To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash +To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v5.0.0...v5.0.1 + +* 5.0.10 (2020-06-12) + + * bug #37227 [DependencyInjection][CheckTypeDeclarationsPass] Handle unresolved parameters pointing to environment variables (fancyweb) + * bug #37103 [Form] switch the context when validating nested forms (xabbuh) + * bug #37182 [HttpKernel] Fix regression where Store does not return response body correctly (mpdude) + * bug #37193 [DependencyInjection][CheckTypeDeclarationsPass] Always resolve parameters (fancyweb) + * bug #37191 [HttpClient] fix offset computation for data chunks (nicolas-grekas) + * bug #37177 [Ldap] fix refreshUser() ignoring extra_fields (arkste) + * bug #37181 [Mailer] Remove an internal annot (fabpot) + * bug #36913 [FrameworkBundle] fix type annotation on ControllerTrait::addFlash() (ThomasLandauer) + * bug #37162 [Mailer] added the reply-to addresses to the API SES transport request. (ribeiropaulor) + * bug #37167 [Mime] use fromString when creating a new Address (fabpot) + * bug #37169 [Cache] fix forward compatibility with Doctrine DBAL 3 (xabbuh) + * bug #37159 [Mailer] Fixed generator bug when creating multiple transports using Transport::fromDsn (atailouloute) + * bug #37048 [HttpClient] fix monitoring timeouts when other streams are active (nicolas-grekas) + * bug #37085 [Form] properly cascade validation to child forms (xabbuh) + * bug #37095 [PhpUnitBridge] Fix undefined index when output of "composer show" cannot be parsed (nicolas-grekas) + * bug #37092 [PhpUnitBridge] fix undefined var on version 3.4 (nicolas-grekas) + * bug #37065 [HttpClient] Throw JsonException instead of TransportException on empty response in Response::toArray() (jeroennoten) + * bug #37077 [WebProfilerBundle] Move ajax clear event listener initialization on loadToolbar (Bruno BOUTAREL) + * bug #37049 [Serializer] take into account the context when preserving empty array objects (xabbuh) + +* 5.0.9 (2020-05-31) + + * bug #37008 [Security] Fixed AbstractToken::hasUserChanged() (wouterj) + * bug #36894 [Validator] never directly validate Existence (Required/Optional) constraints (xabbuh) + * bug #37007 [Console] Fix QuestionHelper::disableStty() (chalasr) + * bug #36865 [Form] validate subforms in all validation groups (xabbuh) + * bug #36907 Fixes sprintf(): Too few arguments in form transformer (pedrocasado) + * bug #36868 [Validator] Use Mime component to determine mime type for file validator (pierredup) + * bug #37000 Add meaningful message when using ProcessHelper and Process is not installed (l-vo) + * bug #36995 [TwigBridge] fix fallback html-to-txt body converter (nicolas-grekas) + * bug #36993 [ErrorHandler] fix setting $trace to null in FatalError (nicolas-grekas) + * bug #36987 Handle fetch mode deprecation of DBAL 2.11. (derrabus) + * bug #36974 [Security] Fixed handling of CSRF logout error (wouterj) + * bug #36947 [Mime] Allow email message to have "To", "Cc", or "Bcc" header to be valid (Ernest Hymel) + * bug #36914 Parse and render anonymous classes correctly on php 8 (derrabus) + * bug #36921 [OptionsResolver][Serializer] Remove calls to deprecated ReflectionParameter::getClass() (derrabus) + * bug #36920 [VarDumper] fix PHP 8 support (nicolas-grekas) + * bug #36917 [Cache] Accessing undefined constants raises an Error in php8 (derrabus) + * bug #36891 Address deprecation of ReflectionType::getClass() (derrabus) + * bug #36899 [VarDumper] ReflectionFunction::isDisabled() is deprecated (derrabus) + * bug #36905 [Validator] Catch expected ValueError (derrabus) + * bug #36915 [DomCrawler] Catch expected ValueError (derrabus) + * bug #36908 [Cache][HttpClient] Made method signatures compatible with their corresponding traits (derrabus) + * bug #36906 [DomCrawler] Catch expected ValueError (derrabus) + * bug #36904 [PropertyAccess] Parse php 8 TypeErrors correctly (derrabus) + * bug #36839 [BrowserKit] Raw body with custom Content-Type header (azhurb) + * bug #36896 [Config] Removed implicit cast of ReflectionProperty to string (derrabus) + * bug #35944 [Security/Core] Fix wrong roles comparison (thlbaut) + * bug #36882 [PhpUnitBridge] fix installing under PHP >= 8 (nicolas-grekas) + * bug #36833 [HttpKernel] Fix that the `Store` would not save responses with the X-Content-Digest header present (mpdude) + * bug #36867 [PhpUnitBridge] fix bad detection of unsilenced deprecations (nicolas-grekas) + * bug #36862 [Security] Unserialize $parentData, if needed, to avoid errors (rfaivre) + * bug #36855 [HttpKernel] Fix error logger when stderr is redirected to /dev/null (fabpot) + * bug #36838 [HttpKernel] Bring back the debug toolbar (derrabus) + * bug #36592 [BrowserKit] Allow Referer set by history to be overridden (Slamdunk) + * bug #36823 [HttpClient] fix PHP warning + accept status code >= 600 (nicolas-grekas) + * bug #36824 [Security/Core] fix compat of `NativePasswordEncoder` with pre-PHP74 values of `PASSWORD_*` consts (nicolas-grekas) + * bug #36811 [DependencyInjection] Fix register event listeners compiler pass (X-Coder264) + * bug #36789 Change priority of KernelEvents::RESPONSE subscriber (marcw) + * bug #36794 [Serializer] fix issue with PHP 8 (nicolas-grekas) + * bug #36786 [WebProfiler] Remove 'none' when appending CSP tokens (ndench) + * bug #36743 [Yaml] Fix escaped quotes in quoted multi-line string (ossinkine) + * bug #36777 [TwigBundle] FormExtension does not have a constructor anymore since sf 4.0 (Tobion) + * bug #36716 [Mime] handle passing custom mime types as string (mcneely) + * bug #36747 Queue name is a required parameter (theravel) + * bug #36751 [Mime] fix bad method call on `EmailAddressContains` (Kocal) + * bug #36696 [Console] don't check tty on stdin, it breaks with "data lost during stream conversion" (nicolas-grekas) + * bug #36569 [PhpUnitBridge] Mark parent class also covered in CoverageListener (lyrixx) + * bug #36690 [Yaml] prevent notice for invalid octal numbers on PHP 7.4 (xabbuh) + * bug #36590 [Console] Default hidden question to 1 attempt for non-tty session (ostrolucky) + * bug #36497 [Filesystem] Handle paths on different drives (crishoj) + * bug #36678 [WebProfiler] Do not add src-elem CSP directives if they do not exist (ndench) + * bug #36501 [DX] Show the ParseException message in all YAML file loaders (fancyweb) + * bug #36683 [Yaml] fix parse error when unindented collections contain a comment (wdiesveld) + * bug #36672 [Validator] Skip validation when email is an empty object (acrobat) + * bug #36673 [PhpUnitBridge] fix PHP 5.3 compat again (nicolas-grekas) + * bug #36505 [Translation] Fix for translation:update command updating ICU messages (artemoliynyk) + * bug #36627 [Validator] fix lazy property usage. (bendavies) + * bug #36601 [Serializer] do not transform empty \Traversable to Array (soyuka) + * bug #36606 [Cache] Fixed not supported Redis eviction policies (SerheyDolgushev) + * bug #36625 [PhpUnitBridge] fix compat with PHP 5.3 (nicolas-grekas) + +* 5.0.8 (2020-04-28) + + * bug #36536 [Cache] Allow invalidateTags calls to be traced by data collector (l-vo) + * bug #36566 [PhpUnitBridge] Use COMPOSER_BINARY env var if available (fancyweb) + * bug #36560 [YAML] escape DEL(\x7f) (sdkawata) + * bug #36539 [PhpUnitBridge] fix compatibility with phpunit 9 (garak) + * bug #36555 [Cache] skip APCu in chains when the backend is disabled (nicolas-grekas) + * bug #36523 [Form] apply automatically step=1 for datetime-local input (ottaviano) + * bug #36519 [FrameworkBundle] debug:autowiring: Fix wrong display when using class_alias (weaverryan) + * bug #36454 [DependencyInjection][ServiceSubscriber] Support late aliases (fancyweb) + * bug #36162 [Profiler] Fix profiler nullable string type (mRoca) + * bug #36498 [Security/Core] fix escape for username in LdapBindAuthenticationProvider.php (stoccc) + * bug #36506 [FrameworkBundle] Fix session.attribute_bag service definition (fancyweb) + * bug #36500 [Routing][PrefixTrait] Add the _locale requirement (fancyweb) + * bug #36457 [Cache] CacheItem with tag is never a hit after expired (alexander-schranz, nicolas-grekas) + * bug #36490 [HttpFoundation] workaround PHP bug in the session module (nicolas-grekas) + * bug #36483 [SecurityBundle] fix accepting env vars in remember-me configurations (zek) + * bug #36343 [Form] Fixed handling groups sequence validation (HeahDude) + * bug #36463 [Mime] Ensure proper line-ending for SMIME (sstok) + * bug #36460 [Cache] Avoid memory leak in TraceableAdapter::reset() (lyrixx) + * bug #36467 Mailer from sender fixes (fabpot) + * bug #36408 [PhpUnitBridge] add PolyfillTestCaseTrait::expectExceptionMessageMatches to provide FC with recent phpunit versions (soyuka) + * bug #36447 Remove return type for Twig function workflow_metadata() (gisostallenberg) + * bug #36449 [Messenger] Make sure redis transports are initialized correctly (Seldaek) + * bug #36411 [Form] RepeatedType should always have inner types mapped (biozshock) + * bug #36441 [DI] fix loading defaults when using the PHP-DSL (nicolas-grekas) + * bug #36434 [HttpKernel] silence E_NOTICE triggered since PHP 7.4 (xabbuh) + * bug #36365 [Validator] Fixed default group for nested composite constraints (HeahDude) + * bug #36422 [HttpClient] fix HTTP/2 support on non-SSL connections - CurlHttpClient only (nicolas-grekas) + * bug #36417 Force ping after transport exception (oesteve) + * bug #35591 [Validator] do not merge constraints within interfaces (greedyivan) + * bug #36377 [HttpClient] Fix scoped client without query option configuration (X-Coder264) + * bug #36387 [DI] fix detecting short service syntax in yaml (nicolas-grekas) + * bug #36392 [DI] add missing property declarations in InlineServiceConfigurator (nicolas-grekas) + * bug #36400 Allowing empty secrets to be set (weaverryan) + * bug #36380 [Process] Fixed input/output error on PHP 7.4 (mbardelmeijer) + * bug #36376 [Workflow] Use a strict comparison when retrieving raw marking in MarkingStore (lyrixx) + * bug #36375 [Workflow] Use a strict comparison when retrieving raw marking in MarkingStore (lyrixx) + * bug #36305 [PropertyInfo][ReflectionExtractor] Check the array mutator prefixes last when the property is singular (fancyweb) + * bug #35656 [HttpFoundation] Fixed session migration with custom cookie lifetime (Guite) + * bug #36342 [HttpKernel][FrameworkBundle] fix compat with Debug component (nicolas-grekas) + * bug #36315 [WebProfilerBundle] Support for Content Security Policy style-src-elem and script-src-elem in WebProfiler (ampaze) + * bug #36286 [Validator] Allow URL-encoded special characters in basic auth part of URLs (cweiske) + * bug #36335 [Security] Track session usage whenever a new token is set (wouterj) + * bug #36332 [Serializer] Fix unitialized properties (from PHP 7.4.2) when serializing context for the cache key (alanpoulain) + * bug #36338 [MonologBridge] Fix $level type (fancyweb) + * bug #36337 [MonologBridge] Fix $level type (fancyweb) + * bug #36223 [Security][Http][SwitchUserListener] Ignore all non existent username protection errors (fancyweb) + * bug #36239 [HttpKernel][LoggerDataCollector] Prevent keys collisions in the sanitized logs processing (fancyweb) + * bug #36245 [Validator] Fixed calling getters before resolving groups (HeahDude) + * bug #36265 Fix the reporting of deprecations in twig:lint (stof) + * bug #36283 [Security] forward multiple attributes voting flag (xabbuh) + +* 5.0.7 (2020-03-30) + + * security #cve-2020-5255 [HttpFoundation] Do not set the default Content-Type based on the Accept header (yceruto) + * security #cve-2020-5275 [Security] Fix access_control behavior with unanimous decision strategy (chalasr) + * bug #36262 [DI] fix generating TypedReference from PriorityTaggedServiceTrait (nicolas-grekas) + * bug #36252 [Security/Http] Allow setting cookie security settings for delete_cookies (wouterj) + * bug #36261 [FrameworkBundle] revert to legacy wiring of the session when circular refs are detected (nicolas-grekas) + * bug #36259 [DomCrawler] Fix BC break in assertions breaking Panther (dunglas) + * bug #36181 [BrowserKit] fixed missing post request parameters in file uploads (codebay) + * bug #36216 [Validator] Assert Valid with many groups (phucwan91) + * bug #36222 [Console] Fix OutputStream for PHP 7.4 (guillbdx) + +* 5.0.6 (2020-03-27) + + * bug #36169 [HttpKernel] fix locking for PHP 7.4+ (nicolas-grekas) + * bug #36175 [Security/Http] Remember me: allow to set the samesite cookie flag (dunglas) + * bug #36173 [Http Foundation] Fix clear cookie samesite (guillbdx) + * bug #36176 [Security] Check if firewall is stateless before checking for session/previous session (koenreiniers) + * bug #36149 [Form] Support customized intl php.ini settings (jorrit) + * bug #36172 [Debug] fix for PHP 7.3.16+/7.4.4+ (nicolas-grekas) + * bug #36151 [Security] Fixed hardcoded value of SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE (lyrixx) + * bug #36141 Prevent warning in proc_open() (BenMorel) + * bug #36143 [FrameworkBundle] Fix Router Cache (guillbdx) + * bug #36103 [DI] fix preloading script generation (nicolas-grekas) + * bug #36118 [Security/Http] don't require the session to be started when tracking its id (nicolas-grekas) + * bug #36108 [DI] Fix CheckTypeDeclarationPass (guillbdx) + * bug #36121 [VarDumper] fix side-effect by not using mt_rand() (nicolas-grekas) + * bug #36073 [PropertyAccess][DX] Improved errors when reading uninitialized properties (HeahDude) + * bug #36063 [FrameworkBundle] start session on flashbag injection (William Arslett) + * bug #36031 [Console] Fallback to default answers when unable to read input (ostrolucky) + * bug #36083 [DI][Form] Fixed test suite (TimeType changes & unresolved merge conflict) (wouterj) + * bug #36026 [Mime] Fix boundary header (guillbdx) + * bug #36020 [Form] ignore microseconds submitted by Edge (xabbuh) + * bug #36038 [HttpClient] disable debug log with curl 7.64.0 (nicolas-grekas) + * bug #36041 fix import from config file using type: glob (Tobion) + * bug #35987 [DoctrineBridge][DoctrineExtractor] Fix wrong guessed type for "json" type (fancyweb) + * bug #35949 [DI] Fix container lint command when a synthetic service is used in an expression (HypeMC) + * bug #36023 [HttpClient] fix requests to hosts that idn_to_ascii() cannot handle (nicolas-grekas) + * bug #35938 [Form] Handle false as empty value on expanded choices (fancyweb) + * bug #36030 [SecurityBundle] Minor fix in LDAP config tree builder (HeahDude) + * bug #36017 [HttpKernel] Fix support for single-colon syntax for controllers (nicolas-grekas) + * bug #35993 Remove int return type from FlattenException::getCode (wucdbm) + * bug #36004 [Yaml] fix dumping strings containing CRs (xabbuh) + * bug #35982 [DI] Fix XmlFileLoader bad error message (przemyslaw-bogusz) + * bug #35957 [DI] ignore extra tags added by autoconfiguration in PriorityTaggedServiceTrait (nicolas-grekas) + * bug #35937 Revert "bug symfony#28179 [DomCrawler] Skip disabled fields processing in Form" (dmaicher) + * bug #35928 [Routing] Prevent localized routes _locale default & requirement from being overridden (fancyweb) + * bug #35912 [FrameworkBundle] register only existing transport factories (xabbuh) + * bug #35899 [DomCrawler] prevent deprecation being triggered from assertion (xabbuh) + * bug #35910 [SecurityBundle] Minor fixes in configuration tree builder (HeahDude) + +* 5.0.5 (2020-02-29) + + * bug #35781 [Form] NumberToLocalizedStringTransformer return int if scale = 0 (VincentLanglet) + * bug #35846 [Serializer] prevent method calls on null values (xabbuh) + * bug #35897 [FrameworkBundle] add missing Messenger options to XML schema definition (xabbuh) + * bug #35870 [ErrorHandler] fix parsing static return type on interface method annotation (alekitto) + * bug #35839 [Security] Allow switching to another user when already switched (chalasr) + * bug #35851 [DoctrineBridge] Use new Types::* constants and support new json types (fancyweb) + * bug #35841 [Notifier] Dispatch message event in null transport (jschaedl) + * bug #35716 [PhpUnitBridge] Fix compatibility to PHPUnit 9 (Benjamin) + * bug #35803 [Cache] Fix versioned namespace atomic clears (trvrnrth) + * bug #35817 [DoctrineBridge] Use new Types::* constants and support new json type (fancyweb) + * bug #35832 [Debug][ErrorHandler] improved deprecation notices for methods new args and return type (HeahDude) + * bug #35827 [BrowserKit] Nested file array prevents uploading file (afilina) + * bug #35826 [Notifier] Add correct tags for NullTransportFactory (jschaedl) + * bug #35830 [FrameworkBundle] Skip notifiers tags in UnusedTagsPass (chalasr) + * bug #35707 [ExpressionLanguage] Fixed collisions of character operators with object properties (Andrej-in-ua) + * bug #35794 [DoctrineBridge][DoctrineExtractor] Fix indexBy with custom and some core types (fancyweb) + * bug #35787 [PhpUnitBridge] Use trait instead of extending deprecated class (marcello-moenkemeyer) + * bug #35792 [Security] Prevent TypeError in case RememberMetoken has no attached user (nikophil) + * bug #35735 [Routing] Add locale requirement for localized routes (mtarld) + * bug #35772 [Config] don't throw on missing excluded paths (nicolas-grekas) + * bug #35774 [Ldap] force default network timeout (nicolas-grekas) + * bug #35702 [VarDumper] fixed DateCaster not displaying additional fields (Makdessi Alex) + * bug #35722 [HttpKernel] Set previous exception when rethrown from controller resolver (danut007ro) + * bug #35714 [HttpClient] Correctly remove trace level options for HttpCache (aschempp) + * bug #35718 [HttpKernel] fix registering DebugHandlersListener regardless of the PHP_SAPI (nicolas-grekas) + * bug #35728 Add missing autoload calls (greg0ire) + * bug #35693 [Finder] Fix unix root dir issue (chr-hertel) + * bug #35709 [HttpFoundation] fix not sending Content-Type header for 204 responses (Tobion) + * bug #35710 [ErrorHandler] silence warning when zend.assertions=-1 (nicolas-grekas) + * bug #35676 [Console] Handle zero row count in appendRow() for Table (Adam Prickett) + * bug #35696 [Console] Don't load same-namespace alternatives on exact match (chalasr) + * bug #35674 [HttpClient] fix getting response content after its destructor throwed an HttpExceptionInterface (nicolas-grekas) + * bug #35672 [HttpClient] fix HttpClientDataCollector when handling canceled responses (thematchless) + * bug #35641 [Process] throw when PhpProcess::fromShellCommandLine() is used (Guikingone) + * bug #35645 [ErrorHandler] Never throw on warnings triggered by assert() and set assert.exception=1 in Debug::enable() (nicolas-grekas) + * bug #35633 [Mailer] Do not ping the SMTP server before sending every message (micheh) + * bug #33897 [Console] Consider STDIN interactive (ostrolucky) + * bug #35605 [HttpFoundation][FrameworkBundle] fix support for samesite in session cookies (fabpot) + * bug #35609 [DoctrineBridge] Fixed submitting ids with query limit or offset (HeahDude) + * bug #35616 [Workflow] Make method signature compatible with 4.4 (pbowyer) + * bug #35597 [PHPunit bridge] Provide current file as file path (greg0ire) + * bug #33960 [DI] Unknown env prefix not recognized as such (ro0NL) + * bug #35342 [DI] Fix support for multiple tags for locators and iterators (Alexandre Parent) + * bug #33820 [PhpUnitBridge] Fix some errors when using serialized deprecations (l-vo) + * bug #35553 Fix HTTP client config handling (julienfalque) + * bug #35588 [ErrorHandler] Escape variable in Exception template (jderusse) + * bug #35583 Add missing use statements (fabpot) + * bug #35582 Missing use statement 4.4 (fabpot) + * bug #34123 [Form] Fix handling of empty_data's \Closure value in Date/Time form types (yceruto) + * bug #35537 [Config][XmlReferenceDumper] Prevent potential \TypeError (fancyweb) + * bug #35227 [Mailer] Fix broken mandrill http send for recipients with names (vilius-g) + * bug #35430 [Translation] prefer intl domain when adding messages to catalogue (Guite) + * bug #35497 Fail on empty password verification (without warning on any implementation) (Stefan Kruppa) + * bug #35546 [Validator] check for __get method existence if property is uninitialized (alekitto) + * bug #35332 [Yaml][Inline] Fail properly on empty object tag and empty const tag (fancyweb) + * bug #35489 [PhpUnitBridge] Fix running skipped tests expecting only deprecations (chalasr) + * bug #35161 [FrameworkBundle] Check non-null type for numeric type (Arman-Hosseini) + * bug #34059 [DomCrawler] Skip disabled fields processing in Form (sbogx) + * bug #34114 [Console] SymonfyStyle - Check value isset to avoid PHP notice (leevigraham) + * bug #35557 [Config] dont catch instances of Error (nicolas-grekas) + * bug #35562 [HttpClient] fix HttpClientDataCollector when handling canceled responses (nicolas-grekas) + +* 5.0.4 (2020-01-31) + + * bug #35530 [HttpClient] Fix regex bearer (noniagriconomie) + * bug #35532 [Validator] fix access to uninitialized property when getting value (greedyivan) + * bug #35486 [Translator] Default value for 'sort' option in translation:update should be 'asc' (versgui) + * bug #35305 [HttpKernel] Fix stale-if-error behavior, add tests (mpdude) + * bug #34808 [PhpUnitBridge] Properly handle phpunit arguments for configuration file (biozshock) + * bug #35517 [Intl] Provide more locale translations (ro0NL) + * bug #35518 [Mailer] Fix STARTTLS support for Postmark and Mandrill (fabpot) + * bug #35480 [Messenger] Check for all serialization exceptions during message dec… (Patrick Berenschot) + * bug #35502 [Messenger] Fix bug when using single route with XML config (Nyholm) + * bug #35438 [SecurityBundle] fix ldap_bind service arguments (Ioni14) + * bug #35429 [DI] CheckTypeDeclarationsPass now checks if value is type of parameter type (pfazzi) + * bug #35464 [ErrorHandler] Add debug argument to decide whether debug page is shown or not (yceruto) + * bug #35423 Fixes a runtime error when accessing the cache panel (DamienHarper) + * bug #35428 [Cache] fix checking for igbinary availability (nicolas-grekas) + * bug #35424 [HttpKernel] Check if lock can be released (sjadema) + +* 5.0.3 (2020-01-21) + + * bug #35364 [Yaml] Throw on unquoted exclamation mark (fancyweb) + * bug #35065 [Security] Use supportsClass in addition to UnsupportedUserException (linaori) + * bug #35351 Revert #34797 "Fixed translations file dumper behavior" and fix #34713 (yceruto) + * bug #35356 [Filesystem] chown and chgrp should also accept int as owner and group (Slamdunk) + * bug #35335 [Security] Fix RememberMe with null password (jderusse) + * bug #35339 [String] add missing encoding when calling mb_ord() (nicolas-grekas) + * bug #35355 [DI] Fix EnvVar not loaded when Loader requires an env var (jderusse) + * bug #35343 [Security] Fix RememberMe with null password (jderusse) + * bug #34223 [DI] Suggest typed argument when binding fails with untyped argument (gudfar) + * bug #35323 [FrameworkBundle] Set booted flag to false when test kernel is unset (thiagocordeiro) + * bug #35324 [HttpClient] Fix strict parsing of response status codes (Armando-Walmeric) + * bug #35318 [Yaml] fix PHP const mapping keys using the inline notation (xabbuh) + * bug #35306 [FrameworkBundle] Make sure one can use fragments.hinclude_default_template (Nyholm) + * bug #35304 [HttpKernel] Fix that no-cache MUST revalidate with the origin (mpdude) + * bug #35299 Avoid `stale-if-error` in FrameworkBundle's HttpCache if kernel.debug = true (mpdude) + * bug #35240 [SecurityBundle] Fix collecting traceable listeners info on lazy firewalls (chalasr) + * bug #35151 [DI] deferred exceptions in ResolveParameterPlaceHoldersPass (Islam93) + * bug #35290 [Filesystem][FilesystemCommonTrait] Use a dedicated directory when there are no namespace (fancyweb) + * bug #35099 [FrameworkBundle] Do not throw exception on value generate key (jderusse) + * bug #35278 [EventDispatcher] expand listener in place (xabbuh) + * bug #35269 [HttpKernel][FileLocator] Fix deprecation message (fancyweb) + * bug #35254 [PHPUnit-Bridge] Fail-fast in simple-phpunit if one of the passthru() commands fails (mpdude) + * bug #35261 [Routing] Fix using a custom matcher & generator dumper class (fancyweb) + * bug #34643 [Dotenv] Fixed infinite loop with missing quote followed by quoted value (naitsirch) + * bug #35239 [Security\Http] Prevent canceled remember-me cookie from being accepted (chalasr) + * bug #35267 [Debug] fix ClassNotFoundFatalErrorHandler (nicolas-grekas) + * bug #35252 [Serializer] Fix cache in MetadataAwareNameConverter (bastnic) + * bug #35200 [TwigBridge] do not render preferred choices as selected (xabbuh) + * bug #35243 [HttpKernel] release lock explicitly (nicolas-grekas) + * bug #35193 [TwigBridge] button_widget now has its title attr translated even if its label = null or false (stephen-lewis) + * bug #35219 [PhpUnitBridge] When using phpenv + phpenv-composer plugin, composer executable is wrapped into a bash script (oleg-andreyev) + * bug #35150 [Messenger] Added check if json_encode succeeded (toooni) + * bug #35137 [Messenger] Added check if json_encode succeeded (toooni) + * bug #35170 [FrameworkBundle][TranslationUpdateCommand] Do not output positive feedback on stderr (fancyweb) + * bug #35245 [HttpClient] fix exception in case of PSR17 discovery failure (nicolas-grekas) + * bug #35244 [Cache] fix processing chain adapter based cache pool (xabbuh) + * bug #35247 [FrameworkBundle][ContainerLintCommand] Only skip .errored. services (fancyweb) + * bug #35225 [DependencyInjection] Handle ServiceClosureArgument for callable in container linting (shieldo) + * bug #35223 [HttpClient] Don't read from the network faster than the CPU can deal with (nicolas-grekas) + * bug #35214 [DI] DecoratorServicePass should keep container.service_locator on the decorated definition (malarzm) + * bug #35209 [HttpClient] fix support for non-blocking resource streams (nicolas-grekas) + * bug #35210 [HttpClient] NativeHttpClient should not send >1.1 protocol version (nicolas-grekas) + * bug #35162 [Mailer] Make sure you can pass custom headers to Mailgun (Nyholm) + * bug #33672 [Mailer] Remove line breaks in email attachment content (Stuart Fyfe) + * bug #35101 [Routing] Fix i18n routing when the url contains the locale (fancyweb) + * bug #35124 [TwigBridge][Form] Added missing help messages in form themes (cmen) + * bug #35195 [HttpClient] fix casting responses to PHP streams (nicolas-grekas) + * bug #35168 [HttpClient] fix capturing SSL certificates with NativeHttpClient (nicolas-grekas) + * bug #35134 [PropertyInfo] Fix BC issue in phpDoc Reflection library (jaapio) + * bug #35184 [Mailer] Payload sent to Sendgrid doesn't include names (versgui) + * bug #35173 [Mailer][MailchimpBridge] Fix missing attachments when sending via Mandrill API (vilius-g) + * bug #35172 [Mailer][MailchimpBridge] Fix incorrect sender address when sender has name (vilius-g) + * bug #35125 [Translator] fix performance issue in MessageCatalogue and catalogue operations (ArtemBrovko) + * bug #35120 [HttpClient] fix scheduling pending NativeResponse (nicolas-grekas) + * bug #35117 [Cache] do not overwrite variable value (xabbuh) + * bug #35113 [VarDumper] Fix "Undefined index: argv" when using CliContextProvider (xepozz) + * bug #34673 Migrate server:log command away from WebServerBundle (jderusse) + * bug #35103 [Translation] Use `locale_parse` for computing fallback locales (alanpoulain) + * bug #35060 [Security] Fix missing defaults for auto-migrating encoders (chalasr) + * bug #35067 [DependencyInjection][CheckTypeDeclarationsPass] Handle \Closure for callable (fancyweb) + * bug #35094 [Console] Fix filtering out identical alternatives when there is a command loader (fancyweb) + +* 5.0.2 (2019-12-19) + + * bug #35051 [DependencyInjection] Fix binding tagged services to containers (nicolas-grekas) + * bug #35039 [DI] skip looking for config class when the extension class is anonymous (nicolas-grekas) + * bug #35049 [ProxyManager] fix generating proxies for root-namespaced classes (nicolas-grekas) + * bug #35022 [Dotenv] FIX missing getenv (mccullagh) + * bug #35023 [HttpKernel] ignore failures generated by opcache.restrict_api (nicolas-grekas) + * bug #35024 [HttpFoundation] fix pdo session handler for sqlsrv (azjezz) + * bug #35025 [HttpClient][Psr18Client] Remove Psr18ExceptionTrait (fancyweb) + * bug #35028 [TwigBridge] Fix invalid typehint for subject in is_granted Twig function (emodric) + * bug #35015 [Config] fix perf of glob discovery when GLOB_BRACE is not available (nicolas-grekas) + * bug #35014 [HttpClient] make pushed responses retry-able (nicolas-grekas) + * bug #35010 [VarDumper] ignore failing __debugInfo() (nicolas-grekas) + * bug #34998 [DI] fix auto-binding service providers to their service subscribers (nicolas-grekas) + * bug #34954 [Mailer] Fixed undefined index when sending via Mandrill API (wulff) + * bug #33670 [DI] Service locators can't be decorated (malarzm) + * bug #35000 [Console][SymfonyQuestionHelper] Handle multibytes question choices keys and custom prompt (fancyweb) + * bug #35005 [HttpClient] force HTTP/1.1 when NTLM auth is used (nicolas-grekas) + * bug #34707 [Validation][FrameworkBundle] Allow EnableAutoMapping to work without auto-mapping namespaces (ogizanagi) + * bug #34996 Fix displaying anonymous classes on PHP 7.4 (nicolas-grekas) + * bug #29839 [Validator] fix comparisons with null values at property paths (xabbuh) + * bug #34900 [DoctrineBridge] Fixed submitting invalid ids when using queries with limit (HeahDude) + * bug #34791 [Serializer] Skip uninitialized (PHP 7.4) properties in PropertyNormalizer and ObjectNormalizer (vudaltsov) + * bug #34956 [Messenger][AMQP] Use delivery_mode=2 by default (lyrixx) + * bug #34915 [FrameworkBundle] Fix invalid Windows path normalization in TemplateNameParser (mvorisek) + * bug #34981 stop using deprecated Doctrine persistence classes (xabbuh) + * bug #34904 [Validator][ConstraintValidator] Safe fail on invalid timezones (fancyweb) + * bug #34935 [FrameworkBundle][DependencyInjection] Skip removed ids in the lint container command and its associated pass (fancyweb) + * bug #34957 [Security] Revert "AbstractAuthenticationListener.php error instead info" (larzuk91) + * bug #34922 [FrameworkBundle][Secrets] Hook configured local dotenv file (fancyweb) + * bug #34967 [HttpFoundation] fix redis multi host dsn not recognized (Jan Christoph Beyer) + * bug #34963 [Lock] fix constructor argument type declaration (xabbuh) + * bug #34955 Require doctrine/persistence ^1.3 (nicolas-grekas) + * bug #34923 [DI] Fix support for immutable setters in CallTrait (Lctrs) + * bug #34878 [TwigBundle] fix broken FilesystemLoader::exists() with Twig 3 (dpesch) + * bug #34921 [HttpFoundation] Removed "Content-Type" from the preferred format guessing mechanism (yceruto) + * bug #34886 [HttpKernel] fix triggering deprecation in file locator (xabbuh) + * bug #34918 [Translation] fix memoryleak in PhpFileLoader (nicolas-grekas) + * bug #34920 [Routing] fix memoryleak when loading compiled routes (nicolas-grekas) + * bug #34787 [Cache] Propagate expiry when syncing items in ChainAdapter (trvrnrth) + * bug #34694 [Validator] Fix auto-mapping constraints should not be validated (ogizanagi) + * bug #34848 [Process] change the syntax of portable command lines (nicolas-grekas) + * bug #34862 [FrameworkBundle][ContainerLintCommand] Reinitialize bundles when the container is reprepared (fancyweb) + * bug #34896 [Cache] fix memory leak when using PhpFilesAdapter (nicolas-grekas) + * bug #34438 [HttpFoundation] Use `Cache-Control: must-revalidate` only if explicit lifetime has been given (mpdude) + * bug #34449 [Yaml] Implement multiline string as scalar block for tagged values (natepage) + * bug #34601 [MonologBridge] Fix debug processor datetime type (mRoca) + * bug #34842 [ExpressionLanguage] Process division by zero (tigr1991) + * bug #34902 [PropertyAccess] forward caught exception (xabbuh) + * bug #34903 Fixing bad order of operations with null coalescing operator (weaverryan) + * bug #34888 [TwigBundle] add tags before processing them (xabbuh) + * bug #34760 [Mailer] Fix SMTP Authentication when using STARTTLS (DjLeChuck) + * bug #34762 [Config] never try loading failed classes twice with ClassExistenceResource (nicolas-grekas) + * bug #34783 [DependencyInjection] Handle env var placeholders in CheckTypeDeclarationsPass (fancyweb) + * bug #34839 [Cache] fix memory leak when using PhpArrayAdapter (nicolas-grekas) + * bug #34801 [String] implement __sleep()/__wakeup() on strings (nicolas-grekas) + * bug #34782 [String] inline Latin-ASCII rules (nicolas-grekas) + * bug #34812 [Yaml] fix parsing negative octal numbers (xabbuh) + * bug #34854 [Messenger] gracefully handle missing event dispatchers (xabbuh) + * bug #34802 [Security] Check UserInterface::getPassword is not null before calling needsRehash (dbrekelmans) + * bug #34788 [SecurityBundle] Properly escape regex in AddSessionDomainConstraintPass (fancyweb) + * bug #34859 [SecurityBundle] Fix TokenStorage::reset not called in stateless firewall (jderusse) + * bug #34827 [HttpFoundation] get currently session.gc_maxlifetime if ttl doesnt exists (rafaeltovar) + * bug #34755 [FrameworkBundle] resolve service locators in `debug:*` commands (nicolas-grekas) + * bug #34832 [Validator] Allow underscore character "_" in URL username and password (romainneutron) + * bug #34765 [DoctrineBridge] Removed QueryBuilder type hint in getLoader() (HeahDude) + * bug #34811 [TwigBridge] Update bootstrap_4_layout.html.twig missing switch-custom label (sabruss) + * bug #34820 [FrameworkBundle][SodiumVault] Create secrets directory only when it is used (fancyweb) + * bug #34776 [DI] fix resolving bindings for named TypedReference (nicolas-grekas) + * bug #34794 [DependencyInjection] Resolve expressions in CheckTypeDeclarationsPass (fancyweb) + * bug #34795 [Routing][ObjectLoader] Remove forgotten deprecation after merge (fancyweb) + * bug #34797 [Translation] Fix FileDumper behavior (yceruto) + * bug #34738 [SecurityBundle] Passwords are not encoded when algorithm set to "true" (nieuwenhuisen) + * bug #34759 [SecurityBundle] Fix switch_user provider configuration handling (fancyweb) + * bug #34779 [Security] do not validate passwords when the hash is null (xabbuh) + * bug #34786 [SecurityBundle] Use config variable in AnonymousFactory (martijnboers) + * bug #34784 [FrameworkBundle] Set the parameter bag as resolved in ContainerLintCommand (fancyweb) + * bug #34763 [Security/Core] Fix checking for SHA256/SHA512 passwords (David Brooks) + * bug #34757 [DI] Fix making the container path-independent when the app is in /app (nicolas-grekas) + +* 5.0.1 (2019-12-01) + + * bug #34732 [DependencyInjection][Xml] Fix the attribute 'tag' is not allowed in 'bind' tag (tienvx) + * bug #34729 [DI] auto-register singly implemented interfaces by default (nicolas-grekas) + * bug #34728 [DI] fix overriding existing services with aliases for singly-implemented interfaces (nicolas-grekas) + * bug #34649 more robust initialization from request (dbu) + * bug #34715 [TwigBundle] remove service when base class is missing (xabbuh) + * bug #34600 [DoctrineBridge] do not depend on the QueryBuilder from the ORM (xabbuh) + * bug #34627 [Security/Http] call auth listeners/guards eagerly when they "support" the request (nicolas-grekas) + * bug #34671 [Security] Fix clearing remember-me cookie after deauthentication (chalasr) + * bug #34711 Fix the translation commands when a template contains a syntax error (fabpot) + * bug #34032 [Mime] Fixing multidimensional array structure with FormDataPart (jvahldick) + * bug #34697 [MonologBridge] Fix compatibility of ServerLogHandler with Monolog 2 (jderusse) + * bug #34560 [Config][ReflectionClassResource] Handle parameters with undefined constant as their default values (fancyweb) + * bug #34695 [Config] don't break on virtual stack frames in ClassExistenceResource (nicolas-grekas) + * bug #34716 [DependencyInjection] fix dumping number-like string parameters (xabbuh) + * bug #34558 [Console] Fix autocomplete multibyte input support (fancyweb) + * bug #34130 [Console] Fix commands description with numeric namespaces (fancyweb) + * bug #34562 [DI] Skip unknown method calls for factories in check types pass (fancyweb) + * bug #34677 [EventDispatcher] Better error reporting when arguments to dispatch() are swapped (rimas-kudelis) + * bug #33573 [TwigBridge] Add row_attr to all form themes (fancyweb) + * bug #34019 [Serializer] CsvEncoder::NO_HEADERS_KEY ignored when used in constructor (Dario Savella) + * bug #34083 [Form] Keep preferred_choices order for choice groups (vilius-g) + * bug #34091 [Debug] work around failing chdir() on Darwin (mary2501) + * bug #34305 [PhpUnitBridge] Read configuration CLI directive (ro0NL) + * bug #34490 [Serializer] Fix MetadataAwareNameConverter usage with string group (antograssiot) + * bug #34632 [Console] Fix trying to access array offset on value of type int (Tavafi) + * bug #34669 [HttpClient] turn exception into log when the request has no content-type (nicolas-grekas) + * bug #34662 [HttpKernel] Support typehint to deprecated FlattenException in controller (andrew-demb) + * bug #34619 Restores preview mode support for Html and Serializer error renderers (yceruto) + * bug #34636 [VarDumper] notice on potential undefined index (sylvainmetayer) + * bug #34668 [Cache] Make sure we get the correct number of values from redis::mget() (thePanz) + * bug #34621 [Routing] Continue supporting single colon in object route loaders (fancyweb) + * bug #34554 [HttpClient] Fix early cleanup of pushed HTTP/2 responses (lyrixx) + * bug #34607 [HttpKernel] Ability to define multiple kernel.reset tags (rmikalkenas) + * bug #34599 [Mailer][Mailchimp Bridge] Throwing undefined index _id when setting message id (monteiro) + * bug #34569 [Workflow] Apply the same logic of precedence between the apply() and the buildTransitionBlockerList() method (lyrixx) + * bug #34580 [HttpKernel] Don't cache "not-fresh" state (nicolas-grekas) + * bug #34577 [FrameworkBundle][Cache] Don't deep-merge cache pools configuration (alxndrbauer) + * bug #34515 [DependencyInjection] definitions are valid objects (xabbuh) + * bug #34536 [SecurityBundle] Don't require a user provider for the anonymous listener (chalasr) + * bug #34533 [Monolog Bridge] Fixed accessing static property as non static. (Sander-Toonen) + * bug #34502 [FrameworkBundle][ContainerLint] Keep "removing" compiler passes (fancyweb) + * bug #34552 [Dotenv] don't fail when referenced env var does not exist (xabbuh) + * bug #34546 [Serializer] Add DateTimeZoneNormalizer into Dependency Injection (jewome62) + * bug #34547 [Messenger] Error when specified default bus is not among the configured (vudaltsov) + * bug #34513 [Validator] remove return type declaration from __sleep() (xabbuh) + * bug #34551 [Security] SwitchUser is broken when the User Provider always returns a valid user (tucksaun) + * bug #34570 [FrameworkBundle][Notifier] Fixing notifier email definition without mailer (chr-hertel) + * bug #34385 Avoid empty "If-Modified-Since" header in validation request (mpdude) + * bug #34458 [Validator] ConstraintValidatorTestCase: add missing return value to mocked validate method calls (ogizanagi) + * bug #34516 [HttpKernel] drop return type declaration (xabbuh) + * bug #34474 [Messenger] Ignore stamps in in-memory transport (tienvx) + +* 5.0.0 (2019-11-21) + + * bug #34464 [Form] group constraints when calling the validator (nicolas-grekas) + * bug #34451 [DependencyInjection] Fix dumping multiple deprecated aliases (shyim) + * bug #34448 [Form] allow button names to start with uppercase letter (xabbuh) + * bug #34434 [Routing] Fix ContainerLoader and ObjectLoaderTest (fancyweb) + * bug #34428 [Security] Fix best encoder not wired using migrate_from (chalasr) + +* 5.0.0-RC1 (2019-11-17) + + * bug #34419 [Cache] Disable igbinary on PHP >= 7.4 (nicolas-grekas) + * bug #34347 [Messenger] Perform no deep merging of bus middleware (vudaltsov) + * bug #34366 [HttpFoundation] Allow redirecting to URLs that contain a semicolon (JayBizzle) + * feature #34405 [HttpFoundation] Added possibility to configure expiration time in redis session handler (mantulo) + * bug #34397 [FrameworkBundle] Remove project dir from Translator cache vary scanned directories (fancyweb) + * bug #34384 [DoctrineBridge] Improve queries parameters display in Profiler (fancyweb) + * bug #34408 [Cache] catch exceptions when using PDO directly (xabbuh) + * bug #34411 [HttpKernel] Flatten "exception" controller argument if not typed (chalasr) + * bug #34410 [HttpFoundation] Fix MySQL column type definition. (jbroutier) + * bug #34403 [Cache] Redis Tag Aware warn on wrong eviction policy (andrerom) + * bug #34400 [HttpKernel] collect bundle classes, not paths (nicolas-grekas) + * bug #34398 [Config] fix id-generation for GlobResource (nicolas-grekas) + * bug #34404 [HttpClient] fix HttpClientDataCollector (nicolas-grekas) + * bug #34396 [Finder] Allow ssh2 stream wrapper for sftp (damienalexandre) + * bug #34383 [DI] Use reproducible entropy to generate env placeholders (nicolas-grekas) + * bug #34389 [WebProfilerBundle] add FrameworkBundle requirement (xabbuh) + * bug #34381 [WebProfilerBundle] Require symfony/twig-bundle (fancyweb) + * bug #34358 [Security] always check the token on non-lazy firewalls (nicolas-grekas, lyrixx) + * bug #34390 [FrameworkBundle] fix wiring of httplug client (nicolas-grekas) + * bug #34369 [FrameworkBundle] Disallow WebProfilerBundle < 4.4 (derrabus) + * bug #34370 [DI] fix detecting singly implemented interfaces (nicolas-grekas) + +* 5.0.0-BETA2 (2019-11-13) + + * bug #34344 [Console] Constant STDOUT might be undefined (nicolas-grekas) + * bug #34348 [Serializer] Fix ProblemNormalizer signature mismatch (chalasr) + * security #cve-2019-18886 [Security\Core] throw AccessDeniedException when switch user fails (nicolas-grekas) + * security #cve-2019-18888 [Mime] fix guessing mime-types of files with leading dash (nicolas-grekas) + * security #cve-2019-11325 [VarExporter] fix exporting some strings (nicolas-grekas) + * security #cve-2019-18889 [Cache] forbid serializing AbstractAdapter and TagAwareAdapter instances (nicolas-grekas) + * security #cve-2019-18888 [HttpFoundation] fix guessing mime-types of files with leading dash (nicolas-grekas) + * security #cve-2019-18887 [HttpKernel] Use constant time comparison in UriSigner (stof) + +* 5.0.0-BETA1 (2019-11-12) + + * feature #34333 Revert "feature #34329 [ExpressionLanguage] add XOR operator (ottaviano)" (nicolas-grekas) + * feature #34332 Allow \Throwable $previous everywhere (fancyweb) + * feature #34329 [ExpressionLanguage] add XOR operator (ottaviano) + * feature #34312 [ErrorHandler] merge and remove the ErrorRenderer component (nicolas-grekas, yceruto) + * feature #34309 [HttpKernel] make ExceptionEvent able to propagate any throwable (nicolas-grekas) + * feature #33497 [Contracts] Add parameter type declarations to contracts (derrabus) + * feature #34139 [Security] Add migrating encoder configuration (chalasr) + * feature #32194 [HttpFoundation] Add a way to anonymize IPs (Seldaek) + * feature #34252 [Console] Add support for NO_COLOR env var (Seldaek) + * feature #34295 [DI][FrameworkBundle] add EnvVarLoaderInterface - remove SecretEnvVarProcessor (nicolas-grekas) + * feature #31310 [DependencyInjection] Added option `ignore_errors: not_found` for imported config files (pulzarraider) + * feature #34216 [HttpClient] allow arbitrary JSON values in requests (pschultz) + * feature #31977 Add handling for delayed message to redis transport (alexander-schranz) + * feature #34217 [Messenger] use events consistently in worker (Tobion) + * feature #33065 Deprecate things that prevent \Throwable from bubbling down (fancyweb) + * feature #34184 [VarDumper] display the method we're in when dumping stack traces (nicolas-grekas) + * feature #33732 [Console] Rename some methods related to redraw frequency (javiereguiluz) + * feature #31587 [Routing][Config] Allow patterns of resources to be excluded from config loading (tristanbes) + * feature #32256 [DI] Add compiler pass and command to check that services wiring matches type declarations (alcalyn, GuilhemN, nicolas-grekas) + * feature #32061 Add new Form WeekType (dFayet) + * feature #33954 Form theme: support Bootstrap 4 custom switches (romaricdrigon) + * feature #33854 [DI] Add ability to choose behavior of decorations on non existent decorated services (mtarld) + * feature #34185 [Messenger] extract worker logic to listener and get rid of SendersLocatorInterface::getSenderByAlias (Tobion) + * feature #34156 Adding DoctrineClearEntityManagerWorkerSubscriber to reset EM in worker (weaverryan) + * feature #34133 [Cache] add DeflateMarshaller - remove phpredis compression (nicolas-grekas) + * feature #34177 [HttpFoundation][FrameworkBundle] allow configuring the session handler with a DSN (nicolas-grekas) + * feature #32107 [Validator] Add AutoMapping constraint to enable or disable auto-validation (dunglas) + * feature #34170 Re-allow to use "tagged" in service definitions (dunglas) + * feature #34043 [Lock] Add missing lock connection string in FrameworkExtension (jderusse) + * feature #34057 [Lock][Cache] Allows URL DSN in PDO adapters (jderusse) + * feature #34151 [DomCrawler] normalizeWhitespace should be true by default (dunglas) + * feature #34020 [Security] Allow to stick to a specific password hashing algorithm (chalasr) + * feature #34141 Slack notifier actions (fabpot) + * feature #34131 [FrameworkBundle] Remove suffix convention when using env vars to override secrets from the vault (nicolas-grekas) + * feature #34051 [HttpClient] allow option "buffer" to be a stream resource (nicolas-grekas) + * feature #34028 [ExpressionLanguage][Lexer] Exponential format for number (tigr1991) + * feature #34069 [Messenger] Removing "sync" transport and replacing it with config trick (weaverryan) + * feature #34014 [DI] made the `env(base64:...)` processor able to decode base64url (nicolas-grekas) + * feature #34044 [HttpClient] Add a canceled state to the ResponseInterface (Toflar) + * feature #33997 [FrameworkBundle] Add `secrets:*` commands and `env(secret:...)` processor to deal with secrets seamlessly (Tobion, jderusse, nicolas-grekas) + * feature #34013 [DI] add `LazyString` for lazy computation of string values injected into services (nicolas-grekas) + * feature #33961 [TwigBridge] Add show-deprecations option to the lint:twig command (yceruto) + * feature #33973 [HttpClient] add HttpClient::createForBaseUri() (nicolas-grekas) + * feature #33980 [HttpClient] try using php-http/discovery when nyholm/psr7 is not installed (nicolas-grekas) + * feature #33967 [Mailer] Add Message-Id to SentMessage when sending an email (fabpot) + * feature #33896 [Serializer][CSV] Add context options to handle BOM (malarzm) + * feature #33883 [Mailer] added ReplyTo option for PostmarkApiTransport (pierregaste) + * feature #33053 [ErrorHandler] Rework fatal errors (fancyweb) + * feature #33939 [Cache] add TagAwareMarshaller to optimize data storage when using AbstractTagAwareAdapter (nicolas-grekas) + * feature #33941 Keeping backward compatibility with legacy FlattenException usage (yceruto) + * feature #33851 [EventDispatcher] Allow to omit the event name when registering listeners (derrabus) + * feature #33461 [Cache] Improve RedisTagAwareAdapter invalidation logic & requirements (andrerom) + * feature #33779 [DI] enable improved syntax for defining method calls in Yaml (nicolas-grekas) + * feature #33743 [HttpClient] Async HTTPlug client (Nyholm) + * feature #33856 [Messenger] Allow to configure the db index on Redis transport (chalasr) + * feature #33881 [VarDumper] Added a support for casting Ramsey/Uuid (lyrixx) + * feature #33687 Notifier Component (fabpot) + * feature #33861 [CssSelector] Support *:only-of-type (jakzal) + * feature #33793 [EventDispatcher] A compiler pass for aliased userland events (derrabus) + * feature #33791 [Form] Added CountryType option for using alpha3 country codes (creiner) + * feature #33628 [DependencyInjection] added Ability to define a priority method for tagged service (lyrixx) + * feature #33768 [String] Introduce a locale-aware Slugger in the String component (tgalopin) + * feature #33775 [Console] Add deprecation message for non-int statusCode (jschaedl) + * feature #33783 [WebProfilerBundle] Try to display the most useful panel by default (fancyweb) + * feature #33701 [HttpKernel] wrap compilation of the container in an opportunistic lock (nicolas-grekas) + * feature #33789 [Serializer] Deprecate the XmlEncoder::TYPE_CASE_ATTRIBUTES constant (pierredup) + * feature #31446 [VarDumper] Output the location of calls to dump() (ktherage) + * feature #33412 [Console] Do not leak hidden console commands (m-vo) + * feature #33676 [Security] add "anonymous: lazy" mode to firewalls (nicolas-grekas) + * feature #32440 [DomCrawler] add a normalizeWhitespace argument to text() method (Simperfit) + * feature #33148 [Intl] Excludes locale from language codes (split localized language names) (ro0NL) + * feature #31202 [FrameworkBundle] WebTestCase KernelBrowser::getContainer null return type (Simperfit) + * feature #33038 [ErrorHandler] Forward \Throwable (fancyweb) + * feature #33574 [Http][DI] Replace REMOTE_ADDR in trusted proxies with the current REMOTE_ADDR (mcfedr) + * feature #33553 [String] a new component for object-oriented strings management with an abstract unit system (nicolas-grekas, hhamon, gharlan) + * feature #33113 [Messenger][DX] Display real handler if handler is wrapped (DavidBadura) + * feature #33128 [FrameworkBundle] Sort tagged services (krome162504) + * feature #33658 [Yaml] fix parsing inline YAML spanning multiple lines (xabbuh) + * feature #33698 [HttpKernel] compress files generated by the profiler (nicolas-grekas) + * feature #33317 [Messenger] Added support for `from_transport` attribute on `messenger.message_handler` tag (ruudk) + * feature #33584 [Security] Deprecate isGranted()/decide() on more than one attribute (wouterj) + * feature #33663 [Security] Make stateful firewalls turn responses private only when needed (nicolas-grekas) + * feature #33609 [Form][SubmitType] Add "validate" option (fancyweb) + * feature #33621 Revert "feature #33507 [WebProfiler] Deprecated intercept_redirects in 4.4 (dorumd)" (lyrixx) + * feature #33635 [FrameworkBundle] Cleanup (yceruto) + * feature #33605 [Twig] Add NotificationEmail (fabpot) + * feature #33623 [DependencyInjection] Allow binding iterable and tagged services (lyrixx) + * feature #33507 [WebProfiler] Deprecated intercept_redirects in 4.4 (dorumd) + * feature #33579 Adding .gitattributes to remove Tests directory from "dist" (Nyholm) + * feature #33562 [Mailer] rename SmtpEnvelope to Envelope (xabbuh) + * feature #33565 [Mailer] Rename an exception class (fabpot) + * feature #33516 [Cache] Added reserved characters constant for CacheItem (andyexeter) + * feature #33503 [SecurityBundle] Move Anonymous DI integration to new AnonymousFactory (wouterj) + * feature #33535 [WebProfilerBundle] Assign automatic colors to custom Stopwatch categories (javiereguiluz) + * feature #32565 [HttpClient] Allow enabling buffering conditionally with a Closure (rjwebdev) + * feature #32032 [DI] generate preload.php file for PHP 7.4 in cache folder (nicolas-grekas) + * feature #33117 [FrameworkBundle] Added --sort option for TranslationUpdateCommand (k0d3r1s) + * feature #32832 [Serializer] Allow multi-dimenstion object array in AbstractObjectNormalizer (alediator) + * feature #33189 New welcome page on startup for 4.4 LTS & 5.0 (yceruto) + * feature #33295 [OptionsResolver] Display full nested option hierarchy in exceptions (fancyweb) + * feature #33486 [VarDumper] Display fully qualified title (pavinthan, nicolas-grekas) + * feature #33496 Deprecated not passing dash symbol (-) to STDIN commands (yceruto) + * feature #32742 [Console] Added support for definition list and horizontal table (lyrixx) + * feature #33494 [Mailer] Change DSN syntax (fabpot) + * feature #33471 [Mailer] Check email validity before opening an SMTP connection (fabpot) + * feature #31177 #21571 Comparing roles to detected that users has changed (oleg-andreyev) + * feature #33459 [Validator] Deprecated CacheInterface in favor of PSR-6 (derrabus) + * feature #33271 Added new ErrorController + Preview and enabling there the error renderer mechanism (yceruto) + * feature #33454 [Mailer] Improve an exception when trying to send a RawMessage without an Envelope (fabpot) + * feature #33327 [ErrorHandler] Registering basic exception handler for late failures (yceruto) + * feature #33446 [TwigBridge] lint all templates from configured Twig paths if no argument was provided (yceruto) + * feature #33409 [Mailer] Add support for multiple mailers (fabpot) + * feature #33424 [Mailer] Change the DSN semantics (fabpot) + * feature #33352 [Security] drop support for non-boolean return values from checkCredentials() (xabbuh) + * feature #33319 Allow configuring class names through methods instead of class parameters in Doctrine extensions (alcaeus) + * feature #33283 [ErrorHandler] make DebugClassLoader able to add return type declarations (nicolas-grekas) + * feature #33323 [TwigBridge] Throw an exception when one uses email as a context variable in a TemplatedEmail (fabpot) + * feature #33308 [SecurityGuard] Deprecate returning non-boolean values from checkCredentials() (derrabus) + * feature #33217 [FrameworkBundle][DX] Improving the redirect config when using RedirectController (yceruto) + * feature #33015 [HttpClient] Added TraceableHttpClient and WebProfiler panel (jeremyFreeAgent) + * feature #33091 [Mime] Add Address::fromString (gisostallenberg) + * feature #33144 [DomCrawler] Added Crawler::matches(), ::closest(), ::outerHtml() (lyrixx) + * feature #33152 Mark all dispatched event classes as final (Tobion) + * feature #33258 [HttpKernel] deprecate global dir to load resources from (Tobion) + * feature #33272 [Translation] deprecate support for null locales (xabbuh) + * feature #33269 [TwigBridge] Mark all classes extending twig as @final (fabpot) + * feature #33270 [Mime] Remove NamedAddress (fabpot) + * feature #33169 [HttpFoundation] Precalculate session expiry timestamp (azjezz) + * feature #33237 [Mailer] Remove the auth mode DSN option and support in the eSMTP transport (fabpot) + * feature #33233 [Mailer] Simplify the way TLS/SSL/STARTTLS work (fabpot) + * feature #32360 [Monolog] Added ElasticsearchLogstashHandler (lyrixx) + * feature #32489 [Messenger] Allow exchange type headers binding (CedrickOka) + * feature #32783 [Messenger] InMemoryTransport handle acknowledged and rejected messages (tienvx) + * feature #33098 added `Process::getLastOutputTime()` method (connorhu) + * feature #33155 [ErrorHandler] Added call() method utility to turns any PHP error into \ErrorException (yceruto) + * feature #33203 [Mailer] Add support for the queued flag in the EmailCount assertion (fabpot) + * feature #30323 [ErrorHandler] trigger deprecation in DebugClassLoader when child class misses a return type (fancyweb, nicolas-grekas) + * feature #33137 [DI] deprecate support for non-object services (nicolas-grekas) + * feature #32845 [HttpKernel][FrameworkBundle] Add alternative convention for bundle directories (yceruto) + * feature #32548 [Translation] XliffLintCommand: allow .xliff file extension (codegain) + * feature #28363 [Serializer] Encode empty objects as objects, not arrays (mcfedr) + * feature #33122 [WebLink] implement PSR-13 directly (nicolas-grekas) + * feature #33078 Add compatibility trait for PHPUnit constraint classes (alcaeus) + * feature #32988 [Intl] Support ISO 3166-1 Alpha-3 country codes (terjebraten-certua) + * feature #32598 [FrameworkBundle][Routing] Private service route loaders (fancyweb) + * feature #32486 [DoctrineBridge] Invokable event listeners (fancyweb) + * feature #31083 [Validator] Allow objects implementing __toString() to be used as violation messages (mdlutz24) + * feature #32122 [HttpFoundation] deprecate HeaderBag::get() returning an array and add all($key) instead (Simperfit) + * feature #32807 [HttpClient] add "max_duration" option (fancyweb) + * feature #31546 [Dotenv] Use default value when referenced variable is not set (j92) + * feature #32930 [Mailer][Mime] Add PHPUnit constraints and assertions for the Mailer (fabpot) + * feature #32912 [Mailer] Add support for the profiler (fabpot) + * feature #32940 [PhpUnitBridge] Add polyfill for PhpUnit namespace (jderusse) + * feature #31843 [Security] add support for opportunistic password migrations (nicolas-grekas) + * feature #32824 [Ldap] Add security LdapUser and provider (chalasr) + * feature #32922 [PhpUnitBridge] make the bridge act as a polyfill for newest PHPUnit features (nicolas-grekas) + * feature #32927 [Mailer] Add message events logger (fabpot) + * feature #32916 [Mailer] Add a name to the transports (fabpot) + * feature #32917 [Mime] Add AbstractPart::asDebugString() (fabpot) + * feature #32543 [FrameworkBundle] add config translator cache_dir (Raulnet) + * feature #32669 [Yaml] Add flag to dump NULL as ~ (OskarStark) + * feature #32896 [Mailer] added debug info to TransportExceptionInterface (fabpot) + * feature #32817 [DoctrineBridge] Deprecate RegistryInterface (Koc) + * feature #32504 [ErrorRenderer] Add DebugCommand for easy debugging and testing (yceruto) + * feature #32581 [DI] Allow dumping the container in one file instead of many files (nicolas-grekas) + * feature #32762 [Form][DX] derive default timezone from reference_date option when possible (yceruto) + * feature #32745 [Messenger][Profiler] Attempt to give more useful source info when using HandleTrait (ogizanagi) + * feature #32680 [Messenger][Profiler] Collect the stamps at the end of dispatch (ogizanagi) + * feature #32683 [VarDumper] added support for Imagine/Image (lyrixx) + * feature #32749 [Mailer] Make transport factory test case public (Koc) + * feature #32718 [Form] use a reference date to handle times during DST (xabbuh) + * feature #32637 [ErrorHandler] Decouple from ErrorRenderer component (yceruto) + * feature #32609 [Mailer][DX][RFC] Rename mailer bridge transport classes (Koc) + * feature #32587 [Form][Validator] Generate accept attribute with file constraint and mime types option (Coosos) + * feature #32658 [Form] repeat preferred choices in list of all choices (Seb33300, xabbuh) + * feature #32698 [WebProfilerBundle] mark all classes as internal (Tobion) + * feature #32695 [WebProfilerBundle] Decoupling TwigBundle and using the new ErrorRenderer mechanism (yceruto) + * feature #31398 [TwigBundle] Deprecating error templates for non-html formats and using ErrorRenderer as fallback (yceruto) + * feature #32582 [Routing] Deprecate ServiceRouterLoader and ObjectRouteLoader in favor of ContainerLoader and ObjectLoader (fancyweb) + * feature #32661 [ErrorRenderer] Improving the exception page provided by HtmlErrorRenderer (yceruto) + * feature #32332 [DI] Move non removing compiler passes to after removing passes (alexpott) + * feature #32475 [Process] Deprecate Process::inheritEnvironmentVariables() (ogizanagi) + * feature #32583 [Mailer] Logger vs debug mailer (fabpot) + * feature #32471 Add a new ErrorHandler component (mirror of the Debug component) (yceruto) + * feature #32463 [VarDumper] Allow to configure VarDumperTestTrait casters & flags (ogizanagi) + * feature #31946 [Mailer] Extract transport factory and allow create custom transports (Koc) + * feature #31194 [PropertyAccess] Improve errors when trying to find a writable property (pierredup) + * feature #32435 [Validator] Add a new constraint message when there is both min and max (Lctrs) + * feature #32470 Rename ErrorCatcher to ErrorRenderer (rendering part only) (yceruto) + * feature #32462 [WebProfilerBundle] Deprecating templateExists method (yceruto) + * feature #32458 Remove support for Twig 1.x (fabpot) + * feature #32446 [Lock] rename and deprecate Factory into LockFactory (Simperfit) + * feature #31975 Dynamic bundle assets (garak) + * feature #32429 [VarDumper] Let browsers trigger their own search on double CMD/CTRL + F (ogizanagi) + * feature #32198 [Lock] Split "StoreInterface" into multiple interfaces with less responsibility (Simperfit) + * feature #31511 [Validator] Allow to use property paths to get limits in range constraint (Lctrs) + * feature #32424 [Console] don't redraw progress bar more than every 100ms by default (nicolas-grekas) + * feature #27905 [MonologBridge] Monolog 2 compatibility (derrabus) + * feature #32418 [Console] Added Application::reset() (lyrixx) + * feature #31217 [WebserverBundle] Deprecate the bundle in favor of symfony local server (Simperfit) + * feature #31554 [SECURITY] AbstractAuthenticationListener.php error instead info. Rebase of #28462 (berezuev) + * feature #32284 [Cache] Add argument $prefix to AdapterInterface::clear() (nicolas-grekas) + * feature #32423 [ServerBundle] Display all logs by default (lyrixx) + * feature #26339 [Console] Add ProgressBar::preventRedrawFasterThan() and forceRedrawSlowerThan() methods (ostrolucky) + * feature #31269 [Translator] Dump native plural formats to po files (Stadly) + * feature #31560 [Ldap][Security] LdapBindAuthenticationProvider does not bind before search query (Simperfit) + * feature #31626 [Console] allow answer to be trimmed by adding a flag (Simperfit) + * feature #31876 [WebProfilerBundle] Add clear button to ajax tab (Matts) + * feature #32415 [Translation] deprecate passing a null locale (Simperfit) + * feature #32290 [HttpClient] Add $response->toStream() to cast responses to regular PHP streams (nicolas-grekas) + * feature #32402 [Intl] Exclude root language (ro0NL) + * feature #32295 [FrameworkBundle] Add autowiring alias for PSR-14 (nicolas-grekas) + * feature #32390 [DependencyInjection] Deprecated passing Parameter instances as class name to Definition (derrabus) + * feature #32106 [FrameworkBundle] Use default_locale as default value for translator.fallbacks (dunglas) + * feature #32294 [FrameworkBundle] Allow creating chained cache pools by providing several adapters (nicolas-grekas) + * feature #32373 [Validator] Change Length::$allowEmptyString default to false & make it optional (ogizanagi) + * feature #32207 [FrameworkBundle] Allow to use the BrowserKit assertions with Panther and API Platform's test client (dunglas) + * feature #32344 [HttpFoundation][HttpKernel] Improving the request/response format autodetection (yceruto) + * feature #32231 [HttpClient] Add support for NTLM authentication (nicolas-grekas) + * feature #32265 [Validator] deprecate non-string constraint violation codes (xabbuh) + * feature #31528 [Validator] Add a Length::$allowEmptyString option to reject empty strings (ogizanagi) + * feature #32081 [WIP][Mailer] Overwrite envelope sender and recipients from config (Devristo) + * feature #32255 [HttpFoundation] Drop support for ApacheRequest (lyrixx) + * feature #31825 [Messenger] Added support for auto trimming of redis streams (Toflar) + * feature #32277 Remove @experimental annotations (fabpot) + * feature #30981 [Mime] S/MIME Support (sstok) + * feature #32180 [Lock] add an InvalidTTLException to be more accurate (Simperfit) + * feature #32241 [PropertyAccess] Deprecate null as allowed value for defaultLifetime argument in createCache method (jschaedl) + * feature #32221 [ErrorCatcher] Make IDEs and static analysis tools happy (fabpot) + * feature #32227 Rename the ErrorHandler component to ErrorCatcher (fabpot) + * feature #31065 Add ErrorHandler component (yceruto) + * feature #32126 [Process] Allow writing portable "prepared" command lines (Simperfit) + * feature #31996 Add return types in final classes (dFayet) + * feature #31532 [Ldap] Add users extraFields in ldap component (Simperfit) + * feature #32104 Add autowiring for HTTPlug (nicolas-grekas) + * feature #32130 [Form] deprecate int/float for string input in NumberType (xabbuh) + * feature #31547 [Ldap] Add exception for mapping ldap errors (Simperfit) + * feature #31764 [FrameworkBundle] add attribute stamps (walidboughdiri) + * feature #32059 [PhpUnitBridge] Bump PHPUnit 7+8 (ro0NL) + * feature #32041 [Validator] Deprecate unused arg in ExpressionValidator (ogizanagi) + * feature #31287 [Config] Introduce find method in ArrayNodeDefinition to ease configuration tree manipulation (jschaedl) + * feature #31959 [DomCrawler][Feature][DX] Add Form::getName() method (JustBlackBird) + * feature #32026 [VarDumper] caster for HttpClient's response dumps all info (nicolas-grekas) + * feature #31976 [HttpClient] add HttplugClient for compat with libs that need httplug v1 or v2 (nicolas-grekas) + * feature #31956 [Mailer] Changed EventDispatcherInterface dependency from Component to Contracts (Koc) + * feature #31980 [HttpClient] make Psr18Client implement relevant PSR-17 factories (nicolas-grekas) + * feature #31919 [WebProfilerBundle] Select default theme based on user preferences (javiereguiluz) + * feature #31451 [FrameworkBundle] Allow dots in translation domains (jschaedl) + * feature #31321 [DI] deprecates tag !tagged in favor of !tagged_iterator (jschaedl) + * feature #31658 [HTTP Foundation] Deprecate passing argument to method Request::isMethodSafe() (dFayet) + * feature #31597 [Security] add MigratingPasswordEncoder (nicolas-grekas) + * feature #31351 [Validator] Improve TypeValidator to handle array of types (jschaedl) + * feature #31526 [Validator] Add compared value path to violation parameters (ogizanagi) + * feature #31514 Add exception as HTML comment to beginning and end of `exception_full.html.twig` (ruudk) + * feature #31739 [FrameworkBundle] Add missing BC layer for deprecated ControllerNameParser injections (chalasr) + * feature #31831 [HttpClient] add $response->cancel() (nicolas-grekas) + * feature #31334 [Messenger] Add clear Entity Manager middleware (Koc) + * feature #31800 Removed support for PHP templating everywhere (yceruto) + * feature #31594 [Security] add PasswordEncoderInterface::needsRehash() (nicolas-grekas) + * feature #31821 [FrameworkBundle][TwigBundle] Add missing deprecations for PHP templating layer (yceruto) + * feature #31509 [Monolog] Setup the LoggerProcessor after all other processor (lyrixx) + * feature #31777 [Form] remove deprecated date types options handling (xabbuh) + * feature #31785 [Messenger] Deprecate passing a bus locator to ConsumeMessagesCommand's constructor (chalasr) + * feature #31700 [MonologBridge] RouteProcessor class is now final to ease the the removal of deprecated event (Simperfit) + * feature #31732 [HttpKernel] Make DebugHandlersListener internal (chalasr) + * feature #31539 [HttpKernel] Add lts config (noniagriconomie) + * feature #31437 [Cache] Add Redis Sentinel support (StephenClouse) + * feature #31543 [DI] deprecate short callables in yaml (nicolas-grekas) + diff --git a/CHANGELOG-5.1.md b/CHANGELOG-5.1.md new file mode 100644 index 0000000000000..bda51d0eaa507 --- /dev/null +++ b/CHANGELOG-5.1.md @@ -0,0 +1,726 @@ +CHANGELOG for 5.1.x +=================== + +This changelog references the relevant changes (bug and security fixes) done +in 5.1 minor versions. + +To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash +To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v5.1.0...v5.1.1 + +* 5.1.10 (2020-12-18) + + * bug #39545 [Notifier] [Mattermost] Host is required (OskarStark) + * bug #39538 [Notifier] Fix parsing Dsn with empty user/password (OskarStark) + * bug #39531 [Mailer] Fix parsing Dsn with empty user/password (OskarStark) + * bug #39518 [Ldap] Incorrect determination of RelativeDistinguishedName for the "move" operation (astepin) + * bug #39510 [Notifier]  [Free Mobile] Could not use custom host in DSN (OskarStark) + * bug #39514 [Notifier] Fix wrong package names (OskarStark) + * bug #39494 Add missing symfony/deprecation-contracts requirement (jderusse) + * bug #39476 [Lock] Prevent store exception break combined store (dzubchik) + * bug #39456 [Notifier] [Free Mobile] Fix wrong scheme in mapping (OskarStark) + * bug #39299 [PropertyInfo][Serializer] Fixed extracting ignored properties for Serializer (javer) + * bug #39433 [Cache] fix setting "read_timeout" when using Redis (nicolas-grekas) + * bug #39420 [Cache] Prevent notice on case matching metadata trick (bastnic) + * bug #39203 [DI] Fix not working if only "default_index_method" used (malteschlueter) + * bug #39409 [Notifier] [Twilio] Add tests (OskarStark) + * bug #39142 [Config] Stop treating multiline resources as globs (michaelKaefer) + * bug #39341 [Form] Fixed StringUtil::trim() to trim ZERO WIDTH SPACE (U+200B) and SOFT HYPHEN (U+00AD) (pmishev) + * bug #39334 [Config][TwigBundle] Fixed syntax error in config (Nyholm) + * bug #39196 [DI] Fix Xdebug 3.0 detection (vertexvaar) + * bug #39226 [PhpUnitBridge] Fix disabling DeprecationErrorHandler from PHPUnit configuration file (fancyweb) + * bug #39361 [FrameworkBundle] acces public-deprecated services via the private container to remove false-positive deprecations (nicolas-grekas) + * bug #39357 [FrameworkBundle] fix preserving some special chars in the query string (nicolas-grekas) + * bug #39271 [HttpFoundation] Fix TypeError: Argument 1 passed to JsonResponse::setJson() must be of the type string, object given (sidz) + * bug #39251 [DependencyInjection] Fix container linter for union types (derrabus) + * bug #39336 [Config] YamlReferenceDumper: No default value required for VariableNode with array example (Nyholm) + * bug #39333 [Form] do not apply the Valid constraint on scalar form data (lchrusciel, xabbuh) + * bug #39331 [PhpUnitBridge] Fixed PHPunit 9.5 compatibility (wouterj) + * bug #39220 [HttpKernel] Fix bug with whitespace in Kernel::stripComments() (ausi) + * bug #39252 [Mime] Leverage PHP 8's detection of CSV files (derrabus) + * bug #39313 [FrameworkBundle] TextDescriptor::formatControllerLink checked method… (fjogeleit) + * bug #39286 [HttpClient] throw clearer error when no scheme is provided (BackEndTea) + * bug #39267 [Yaml] fix lexing backslashes in single quoted strings (xabbuh) + * bug #39151 [DependencyInjection] Fixed incorrect report for private services if required service does not exist (Islam93) + * bug #39274 [Yaml] fix lexing mapping values with trailing whitespaces (xabbuh) + * bug #39244 [String] Fix Notice when argument is empty string (moldman) + * bug #39270 [Inflector] Fix Notice when argument is empty string (moldman) + * bug #39247 [Security] remove return type definition in order to avoid type juggling (adeptofvoltron) + * bug #39223 [Console] Re-enable hyperlinks in Konsole/Yakuake (OndraM) + * bug #39241 [Yaml] fix lexing inline sequences/mappings with trailing whitespaces (Nyholm, xabbuh) + * bug #39243 [Filesystem] File existence check before calling unlink method (gechetspr) + +* 5.1.9 (2020-11-29) + + * bug #39166 [Messenger] Fix mssql compatibility for doctrine transport. (bill moll) + * bug #39211 [HttpClient] fix binding to network interfaces (nicolas-grekas) + * bug #39129 [DependencyInjection] Fix circular in DI with lazy + byContruct loop (jderusse) + * bug #39068 [DependencyInjection][Translator] Silent deprecation triggered by libxml_disable_entity_loader (jderusse) + * bug #39119 [Form] prevent duplicated error message for file upload limits (xabbuh) + * bug #39099 [Form] ignore the pattern attribute for textareas (xabbuh) + * bug #39154 [Yaml] fix lexing strings containing escaped quotation characters (xabbuh) + * bug #39180 [Serializer] Fix denormalizing scalar with UnwrappingDenormalizer (camilledejoye) + * bug #38597 [PhpUnitBridge] Fix qualification of deprecations triggered by the debug class loader (fancyweb) + * bug #39160 [Console] Use a partial buffer in SymfonyStyle (jderusse) + * bug #39168 [Console] Fix console closing tag (jderusse) + * bug #39155 [VarDumper] fix casting resources turned into objects on PHP 8 (nicolas-grekas) + * bug #39131 [Cache] Fix CI because of Couchbase version (jderusse) + * bug #39115 [HttpClient] don't fallback to HTTP/1.1 when HTTP/2 streams break (nicolas-grekas) + * bug #33763 [Yaml] fix lexing nested sequences/mappings (xabbuh) + * bug #39083 [Dotenv] Check if method inheritEnvironmentVariables exists (Chi-teck) + * bug #39094 [Ldap] Fix undefined variable $con (derrabus) + * bug #39091 [Config] Recheck glob brace support after GlobResource was serialized (wouterj) + * bug #39092 Fix critical extension when reseting paged control (jderusse) + * bug #38614 [HttpFoundation] Fix for virtualhosts based on URL path (mvorisek) + * bug #39072 [FrameworkBundle] [Notifier] fix firebase transport factory DI tag type (xabbuh) + * bug #38387 [Validator] prevent hash collisions caused by reused object hashes (fancyweb, xabbuh) + * bug #38999 [DependencyInjection] autoconfigure behavior describing tags on decorators (xabbuh) + * bug #39058 [DependencyInjection] Fix circular detection with multiple paths (jderusse) + * bug #39059 [Filesystem] fix cleaning up tmp files when dumpFile() fails (nicolas-grekas) + * bug #38628 [DoctrineBridge] indexBy could reference to association columns (juanmiguelbesada) + * bug #39021 [DependencyInjection] Optimize circular collection by removing flattening (jderusse) + * bug #39031 [Ldap] Fix pagination (jderusse) + * bug #39038 [DoctrineBridge] also reset id readers (xabbuh) + * bug #39026 [Messenger] Fix DBAL deprecations in PostgreSqlConnection (chalasr) + * bug #39025 [DoctrineBridge] Fix DBAL deprecations in middlewares (derrabus) + * bug #38991 [Console] Fix ANSI when stdErr is not a tty (jderusse) + * bug #38980 [DependencyInjection] Fix circular reference with Factory + Lazy Iterrator (jderusse) + * bug #38977 [HttpClient] Check status code before decoding content in TraceableResponse (chalasr) + * bug #38971 [PhpUnitBridge] fix replaying skipped tests (nicolas-grekas) + * bug #38910 [HttpKernel] Fix session initialized several times (jderusse) + * bug #38882 [DependencyInjection] Improve performances in CircualReference detection (jderusse) + * bug #38950 [Process] Dont test TTY if there is no TTY support (Nyholm) + * bug #38921 [PHPUnitBridge] Fixed crash on Windows with PHP 8 (villfa) + * bug #38869 [SecurityBundle] inject only compatible token storage implementations for usage tracking (xabbuh) + * bug #38894 [HttpKernel] Remove Symfony 3 compatibility code (derrabus) + * bug #38895 [PhpUnitBridge] Fix wrong check for exporter in ConstraintTrait (alcaeus) + * bug #38879 [Cache] Fixed expiry could be int in ChainAdapter due to race conditions (phamviet) + * bug #38867 [FrameworkBundle] Fixing TranslationUpdateCommand failure when using "--no-backup" (liarco) + * bug #38856 [Cache] Add missing use statement (fabpot) + +* 5.1.8 (2020-10-28) + + * bug #38713 [DI] Fix Preloader exception when preloading a class with an unknown parent/interface (rgeraads) + * bug #38647 [HttpClient] relax auth bearer format requirements (xabbuh) + * bug #38699 [DependencyInjection] Preload classes with union types correctly (derrabus) + * bug #38669 [Serializer] fix decoding float XML attributes starting with 0 (Marcin Kruk) + * bug #38680 [PhpUnitBridge] Support new expect methods in test case polyfill (alcaeus) + * bug #38681 [PHPUnitBridge] Support PHPUnit 8 and PHPUnit 9 in constraint compatibility trait (alcaeus) + * bug #38686 [TwigBridge] Remove "transchoice" from the code base (nicolas-grekas) + * bug #38678 [String] fix before/after[Last]() returning the empty string instead of the original one on non-match (nicolas-grekas) + * bug #38679 [PhpUnitBridge] Add missing exporter function for PHPUnit 7 (alcaeus) + * bug #38659 [String] fix slicing in UnicodeString (nicolas-grekas) + * bug #38595 [TwigBridge] do not translate null placeholders or titles (xabbuh) + * bug #38635 [Cache] Use correct expiry in ChainAdapter (Nyholm) + * bug #38652 [Filesystem] Check if failed unlink was caused by permission denied (Nyholm) + * bug #38645 [PropertyAccess] forward the caught exception (xabbuh) + * bug #38612 [Messenger/Amqp] Allow setting option "login" in DSN (W0rma) + * bug #38618 [Messenger][Doctrine] Avoid early db access for pgsql detection (chalasr) + * bug #38604 [DoctrineBridge] indexBy does not refer to attributes, but to column names (xabbuh) + * bug #38606 [WebProfilerBundle] Hide debug toolbar in print view (jt2k) + * bug #38582 [DI] Fix Reflection file name with eval()\'d code (maxime-aknin) + * bug #38578 Add missing use statement (jderusse) + * bug #38516 [HttpFoundation] Fix Range Requests (BattleRattle) + * bug #38553 [Lock] Reset Key lifetime time before we acquire it (Nyholm) + * bug #38551 Remove content-type check on toArray methods (jderusse) + * bug #38546 [String] fix "is too large" ValueError on PHP 8 (nicolas-grekas) + * bug #38544 [DI] fix dumping env vars (nicolas-grekas) + * bug #38533 [TwigBridge] Fix preload hint and remove "unlinked class class@anonymous" warning (burned42) + * bug #38530 [HttpClient] fix reading the body after a ClientException (nicolas-grekas) + * bug #38510 [PropertyInfo] Support for the mixed type (derrabus) + * bug #38493 [HttpClient] Fix CurlHttpClient memory leak (HypeMC) + * bug #38456 [Cache] skip igbinary < 3.1.6 (nicolas-grekas) + * bug #38392 [Ldap] Bypass the use of `ldap_control_paged_result` on PHP >= 7.3 (lucasaba) + * bug #38444 [PhpUnitBridge] fix running parallel tests with phpunit 9 (nicolas-grekas) + * bug #38446 [PropertyInfo] Extract from default value doesn't set collection boolean (Korbeil) + * bug #38442 [VarDumper] fix truncating big arrays (nicolas-grekas) + * bug #38433 [Mime] Fix serialization of RawMessage (gilbertsoft) + +* 5.1.7 (2020-10-04) + + * bug #38396 Handle consecutive supports() calls in the RememberMeAuthenticator (wouterj) + * bug #36291 [Lock] Fix StoreFactory to accept same DSN syntax as AbstractAdapter (Jontsa) + * bug #38390 [Serializer][Minor] Fix circular reference exception message (bad limit displayed) (l-vo) + * bug #38388 [HttpClient] Always "buffer" empty responses (nicolas-grekas) + * bug #38384 [PhpUnitBridge] Fix Deprecation file when it comes from the TestsListener (fancyweb) + * bug #38380 [Form] propagate validation groups to subforms (johanderuijter, xabbuh) + * bug #38377 Ignore more deprecations for Mockery mocks (fancyweb) + * bug #38375 [HttpClient] fix using proxies with NativeHttpClient (nicolas-grekas) + * bug #38372 [Routing] fix using !important and defaults/reqs in inline route definitions (nicolas-grekas) + * bug #38373 [ErrorHandler][DebugClassLoader] Do not check Mockery mocks classes (fancyweb) + * bug #38368 [HttpClient] Fix using https with proxies (bohanyang) + * bug #38350 [TwigBundle] Only remove kernel exception listener if twig is used (dmolineus) + * bug #38360 [BrowserKit] Cookie expiration at current timestamp (iquito) + * bug #38357 [DI] fix dumping non-shared lazy services (nicolas-grekas) + * bug #38358 [Messenger] Fix redis connection error message (alexander-schranz) + * bug #38343 Revert "bug #38063 [FrameworkBundle] generate preload.php in src/ to make opcache.preload predictable" (nicolas-grekas) + * bug #38348 [FrameworkBundle] Add Mailjet definition (michaelKaefer) + * bug #38336 [PhpUnitBridge] Fixed class_alias() for PHPUnit\Framework\Error\Error (stevegrunwell) + +* 5.1.6 (2020-09-27) + + * bug #38291 [OptionsResolver] Fix deprecation message access (fancyweb) + * bug #38248 [HttpClient] Allow bearer token with colon (stephanvierkant) + * bug #37837 [Form] Fix custom formats deprecation with HTML5 widgets (fancyweb) + * bug #38285 [Contracts][Translation] Optional Intl dependency (ro0NL) + * bug #38283 [Translator] Optional Intl dependency (ro0NL) + * bug #38271 [ErrorHandler] Escape JSON encoded log context (ro0NL) + * bug #38284 [Cache][Lock][Messenger] fix compatibility with Doctrine DBAL 3 (xabbuh) + * bug #38228 [Yaml Parser] Fix edge cases when parsing multiple documents (digilist) + * bug #38226 [FrameworkBundle] loadRoutes shoud receive RoutingPhpFileLoader (grachevko) + * bug #38229 [Yaml] fix parsing comments not prefixed by a space (xabbuh) + * bug #38127 [Translator] Make sure a null locale is handled properly (jschaedl) + * bug #38221 [Cache] Allow cache tags to be objects implementing __toString() (lstrojny) + * bug #38212 [HttpKernel] Do not override max_redirects option in HttpClientKernel (dmolineus) + * bug #38215 [HttpClient] Support for CURLOPT_LOCALPORT (derrabus) + * bug #38202 [FrameworkBundle] Fix xsd definition which prevent to add more than one workflow metadata (l-vo) + * bug #38195 [String] improve slugger's portability accross implementations of iconv() (nicolas-grekas) + * bug #38166 [Console] work around disabled putenv() (SenTisso) + * bug #38190 [Notifier] Fix errors parsing in FirebaseTransport (jderusse) + * bug #38173 [HttpClient][HttpClientTrait] don't calculate alternatives if option is auth_ntlm (ybenhssaien) + * bug #38169 [PhpUnitBridge] Internal classes are not legacy (derrabus) + * feature #38160 [Security] In the new authenticator system, no auth listener is valid (weaverryan) + * bug #38156 [Cache] fix ProxyAdapter not persisting items with infinite expiration (dmaicher) + * bug #38148 [HttpClient] fail properly when the server replies with HTTP/0.9 (nicolas-grekas) + * bug #38131 [Validator] allow consumers to mock all methods (xabbuh) + * bug #38140 [DI] dump OS-indepent paths in the preload file (nicolas-grekas) + * bug #38139 [DI] dump OS-indepent paths in the compiled container (nicolas-grekas) + * bug #38147 [Mailer] Fixed Mailgun API bridge JsonException when API response is not applicaton/json (asprega) + * bug #38126 [Cache] Limit cache version character range (lstrojny) + * bug #38136 [Messenger] Run postgres setup trigger in transaction (akondas) + * bug #38142 [FrameworkBundle] adopt src/.preload.php (nicolas-grekas) + * bug #38108 [Cache] Fix key encoding issue in Memcached adapter (lstrojny) + * bug #38122 [HttpClient] Fix Array to string conversion notice when parsing JSON error body with non-scalar detail property (emarref) + * bug #37097 DateTime validator support for trailing data (stefankleff) + * bug #38116 [Console] Silence warnings on sapi_windows_cp_set() call (chalasr) + * bug #38114 [Console] guard $argv + $token against null, preventing unnecessary exceptions (bilogic) + * bug #38094 [PhpUnitBridge] Skip internal classes in CoverageListenerTrait (sanmai) + * bug #38101 [VarExporter] unserialize() might throw an Exception on php 8 (derrabus) + * bug #38100 [ErrorHandler] Parse "x not found" errors correctly on php 8 (derrabus) + * bug #38099 Prevent parsing invalid octal digits as octal numbers (julienfalque) + * bug #38095 [Mailer] Remove unnecessary check for existing request (jschaedl) + * bug #38091 [DI] fix ContainerBuilder on PHP8 (nicolas-grekas) + * bug #38086 [HttpClient] with "bindto" with NativeHttpClient (nicolas-grekas) + * bug #38063 [FrameworkBundle] generate preload.php in src/ to make opcache.preload predictable (nicolas-grekas) + * bug #38080 [Console] Make sure $maxAttempts is an int or null (derrabus) + * bug #38075 esmtp error not being thrown properly (Anton Zagorskii) + * bug #38040 [Yaml Parser] fixed Parser to skip comments when inlining sequences (korve) + * bug #38073 [VarDumper] Fix caster for invalid SplFileInfo objects on php 8 (derrabus) + * bug #38074 [Messenger] Remove DelaySeconds parameter for FIFO queues (netbull) + * bug #38071 [PhpUnitBridge] Adjust output parsing of CoverageListenerTrait for PHPUnit 9.3 (sanmai, derrabus) + * bug #38062 [DI] fix generating preload file when cache_dir is outside project_dir (nicolas-grekas) + * bug #38059 [Cache] Fix CacheCollectorPass with decorated cache pools (shyim) + * bug #38054 [PhpUnitBridge] CoverageListenerTrait update for PHPUnit 8.5/9.x (sanmai) + * bug #38049 [Debug] Parse "x not found" errors correctly on php 8 (derrabus) + * bug #38041 [PropertyInfo] Fix typed collections in PHP 7.4 (ndench) + * bug #38013 [PHPUnitBridge] Fix deprecation type detection when trigger_deprecation is used (l-vo) + * bug #37959 [PhpunitBridge] Fix deprecation type detection (when several autoload files are used) (l-vo) + * bug #38031 Allow Drupal to wrap the Symfony test listener (5.1 backport) (fabpot, alexpott) + +* 5.1.5 (2020-09-02) + + * security #cve-2020-15094 Remove headers with internal meaning from HttpClient responses (mpdude) + * bug #38024 [Console] Fix undefined index for inconsistent command name definition (chalasr) + * bug #38023 [DI] fix inlining of non-shared services (nicolas-grekas) + * bug #38022 Missed AbstractArgument (a-menshchikov) + * bug #38020 [PhpUnitBridge] swallow deprecations (xabbuh) + * bug #37961 [Mailer] Fixed 'verify_peer' option in mailer DSN being ignored (SnakePin) + * bug #38010 [Cache] Psr16Cache does not handle Proxy cache items (alex-dev) + * bug #37937 [Serializer] fixed fix encoding of cache keys with anonymous classes (michaelzangerle) + * bug #38002 [Validator] Fix PhpUnitBridge version constraint (derrabus) + * bug #38001 Fix symfony/amazon-mailer constraint (Michał Jusięga) + +* 5.1.4 (2020-08-31) + + * bug #37966 [HttpClient][MockHttpClient][DX] Throw when the response factory callable does not return a valid response (fancyweb) + * bug #37971 [PropertyInfo] Backport support for typed properties (PHP 7.4) (dunglas) + * bug #37970 [PhpUnitBridge] Polyfill new phpunit 9.1 assertions (phpfour) + * bug #37960 [PhpUnit] Add polyfill for assertMatchesRegularExpression() (dunglas) + * bug #37941 [TwigBridge] allow null for $message of filter method `trans` (Flinsch) + * bug #37622 [PropertyAccess] Fix accessing dynamic properties (andreyserdjuk) + * bug #37927 [HttpClient] fix chaining promises returned by HttplugClient (CthulhuDen) + * bug #37953 [DI] fix dumping lazy non-shared services (nicolas-grekas) + * bug #37949 [Yaml] fix more numeric cases changing in PHP 8 (xabbuh) + * bug #37943 [Security] Fixed RememberMeAuthenticator::autoLogin() logic in the authenticator (wouterj) + * bug #37921 [Yaml] account for is_numeric() behavior changes in PHP 8 (xabbuh) + * bug #37913 [Mailer] Support Return-Path in SesApiAsyncAwsTransport (cvmiert) + * bug #37912 [ExpressionLanguage] fix passing arguments to call_user_func_array() on PHP 8 (xabbuh) + * bug #37907 [Messenger] stop using the deprecated schema synchronizer API (xabbuh) + * bug #37899 [Mailer] Support reply-to in SesApiAsyncAwsTransport (cvmiert) + * bug #37900 [Mailer] Fixed mandrill api header structure (wulff) + * bug #37890 [Notifier] Fixed base_uri while call auth/time API (leblanc-simon) + * bug #37888 [Mailer] Reorder headers used to determine Sender (cvmiert) + * bug #37857 [PropertyInfo] Fix ReflectionExtractor + minor tweaks (ogizanagi) + * bug #37868 [Lock] MongoDbStore handle duplicate querystring keys in mongodb uri when stripping (kralos) + * bug #37872 [Sendgrid-Mailer] Fixed envelope recipients on sendgridApiTransport (arendjantetteroo) + * bug #37860 [Serializer][ClassDiscriminatorMapping] Fix getMappedObjectType() when a discriminator child extends another one (fancyweb) + * bug #37826 [Messenger] Fix BC layer for stamps moved into separate packages (ogizanagi) + * bug #37853 [Validator] ensure that the validator is a mock object for backwards-compatibility (xabbuh) + * bug #36340 [Serializer] Fix configuration of the cache key (dunglas) + * bug #36810 [Messenger] Do not stack retry stamp (jderusse) + * bug #37849 [FrameworkBundle] Add missing mailer transports in xsd (l-vo) + * bug #37218 [Lock] MongoDbStore skim non-standard options from uri (kralos) + * bug #37586 [ErrorHandler][DebugClassLoader] Add mixed and static return types support (fancyweb) + * bug #37845 [Serializer] Fix variadic support when using type hints (fabpot) + * bug #37841 [VarDumper] Backport handler lock when using VAR_DUMPER_FORMAT (ogizanagi) + * bug #37821 Postpone Range BC layer removal to 6.0. (l-vo) + * bug #37725 [Form] Fix Guess phpdoc return type (franmomu) + * bug #37771 Use PHPUnit 9.3 on php 8 (derrabus) + * bug #36140 [Validator] Add BC layer for notInRangeMessage when min and max are set (l-vo) + * bug #35843 [Validator] Add target guards for Composite nested constraints (ogizanagi) + * bug #37803 Fix for issue #37681 (Rav) + * bug #37744 [Yaml] Fix for #36624; Allow PHP constant as first key in block (jnye) + * bug #37767 [Form] fix mapping errors from unmapped forms (xabbuh) + * bug #37731 [Console] Table: support cells with newlines after a cell with colspan >= 2 (GMTA) + * bug #37791 Fix redis connect with empty password (alexander-schranz) + * bug #37790 Fix deprecated libxml_disable_entity_loader (fabpot) + * bug #37763 Fix deprecated libxml_disable_entity_loader (jderusse) + * bug #37774 [Console] Make sure we pass a numeric array of arguments to call_user_func_array() (derrabus) + * bug #37770 [String] We cannot have a "provides" function in test cases (derrabus) + * bug #37729 [FrameworkBundle] fail properly when the required service is not defined (xabbuh) + * bug #37701 [Serializer] Fix that it will never reach DOMNode (TNAJanssen) + * bug #37671 [Cache] fix saving no-expiry items with ArrayAdapter (philipp-kolesnikov) + * bug #37102 [WebProfilerBundle] Fix error with custom function and web profiler routing tab (JakeFr) + * bug #37560 [Finder] Fix GitIgnore parser when dealing with (sub)directories and take order of lines into account (Jeroeny) + * bug #37700 [VarDumper] Improve previous fix on light array coloration (l-vo) + * bug #37654 [Messenger] Fix invalid option sslmode in AmazonSqs bridge (jderusse) + * bug #37705 [Mailer] Added the missing reset tag to mailer.logger_message_listener (vudaltsov) + * bug #37697 [Messenger] reduce column length for MySQL 5.6 compatibility (xabbuh) + * bug #37690 HttpClient profiler error (noniagriconomie) + +* 5.1.3 (2020-07-24) + + * bug #37590 Allows RedisClusterProxy instance in Lock RedisStore (jderusse) + * bug #37583 [Mime] Fix EmailHeaderSame to make use of decoded value (evertharmeling) + * bug #37569 [Messenger] Allow same middleware to be used multiple times with different arguments (HypeMC) + * bug #37624 [Cache] Connect to RedisCluster with password auth (mforbak) + * bug #37635 [Cache] fix catching auth errors (nicolas-grekas) + * bug #37628 [Serializer] Support multiple levels of discriminator mapping (jeroennoten) + * bug #37629 [Messenger] fix ignored account & endpoint options amazon sqs connection (surikman) + * bug #37572 [FrameworkBundle] set default session.handler alias if handler_id is not provided (Youssef BENHSSAIEN) + * bug #37558 Removed @internal from Composite (vudaltsov) + * bug #37607 Fix checks for phpunit releases on Composer 2 (colinodell) + * bug #37611 [Mailer] Fix failover transport (fabpot) + * bug #37594 Use hexadecimal numerals instead of hexadecimals in strings to repres… (arekzb) + * bug #37576 [WebProfilerBundle] modified url generation to use absolute urls (smatyas) + * bug #36888 [Mailer] Fix mandrill raw http request setting from email/name (JohJohan) + * bug #37527 [Mailer] Fix reply-to functionality in the SendgridApiTransport (jt2k) + * bug #37581 [Mime] Fix compat with HTTP requests (fabpot) + * bug #37580 [Mime] Keep Sender full address when used by non-SMTP transports (fabpot) + * bug #37511 [DependencyInjection][Config] Use several placeholder unique prefixes for dynamic placeholder values (fancyweb) + * bug #37562 [Cache] Use the default expiry when saving (not when creating) items (philipp-kolesnikov) + * bug #37563 Fix DBAL deprecation (nicolas-grekas) + * bug #37521 [Form] Fix ChoiceType translation domain (VincentLanglet) + * bug #37550 [OptionsResolver] Fix force prepend normalizer (hason) + * bug #37520 [Form] silently ignore uninitialized properties when mapping data to forms (ph-fritsche) + * bug #37543 [PhpUnitBridge] consider traits imported in parent classes (xabbuh) + * bug #37515 [PhpUnitBridge] Fix expectDeprecation() in isolation (alexpott) + * bug #37526 [Cache][Config] ensure compatibility with PHP 8 stack traces (xabbuh) + * bug #37513 [PhpUnitBridge] ExcludeList usage for PHPUnit 9.4 (gennadigennadigennadi) + * bug #37514 [String] throw when Alpine is used and translit fails (nicolas-grekas) + * bug #37504 [Security\Http] Skip remember-me logout on empty token (chalasr) + * bug #37461 [Process] Fix Permission Denied error when writing sf_proc_00 lock files on Windows (JasonStephensTAMU) + * bug #37505 [Form] fix handling null as empty data (xabbuh) + * bug #37385 [Console] Fixes question input encoding on Windows (YaFou) + * bug #37499 [Form] Missing return in loadValuesForChoices method (yceruto) + * bug #37491 [HttpClient] Fix promise behavior in HttplugClient (brentybh) + * bug #37469 [Console] always use stty when possible to ask hidden questions (nicolas-grekas) + * bug #37486 [HttpClient] fix parsing response headers in CurlResponse (nicolas-grekas) + * bug #37484 [HttpClient][CurlHttpClient] Fix http_version option usage (fancyweb) + * bug #37447 [Validator] fix validating lazy properties that evaluate to null (xabbuh) + * bug #37464 [ErrorHandler] fix throwing from __toString() (nicolas-grekas) + * bug #37449 [Translation] Fix caching of parent locales file in translator (jvasseur) + * bug #37440 [HttpClient] fix casting TraceableResponse to php streams (nicolas-grekas) + * bug #37418 [PhpUnitBridge] Fix compatibility with phpunit 9.3 (Gennadi Janzen) + * bug #37441 [DoctrineBridge] work around Connection::ping() deprecation (nicolas-grekas) + * bug #37291 [MimeType] Duplicated MimeType due to PHP Bug (juanmrad) + * bug #37435 [DI] fix minor perf regression when creating non-shared services (nicolas-grekas) + * bug #37429 [DI] fix parsing of argument type=binary in xml (Tobion) + * bug #37425 [Form] fix guessing form types for DateTime types (xabbuh) + * bug #37392 [Validator] fix handling typed properties as constraint options (xabbuh) + * bug #37325 Fix the supports() method argument type of the security voter (francoispluchino) + * bug #37358 Directly use the driverConnection executeUpdate method (TristanPouliquen) + * bug #37389 [HttpFondation] Change file extension of "audio/mpeg" from "mpga" to "mp3" (YaFou) + * bug #37379 [HttpClient] Support for cURL handler objects (derrabus) + * bug #37383 [VarDumper] Support for cURL handler objects (derrabus) + * bug #37395 add .body wrapper element (Nemo64) + * bug #37400 [HttpClient] unset activity list when creating CurlResponse (nicolas-grekas) + * bug #37396 [DI] Fix call to sprintf in ServicesConfigurator::stack() (dunglas) + * bug #37368 [Security] Resolve event bubbling of logout + new events in a compiler pass (wouterj) + * bug #36304 Check whether path is file in DataPart::fromPath() (freiondrej) + * bug #37366 [SecurityBundle] Fix UserCheckerListener registration with custom user checker (wouterj) + * bug #37364 [Messenger] fixed queue_name option on amazon sqs connection (ck-developer) + * bug #37345 [Form] collect all transformation failures (xabbuh) + * bug #37362 [SecurityBundle] Drop cache.security_expression_language service if invalid (chalasr) + * bug #37353 [DI] disable preload.php on the CLI (nicolas-grekas) + * bug #37268 [Messenger] Fix precedence of DSN options for 4.4 (jderusse) + * bug #37269 [Lock][Messenger] Fix precedence of DSN options for 5.1 (jderusse) + * bug #37341 Fix support for PHP8 union types (nicolas-grekas) + * bug #37271 [FrameworkBundle] preserve dots in query-string when redirecting (nicolas-grekas) + * bug #37340 Fix support for PHP8 union types (nicolas-grekas) + * bug #37275 [DI] tighten detection of local dirs to prevent false positives (nicolas-grekas) + * bug #37090 [PhpUnitBridge] Streamline ansi/no-ansi of composer according to phpunit --colors option (kick-the-bucket) + * bug #36230 [VarDumper] Fix CliDumper coloration on light arrays (l-vo) + * bug #37270 [FrameworkBundle] preserve dots in query-string when redirecting (nicolas-grekas) + * bug #37312 Fix package rename when releasing (94noni) + * bug #37319 [HttpClient] Convert CurlHttpClient::handlePush() to instance method (mpesari) + * bug #37342 [Cache] fix compat with DBAL v3 (nicolas-grekas) + * bug #37327 [HttpFoundation] Allow `null` in InputBag@set (taylorotwell) + +* 5.1.2 (2020-06-15) + + * bug #37265 [HttpFoundation] use InputBag for Request::$request only if data is coming from a form (nicolas-grekas) + * bug #37283 [SecurityBundle] Fix CookieClearingLogoutListener DI configuration (wouterj) + * bug #37160 Reset question validator attempts only for actual stdin (ostrolucky) + * bug #36975 [PropertyInfo] Make PhpDocExtractor compatible with phpDocumentor v5 (DerManoMann) + * bug #37279 [Form] Fixed prototype block prefixes hierarchy of the CollectionType (yceruto) + * bug #37276 [Form] Fixed block prefixes hierarchy of the CollectionType (yceruto) + * bug #37261 Fix register csrf protection listener (Ne-Lexa) + +* 5.1.1 (2020-06-12) + + * bug #37227 [DependencyInjection][CheckTypeDeclarationsPass] Handle unresolved parameters pointing to environment variables (fancyweb) + * bug #37103 [Form] switch the context when validating nested forms (xabbuh) + * bug #37182 [HttpKernel] Fix regression where Store does not return response body correctly (mpdude) + * bug #37193 [DependencyInjection][CheckTypeDeclarationsPass] Always resolve parameters (fancyweb) + * bug #37044 [DependencyInjection] Apply ExpressionLanguageProviderPass to router.default (wizhippo) + * bug #37054 [String] Fix ellipsis of truncate when not using cut option (DuboisS) + * bug #37190 [HttpClient] disable AMP's inactivity timeout, we deal with it on our own already (nicolas-grekas) + * bug #37191 [HttpClient] fix offset computation for data chunks (nicolas-grekas) + * bug #37176 [Routing] Keeping routes priorities after add a name prefix to the collection (yceruto) + * bug #37140 [Lock] Fixed reading locks from replica set secondary nodes (kralos) + * bug #37177 [Ldap] fix refreshUser() ignoring extra_fields (arkste) + * bug #37181 [Mailer] Remove an internal annot (fabpot) + * bug #36913 [FrameworkBundle] fix type annotation on ControllerTrait::addFlash() (ThomasLandauer) + * bug #37153 [PhpUnitBridge] Fix ExpectDeprecationTrait::expectDeprecation() conflict (fancyweb) + * bug #37162 [Mailer] added the reply-to addresses to the API SES transport request. (ribeiropaulor) + * bug #37144 [DI] Add check around class_alias for generated proxy classes (enumag) + * bug #37167 [Mime] use fromString when creating a new Address (fabpot) + * bug #37169 [Cache] fix forward compatibility with Doctrine DBAL 3 (xabbuh) + * bug #37159 [Mailer] Fixed generator bug when creating multiple transports using Transport::fromDsn (atailouloute) + * bug #37154 [FrameworkBundle] Remove reference to APP_SECRET in MicroKernelTrait (nicolas-grekas) + * bug #37126 [SecurityBundle] Fix the session listener registration under the new authentication manager (johnvandeweghe) + * bug #37130 [Console] allow cursor to be used even when STDIN is not defined (xabbuh) + * bug #37053 [PropertyAccess] Fix getter call order BC (1ed) + * bug #37117 [Messenger/DoctrineBridge] set column length for mysql 5.6 compatibility (Nemo64) + * bug #37127 [Messenger/AmazonSqsBridge] Fixed left-over debug statement (sstok) + * bug #37048 [HttpClient] fix monitoring timeouts when other streams are active (nicolas-grekas) + * bug #37085 [Form] properly cascade validation to child forms (xabbuh) + * bug #37095 [PhpUnitBridge] Fix undefined index when output of "composer show" cannot be parsed (nicolas-grekas) + * bug #37092 [PhpUnitBridge] fix undefined var on version 3.4 (nicolas-grekas) + * bug #37022 [DependencyInjection] Improve missing package/version deprecation (acrobat) + * bug #37038 Fix invalid char in SQS Headers (jderusse) + * bug #37047 [SecurityBundle] Only register CSRF protection listener if CSRF is available (wouterj) + * bug #37065 [HttpClient] Throw JsonException instead of TransportException on empty response in Response::toArray() (jeroennoten) + * bug #37058 [FrameworkBundle] Extension Serializer issue (Korbeil) + * bug #37077 [WebProfilerBundle] Move ajax clear event listener initialization on loadToolbar (Bruno BOUTAREL) + * bug #37056 [DoctrineBridge] register event listeners depending on the installed packages (xabbuh) + * bug #37020 [ExpressionLanguage] reset the internal state when the parser is finished (xabbuh) + * bug #37049 [Serializer] take into account the context when preserving empty array objects (xabbuh) + * bug #37031 [Security] Fixed PUBLIC_ACCESS in authenticated sessions (wouterj) + * bug #37028 [FrameworkBundle] Fix enabled_locales behavior (tgalopin) + +* 5.1.0 (2020-05-31) + + * bug #37009 [Validator] use "allowedVariables" to configure the ExpressionLanguageSyntax constraint (xabbuh) + * bug #37008 [Security] Fixed AbstractToken::hasUserChanged() (wouterj) + * bug #36894 [Validator] never directly validate Existence (Required/Optional) constraints (xabbuh) + * bug #37007 [Console] Fix QuestionHelper::disableStty() (chalasr) + * bug #36865 [Form] validate subforms in all validation groups (xabbuh) + * bug #36907 Fixes sprintf(): Too few arguments in form transformer (pedrocasado) + * bug #36868 [Validator] Use Mime component to determine mime type for file validator (pierredup) + * bug #37000 Add meaningful message when using ProcessHelper and Process is not installed (l-vo) + * bug #36990 [Messenger] Change the default notify timeout value for PostgreSQL (fabpot) + * bug #36995 [TwigBridge] fix fallback html-to-txt body converter (nicolas-grekas) + * bug #36993 [ErrorHandler] fix setting $trace to null in FatalError (nicolas-grekas) + * bug #36987 Handle fetch mode deprecation of DBAL 2.11. (derrabus) + * bug #36984 [SecurityBundle] Fixed version constraint on security-core and security-guard (wouterj) + * bug #36974 [Security] Fixed handling of CSRF logout error (wouterj) + +* 5.1.0-RC2 (2020-05-26) + + * bug #36966 Fix extra SQL support in Doctrine migrations (fabpot) + * bug #36960 [HttpClient] fix management of shorter-than-requested timeouts with AmpHttpClient (nicolas-grekas) + * bug #36947 [Mime] Allow email message to have "To", "Cc", or "Bcc" header to be valid (Ernest Hymel) + * bug #36943 [FrameworkBundle] Fix MicroKernelTrait for php 8 (derrabus) + * bug #36938 Don't call method_exists() with non-objects. (derrabus) + * bug #36936 [FrameworkBundle] don't use abstract methods in MicroKernelTrait, their semantics changed in PHP 8 (nicolas-grekas) + * bug #36935 [HttpClient] Adjust AmpResponse to the stricter trait handling in php 8 (derrabus) + * bug #36914 Parse and render anonymous classes correctly on php 8 (derrabus) + * bug #36921 [OptionsResolver][Serializer] Remove calls to deprecated ReflectionParameter::getClass() (derrabus) + * feature #36918 [Security] Removed "services" prototype node from "custom_authenticator" (wouterj) + * bug #36920 [VarDumper] fix PHP 8 support (nicolas-grekas) + * bug #36917 [Cache] Accessing undefined constants raises an Error in php8 (derrabus) + * bug #36891 Address deprecation of ReflectionType::getClass() (derrabus) + * bug #36899 [VarDumper] ReflectionFunction::isDisabled() is deprecated (derrabus) + * bug #36905 [Validator] Catch expected ValueError (derrabus) + * bug #36915 [DomCrawler] Catch expected ValueError (derrabus) + * bug #36908 [Cache][HttpClient] Made method signatures compatible with their corresponding traits (derrabus) + * bug #36906 [DomCrawler] Catch expected ValueError (derrabus) + * bug #36904 [PropertyAccess] Parse php 8 TypeErrors correctly (derrabus) + * bug #36839 [BrowserKit] Raw body with custom Content-Type header (azhurb) + * bug #36869 [Form] don't add the inputmode attribute on fields whose type is the same (MatTheCat) + * feature #36886 [Validator] Make ExpressionLanguageSyntax validator usable with annotation (jderusse) + * bug #36896 [Config] Removed implicit cast of ReflectionProperty to string (derrabus) + * bug #35944 [Security/Core] Fix wrong roles comparison (thlbaut) + * bug #36873 [Messenger] Fixed check for allowed options in AwsSqs configuration (kroshilin) + * bug #36882 [PhpUnitBridge] fix installing under PHP >= 8 (nicolas-grekas) + * bug #36859 [Validator] allow passing a validator to Validation::createCallable() (nicolas-grekas) + * bug #36833 [HttpKernel] Fix that the `Store` would not save responses with the X-Content-Digest header present (mpdude) + * bug #36867 [PhpUnitBridge] fix bad detection of unsilenced deprecations (nicolas-grekas) + * bug #36862 [Security] Unserialize $parentData, if needed, to avoid errors (rfaivre) + * bug #36855 [HttpKernel] Fix error logger when stderr is redirected to /dev/null (fabpot) + * bug #36838 [HttpKernel] Bring back the debug toolbar (derrabus) + +* 5.1.0-RC1 (2020-05-16) + + * bug #36832 [Security] Improved upgrade path for custom remember me services (wouterj) + * bug #36592 [BrowserKit] Allow Referer set by history to be overridden (Slamdunk) + * bug #36800 [DI] Renamed some PHP-DSL functions (javiereguiluz) + * bug #36806 RememberMeLogoutListener should depend on LogoutHandlerInterface (scheb) + * bug #36805 [Security\Core] Fix NoopAuthenticationManager::authenticate() return value (chalasr) + * bug #36823 [HttpClient] fix PHP warning + accept status code >= 600 (nicolas-grekas) + * bug #36824 [Security/Core] fix compat of `NativePasswordEncoder` with pre-PHP74 values of `PASSWORD_*` consts (nicolas-grekas) + * bug #36811 [DependencyInjection] Fix register event listeners compiler pass (X-Coder264) + * bug #36789 Change priority of KernelEvents::RESPONSE subscriber (marcw) + * bug #36794 [Serializer] fix issue with PHP 8 (nicolas-grekas) + * bug #36786 [WebProfiler] Remove 'none' when appending CSP tokens (ndench) + * bug #36796 [DI] Use require_once instead of require when appending cache warmer-returned files to preload file (ovrflo) + * bug #36743 [Yaml] Fix escaped quotes in quoted multi-line string (ossinkine) + * bug #36773 [HttpClient] preserve the identity of responses streamed by TraceableHttpClient (nicolas-grekas) + * bug #36777 [TwigBundle] FormExtension does not have a constructor anymore since sf 4.0 (Tobion) + * bug #36766 [HttpClient] add TimeoutExceptionInterface (nicolas-grekas) + * bug #36716 [Mime] handle passing custom mime types as string (mcneely) + * bug #36765 [HttpClient] fix dealing with informational response (nicolas-grekas) + * bug #36747 Queue name is a required parameter (theravel) + * bug #36751 [Mime] fix bad method call on `EmailAddressContains` (Kocal) + * bug #36737 [Cache] fix accepting sub-second max-lifetimes in ArrayAdapter (nicolas-grekas) + * bug #36749 [DI] give priority to container.hot_path over container.no_preload (nicolas-grekas) + * bug #36721 [FrameworkBundle] remove getProjectDir method from MicroKernelTrait (garak) + +* 5.1.0-BETA1 (2020-05-05) + + * feature #36711 [Form] deprecate `NumberToLocalizedStringTransformer::ROUND_*` constants (nicolas-grekas) + * feature #36681 [FrameworkBundle] use the router context by default for assets (nicolas-grekas) + * feature #35545 [Serializer] Allow to include the severity in ConstraintViolationList (dunglas) + * feature #36471 [String] allow passing a string of custom characters to ByteString::fromRandom (azjezz) + * feature #35092 [Inflector][String] Move Inflector in String (fancyweb) + * feature #36302 [Form] Add the html5 option to ColorType to validate the input (fancyweb) + * feature #36184 [FrameworkBundle] Deprecate renderView() in favor of renderTemplate() (javiereguiluz) + * feature #36655 Automatically provide Messenger Doctrine schema to "diff" (weaverryan) + * feature #35849 [ExpressionLanguage] Added expression language syntax validator (Andrej-in-ua) + * feature #36656 [Security/Core] Add CustomUserMessageAccountStatusException (VincentLanglet) + * feature #36621 Log deprecations on a dedicated Monolog channel (l-vo) + * feature #34813 [Yaml] support YAML 1.2 octal notation, deprecate YAML 1.1 one (xabbuh) + * feature #36557 [Messenger] Add support for RecoverableException (jderusse) + * feature #36470 [DependencyInjection] Add a mechanism to deprecate public services to private (fancyweb) + * feature #36651 [FrameworkBundle] Allow configuring the default base URI with a DSN (nicolas-grekas) + * feature #36600 [Security] Added LDAP support to Authenticator system (wouterj) + * feature #35453 [Messenger] Add option to stop the worker after a message failed (micheh) + * feature #36094 [AmazonSqsMessenger] Use AsyncAws to handle SQS communication (jderusse) + * feature #36636 Add support of PHP8 static return type for withers (l-vo) + * feature #36586 [DI] allow loading and dumping tags with an attribute named "name" (nicolas-grekas) + * feature #36599 [HttpKernel] make kernels implementing `WarmableInterface` be part of the cache warmup stage (nicolas-grekas) + * feature #35992 [Mailer] Use AsyncAws to handle SES requests (jderusse) + * feature #36574 [Security] Removed anonymous in the new security system (wouterj) + * feature #36666 [Security] Renamed VerifyAuthenticatorCredentialsEvent to CheckPassportEvent (wouterj) + * feature #36575 [Security] Require entry_point to be configured with multiple authenticators (wouterj) + * feature #36570 [Security] Integrated Guards with the Authenticator system (wouterj) + * feature #36562 Revert "feature #30501 [FrameworkBundle][Routing] added Configurators to handle template and redirect controllers (HeahDude)" (nicolas-grekas) + * feature #36373 [DI] add syntax to stack decorators (nicolas-grekas) + * feature #36545 [DI] fix definition and usage of AbstractArgument (nicolas-grekas) + * feature #28744 [Serializer] Add an @Ignore annotation (dunglas) + * feature #36456 [String] Add locale-sensitive map for slugging symbols (lmasforne) + * feature #36535 [DI] skip preloading dependencies of non-preloaded services (nicolas-grekas) + * feature #36525 Improve SQS interoperability (jderusse) + * feature #36516 [Notifier] Throw an exception when the Slack DSN is not valid (fabpot) + * feature #35690 [Notifier] Add Free Mobile notifier (noniagriconomie) + * feature #33558 [Security] AuthenticatorManager to make "authenticators" first-class security (wouterj) + * feature #36187 [Routing] Deal with hosts per locale (odolbeau) + * feature #36464 [RedisMessengerBridge] Add a delete_after_ack option (Seldaek) + * feature #36431 [Messenger] Add FIFO support to the SQS transport (cv65kr) + * feature #36455 [Cache] Added context to log messages (Nyholm) + * feature #34363 [HttpFoundation] Add InputBag (azjezz) + * feature #36445 [WebProfilerBundle] Make a difference between queued and sent emails (fabpot) + * feature #36424 [Mailer][Messenger] add return statement for MessageHandler (ottaviano) + * feature #36426 [Form] Deprecated unused old `ServerParams` util (HeahDude) + * feature #36433 [Console] cursor tweaks (fabpot) + * feature #35828 [Notifier][Slack] Send messages using Incoming Webhooks (birkof, fabpot) + * feature #27444 [Console] Add Cursor class to control the cursor in the terminal (pierredup) + * feature #31390 [Serializer] UnwrappingDenormalizer (nonanerz) + * feature #36390 [DI] remove restriction and allow mixing "parent" and instanceof-conditionals/defaults/bindings (nicolas-grekas) + * feature #36388 [DI] deprecate the `inline()` function from the PHP-DSL in favor of `service()` (nicolas-grekas) + * feature #36389 [DI] allow decorators to reference their decorated service using the special `.inner` id (nicolas-grekas) + * feature #36345 [OptionsResolver] Improve the deprecation feature by handling package and version (atailouloute) + * feature #36372 [VarCloner] Cut Logger in dump (lyrixx) + * feature #35748 [HttpFoundation] Add support for all core response http control directives (azjezz) + * feature #36270 [FrameworkBundle] Add file links to named controllers in debug:router (chalasr) + * feature #35762 [Asset] Allows to download asset manifest over HTTP (GromNaN) + * feature #36195 [DI] add tags `container.preload`/`.no_preload` to declare extra classes to preload/services to not preload (nicolas-grekas) + * feature #36209 [HttpKernel] allow cache warmers to add to the list of preloaded classes and files (nicolas-grekas) + * feature #36243 [Security] Refactor logout listener to dispatch an event instead (wouterj) + * feature #36185 [Messenger] Add a \Throwable argument in RetryStrategyInterface methods (Benjamin Dos Santos) + * feature #35871 [Config] Improve the deprecation features by handling package and version (atailouloute) + * feature #35879 [DependencyInjection] Deprecate ContainerInterface aliases (fancyweb) + * feature #36273 [FrameworkBundle] Deprecate flashbag and attributebag services (William Arslett) + * feature #36257 [HttpKernel] Deprecate single-colon notation for controllers (chalasr) + * feature #35778 [DI] Improve the deprecation features by handling package and version (atailouloute) + * feature #36129 [HttpFoundation][HttpKernel][Security] Improve UnexpectedSessionUsageException backtrace (mtarld) + * feature #36186 [FrameworkBundle] Dump kernel extension configuration (guillbdx) + * feature #34984 [Form] Allowing plural message on extra data validation failure (popnikos) + * feature #36154 [Notifier][Slack] Add fields on Slack Section block (birkof) + * feature #36148 [Mailer][Mailgun] Support more headers (Nyholm) + * feature #36144 [FrameworkBundle][Routing] Add link to source to router:match (l-vo) + * feature #36117 [PropertyAccess][DX] Added an `UninitializedPropertyException` (HeahDude) + * feature #36088 [Form] Added "collection_entry" block prefix to CollectionType entries (HeahDude) + * feature #35936 [String] Add AbstractString::containsAny() (nicolas-grekas) + * feature #35744 [Validator] Add AtLeastOne constraint and validator (przemyslaw-bogusz) + * feature #35729 [Form] Correctly round model with PercentType and add a rounding_mode option (VincentLanglet) + * feature #35733 [Form] Added a "choice_filter" option to ChoiceType (HeahDude) + * feature #36003 [ErrorHandler][FrameworkBundle] better error messages in failing tests (guillbdx) + * feature #36034 [PhpUnitBridge] Deprecate @expectedDeprecation annotation (hkdobrev) + * feature #35924 [HttpClient] make `HttpClient::create()` return an `AmpHttpClient` when `amphp/http-client` is found but curl is not or too old (nicolas-grekas) + * feature #36072 [SecurityBundle] Added XSD for the extension configuration (HeahDude) + * feature #36074 [Uid] add AbstractUid and interop with base-58/32/RFC4122 encodings (nicolas-grekas) + * feature #36066 [Uid] use one class per type of UUID (nicolas-grekas) + * feature #36042 [Uid] add support for Ulid (nicolas-grekas) + * feature #35995 [FrameworkBundle] add --deprecations on debug:container command (Simperfit, noemi-salaun) + * feature #36059 [String] leverage Stringable from PHP 8 (nicolas-grekas) + * feature #35940 [UID] Added the component + Added support for UUID (lyrixx) + * feature #31375 [Form] Add label_html attribute (przemyslaw-bogusz) + * feature #35997 [DX][Testing] Added a loginUser() method to test protected resources (javiereguiluz, wouterj) + * feature #35978 [Messenger] Show message & handler(s) class description in debug:messenger (ogizanagi) + * feature #35960 [Security/Http] Hash Persistent RememberMe token (guillbdx) + * feature #35115 [HttpClient] Add portable HTTP/2 implementation based on Amp's HTTP client (nicolas-grekas) + * feature #35913 [LDAP] Add error code in exceptions generated by ldap (Victor Garcia) + * feature #35782 [Routing] Add stateless route attribute (mtarld) + * feature #35732 [FrameworkBundle][HttpKernel] Add session usage reporting in stateless mode (mtarld) + * feature #35815 [Validator] Allow Sequentially constraints on classes + target guards (ogizanagi) + * feature #35747 [Routing][FrameworkBundle] Allow using env() in route conditions (atailouloute) + * feature #35857 [Routing] deprecate RouteCompiler::REGEX_DELIMITER (nicolas-grekas) + * feature #35804 [HttpFoundation] Added MarshallingSessionHandler (atailouloute) + * feature #35858 [Security] Deprecated ROLE_PREVIOUS_ADMIN (wouterj) + * feature #35848 [Validator] add alpha3 option to Language constraint (xabbuh) + * feature #31189 [Security] Add IS_IMPERSONATOR, IS_ANONYMOUS and IS_REMEMBERED (HeahDude) + * feature #30994 [Form] Added support for caching choice lists based on options (HeahDude) + * feature #35783 [Validator] Add the divisibleBy option to the Count constraint (fancyweb) + * feature #35649 [String] Allow to keep the last word when truncating a text (franmomu) + * feature #34654 [Notifier] added Sinch texter transport (imiroslavov) + * feature #35673 [Process] Add getter for process starttime (dompie) + * feature #35689 [String] Transliterate & to and (Warxcell) + * feature #34550 [Form] Added an AbstractChoiceLoader to simplify implementations and handle global optimizations (HeahDude) + * feature #35688 [Notifier] Simplify OVH implementation (fabpot) + * feature #34540 [Notifier] add OvhCloud bridge (antiseptikk) + * feature #35192 [PhpUnitBridge] Add the ability to expect a deprecation inside a test (fancyweb) + * feature #35667 [DomCrawler] Rename UriExpander.php -> UriResolver (lyrixx) + * feature #35611 [Console] Moved estimated & remaining calculation logic to separate get method (peterjaap) + * feature #33968 [Notifier] Add Firebase bridge (Jeroeny) + * feature #34022 [Notifier] add RocketChat bridge (Jeroeny) + * feature #32454 [Messenger] Add SQS transport (jderusse) + * feature #33875 Add Mattermost notifier bridge (thePanz) + * feature #35400 [RFC][DX][OptionsResolver] Allow setting info message per option (yceruto) + * feature #30501 [FrameworkBundle][Routing] added Configurators to handle template and redirect controllers (HeahDude) + * feature #35373 [Translation] Support name attribute on the xliff2 translator loader (Taluu) + * feature #35550 Leverage trigger_deprecation() from symfony/deprecation-contracts (nicolas-grekas) + * feature #35648 [Contracts/Deprecation] don't use assert(), rename to trigger_deprecation() (nicolas-grekas) + * feature #33456 [MonologBridge] Add Mailer handler (BoShurik) + * feature #35384 [Messenger] Add receiving of old pending messages (redis) (toooni) + * feature #34456 [Validator] Add a constraint to sequentially validate a set of constraints (ogizanagi) + * feature #34334 [Validator] Allow to define a reusable set of constraints (ogizanagi) + * feature #35642 [HttpFoundation] Make dependency on Mime component optional (atailouloute) + * feature #35635 [HttpKernel] Make ErrorListener unaware of the event dispatcher (derrabus) + * feature #35019 [Cache] add SodiumMarshaller (atailouloute) + * feature #35625 [String] Add the s() helper method (fancyweb) + * feature #35624 [String] Remove the @experimental status (fancyweb) + * feature #33848 [OptionsResolver] Add new OptionConfigurator class to define options with fluent interface (lmillucci, yceruto) + * feature #35076 [DI] added possibility to define services with abstract arguments (Islam93) + * feature #35608 [Routing] add priority option to annotated routes (nicolas-grekas) + * feature #35526 [Contracts/Deprecation] Provide a generic function and convention to trigger deprecation notices (nicolas-grekas) + * feature #32747 [Form] Add "is empty callback" to form config (fancyweb) + * feature #34884 [DI] Enable auto alias compiler pass by default (X-Coder264) + * feature #35596 [Serializer] Add support for stdClass (dunglas) + * feature #34278 Update bootstrap_4_layout.html.twig (CoalaJoe) + * feature #31309 [SecurityBundle] add "service" option in remember_me firewall (Pchol) + * feature #31429 [Messenger] add support for abstract handlers (timiTao) + * feature #31466 [Validator] add Validation::createCallable() (janvernieuwe) + * feature #34747 [Notifier] Added possibility to extract path from provided DSN (espectrio) + * feature #35534 [FrameworkBundle] Use MailerAssertionsTrait in KernelTestCase (adrienfr) + * feature #35590 [FrameworkBundle] use framework.translator.enabled_locales to build routes' default "_locale" requirement (nicolas-grekas) + * feature #35167 [Notifier] Remove superfluous parameters in *Message::fromNotification() (fancyweb) + * feature #35415 Extracted code to expand an URI to `UriExpander` (lyrixx) + * feature #35485 [Messenger] Add support for PostgreSQL LISTEN/NOTIFY (dunglas) + * feature #32039 [Cache] Add couchbase cache adapter (ajcerezo) + * feature #32433 [Translation] Introduce a way to configure the enabled locales (javiereguiluz) + * feature #33003 [Filesystem] Add $suffix argument to tempnam() (jdufresne) + * feature #35347 [VarDumper] Add a RdKafka caster (romainneutron) + * feature #34925 Messenger: validate options for AMQP and Redis Connections (nikophil) + * feature #33315 [WebProfiler] Improve HttpClient Panel (ismail1432) + * feature #34298 [String] add LazyString to provide memoizing stringable objects (nicolas-grekas) + * feature #35368 [Yaml] Deprecate using the object and const tag without a value (fancyweb) + * feature #35566 [HttpClient] adding NoPrivateNetworkHttpClient decorator (hallboav) + * feature #35560 [HttpKernel] allow using public aliases to reference controllers (nicolas-grekas) + * feature #34871 [HttpClient] Allow pass array of callable to the mocking http client (Koc) + * feature #30704 [PropertyInfo] Add accessor and mutator extractor interface and implementation on reflection (joelwurtz, Korbeil) + * feature #35525 [Mailer] Randomize the first transport used by the RoundRobin transport (fabpot) + * feature #35116 [Validator] Add alpha3 option to country constraint (maxperrimond) + * feature #29139 [FrameworkBundle][TranslationDebug] Return non-zero exit code on failure (DAcodedBEAT) + * feature #35050 [Mailer] added tag/metadata support (kbond) + * feature #35215 [HttpFoundation] added withers to Cookie class (ns3777k) + * feature #35514 [DI][Routing] add wither to configure the path of PHP-DSL configurators (nicolas-grekas) + * feature #35519 [Mailer] Make default factories public (fabpot) + * feature #35156 [String] Made AbstractString::width() follow POSIX.1-2001 (fancyweb) + * feature #35308 [Dotenv] Add Dotenv::bootEnv() to check for .env.local.php before calling Dotenv::loadEnv() (nicolas-grekas) + * feature #35271 [PHPUnitBridge] Improved deprecations display (greg0ire) + * feature #35478 [Console] Add constants for main exit codes (Chi-teck) + * feature #35503 [Messenger] Add TLS option to Redis transport's DSN (Nyholm) + * feature #35262 [Mailer] add ability to disable the TLS peer verification via DSN (Aurélien Fontaine) + * feature #35194 [Mailer] read default timeout from ini configurations (azjezz) + * feature #35422 [Messenger] Move Transports to separate packages (Nyholm) + * feature #35425 [CssSelector] Added cache on top of CssSelectorConverter (lyrixx) + * feature #35362 [Cache] Add LRU + max-lifetime capabilities to ArrayCache (nicolas-grekas) + * feature #35402 [Console] Set Command::setHidden() final for adding default param in SF 6.0 (lyrixx) + * feature #35407 [HttpClient] collect the body of responses when possible (nicolas-grekas) + * feature #35391 [WebProfilerBundle][HttpClient] Added profiler links in the Web Profiler -> Http Client panel (cristagu) + * feature #35295 [Messenger] Messenger redis local sock dsn (JJarrie) + * feature #35322 [Workflow] Added a way to not fire the announce event (lyrixx) + * feature #35321 [Workflow] Make many internal services as hidden (lyrixx) + * feature #35235 [Serializer] Added scalar denormalization (a-menshchikov) + * feature #35310 [FrameworkBundle] Deprecate *not* setting the "framework.router.utf8" option (nicolas-grekas) + * feature #34387 [Yaml] Added yaml-lint binary (jschaedl) + * feature #35257 [FrameworkBundle] TemplateController should accept extra arguments to be sent to the template (Benjamin RICHARD) + * feature #34980 [Messenger] remove several messages with command messenger:failed:remove (nikophil) + * feature #35298 Make sure the UriSigner can be autowired (Toflar) + * feature #31518 [Validator] Added HostnameValidator (karser) + * feature #35284 Simplify UriSigner when working with HttpFoundation's Request (Toflar) + * feature #35285 [FrameworkBundle] Adding better output to secrets:decrypt-to-local command (weaverryan) + * feature #35273 [HttpClient] Add LoggerAwareInterface to ScopingHttpClient and TraceableHttpClient (pierredup) + * feature #34865 [FrameworkBundle][ContainerLintCommand] Style messages (fancyweb) + * feature #34847 Add support for safe HTTP preference - RFC 8674 (pyrech) + * feature #34880 [Twig][Form] Twig theme for Foundation 6 (Lyssal) + * feature #35281 [FrameworkBundle] Configure RequestContext through router config (benji07) + * feature #34819 [Console] Add SingleCommandApplication to ease creation of Single Command Application (lyrixx) + * feature #35104 [Messenger] Log sender alias in SendMessageMiddleware (ruudk) + * feature #35205 [Form] derive the view timezone from the model timezone (xabbuh) + * feature #34986 [Form] Added default `inputmode` attribute to Search, Email and Tel form types (fre5h) + * feature #35091 [String] Add the reverse() method (fancyweb) + * feature #35029 [DI] allow "." and "-" in env processor lines (nicolas-grekas) + * feature #34548 Added access decision strategy to respect voter priority (aschempp) + * feature #34881 [FrameworkBundle] Allow using the kernel as a registry of controllers and service factories (nicolas-grekas) + * feature #34977 [EventDispatcher] Deprecate LegacyEventDispatcherProxy (derrabus) + * feature #34873 [FrameworkBundle] Allow using a ContainerConfigurator in MicroKernelTrait::configureContainer() (nicolas-grekas) + * feature #34872 [FrameworkBundle] Added flex-compatible default implementations for `MicroKernelTrait::registerBundles()` and `getProjectDir()` (nicolas-grekas) + * feature #34916 [DI] Add support for defining method calls in InlineServiceConfigurator (Lctrs) + * feature #31889 [Lock] add mongodb store (kralos) + * feature #34924 [ErrorHandler] Enabled the dark theme for exception pages (javiereguiluz) + * feature #34769 [DependencyInjection] Autowire public typed properties (Plopix) + * feature #34856 [Validator] mark the Composite constraint as internal (xabbuh) + * feature #34771 Deprecate *Response::create() methods (fabpot) + * feature #32388 [Form] Allow to translate each language into its language in LanguageType (javiereguiluz) + * feature #34119 [Mime] Added MimeType for "msg" (LIBERT Jérémy) + * feature #34648 [Mailer] Allow to configure or disable the message bus to use (ogizanagi) + * feature #34705 [Validator] Label regex in date validator (kristofvc) + * feature #34591 [Workflow] Added `Registry::has()` to check if a workflow exists (lyrixx) + * feature #32937 [Routing] Deprecate RouteCollectionBuilder (vudaltsov) + * feature #34557 [PropertyInfo] Add support for typed properties (PHP 7.4) (dunglas) + * feature #34573 [DX] [Workflow] Added a way to specify a message when blocking a transition + better default message in case it is not set (lyrixx) + * feature #34457 Added context to exceptions thrown in apply method (koenreiniers) + diff --git a/CHANGELOG-5.2.md b/CHANGELOG-5.2.md new file mode 100644 index 0000000000000..5e5f455254f7a --- /dev/null +++ b/CHANGELOG-5.2.md @@ -0,0 +1,623 @@ +CHANGELOG for 5.2.x +=================== + +This changelog references the relevant changes (bug and security fixes) done +in 5.2 minor versions. + +To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash +To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v5.2.0...v5.2.1 + +* 5.2.6 (2021-03-29) + + * bug #40598 [Form] error if the input string couldn't be parsed as a date (xabbuh) + * bug #40587 [HttpClient] fix using stream_copy_to_stream() with responses cast to php streams (nicolas-grekas) + * bug #40510 [Form] IntegerType: Always use en for IntegerToLocalizedStringTransformer (Warxcell) + * bug #40593 Uses the correct assignment action for console options depending if they are short or long (topikito) + * bug #40535 [HttpKernel] ConfigDataCollector to return known data without the need of a Kernel (topikito) + * bug #40552 [Translation] Fix update existing key with existing +int-icu domain (Alexis) + * bug #40541 Fixed parsing deprecated definitions without message key (adamwojs) + * bug #40537 [Security] Handle properly 'auto' option for remember me cookie security (fliespl) + * bug #40524 [Console] fix emojis messing up the line width (MarionLeHerisson) + * bug #40506 [Validator] Avoid triggering the autoloader for user-input values (Seldaek) + * bug #40544 [FrameworkBundle] ensure TestBrowserToken::$firewallName is serialized (kbond) + * bug #40547 [RateLimiter] Security hardening - Rate limiter (jderusse) + * bug #40538 [HttpClient] remove using $http_response_header (nicolas-grekas) + * bug #40508 [PhpUnitBridge] fix reporting deprecations from DebugClassLoader (nicolas-grekas) + * bug #40497 [HttpFoundation] enable HTTP method overrides as early as possible with the HTTP cache (xabbuh) + * bug #40348 [Console] Fix line wrapping for decorated text in block output (grasmash) + * bug #40499 [Inflector][String] Fixed pluralize "coupon" (Nyholm) + * bug #40494 [PhpUnitBridge] fix compat with symfony/debug (nicolas-grekas) + * bug #40453 [VarDumper] Adds support for ReflectionUnionType to VarDumper (Michael Nelson, michaeldnelson) + * bug #40460 Correctly clear lines for multi-line progress bar messages (grasmash) + * bug #40490 [Security] Add XML support for authenticator manager (wouterj) + * bug #40242 [ErrorHandler] Fix error caused by `include` + open_basedir (stlrnz) + * bug #40368 [FrameworkBundle] Make the TestBrowserToken interchangeable with other tokens (Seldaek) + * bug #40450 [Console] ProgressBar clears too many lines on update (danepowell) + * bug #40178 [FrameworkBundle] Exclude unreadable files when executing About command (michaljusiega) + * bug #40472 [Bridge\Twig] Add 'form-control-range' for range input type (Oviglo) + * bug #40481 make async-ses required (jderusse) + * bug #39866 [Mime] Escape commas in address names (YaFou) + * bug #40373 Check if templating engine supports given view (fritzmg) + * bug #39992 [Security] Refresh original user in SwitchUserListener (AndrolGenhald) + * bug #40446 [TwigBridge] Fix "Serialization of 'Closure'" error when rendering an TemplatedEmail (jderusse) + * bug #40416 Fix `ConstraintViolation#getMessageTemplate()` to always return `string` (Ocramius) + * bug #40425 [DoctrineBridge] Fix eventListener initialization when eventSubscriber constructor dispatch an event (jderusse) + * bug #40313 [FrameworkBundle] Fix PropertyAccess definition when not in debug (PedroTroller) + * bug #40417 [Form] clear unchecked choice radio boxes even if clear missing is set to false (xabbuh) + * bug #40388 [ErrorHandler] Added missing type annotations to FlattenException (derrabus) + * bug #40407 [TwigBridge] Allow version 3 of the Twig extra packages (derrabus) + +* 5.2.5 (2021-03-10) + + * bug #40415 Fix `ConstraintViolation#getPropertyPath()` to always return `string` (Ocramius) + * bug #40421 [FrameworkBundle] fix XSD (nicolas-grekas) + * bug #39685 [Mailer][Mime][TwigBridge][Validator] Allow egulias/email-validator 3.x (derrabus) + * bug #40398 [FrameworkBundle] : Fix method name compare in ResolveControllerNameSubscriber (glensc) + * bug #39733 [TwigBridge] Render email once (jderusse) + * bug #40386 [DependencyInjection][Security] Backport psr/container 1.1/2.0 compatibility (derrabus) + * bug #40376 [Messenger] Don't lock tables or start transactions (Nyholm) + * bug #40378 Changing ZulipTransportFactory tag to prevent the exception UnsupportedSchemeException (big-r81) + +* 5.2.4 (2021-03-04) + + * bug #40336 [Messenger] Doctrine setup with migrations (Nyholm) + * bug #40318 [Translation] deal with indented heredoc/nowdoc tokens (xabbuh) + * bug #40350 [DependencyInjection] fix parsing calls of methods named "method" (xabbuh) + * bug #40316 [Serializer] zero parts can be omitted in date interval input (xabbuh) + * bug #40239 MockResponse total_time should not be simulated when provided (Pierrick VIGNAND) + * bug #40299 [Cache] Add server-commands support for Predis Replication Environments (DemigodCode) + * bug #40231 [HttpKernel] Configure `session.cookie_secure` earlier (tamcy) + * bug #40283 [Translation] Make `name` attribute optional in xliff2 (MarieMinasyan) + * bug #40286 [Security] #[CurrentUser] arguments should resolve to null for "anon." (chalasr) + * bug #40281 [FrameworkBundle] Allow x-forwarded-prefix trusted header in config (drupol) + * bug #39599 [Cache] Fix Redis TLS scheme `rediss` for Redis connection (misaert) + * bug #40244 [Routing] fix conflict with param named class in attribute (nlhommet) + * bug #40273 [Cache] fix setting items' metadata on commit() (nicolas-grekas) + * bug #40258 [Form] Ignoring invalid forms from delete_empty behavior in CollectionType (yceruto) + * bug #40246 [EventDispatcher] fix registering subscribers twice on edge-case (nicolas-grekas) + * bug #40162 [Intl] fix Locale::getFallback() throwing exception on long $locale (AmirHo3ein13) + * bug #40211 [Validator] fix taking error message from the correct violation (xabbuh) + * bug #40208 [PropertyInfo] fix resolving self to name of the analyzed class (xabbuh) + * bug #40209 [WebLink] Escape double quotes in attributes values (fancyweb) + * bug #40192 [Console] fix QuestionHelper::getHiddenResponse() not working with space in project directory name (Yendric) + * bug #40203 [String] Check if function exists before declaring it (Nyholm) + * bug #40175 [PropertyInfo]  use the right context for properties defined in traits (xabbuh) + * bug #40172 [Translation] Allow using dashes in locale when linting Xliff files (localheinz) + * bug #39671 [Worflow] Fixed GuardListener when using the new Security system (lyrixx) + * bug #40187 [Console] Fix PHP 8.1 null error for preg_match flag (kylekatarnls) + * bug #39659 [Form] keep valid submitted choices when additional choices are submitted (xabbuh) + * bug #40188 [HttpFoundation] Fix PHP 8.1 null values (kylekatarnls) + * bug #40167 [DependencyInjection] Definition::removeMethodCall should remove all matching calls (ruudk) + * bug #40160 [PropertyInfo] fix extracting mixed type-hinted property types (xabbuh) + * bug #40040 [Finder] Use a lazyIterator to close files descriptors when no longer used (jderusse) + * bug #40141 [RateLimiter] Fix sliding_window misbehaving with stale records (xesxen) + * bug #40135 [FrameworkBundle] Fix freshness checks with boolean parameters on routes (HypeMC) + * bug #40138 [FrameworkBundle] fix registering "annotations.cache" on the "container.hot_path" (nicolas-grekas) + * bug #40137 [Form] forward the label_html option to expanded choice fields (xabbuh) + * bug #40116 [FrameworkBundle][Translator] scan directories for translations sequentially (xabbuh) + * bug #40124 [Form] merge translation parameters with value configured for parent form (xabbuh) + * bug #40104 [HttpKernel] [Kernel] Silence failed deprecations logs writes (fancyweb) + * bug #40098 [DependencyInjection] fix tracking of changes to vendor/ dirs (nicolas-grekas) + * bug #39980 [Mailer][Mime] Update inline part names with newly generated ContentId (ddegentesh) + * bug #40043 [HttpFoundation] Setting `REQUEST_TIME_FLOAT` when constructing a Request object (ctasada) + * bug #40050 [FrameworkBundle][Translator] Fixed updating catalogue metadata from Intl domain (yceruto) + * bug #40080 Fix Request with DNS issue not retried (jderusse) + * bug #40089 [SecurityBundle] role_names variable instead of roles (wickedOne) + * bug #40042 [Doctrine] Restore priority for EventSubscribers (jderusse) + * bug #40066 [ErrorHandler] fix parsing return types in DebugClassLoader (nicolas-grekas) + * bug #40065 [ErrorHandler] fix handling messages with null bytes from anonymous classes (nicolas-grekas) + * bug #40067 [PhpUnitBridge] fix reporting deprecations when they come from DebugClassLoader (nicolas-grekas) + +* 5.2.3 (2021-02-03) + + * bug #39954 [Mailer][Mime] Fix case-sensitive handling of header names (piku235) + * bug #40055 [Messenger] Fix Doctrine setup when using a migration (fabpot) + * bug #40018 [TwigBridge] take into account all label related options (xabbuh) + * bug #40023 [Finder]  use proper keys to not override appended files (xabbuh) + * bug #40019 [ErrorHandler] Fix strpos error when trying to call a method without a name (Deuchnord) + * bug #40027 [DoctrineBridge] add missing `@experimental` annotation on Uid generators (nicolas-grekas) + * bug #40004 [Serializer] Prevent access to private properties without getters (julienfalque) + * bug #40003 [Uid] Fix time to float conversion (fancyweb) + +* 5.2.2 (2021-01-27) + + * bug #38900 [Serializer] Exclude non-initialized properties accessed with getters (BoShurik) + * bug #39982 [SecurityBundle] Fix referencing aliases from RegisterEntryPointsPass (chalasr) + * bug #39872 [Validator] propagate the object being validated to nested constraints (xabbuh) + * bug #39887 [Translator] fix handling plural for floating numbers (kylekatarnls) + * bug #39967 [Messenger] fix redis messenger options with dsn (Kleinast) + * bug #39970 [Messenger] Fix transporting non-UTF8 payloads by encoding them using base 64 (nicolas-grekas) + * bug #39956 [Uid] fix checking for valid UUIDs (nicolas-grekas) + * bug #39951 [Form] check parent types for label_format and translation_domain (xabbuh) + * bug #39911 [RateLimiter] Fix infinite values with NoLimiter (YaFou) + * bug #39936 [Validator] Fix DebugCommand (loic425) + * bug #39909 [PhpUnitBridge] Allow relative path to composer cache (jderusse) + * bug #39944 [HttpKernel] Configure the ErrorHandler even when it is overriden (nicolas-grekas) + * bug #39896 [PropertyInfo] Fix breaking change with has*(arguments...) methods (YaFou) + * bug #39932 [Console] [Command] Fix Closure code binding when it is a static anonymous function (fancyweb) + * bug #39871 [Notifier] [OvhCloud] “Invalid signature” for message with slashes (OneT0uch) + * bug #39900 [Uid] Unable to extend Uuid/Ulid and use fromString() (OskarStark) + * bug #39880 [DoctrineBridge] Add username to UserNameNotFoundException (qurben) + * bug #39633 [HttpFoundation] Drop int return type from parseFilesize() (LukeTowers) + * bug #39889 [HttpClient] Add check for constant in Curl client (pierredup) + * bug #39886 [HttpFoundation] Revert #38614 and add assert to avoid regressions (BafS) + * bug #39873 [DependencyInjection] Fix container injection with TypedReference (jderusse) + * bug #39858 Fix problem when SYMFONY_PHPUNIT_VERSION is empty string value (alexander-schranz) + * bug #39861 [DependencyInjection] Skip deprecated definitions in CheckTypeDeclarationsPass (chalasr) + * bug #39862 [Security] Replace message data in JSON security error response (wouterj) + * bug #39859 [Security] Replace message data in JSON security error response (wouterj) + * bug #39839 [Messenger] [AmazonSqs] Fix auto-setup for fifo queue (starred-gijs) + * bug #39667 [DoctrineBridge] Take into account that indexBy="person_id" could be a db column name, for a referenced entity (victormacko) + * bug #39799 [DoctrineBridge] Fix circular loop with EntityManager (jderusse) + * bug #39821 [DependencyInjection] Don't trigger notice for deprecated aliases pointing to deprecated definitions (chalasr) + * bug #39816 [HttpFoundation] use atomic writes in MockFileSessionStorage (nicolas-grekas) + * bug #39812 Make EmailMessage & SmsMessage transport nullable (odolbeau) + * bug #39735 [Serializer] Rename normalize param (VincentLanglet) + * bug #39797 Dont allow unserializing classes with a destructor (jderusse) + * bug #39743 [Mailer] Fix missing BCC recipients in SES bridge (jderusse) + * bug #39764 [Config]  fix handling float-like key attribute values (xabbuh) + * bug #39787 [Yaml] a colon followed by spaces exclusively separates mapping keys and values (xabbuh) + * bug #39788 [Cache] fix possible collision when writing tmp file in filesystem adapter (nicolas-grekas) + * bug #39796 Dont allow unserializing classes with a destructor - 5.2 (jderusse) + * bug #39794 Dont allow unserializing classes with a destructor - 4.4 (jderusse) + * bug #39795 Dont allow unserializing classes with a destructor - 5.1 (jderusse) + * bug #39389 [Security]  Move the handleAuthenticationSuccess logic outside try/catch block (jderusse) + * bug #39747 [DependencyInjection] Support PHP 8 builtin types in CheckTypeDeclarationsPass (derrabus) + * bug #39738 [VarDumper] fix mutating $GLOBALS while cloning it (nicolas-grekas) + * bug #39746 [DependencyInjection] Fix InvalidParameterTypeException for function parameters (derrabus) + * bug #39681 [HttpFoundation] parse cookie values containing the equal sign (xabbuh) + * bug #39716 [DependencyInjection] do not break when loading schemas from network paths on Windows (xabbuh) + * bug #39703 [Finder] apply the sort callback on the whole search result (xabbuh) + * bug #39717 [TwigBridge] Remove full head content in HTML to text converter (pupaxxo) + * bug #39672 [FrameworkBundle] Fix UidNormalizer priority (fancyweb) + * bug #39649 [Validator] propagate groups to nested constraints (xabbuh) + * bug #39708 [WebProfilerBundle] take query and request parameters into account when matching routes (xabbuh) + * bug #39692 [FrameworkBundle] Dump abstract arguments (jderusse) + * bug #39683 [Yaml] keep trailing newlines when dumping multi-line strings (xabbuh) + * bug #39670 [Form] disable error bubbling by default when inherit_data is configured (xabbuh) + * bug #39686 [Lock] Fix config merging in lock (jderusse) + * bug #39668 [Yaml] do not dump extra trailing newlines for multiline blocks (xabbuh) + * bug #39674 [Messenger] fix postgres transport when the retry table is the same (lyrixx) + * bug #39653 [Form] fix passing null $pattern to IntlDateFormatter (nicolas-grekas) + * bug #39637 [Security] Fix event propagation for AuthenticationTokenCreatedEvent when globally registered (scheb) + * bug #39647 [Validator] Update Isin message to match the translation files (derrabus) + * bug #39598 [Messenger] Fix stopwach usage if it has been reset (lyrixx) + * bug #39636 [Uid] Handle ValueErrors triggered by ext-uuid on PHP 8 (derrabus) + * bug #39631 [VarDumper] Fix display of nullable union return types (derrabus) + * bug #39629 [VarDumper] fixed displaying "mixed" as "?mixed" (nicolas-grekas) + * bug #39597 [Mailer] Handle failure when sending DATA (jderusse) + * bug #39621 [Security] Fix event propagation for globally registered security events (scheb) + * bug #39603 [TwigBridge] allow null values in form helpers (xabbuh) + * bug #39610 [ProxyManagerBridge] fix PHP notice, switch to "friendsofphp/proxy-manager-lts" (nicolas-grekas) + * bug #39584 [Security] Add RememberMe Badge to LoginLinkAuthenticator (jderusse) + * bug #39586 Supports empty path for slack DSN (odolbeau) + +* 5.2.1 (2020-12-18) + + * bug #39555 [FrameworkBundle] Fix NFS detection on macOs (jderusse) + * bug #39545 [Notifier] [Mattermost] Host is required (OskarStark) + * bug #39548 [Notifier] [Infobip][Zulip] Host is required (OskarStark) + * bug #39550 [HttpFoundation] keep turning dots to underscores when using Request::create() (nicolas-grekas) + * bug #39538 [Notifier] Fix parsing Dsn with empty user/password (OskarStark) + * bug #39531 [Mailer] Fix parsing Dsn with empty user/password (OskarStark) + * bug #39492 [Notifier] [Discord] Use private const and mb_strlen() (OskarStark) + * bug #39522 [Notifier] Set message id on SentMessage (OskarStark) + * bug #39532 [Notifier] Fix toString when optional parameter is not set (OskarStark) + * bug #39518 [Ldap] Incorrect determination of RelativeDistinguishedName for the "move" operation (astepin) + * bug #39525 [VarDumper] dont hide any nodes until JS is proven to work (nicolas-grekas) + * bug #39498 [DoctrineBridge] Guess correct form types for DATE_IMMUTABLE and DATETIME_IMMUTABLE (guillaume-sainthillier) + * bug #39510 [Notifier]  [Free Mobile] Could not use custom host in DSN (OskarStark) + * bug #39515 [Notifier] Fix wrong package name (OskarStark) + * bug #39514 [Notifier] Fix wrong package names (OskarStark) + * bug #39502 Add missing symfony/deprecation-contracts requirement - 5.2 (jderusse) + * bug #39494 Add missing symfony/deprecation-contracts requirement (jderusse) + * bug #39360 [FrameworkBundler] Fix cache:clear with buildDir (jderusse) + * bug #39476 [Lock] Prevent store exception break combined store (dzubchik) + * bug #39478 [FrameworkBundle] Fix missing kernel.build_dir on cache clear (chalasr) + * bug #39456 [Notifier] [Free Mobile] Fix wrong scheme in mapping (OskarStark) + * bug #39442 Fix enabled key for ratelimiter config (pierredup) + * bug #39299 [PropertyInfo][Serializer] Fixed extracting ignored properties for Serializer (javer) + * bug #39433 [Cache] fix setting "read_timeout" when using Redis (nicolas-grekas) + * bug #39228 [HttpClient] Fix content swallowed by AsyncClient initializer (jderusse) + * bug #39420 [Cache] Prevent notice on case matching metadata trick (bastnic) + * bug #39413 [Notifier] [Discord] Make webhookId argument required (OskarStark) + * bug #39203 [DI] Fix not working if only "default_index_method" used (malteschlueter) + * bug #39409 [Notifier] [Twilio] Add tests (OskarStark) + * bug #39401 [DoctrineBridge] no-op RegisterUidTypePass if DBAL types aren't loaded (craue) + * bug #39417 [Form] Fix UUID exception (jderusse) + * bug #39142 [Config] Stop treating multiline resources as globs (michaelKaefer) + * bug #39341 [Form] Fixed StringUtil::trim() to trim ZERO WIDTH SPACE (U+200B) and SOFT HYPHEN (U+00AD) (pmishev) + * bug #39268 [HttpClient] Use decoration instead of class replacement for mock factory (GaryPEGEOT) + * bug #39334 [Config][TwigBundle] Fixed syntax error in config (Nyholm) + * bug #39196 [DI] Fix Xdebug 3.0 detection (vertexvaar) + * bug #39375 [SecurityBundle] fix LDAP-based HTTP Basic Auth entry point registration (xabbuh) + * bug #39226 [PhpUnitBridge] Fix disabling DeprecationErrorHandler from PHPUnit configuration file (fancyweb) + * bug #39298 [Cache] Fixed incorrect usage of UNLINK with PHPRedis with Redis < 4.0 (wickex) + * bug #39361 [FrameworkBundle] acces public-deprecated services via the private container to remove false-positive deprecations (nicolas-grekas) + * bug #39358 [HttpFoundation] fix parsing some special chars with HeaderUtils::parseQuery() (nicolas-grekas) + * bug #39357 [FrameworkBundle] fix preserving some special chars in the query string (nicolas-grekas) + * bug #39310 [Notifier] Add exception for deprecated slack dsn (malteschlueter) + * bug #39271 [HttpFoundation] Fix TypeError: Argument 1 passed to JsonResponse::setJson() must be of the type string, object given (sidz) + * bug #39251 [DependencyInjection] Fix container linter for union types (derrabus) + * bug #39336 [Config] YamlReferenceDumper: No default value required for VariableNode with array example (Nyholm) + * bug #39333 [Form] do not apply the Valid constraint on scalar form data (lchrusciel, xabbuh) + * bug #39331 [PhpUnitBridge] Fixed PHPunit 9.5 compatibility (wouterj) + * bug #39220 [HttpKernel] Fix bug with whitespace in Kernel::stripComments() (ausi) + * bug #39252 [Mime] Leverage PHP 8's detection of CSV files (derrabus) + * bug #39313 [FrameworkBundle] TextDescriptor::formatControllerLink checked method… (fjogeleit) + * bug #39286 [HttpClient] throw clearer error when no scheme is provided (BackEndTea) + * bug #39267 [Yaml] fix lexing backslashes in single quoted strings (xabbuh) + * bug #39151 [DependencyInjection] Fixed incorrect report for private services if required service does not exist (Islam93) + * bug #39236 [Notifier] Fix slack section block (norkunas) + * bug #39274 [Yaml] fix lexing mapping values with trailing whitespaces (xabbuh) + * bug #39256 [Workflow] Fixed case when the marking store is not defined (lyrixx) + * bug #39244 [String] Fix Notice when argument is empty string (moldman) + * bug #39270 [Inflector] Fix Notice when argument is empty string (moldman) + * bug #39263 [Security] more defensive PasswordMigratingListener (romaricdrigon) + * bug #39261 [Security] fix #39249, default entry_point compiler pass was returning too early (romaricdrigon) + * bug #39247 [Security] remove return type definition in order to avoid type juggling (adeptofvoltron) + * bug #39223 [Console] Re-enable hyperlinks in Konsole/Yakuake (OndraM) + * bug #39241 [Yaml] fix lexing inline sequences/mappings with trailing whitespaces (Nyholm, xabbuh) + * bug #39243 [Filesystem] File existence check before calling unlink method (gechetspr) + +* 5.2.0 (2020-11-30) + + * feature #39213 [Security] [DX] Automatically add PasswordUpgradeBadge + default support() impl in AbstractFormLoginAuthenticator (wouterj) + * bug #39166 [Messenger] Fix mssql compatibility for doctrine transport. (bill moll) + * bug #39210 [DoctrineBridge] Fix form EntityType with filter on UID (jderusse) + * bug #39211 [HttpClient] fix binding to network interfaces (nicolas-grekas) + * bug #39129 [DependencyInjection] Fix circular in DI with lazy + byContruct loop (jderusse) + * feature #39153 [Security] Automatically register custom authenticator as entry_point (if supported) (wouterj) + * bug #39068 [DependencyInjection][Translator] Silent deprecation triggered by libxml_disable_entity_loader (jderusse) + * bug #39119 [Form] prevent duplicated error message for file upload limits (xabbuh) + * bug #39099 [Form] ignore the pattern attribute for textareas (xabbuh) + * feature #39118 [DoctrineBridge] Require doctrine/persistence 2 (greg0ire) + * feature #39128 [HttpFoundation] Deprecate BinaryFileResponse::create() (derrabus) + * bug #39154 [Yaml] fix lexing strings containing escaped quotation characters (xabbuh) + * bug #39187 [Security] Support for SwitchUserToken instances serialized with 4.4/5.1 (derrabus) + * bug #39180 [Serializer] Fix denormalizing scalar with UnwrappingDenormalizer (camilledejoye) + * bug #38597 [PhpUnitBridge] Fix qualification of deprecations triggered by the debug class loader (fancyweb) + * bug #39160 [Console] Use a partial buffer in SymfonyStyle (jderusse) + * bug #39168 [Console] Fix console closing tag (jderusse) + * bug #39155 [VarDumper] fix casting resources turned into objects on PHP 8 (nicolas-grekas) + * bug #39131 [Cache] Fix CI because of Couchbase version (jderusse) + * bug #39115 [HttpClient] don't fallback to HTTP/1.1 when HTTP/2 streams break (nicolas-grekas) + * bug #33763 [Yaml] fix lexing nested sequences/mappings (xabbuh) + +* 5.2.0-RC2 (2020-11-21) + + * bug #39113 [DoctrineBridge] drop binary variants of UID types (nicolas-grekas) + * feature #39111 [Security] Update password upgrader listener to work with the new UserBadge (wouterj) + * bug #39083 [Dotenv] Check if method inheritEnvironmentVariables exists (Chi-teck) + * bug #39094 [Ldap] Fix undefined variable $con (derrabus) + * bug #39091 [Config] Recheck glob brace support after GlobResource was serialized (wouterj) + * bug #39092 Fix critical extension when reseting paged control (jderusse) + * bug #38614 [HttpFoundation] Fix for virtualhosts based on URL path (mvorisek) + * bug #39072 [FrameworkBundle] [Notifier] fix firebase transport factory DI tag type (xabbuh) + * bug #39070 [Validator] Remove IsinValidator's validator dependency (derrabus) + * bug #38387 [Validator] prevent hash collisions caused by reused object hashes (fancyweb, xabbuh) + * bug #38999 [DependencyInjection] autoconfigure behavior describing tags on decorators (xabbuh) + * bug #39058 [DependencyInjection] Fix circular detection with multiple paths (jderusse) + * bug #39059 [Filesystem] fix cleaning up tmp files when dumpFile() fails (nicolas-grekas) + +* 5.2.0-RC1 (2020-11-10) + + * bug #39004 [Messenger] Fix JSON deserialization of ErrorDetailsStamp and normalization of FlattenException::$statusText (Jean85) + * bug #38628 [DoctrineBridge] indexBy could reference to association columns (juanmiguelbesada) + * bug #39021 [DependencyInjection] Optimize circular collection by removing flattening (jderusse) + * bug #39031 [Ldap] Fix pagination (jderusse) + * bug #39038 [DoctrineBridge] also reset id readers (xabbuh) + * feature #39032 [Validator] Allow load mappings from attributes without doctrine/annotations (derrabus) + * feature #39022 [FrameworkBundle] Allow to use attribute-based configuration of routing/serializer without doctrine/annotations (derrabus) + * bug #39002 [Validator] Override the default option of the choice constraint (benji07) + * bug #39026 [Messenger] Fix DBAL deprecations in PostgreSqlConnection (chalasr) + * bug #39025 [DoctrineBridge] Fix DBAL deprecations in middlewares (derrabus) + * bug #38991 [Console] Fix ANSI when stdErr is not a tty (jderusse) + * bug #38980 [DependencyInjection] Fix circular reference with Factory + Lazy Iterrator (jderusse) + * bug #38986 [DoctrineBridge] accept converting Uid-as-strings to db-values (nicolas-grekas) + * feature #38850 [Messenger] Do not call getQueueUrl when the url is known in AmazonSqs transport (jderusse) + * feature #38940 [Messenger] Improve formatting of exception in failed message (Jeroen Noten) + * feature #38954 [HttpFundation][FrameworkBundle] Deprecate the HEADER_X_FORWARDED_ALL constant (jderusse) + * bug #38977 [HttpClient] Check status code before decoding content in TraceableResponse (chalasr) + * bug #38971 [PhpUnitBridge] fix replaying skipped tests (nicolas-grekas) + * bug #38910 [HttpKernel] Fix session initialized several times (jderusse) + * bug #38882 [DependencyInjection] Improve performances in CircualReference detection (jderusse) + * bug #38950 [Process] Dont test TTY if there is no TTY support (Nyholm) + * bug #38921 [PHPUnitBridge] Fixed crash on Windows with PHP 8 (villfa) + * feature #38919 [Console] Make error message more verbose (Nyholm) + * bug #38869 [SecurityBundle] inject only compatible token storage implementations for usage tracking (xabbuh) + * feature #38859 [HttpFoundation] Deprecate not passing a `Closure` together with `FILTER_CALLBACK` to `ParameterBag::filter()` (nicolas-grekas) + * bug #38894 [HttpKernel] Remove Symfony 3 compatibility code (derrabus) + * bug #38888 remove reflection-docblock from mime requirements (garak) + * bug #38895 [PhpUnitBridge] Fix wrong check for exporter in ConstraintTrait (alcaeus) + * bug #38879 [Cache] Fixed expiry could be int in ChainAdapter due to race conditions (phamviet) + * bug #38867 [FrameworkBundle] Fixing TranslationUpdateCommand failure when using "--no-backup" (liarco) + * bug #38856 [Cache] Add missing use statement (fabpot) + +* 5.2.0-BETA3 (2020-10-28) + + * bug #38845 [Console] Register signal handling only for commands implemeting SignalableCommandInterface (lyrixx) + * bug #38751 [Security] Move AbstractListener abstract methods to the new FirewallListenerInterface (chalasr) + * bug #38713 [DI] Fix Preloader exception when preloading a class with an unknown parent/interface (rgeraads) + * feature #38664 [RateLimiter] Moved classes implementing LimiterInterface to a new namespace (Nyholm) + * bug #38647 [HttpClient] relax auth bearer format requirements (xabbuh) + * bug #38675 [RateLimiter] Rename RateLimiter to RateLimiterFactory (Nyholm) + * bug #38699 [DependencyInjection] Preload classes with union types correctly (derrabus) + * feature #38688 [HttpClient] Add a Stopwatch on TraceableHttpClient (jderusse) + * bug #38669 [Serializer] fix decoding float XML attributes starting with 0 (Marcin Kruk) + * bug #38680 [PhpUnitBridge] Support new expect methods in test case polyfill (alcaeus) + * bug #38681 [PHPUnitBridge] Support PHPUnit 8 and PHPUnit 9 in constraint compatibility trait (alcaeus) + * bug #38686 [TwigBridge] Remove "transchoice" from the code base (nicolas-grekas) + * bug #38661 [RateLimiter] Fix delete method of the cache storage (GregOriol, Nyholm) + * bug #38678 [String] fix before/after[Last]() returning the empty string instead of the original one on non-match (nicolas-grekas) + * bug #38682 [HttpClient] never trace content of event-stream responses (nicolas-grekas) + * bug #38679 [PhpUnitBridge] Add missing exporter function for PHPUnit 7 (alcaeus) + * bug #38674 [RateLimiter] Make sure we actually can use sliding_window and no_limit (Nyholm) + * bug #38670 [RateLimiter] Be more type safe when fetching from cache (Nyholm) + * bug #38665 [RateLimiter] Allow configuration value "no_limit" (Nyholm) + * bug #38659 [String] fix slicing in UnicodeString (nicolas-grekas) + * bug #38633 [HttpClient] Fix decorating progress info in AsyncResponse (jderusse) + * feature #38543 [HttpKernel] add `kernel.runtime_environment` = `env(default:kernel.environment:APP_RUNTIME_ENV)` parameter (nicolas-grekas) + * bug #38595 [TwigBridge] do not translate null placeholders or titles (xabbuh) + * feature #38653 [DoctrineBridge] Enabled to use the UniqueEntity constraint as an attribute (derrabus) + * bug #38635 [Cache] Use correct expiry in ChainAdapter (Nyholm) + * bug #38652 [Filesystem] Check if failed unlink was caused by permission denied (Nyholm) + * bug #38645 [PropertyAccess] forward the caught exception (xabbuh) + * bug #38644 [FrameworkBundle] remove transport factory service when class does not exist (xabbuh) + * feature #38426 [HttpClient] Parameterize list of retryable methods (jderusse) + * feature #38608 [RateLimiter] rename Limit to RateLimit and add RateLimit::getLimit() (kbond) + * bug #38617 [Form] Add missing invalid_message translations (wouterj) + * bug #38612 [Messenger/Amqp] Allow setting option "login" in DSN (W0rma) + * bug #38618 [Messenger][Doctrine] Avoid early db access for pgsql detection (chalasr) + * bug #38623 [HttpFoundation][RateLimiter] fix RequestRateLimiterInterface::reset() (kbond) + * bug #38604 [DoctrineBridge] indexBy does not refer to attributes, but to column names (xabbuh) + * bug #38605 [DoctrinBridge] make Uid types stricter (nicolas-grekas) + * bug #38606 [WebProfilerBundle] Hide debug toolbar in print view (jt2k) + * bug #38602 [Console] Fix signal management (chalasr) + * bug #38600 [DoctrineBridge] Convert values to Rfc4122 before inserting them into the database (Kai) + * feature #38562 [RateLimiter] Added reserve() to LimiterInterface and rename Limiter to RateLimiter (wouterj) + * feature #38593 [Lock][Semaphore] Add Factory::createFromKey and deprecate lock.store services (jderusse) + * feature #38587 [HttpClient] added `extra.trace_content` option to `TraceableHttpClient` to prevent it from keeping the content in memory (nicolas-grekas) + * bug #38580 [FrameworkBundle] fix config declaration of http_cache option (nicolas-grekas) + * bug #38589 [Console] Don't register signal handlers if pcntl is disabled (chalasr) + * bug #38581 [Semaphore] Reset Key lifetime time before we acquire it (jderusse) + * bug #38582 [DI] Fix Reflection file name with eval()\'d code (maxime-aknin) + * feature #38565 [RateLimiter] Adding SlidingWindow algorithm (Nyholm) + * feature #38576 Deeprecate lock service (jderusse) + * bug #38578 Add missing use statement (jderusse) + * bug #38516 [HttpFoundation] Fix Range Requests (BattleRattle) + +* 5.2.0-BETA2 (2020-10-14) + + * feature #38552 [Security][Notifier] Added integration of Login Link with the Notifier component (wouterj) + * bug #38566 Fix minor issue when sharing windows between Limiters (Nyholm) + * feature #38563 [Messenger][Redis] Adding support for lazy connect (Nyholm) + * bug #38553 [Lock] Reset Key lifetime time before we acquire it (Nyholm) + * bug #38559 [Lock] Reset lifetime on acquireRead() (Nyholm) + * bug #38548 [FrameworkBundle] Bugfixes in buildDir in the CacheClear command (Nyholm) + * bug #38551 Remove content-type check on toArray methods (jderusse) + * feature #38550 [Security] Added check_post_only to the login link authenticator (wouterj) + * bug #38546 [String] fix "is too large" ValueError on PHP 8 (nicolas-grekas) + * bug #38544 [DI] fix dumping env vars (nicolas-grekas) + * feature #38532 [HttpClient] simplify retry mechanism around RetryStrategyInterface (nicolas-grekas) + * bug #38533 [TwigBridge] Fix preload hint and remove "unlinked class class@anonymous" warning (burned42) + * bug #38528 [Security] Making login link signature_properties option required (weaverryan) + * feature #38525 [Serializer] Enabled mapping configuration via attributes (derrabus) + * feature #38522 [Notifier ] Add Discord notifier (mpiot, connorhu) + * bug #38477 [Form] fix ViolationMapper was always generating a localized label for each FormType (romaricdrigon) + * bug #38529 [Mailer] Fix mailjet image embedding (Sandldan) + * bug #38530 [HttpClient] fix reading the body after a ClientException (nicolas-grekas) + * bug #38523 [HttpClient] Fix multiple timeout with multiple retry (jderusse) + * bug #38520 [HttpClient] Fix nesteed stream in AsyncResponse (jderusse) + * bug #38518 [HttpClient] fix decorating timeout errors (nicolas-grekas) + * feature #38499 [Validator] Upgraded constraints to enable named arguments and attributes (derrabus) + * feature #38505 [Security][Login Link] Allow null and DateTime objects to be used as signatureProperties (wouterj) + * bug #38507 [Bug] Fix RateLimiter framework configuration (bobvandevijver) + * bug #38510 [PropertyInfo] Support for the mixed type (derrabus) + * bug #38493 [HttpClient] Fix CurlHttpClient memory leak (HypeMC) + * feature #38484 [Messenger] Add DelayStamp::delayFor() and DelayStamp::delayUntil() (Nyholm) + * bug #38476 [HttpClient] Fix missing abstract arg (jderusse) + * feature #37733 [PhpUnitBridge] Add ability to set a baseline for deprecation testing (alexpott) + * bug #38456 [Cache] skip igbinary < 3.1.6 (nicolas-grekas) + * bug #38453 [lock] Mark Key unserializable whith PgsqlStore (jderusse) + * bug #38452 [SecurityBundle] Make user lazy loading working without user provider (tyx) + * bug #38455 [Form] Fix field_value Twig helper for multiple choices (tgalopin) + * bug #38392 [Ldap] Bypass the use of `ldap_control_paged_result` on PHP >= 7.3 (lucasaba) + * feature #38434 [HttpClient] Add jitter to RetryBackoff (jderusse) + * feature #38346 [lock] Add store dedicated to postgresql (jderusse) + * bug #38444 [PhpUnitBridge] fix running parallel tests with phpunit 9 (nicolas-grekas) + * bug #38446 [PropertyInfo] Extract from default value doesn't set collection boolean (Korbeil) + * feature #38424 [Translation] Rename Translatable class to TranslatableMessage (natewiebe13) + * bug #38442 [VarDumper] fix truncating big arrays (nicolas-grekas) + * bug #38433 [Mime] Fix serialization of RawMessage (gilbertsoft) + * bug #38422 [SecurityGuard] Implement PostAuthenticationGuardToken::getFirewallName() (derrabus) + * feature #38393 [FrameworkBundle] Add option --as-tree to translation:update command (jschaedl) + * bug #38419 [DoctrineBridge] fix and replace namespace to Uid (maxhelias) + * feature #38410 [Validator] Migrate File and Image constraints to attributes (derrabus) + * bug #38418 [HttpClient] minor fixes in RetryableHttpClient (nicolas-grekas) + * feature #38253 [Cache] Allow ISO 8601 time intervals to specify default lifetime (lstrojny) + +* 5.2.0-BETA1 (2020-10-05) + + * feature #38382 [Validator] Use comparison constraints as attributes (derrabus) + * feature #38369 [HttpFoundation] Expired cookies string representation consistency & tests (iquito) + * feature #38407 [Mime] Prefer .jpg instead of .jpeg (fabpot) + * feature #36479 [Notifier][WebProfilerBundle][FrameworkBundle] Add notifier section to profiler (jschaedl) + * feature #38395 [lock] Prevent user serializing the key when store does not support it. (jderusse) + * feature #38307 [Form] Implement Twig helpers to get field variables (tgalopin) + * feature #38177 [Security] Magic login link authentication (weaverryan) + * feature #38224 [HttpFoundation] Add Request::toArray() for JSON content (Nyholm) + * feature #38323 [Mime] Allow multiple parts with the same name in FormDataPart (HypeMC) + * feature #38354 [RateLimiter] add Limit::ensureAccepted() which throws RateLimitExceededException if not accepted (kbond) + * feature #32904 [Messenger] Added ErrorDetailsStamp (TimoBakx) + * feature #36152 [Messenger] dispatch event when a message is retried (nikophil) + * feature #38361 Can define ChatMessage transport to null (odolbeau) + * feature #38289 [HttpClient] provide response body to the RetryDecider (jderusse) + * feature #38308 [Security][RateLimiter] Added request rate limiter to prevent breadth-first attacks (wouterj) + * feature #38257 [RateLimiter] Add limit object on RateLimiter consume method (Valentin, vasilvestre) + * feature #38309 [Validator] Constraints as php 8 Attributes (derrabus) + * feature #38332 [Validator] Add support for UUIDv6 in Uuid constraint (nicolas-grekas) + * feature #38330 [Contracts] add TranslatableInterface (nicolas-grekas) + * feature #38322 [Validator] Add Ulid constraint and validator (Laurent Clouet) + * feature #38333 [Uid] make UUIDv6 always return truly random nodes to prevent leaking the MAC of the host (nicolas-grekas) + * feature #38296 [lock] Provides default implementation when store does not supports the behavior (jderusse) + * feature #38298 [Notifier] Add Sendinblue notifier. (ptondereau) + * feature #38305 [PhpUnitBridge] Enable a maximum PHPUnit version to be set via SYMFONY_MAX_PHPUNIT_VERSION (stevegrunwell) + * feature #38288 [DomCrawler] Add `assertFormValue()` in `WebTestCase` (mnapoli) + * feature #38287 [DomCrawler] Add checkbox assertions for functional tests (mnapoli) + * feature #36326 [Validator] Add invalid datetime message in Range validator (przemyslaw-bogusz) + * feature #38243 [HttpKernel] Auto-register kernel as an extension (HypeMC) + * feature #38277 [Mailer] Added Sendinblue bridge (drixs6o9) + * feature #35956 [Form] Added "html5" option to both MoneyType and PercentType (romaricdrigon) + * feature #38269 [String] allow passing null to string functions (kbond) + * feature #38176 [Config] Adding the "info" to a missing option error messages (weaverryan) + * feature #38167 [VarDumper] Support for ReflectionAttribute (derrabus) + * feature #35740 [MonologBridge] Use composition instead of inheritance in monolog bridge (pvgnd, mm-pvgnd) + * feature #38182 [HttpClient] Added RetryHttpClient (jderusse) + * feature #38204 [Security] Added login throttling feature (wouterj) + * feature #38007 [Amqp] Add amqps support (vasilvestre-OS) + * feature #37546 [RFC] Introduce a RateLimiter component (wouterj) + * feature #38193 Make RetryTillSaveStore implements the SharedLockStoreInterface (jderusse) + * feature #37968 [Form] Add new way of mapping data using callback functions (yceruto) + * feature #38198 [String] allow translit rules to be given as closure (nicolas-grekas) + * feature #37829 [RFC][HttpKernel][Security] Allowed adding attributes on controller arguments that will be passed to argument resolvers. (jvasseur) + * feature #37752 [RFC][lock] Introduce Shared Lock (or Read/Write Lock) (jderusse) + * feature #37759 [Messenger] - Add option to confirm message delivery in Amqp connection (scyzoryck) + * feature #30572 [Cache] add integration with Messenger to allow computing cached values in a worker (nicolas-grekas) + * feature #38149 [SecurityBundle] Comma separated ips for security.access_control (a-menshchikov) + * feature #38151 [Serializer] add UidNormalizer (guillbdx, norkunas) + * feature #37976 [Messenger] Don't prevent dispatch out of another bus (ogizanagi) + * feature #38134 [Lock] Fix wrong interface for MongoDbStore (jderusse) + * feature #38135 [AmazonSqsMessenger] Added the count message awareness on the transport (raphahardt) + * feature #38026 [HttpClient] Allow to provide additional curl options to CurlHttpClient (pizzaminded) + * feature #37559 [PropertyInfo] fix array types with keys (array) (digilist) + * feature #37519 [Process] allow setting options esp. "create_new_console" to detach a subprocess (andrei0x309) + * feature #37704 [MonologBridge] Added SwitchUserTokenProcessor to log the impersonator (IgorTimoshenko) + * feature #37545 [DependencyInjection] Add the Required attribute (derrabus) + * feature #37474 [RFC][Routing] Added the Route attribute (derrabus) + * feature #38068 [Notifier] Register NotificationDataCollector and NotificationLoggerListener service (jschaedl) + * feature #32841 Create impersonation_exit_path() and *_url() functions (dFayet) + * feature #37706 [Validator] Debug validator command (loic425, fabpot) + * feature #38052 Increase HttpBrowser::getHeaders() visibility to protected (iansltx) + * feature #36727 [Messenger] Add option to prevent Redis from deleting messages on rejection (Steveb-p) + * feature #37678 [DoctrineBridge] Ulid and Uuid as Doctrine Types (gennadigennadigennadi) + * feature #38037 Translate failure messages of json authentication (Malte Schlüter) + * feature #35890 [Cache] give control over cache prefix seed (Tobion) + * feature #37337 [Security] Configurable execution order for firewall listeners (scheb) + * feature #33850 [Serializer] fix denormalization of basic property-types in XML and CSV (mkrauser) + * feature #38017 [PHPUnitBridge] deprecations not disabled anymore when disabled=0 (l-vo) + * feature #33381 [Form] dispatch submit events for disabled forms too (xabbuh) + * feature #35338 Added support for using the "{{ label }}" placeholder in constraint messages (a-menshchikov) + * feature #34790 [Console] Remove restriction for choices to be strings (LordZardeck, YaFou, ogizanagi) + * feature #37979 [Workflow] Expose the Metadata Store in the DIC (lyrixx) + * feature #37371 [Translation] Add support for calling 'trans' with ICU formatted messages (someonewithpc) + * feature #37670 [Translation] Translatable objects (natewiebe13) + * feature #37432 [Mailer] Implement additional mailer transport options (fritzmg) + * feature #35893 [HttpClient][DI] Add an option to use the MockClient in functional tests (GaryPEGEOT) + * feature #35780 [Semaphore] Added the component (lyrixx) + * feature #37846 [Security] Lazily load the user during the check passport event (wouterj) + * feature #37934 [Mailer] Mailjet Add ability to pass custom headers to API (tcheymol) + * feature #37942 [Security] Renamed provider key to firewall name (wouterj) + * feature #37951 [FrameworkBundle] Make AbstractPhpFileCacheWarmer public (ossinkine) + * feature #30335 [PropertyInfo] ConstructorExtractor which has higher priority than PhpDocExtractor and ReflectionExtractor (karser) + * feature #37926 [lock] Lazy create table in lock PDO store (jderusse) + * feature #36573 [Notifier] Add Esendex bridge (odolbeau) + * feature #33540 [Serializer] Add special '*' serialization group that allows any group (nrobinaubertin) + * feature #37708 Allow Drupal to wrap the Symfony test listener (alexpott) + * feature #36211 [Serializer] Adds FormErrorNormalizer (YaFou) + * feature #37087 [Messenger] Add FlattenException Normalizer (monteiro) + * feature #37917 [Security] Pass Passport to LoginFailureEvent (ihmels) + * feature #37734 [HttpFoundation] add support for X_FORWARDED_PREFIX header (jeff1985) + * feature #37897 [Mailer] Support Amazon SES ConfigurationSetName (cvmiert) + * feature #37915 Improve link script with rollback when using symlink (noniagriconomie) + * feature #37889 Toolbar toggler accessibility (Chi-teck) + * feature #36515 [HttpKernel] Add `$kernel->getBuildDir()` to separate it from the cache directory (mnapoli) + * feature #32133 [PropertyAccess] Allow to disable magic __get & __set (ogizanagi) + * feature #36016 [Translation] Add a pseudo localization translator (fancyweb) + * feature #37755 Fix #37740: Cast all Request parameter values to string (rgeraads) + * feature #36541 ✨ [Mailer] Add Mailjet bridge (tcheymol) + * feature #36940 [Notifier] add support for smsapi-notifier (szepczynski) + * feature #37830 [Notifier] Add LinkedIn provider (ismail1432) + * feature #37867 [Messenger] Add message timestamp to amqp connection (Bartłomiej Zając) + * feature #36925 [Security] Verifying if the password field is null (Mbechezi Nawo) + * feature #37847 [Serializer][Mime] Fix Mime message serialization (fabpot) + * feature #37338 [Console] added TableCellStyle (khoptynskyi) + * feature #37840 [VarDumper] Support PHPUnit --colors option (ogizanagi) + * feature #37138 [Notifier][Slack] Use Slack Web API chat.postMessage instead of WebHooks (xavierbriand) + * feature #37827 [Console] Rework the signal integration (lyrixx) + * feature #36131 [Mailer] Add a transport that uses php.ini settings for configuration (l-vo) + * feature #36596 Add cache.adapter.redis_tag_aware to use RedisCacheAwareAdapter (l-vo) + * feature #36582 [Messenger] Add Beanstalkd bridge (X-Coder264) + * feature #35967 [VarDumper] Add VAR_DUMPER_FORMAT=server format (ogizanagi) + * feature #37815 [Workflow] Choose which Workflow events should be dispatched (stewartmalik, lyrixx) + * feature #20054 [Console] Different approach on merging application definition (ro0NL) + * feature #36648 [Notifier] Add Mobyt bridge (Deamon) + * feature #37332 [FrameworkBundle] Allow to leverage autoconfiguration for DataCollectors with template (l-vo) + * feature #37359 [Security] Add event to inspect authenticated token before it becomes effective (scheb) + * feature #37539 [Workflow] Added Context to Workflow Event (epitre) + * feature #37683 [Console] allow multiline responses to console questions (ramsey) + * feature #29117 [Serializer] Add CompiledClassMetadataFactory (fbourigault) + * feature #37676 [Stopwatch] Add name property to the stopwatchEvent (AhmedRaafat14) + * feature #34704 [Messenger] Add method HandlerFailedException::getNestedExceptionOfClass (tyx) + * feature #37793 Revert "[DependencyInjection] Resolve parameters in tag arguments" (rpkamp) + * feature #37537 [HttpKernel] Provide status code in fragment handler exception (gonzalovilaseca) + * feature #36480 [Notifier] Add Infobip bridge (jeremyFreeAgent) + * feature #36496 [Notifier] added telegram options (krasilnikovm) + * feature #37754 [FrameworkBundle] Add days before expiration in "about" command (noniagriconomie) + * feature #35773 [Notifier] Change notifier recipient handling (jschaedl) + * feature #36488 [Notifier] Add Google Chat bridge (GromNaN) + * feature #36692 [HttpClient] add EventSourceHttpClient to consume Server-Sent Events (soyuka) + * feature #36616 [Notifier] Add Zulip notifier bridge (phpfour) + * feature #37747 [Notifier] Make Freemobile config more flexible (fabpot) + * feature #37718 [Security] class Security implements AuthorizationCheckerInterface (SimonHeimberg) + * feature #37732 [Console] Allow testing single command apps using CommandTester (chalasr) + * feature #37480 [Messenger] add redeliveredAt in RedeliveryStamp construct (qkdreyer) + * feature #37565 [Validator] Add Isin validator constraint (lmasforne) + * feature #37712 [Mailer] Prevent MessageLoggerListener from leaking in env=prod (vudaltsov) + * feature #33729 [Console] Add signal event (marie) + * feature #36352 [Validator] Added support for cascade validation on typed properties (HeahDude) + * feature #37243 [DependencyInjection] Resolve parameters in tag arguments (rpkamp) + * feature #37415 [Console] added info method to symfony style (titospeakap, titomiguelcosta) + * feature #36691 [FrameworkBundle] Deprecate some public services to private (fancyweb) + * feature #36929 Added a FrenchInflector for the String component (Alexandre-T) + * feature #37620 [Security] Use NullToken while checking authorization (wouterj) + * feature #37711 [Router] allow to use \A and \z as regex start and end (zlodes) + * feature #37703 Update StopwatchPeriod.php (ThomasLandauer) + * feature #37696 [Routing] Allow inline definition of requirements and defaults for host (julienfalque) + * feature #37567 [PhpUnitBridge] Polyfill new phpunit 9.1 assertions (phpfour) + * feature #37479 [HttpFoundation] Added File::getContent() (lyrixx) + * feature #36178 [Mime] allow non-ASCII characters in local part of email (dmaicher) + * feature #30931 [Form] Improve invalid messages for form types (hiddewie) + * feature #37492 [ErrorHandler] Allow override of the default non-debug template (PhilETaylor) + * feature #37482 [HttpClient] always yield a LastChunk in AsyncResponse on destruction (nicolas-grekas) + * feature #36364 [HttpKernel][WebProfilerBundle] Add session profiling (mtarld) + * feature #37428 [Workflow] Added Function (and Twig extension) to retrieve a specific transition (Carlos Pereira De Amorim) + * feature #36487 [HttpClient] Add MockResponse::getRequestMethod() and getRequestUrl() to allow inspecting which request has been sent (javespi) + * feature #37295 Move event alias mappings to their components (derrabus) + * feature #37443 [HttpClient] add StreamableInterface to ease turning responses into PHP streams (nicolas-grekas) + * feature #36739 [TwigBundle] Deprecate the public "twig" service to private (fancyweb) + * feature #37272 [HttpFoundation] add `HeaderUtils::parseQuery()`: it does the same as `parse_str()` but preserves dots in variable names (nicolas-grekas) + * feature #37403 [Notifier] Return SentMessage from the Notifier message handler (fabpot) + * feature #36611 Add Notifier SentMessage (jeremyFreeAgent) + * feature #37357 [FrameworkBundle] allow configuring trusted proxies using semantic configuration (nicolas-grekas) + * feature #37373 [DI] deprecate Definition/Alias::setPrivate() (nicolas-grekas) + * feature #37351 [FrameworkBundle] allow enabling the HTTP cache using semantic configuration (nicolas-grekas) + * feature #37306 [Messenger] added support for Amazon SQS QueueUrl as DSN (starred-gijs) + * feature #37336 [Security] Let security factories add firewall listeners (scheb) + * feature #37318 [Security] Add attributes on Passport (fabpot) + * feature #37241 [Console] Fix Docblock for CommandTester::getExitCode (Jean85) + * feature #35834 [Notifier] Remove default transport property in Transports class (jschaedl) + * feature #37198 [FrameworkBundle] Add support for tagged_iterator/tagged_locator in unused tags util (fabpot) + * feature #37165 [Mime] Add DKIM support (fabpot) + * feature #36778 Use PHP instead of XML as the prefered service/route configuration in core (fabpot) + * feature #36802 [Console] Add support for true colors (fabpot) + * feature #36775 [DependencyInjection] Add abstract_arg() and param() (fabpot) + * feature #37040 [PropertyInfo] Support using the SerializerExtractor with no group check (GuilhemN) + * feature #37175 [Mime] Deprecate Address::fromString() (fabpot) + * feature #37114 Provides a way to override cache and log folders from the ENV (Plopix) + * feature #36736 [FrameworkBundle][Mailer] Add a way to configure some email headers from semantic configuration (fabpot) + * feature #37136 [HttpClient] added support for pausing responses with a new `pause_handler` callable exposed as an info item (nicolas-grekas) + * feature #36779 [HttpClient] add AsyncDecoratorTrait to ease processing responses without breaking async (nicolas-grekas) + * feature #36790 Bump Doctrine DBAL to 2.10+ (fabpot) + * feature #36818 [Validator] deprecate the "allowEmptyString" option (xabbuh) + diff --git a/README.md b/README.md index bddcd21f97762..d3f5b5588d75a 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Documentation * Read the [Getting Started guide][7] if you are new to Symfony. * Try the [Symfony Demo application][23] to learn Symfony in practice. +* Discover Symfony ecosystem in detail with [Symfony The Fast Track][26]. * Master Symfony with the [Guides and Tutorials][8], the [Components docs][9] and the [Best Practices][10] reference. @@ -74,3 +75,4 @@ Symfony development is sponsored by [SensioLabs][21], led by the [23]: https://github.com/symfony/symfony-demo [24]: https://symfony.com/coc [25]: https://symfony.com/doc/current/contributing/code_of_conduct/care_team.html +[26]: https://symfony.com/book diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md deleted file mode 100644 index a7e49d469c502..0000000000000 --- a/UPGRADE-4.0.md +++ /dev/null @@ -1,1143 +0,0 @@ -UPGRADE FROM 3.x to 4.0 -======================= - -Symfony Framework ------------------ - -The first step to upgrade a Symfony 3.x application to 4.x is to update the -file and directory structure of your application: - -| Symfony 3.x | Symfony 4.x -| ----------------------------------- | -------------------------------- -| `app/config/` | `config/` -| `app/config/*.yml` | `config/*.yaml` and `config/packages/*.yaml` -| `app/config/parameters.yml.dist` | `config/services.yaml` and `.env.dist` -| `app/config/parameters.yml` | `config/services.yaml` and `.env` -| `app/Resources//views/` | `templates/bundles//` -| `app/Resources/` | `src/Resources/` -| `app/Resources/assets/` | `assets/` -| `app/Resources/translations/` | `translations/` -| `app/Resources/views/` | `templates/` -| `src/AppBundle/` | `src/` -| `var/logs/` | `var/log/` -| `web/` | `public/` -| `web/app.php` | `public/index.php` -| `web/app_dev.php` | `public/index.php` - -Then, upgrade the contents of your console script and your front controller: - -* `bin/console`: https://github.com/symfony/recipes/blob/master/symfony/console/4.4/bin/console -* `public/index.php`: https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/4.4/public/index.php - -Lastly, read the following article to add Symfony Flex to your application and -upgrade the configuration files: https://symfony.com/doc/current/setup/flex.html - -If you use Symfony components instead of the whole framework, you can find below -the upgrading instructions for each individual bundle and component. - -ClassLoader ------------ - - * The component has been removed. Use Composer instead. - -Config ------- - - * The protected `TreeBuilder::$builder` property has been removed. - -Console -------- - - * Setting unknown style options is not supported anymore and throws an - exception. - - * The `QuestionHelper::setInputStream()` method is removed. Use - `StreamableInputInterface::setStream()` or `CommandTester::setInputs()` - instead. - - Before: - - ```php - $input = new ArrayInput(); - - $questionHelper->setInputStream($stream); - $questionHelper->ask($input, $output, $question); - ``` - - After: - - ```php - $input = new ArrayInput(); - $input->setStream($stream); - - $questionHelper->ask($input, $output, $question); - ``` - - Before: - - ```php - $commandTester = new CommandTester($command); - - $stream = fopen('php://memory', 'r+', false); - fputs($stream, "AppBundle\nYes"); - rewind($stream); - - $command->getHelper('question')->setInputStream($stream); - - $commandTester->execute(); - ``` - - After: - - ```php - $commandTester = new CommandTester($command); - - $commandTester->setInputs(['AppBundle', 'Yes']); - - $commandTester->execute(); - ``` - - * The `console.exception` event and the related `ConsoleExceptionEvent` class have - been removed in favor of the `console.error` event and the `ConsoleErrorEvent` class. - - * The `SymfonyQuestionHelper::ask` default validation has been removed in favor of `Question::setValidator`. - -Debug ------ - - - * The `ContextErrorException` class has been removed. Use `\ErrorException` instead. - - * `FlattenException::getTrace()` now returns additional type descriptions - `integer` and `float`. - - * Support for stacked errors in the `ErrorHandler` has been removed - -DependencyInjection -------------------- - - * Definitions and aliases are now private by default in 4.0. You should either use service injection - or explicitly define your services as public if you really need to inject the container. - - * Relying on service auto-registration while autowiring is not supported anymore. - Explicitly inject your dependencies or create services whose ids are - their fully-qualified class name. - - Before: - - ```php - namespace App\Controller; - - use App\Mailer; - - class DefaultController - { - public function __construct(Mailer $mailer) { - // ... - } - - // ... - } - ``` - ```yml - services: - App\Controller\DefaultController: - autowire: true - ``` - - After: - - ```php - // same PHP code - ``` - ```yml - services: - App\Controller\DefaultController: - autowire: true - - # or - # App\Controller\DefaultController: - # arguments: { $mailer: "@App\Mailer" } - - App\Mailer: - autowire: true - ``` - - * Autowiring services based on the types they implement is not supported anymore. - It will only look for an alias or a service id that matches a given FQCN. - Rename (or alias) your services to their FQCN id to make them autowirable. - In 3.4, you can activate this behavior instead of having deprecation messages - by setting the following parameter: - - ```yml - parameters: - container.autowiring.strict_mode: true - ``` - - From 4.0, you can remove it as it's the default behavior and the parameter is not handled anymore. - - * `_defaults` and `_instanceof` are now reserved service names in Yaml configurations. Please rename any services with that names. - - * Non-numeric keys in methods and constructors arguments have never been supported and are now forbidden. Please remove them if you happen to have one. - - * Service names that start with an underscore are now reserved in Yaml files. Please rename any services with such names. - - * Autowiring-types have been removed, use aliases instead. - - Before: - - ```xml - - Doctrine\Common\Annotations\Reader - - ``` - - After: - - ```xml - - - ``` - - * Service identifiers and parameter names are now case sensitive. - - * The `Reference` and `Alias` classes do not make service identifiers lowercase anymore. - - * Using the `PhpDumper` with an uncompiled `ContainerBuilder` is not supported - anymore. - - * Extending the containers generated by `PhpDumper` is not supported - anymore. - - * The `DefinitionDecorator` class has been removed. Use the `ChildDefinition` - class instead. - - * The `ResolveDefinitionTemplatesPass` class has been removed. - Use the `ResolveChildDefinitionsPass` class instead. - - * Using unsupported configuration keys in YAML configuration files raises an - exception. - - * Using unsupported options to configure service aliases raises an exception. - - * Setting or unsetting a service with the `Container::set()` method is - no longer supported. Only synthetic services can be set or unset. - - * Checking the existence of a private service with the `Container::has()` - method is no longer supported and will return `false`. - - * Requesting a private service with the `Container::get()` method is no longer - supported. - - * The ``strict`` attribute in service arguments has been removed. - The attribute is ignored since 3.0, you can remove it. - - * Top-level anonymous services in XML are no longer supported. - - * The `ExtensionCompilerPass` has been moved to before-optimization passes with priority -1000. - - * In 3.4, parameter `container.dumper.inline_class_loader` was introduced. Unless - you're using a custom autoloader, you should enable this parameter. This can - drastically improve DX by reducing the time to load classes when the `DebugClassLoader` - is enabled. If you're using `FrameworkBundle`, this performance improvement will - also impact the "dev" environment: - - ```yml - parameters: - container.dumper.inline_class_loader: true - ``` - -DoctrineBridge --------------- - - * The `Symfony\Bridge\Doctrine\HttpFoundation\DbalSessionHandler` and - `Symfony\Bridge\Doctrine\HttpFoundation\DbalSessionHandlerSchema` have been removed. Use - `Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler` instead. - -EventDispatcher ---------------- - - * The `ContainerAwareEventDispatcher` class has been removed. - Use `EventDispatcher` with closure factories instead. - - * The `reset()` method has been added to `TraceableEventDispatcherInterface`. - -ExpressionLanguage ------------------- - - * The ability to pass a `ParserCacheInterface` instance to the `ExpressionLanguage` - class has been removed. You should use the `CacheItemPoolInterface` interface - instead. - -Filesystem ----------- - - * The `Symfony\Component\Filesystem\LockHandler` has been removed, - use the `Symfony\Component\Lock\Store\FlockStore` class - or the `Symfony\Component\Lock\Store\FlockStore\SemaphoreStore` class directly instead. - * Support for passing relative paths to `Filesystem::makePathRelative()` has been removed. - -Finder ------- - - * The `ExceptionInterface` has been removed. - * The `Symfony\Component\Finder\Iterator\FilterIterator` class has been - removed as it used to fix a bug which existed before version 5.5.23/5.6.7 - -Form ----- - - * The values of the `FormEvents::*` constants have been updated to match the - constant names. You should only update your application if you relied on the - constant values instead of their names. - - * The `choices_as_values` option of the `ChoiceType` has been removed. - - * Support for data objects that implements both `Traversable` and - `ArrayAccess` in `ResizeFormListener::preSubmit` method has been removed. - - * Using callable strings as choice options in ChoiceType is not supported - anymore. - - Before: - - ```php - 'choice_label' => 'strtoupper', - ``` - - After: - - ```php - 'choice_label' => function ($choice) { - return strtoupper($choice); - }, - ``` - - * Caching of the loaded `ChoiceListInterface` in the `LazyChoiceList` has been removed, - it must be cached in the `ChoiceLoaderInterface` implementation instead. - - * Calling `isValid()` on a `Form` instance before submitting it is not supported - anymore and raises an exception. - - Before: - - ```php - if ($form->isValid()) { - // ... - } - ``` - - After: - - ```php - if ($form->isSubmitted() && $form->isValid()) { - // ... - } - ``` - - * Using the "choices" option in ``CountryType``, ``CurrencyType``, ``LanguageType``, - ``LocaleType``, and ``TimezoneType`` without overriding the ``choice_loader`` - option is now ignored. - - Before: - ```php - $builder->add('custom_locales', LocaleType::class, [ - 'choices' => $availableLocales, - ]); - ``` - - After: - ```php - $builder->add('custom_locales', LocaleType::class, [ - 'choices' => $availableLocales, - 'choice_loader' => null, - ]); - // or - $builder->add('custom_locales', LocaleType::class, [ - 'choice_loader' => new CallbackChoiceLoader(function () { - return $this->getAvailableLocales(); - }), - ]); - ``` - - * Removed `ChoiceLoaderInterface` implementation in `TimezoneType`. Use the "choice_loader" option instead. - - Before: - ```php - class MyTimezoneType extends TimezoneType - { - public function loadChoiceList() - { - // override the method - } - } - ``` - - After: - ```php - class MyTimezoneType extends AbstractType - { - public function getParent() - { - return TimezoneType::class; - } - - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefault('choice_loader', ...); // override the option instead - } - } - ``` - - * `FormRendererInterface::setTheme` and `FormRendererEngineInterface::setTheme` have a new optional argument `$useDefaultThemes` with a default value set to `true`. - -FrameworkBundle ---------------- - - * The `session.use_strict_mode` option has been removed and strict mode is always enabled. - - * The `validator.mapping.cache.doctrine.apc` service has been removed. - - * The "framework.trusted_proxies" configuration option and the corresponding "kernel.trusted_proxies" parameter have been removed. Use the `Request::setTrustedProxies()` method in your front controller instead. - - * The default value of the `framework.workflows.[name].type` configuration options is now `state_machine`. - - * Support for absolute template paths has been removed. - - * The following form types registered as services have been removed; use their - fully-qualified class name instead: - - - `"form.type.birthday"` - - `"form.type.checkbox"` - - `"form.type.collection"` - - `"form.type.country"` - - `"form.type.currency"` - - `"form.type.date"` - - `"form.type.datetime"` - - `"form.type.email"` - - `"form.type.file"` - - `"form.type.hidden"` - - `"form.type.integer"` - - `"form.type.language"` - - `"form.type.locale"` - - `"form.type.money"` - - `"form.type.number"` - - `"form.type.password"` - - `"form.type.percent"` - - `"form.type.radio"` - - `"form.type.range"` - - `"form.type.repeated"` - - `"form.type.search"` - - `"form.type.textarea"` - - `"form.type.text"` - - `"form.type.time"` - - `"form.type.timezone"` - - `"form.type.url"` - - `"form.type.button"` - - `"form.type.submit"` - - `"form.type.reset"` - - * The `framework.serializer.cache` option and the services - `serializer.mapping.cache.apc` and `serializer.mapping.cache.doctrine.apc` - have been removed. APCu should now be automatically used when available. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDumpPass` has been removed. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass` has been removed. - Use `Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass` instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SerializerPass` class has been removed. - Use the `Symfony\Component\Serializer\DependencyInjection\SerializerPass` class instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass` class has been - removed. Use the `Symfony\Component\Form\DependencyInjection\FormPass` class instead. - - * The `Symfony\Bundle\FrameworkBundle\EventListener\SessionListener` class has been removed. - Use the `Symfony\Component\HttpKernel\EventListener\SessionListener` class instead. - - * The `Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListener` class has been - removed. Use the `Symfony\Component\HttpKernel\EventListener\TestSessionListener` - class instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConfigCachePass` class has been removed. - Use tagged iterator arguments instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass` class has been - removed. Use the `Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass` - class instead. - - * Class parameters related to routing have been removed - * router.options.generator_class - * router.options.generator_base_class - * router.options.generator_dumper_class - * router.options.matcher_class - * router.options.matcher_base_class - * router.options.matcher_dumper_class - * router.options.matcher.cache_class - * router.options.generator.cache_class - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ControllerArgumentValueResolverPass` class - has been removed. Use the `Symfony\Component\HttpKernel\DependencyInjection\ControllerArgumentValueResolverPass` - class instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RoutingResolverPass` - class has been removed. Use the - `Symfony\Component\Routing\DependencyInjection\RoutingResolverPass` class instead. - - * The `Symfony\Bundle\FrameworkBundle\Translation\Translator` constructor now takes the - default locale as mandatory 3rd argument. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass` class has been - removed. Use the `Symfony\Component\Validator\DependencyInjection\AddValidatorInitializersPass` - class instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass` class has been - removed. Use the `Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass` - class instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ValidateWorkflowsPass` class - has been removed. Use the `Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass` - class instead. - - * Using the `KERNEL_DIR` environment variable and the automatic guessing based - on the `phpunit.xml` file location have been removed from the `KernelTestCase::getKernelClass()` - method implementation. Set the `KERNEL_CLASS` environment variable to the - fully-qualified class name of your Kernel or override the `KernelTestCase::createKernel()` - or `KernelTestCase::getKernelClass()` method instead. - - * The methods `KernelTestCase::getPhpUnitXmlDir()` and `KernelTestCase::getPhpUnitCliConfigArgument()` - have been removed. - - * The `Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory` class has been removed. - Use `Symfony\Component\Validator\ContainerConstraintValidatorFactory` instead. - - * The `--no-prefix` option of the `translation:update` command has - been removed. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheClearerPass` class has been removed. - Use tagged iterator arguments instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass` class has been removed. - Use tagged iterator arguments instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationDumperPass` - class has been removed. Use the - `Symfony\Component\Translation\DependencyInjection\TranslationDumperPass` class instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationExtractorPass` - class has been removed. Use the - `Symfony\Component\Translation\DependencyInjection\TranslationExtractorPass` class instead. - - * The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass` - class has been removed. Use the - `Symfony\Component\Translation\DependencyInjection\TranslatorPass` class instead. - - * The `Symfony\Bundle\FrameworkBundle\Translation\TranslationLoader` - class has been deprecated and will be removed in 4.0. Use the - `Symfony\Component\Translation\Reader\TranslationReader` class instead. - - * The `translation.loader` service has been removed. - Use the `translation.reader` service instead. - - * `AssetsInstallCommand::__construct()` now requires an instance of - `Symfony\Component\Filesystem\Filesystem` as first argument. - - * `CacheClearCommand::__construct()` now requires an instance of - `Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface` as - first argument. - - * `CachePoolClearCommand::__construct()` now requires an instance of - `Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer` as - first argument. - - * `EventDispatcherDebugCommand::__construct()` now requires an instance of - `Symfony\Component\EventDispatcher\EventDispatcherInterface` as - first argument. - - * `RouterDebugCommand::__construct()` now requires an instance of - `Symfony\Component\Routing\RouterInterface` as - first argument. - - * `RouterMatchCommand::__construct()` now requires an instance of - `Symfony\Component\Routing\RouterInterface` as - first argument. - - * `TranslationDebugCommand::__construct()` now requires an instance of - `Symfony\Component\Translation\TranslatorInterface` as - first argument. - - * `TranslationUpdateCommand::__construct()` now requires an instance of - `Symfony\Component\Translation\TranslatorInterface` as - first argument. - - * The `Symfony\Bundle\FrameworkBundle\Translation\PhpExtractor` - class has been deprecated and will be removed in 4.0. Use the - `Symfony\Component\Translation\Extractor\PhpExtractor` class instead. - - * The `Symfony\Bundle\FrameworkBundle\Translation\PhpStringTokenParser` - class has been deprecated and will be removed in 4.0. Use the - `Symfony\Component\Translation\Extractor\PhpStringTokenParser` class instead. - -HttpFoundation --------------- - - * The `Request::setTrustedProxies()` method takes a new `$trustedHeaderSet` argument. - See http://symfony.com/doc/current/components/http_foundation/trusting_proxies.html for more info. - - * The `Request::setTrustedHeaderName()` and `Request::getTrustedHeaderName()` methods have been removed. - - * Extending the following methods of `Response` - is no longer possible (these methods are now `final`): - - - `setDate`/`getDate` - - `setExpires`/`getExpires` - - `setLastModified`/`getLastModified` - - `setProtocolVersion`/`getProtocolVersion` - - `setStatusCode`/`getStatusCode` - - `setCharset`/`getCharset` - - `setPrivate`/`setPublic` - - `getAge` - - `getMaxAge`/`setMaxAge` - - `setSharedMaxAge` - - `getTtl`/`setTtl` - - `setClientTtl` - - `getEtag`/`setEtag` - - `hasVary`/`getVary`/`setVary` - - `isInvalid`/`isSuccessful`/`isRedirection`/`isClientError`/`isServerError` - - `isOk`/`isForbidden`/`isNotFound`/`isRedirect`/`isEmpty` - - * The ability to check only for cacheable HTTP methods using `Request::isMethodSafe()` is - not supported anymore, use `Request::isMethodCacheable()` instead. - - * The `Symfony\Component\HttpFoundation\Session\Storage\Handler\WriteCheckSessionHandler` class has been - removed. Implement `SessionUpdateTimestampHandlerInterface` or extend `AbstractSessionHandler` instead. - - * The `Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler` and - `Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy` classes have been removed. - - * The `Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler` does not work with the legacy - mongo extension anymore. It requires mongodb/mongodb package and ext-mongodb. - - * The `Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcacheSessionHandler` class has been removed. - Use `Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcachedSessionHandler` instead. - -HttpKernel ----------- - - * Bundle inheritance has been removed. - - * Relying on convention-based commands discovery is not supported anymore. - Use PSR-4 based service discovery instead. - - Before: - - ```yml - # app/config/services.yml - services: - # ... - - # implicit registration of all commands in the `Command` folder - ``` - - After: - - ```yml - # app/config/services.yml - services: - # ... - - # explicit commands registration - AppBundle\Command\: - resource: '../../src/AppBundle/Command/*' - tags: ['console.command'] - ``` - - * The `Extension::addClassesToCompile()` and `Extension::getClassesToCompile()` methods have been removed. - - * Possibility to pass non-scalar values as URI attributes to the ESI and SSI - renderers has been removed. The inline fragment renderer should be used with - non-scalar attributes. - - * The `ControllerResolver::getArguments()` method has been removed. If you - have your own `ControllerResolverInterface` implementation, you should - inject an `ArgumentResolverInterface` instance. - - * The `DataCollector::varToString()` method has been removed in favor of `cloneVar()`. - - * The `Psr6CacheClearer::addPool()` method has been removed. Pass an array of pools indexed - by name to the constructor instead. - - * The `LazyLoadingFragmentHandler::addRendererService()` method has been removed. - - * The `X-Status-Code` header method of setting a custom status code in the - response when handling exceptions has been removed. There is now a new - `GetResponseForExceptionEvent::allowCustomResponseCode()` method instead, - which will tell the Kernel to use the response code set on the event's - response object. - - * The `Kernel::getEnvParameters()` method has been removed. - - * The `SYMFONY__` environment variables are no longer processed automatically - by Symfony. Use the `%env()%` syntax to get the value of any environment - variable from configuration files instead. - - * The `getCacheDir()` method of your kernel should not be called while building the container. - Use the `%kernel.cache_dir%` parameter instead. Not doing so may break the `cache:clear` command. - - * The `Symfony\Component\HttpKernel\Config\EnvParametersResource` class has been removed. - - * The `reset()` method has been added to `Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface`. - - * The `clear()` method has been added to `Symfony\Component\HttpKernel\Log\DebugLoggerInterface`. - - * The `ChainCacheClearer::add()` method has been removed, - inject the list of clearers as a constructor argument instead. - - * The `CacheWarmerAggregate::add()` and `setWarmers()` methods have been removed, - inject the list of clearers as a constructor argument instead. - - * The `CacheWarmerAggregate` and `ChainCacheClearer` classes have been made final. - -Ldap ----- - - * The `RenameEntryInterface` has been removed, and merged with `EntryManagerInterface` - -Process -------- - - * Passing a not existing working directory to the constructor of the `Symfony\Component\Process\Process` class is not supported anymore. - - * The `Symfony\Component\Process\ProcessBuilder` class has been removed, - use the `Symfony\Component\Process\Process` class directly instead. - - * The `ProcessUtils::escapeArgument()` method has been removed, use a command line array or give env vars to the `Process::start/run()` method instead. - - * Environment variables are always inherited in sub-processes. - - * Configuring `proc_open()` options has been removed. - - * Configuring Windows and sigchild compatibility is not possible anymore - they are always enabled. - - * Extending `Process::run()`, `Process::mustRun()` and `Process::restart()` is - not supported anymore. - - * The `getEnhanceWindowsCompatibility()` and `setEnhanceWindowsCompatibility()` methods of the `Process` class have been removed. - -Profiler --------- - - * The `profiler.matcher` option has been removed. - -ProxyManager ------------- - - * The `ProxyDumper` class has been made final - -Security --------- - - * The `RoleInterface` has been removed. Extend the `Symfony\Component\Security\Core\Role\Role` - class instead. - - * The `LogoutUrlGenerator::registerListener()` method expects a 6th `string $context = null` argument. - - * The `AccessDecisionManager::setVoters()` method has been removed. Pass the - voters to the constructor instead. - - * Support for defining voters that don't implement the `VoterInterface` has been removed. - - * Calling `ContextListener::setLogoutOnUserChange(false)` won't have any - effect anymore. - - * Removed the HTTP digest authentication system. The `NonceExpiredException`, - `DigestAuthenticationListener` and `DigestAuthenticationEntryPoint` classes - have been removed. Use another authentication system like `http_basic` instead. - - * The `GuardAuthenticatorInterface` interface has been removed. - Use `AuthenticatorInterface` instead. - - * When extending `AbstractGuardAuthenticator` getCredentials() cannot return - `null` anymore, return false from `supports()` if no credentials available instead. - -SecurityBundle --------------- - - * The `FirewallContext::getContext()` method has been removed, use the `getListeners()` and/or `getExceptionListener()` method instead. - - * The `FirewallMap::$map` and `$container` properties have been removed. - - * The `UserPasswordEncoderCommand` class does not allow `null` as the first argument anymore. - - * `UserPasswordEncoderCommand` does not extend `ContainerAwareCommand` nor implement `ContainerAwareInterface` anymore. - - * `InitAclCommand` has been removed. Use `Symfony\Bundle\AclBundle\Command\InitAclCommand` instead - - * `SetAclCommand` has been removed. Use `Symfony\Bundle\AclBundle\Command\SetAclCommand` instead - - * The firewall option `logout_on_user_change` is now always true, which will - trigger a logout if the user changes between requests. - - * Removed the HTTP digest authentication system. The `HttpDigestFactory` class - has been removed. Use another authentication system like `http_basic` instead. - - * The `switch_user.stateless` option is now always true if the firewall is stateless. - - * Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider. - The first configured provider is not used anymore and an exception is thrown instead. - Explicitly configure the provider to use on your firewalls. - -Serializer ----------- - - * The ability to pass a Doctrine `Cache` instance to the `ClassMetadataFactory` - class has been removed. You should use the `CacheClassMetadataFactory` class - instead. - - * Not defining the 6th argument `$format = null` of the - `AbstractNormalizer::instantiateObject()` method when overriding it is not - supported anymore. - - * Extending `ChainDecoder`, `ChainEncoder`, `ArrayDenormalizer` is not supported - anymore. - -Translation ------------ - - * Removed the backup feature from the file dumper classes. - - * The default value of the `$readerServiceId` argument of `TranslatorPass::__construct()` has been changed to `"translation.reader"`. - - * Removed `Symfony\Component\Translation\Writer\TranslationWriter::writeTranslations`, - use `Symfony\Component\Translation\Writer\TranslationWriter::write` instead. - - * Removed support for passing `Symfony\Component\Translation\MessageSelector` as a second argument to the - `Translator::__construct()`. You should pass an instance of `Symfony\Component\Translation\Formatter\MessageFormatterInterface` instead. - -TwigBundle ----------- - - * The `ContainerAwareRuntimeLoader` class has been removed. Use the - Twig `Twig_ContainerRuntimeLoader` class instead. - - * Removed `DebugCommand` in favor of `Symfony\Bridge\Twig\Command\DebugCommand`. - - * Removed `ContainerAwareInterface` implementation in `Symfony\Bundle\TwigBundle\Command\LintCommand`. - -TwigBridge ----------- - - * removed the `Symfony\Bridge\Twig\Form\TwigRenderer` class, use the `FormRenderer` - class from the Form component instead - - * Removed the possibility to inject the Form `TwigRenderer` into the `FormExtension`. - Upgrade Twig to `^1.30`, inject the `Twig_Environment` into the `TwigRendererEngine` and load - the `TwigRenderer` using the `Twig_FactoryRuntimeLoader` instead. - - Before: - - ```php - use Symfony\Bridge\Twig\Extension\FormExtension; - use Symfony\Bridge\Twig\Form\TwigRenderer; - use Symfony\Bridge\Twig\Form\TwigRendererEngine; - - // ... - $rendererEngine = new TwigRendererEngine(['form_div_layout.html.twig']); - $rendererEngine->setEnvironment($twig); - $twig->addExtension(new FormExtension(new TwigRenderer($rendererEngine, $csrfTokenManager))); - ``` - - After: - - ```php - $rendererEngine = new TwigRendererEngine(['form_div_layout.html.twig'], $twig); - $twig->addRuntimeLoader(new \Twig_FactoryRuntimeLoader([ - TwigRenderer::class => function () use ($rendererEngine, $csrfTokenManager) { - return new TwigRenderer($rendererEngine, $csrfTokenManager); - }, - ])); - $twig->addExtension(new FormExtension()); - ``` - - * Removed the `TwigRendererEngineInterface` interface. - - * The `TwigRendererEngine::setEnvironment()` method has been removed. - Pass the Twig Environment as second argument of the constructor instead. - - * Removed `DebugCommand::set/getTwigEnvironment`. Pass an instance of - `Twig\Environment` as first argument of the constructor instead. - - * Removed `LintCommand::set/getTwigEnvironment`. Pass an instance of - `Twig\Environment` as first argument of the constructor instead. - -Validator ---------- - - * The default value of the `strict` option of the `Choice` constraint was changed - to `true`. Using any other value will throw an exception. - - * The `DateTimeValidator::PATTERN` constant was removed. - - * `Tests\Constraints\AbstractConstraintValidatorTest` has been removed in - favor of `Test\ConstraintValidatorTestCase`. - - Before: - - ```php - // ... - use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest; - - class MyCustomValidatorTest extends AbstractConstraintValidatorTest - { - // ... - } - ``` - - After: - - ```php - // ... - use Symfony\Component\Validator\Test\ConstraintValidatorTestCase; - - class MyCustomValidatorTest extends ConstraintValidatorTestCase - { - // ... - } - ``` - - * Setting the `checkDNS` option of the `Url` constraint to `true` is dropped - in favor of `Url::CHECK_DNS_TYPE_*` constants values. - - Before: - - ```php - $constraint = new Url(['checkDNS' => true]); - ``` - - After: - - ```php - $constraint = new Url(['checkDNS' => Url::CHECK_DNS_TYPE_ANY]); - ``` - -VarDumper ---------- - - * The `VarDumperTestTrait::assertDumpEquals()` method expects a 3rd `$filter = 0` - argument and moves `$message = ''` argument at 4th position. - - Before: - - ```php - VarDumperTestTrait::assertDumpEquals($dump, $data, $message = ''); - ``` - - After: - - ```php - VarDumperTestTrait::assertDumpEquals($dump, $data, $filter = 0, $message = ''); - ``` - - * The `VarDumperTestTrait::assertDumpMatchesFormat()` method expects a 3rd `$filter = 0` - argument and moves `$message = ''` argument at 4th position. - - Before: - - ```php - VarDumperTestTrait::assertDumpMatchesFormat($dump, $data, $message = ''); - ``` - - After: - - ```php - VarDumperTestTrait::assertDumpMatchesFormat($dump, $data, $filter = 0, $message = ''); - ``` - -WebProfilerBundle ------------------ - - * Removed the `getTemplates()` method of the `TemplateManager` class in favor - of the `getNames()` method - -Workflow --------- - - * Removed class name support in `WorkflowRegistry::add()` as second parameter. - -Yaml ----- - - * Support for the `!str` tag was removed, use the `!!str` tag instead. - - * Starting an unquoted string with a question mark followed by a space - throws a `ParseException`. - - * Removed support for implicitly parsing non-string mapping keys as strings. - Mapping keys that are no strings will result in a `ParseException`. Use - quotes to opt-in for keys to be parsed as strings. - - Before: - - ```php - $yaml = << new A(), 'bar' => 1], 0, 0, true); - ``` - - After: - - ```php - Yaml::dump(['foo' => new A(), 'bar' => 1], 0, 0, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE); - ``` - - * Removed support for passing `true`/`false` as the fifth argument to the - `dump()` method to toggle object support. - - Before: - - ```php - Yaml::dump(['foo' => new A(), 'bar' => 1], 0, 0, false, true); - ``` - - After: - - ```php - Yaml::dump(['foo' => new A(), 'bar' => 1], 0, 0, false, Yaml::DUMP_OBJECT); - ``` - - * The `!!php/object` tag to indicate dumped PHP objects was removed in favor of - the `!php/object` tag. - - * Duplicate mapping keys lead to a `ParseException`. - - * The constructor arguments `$offset`, `$totalNumberOfLines` and - `$skippedLineNumbers` of the `Parser` class were removed. - - * The behavior of the non-specific tag `!` is changed and now forces - non-evaluating your values. - - * The `!php/object:` tag was removed in favor of the `!php/object` tag (without - the colon). - - * The `!php/const:` tag was removed in favor of the `!php/const` tag (without - the colon). - - Before: - - ```yml - !php/const:PHP_INT_MAX - ``` - - After: - - ```yml - !php/const PHP_INT_MAX - ``` diff --git a/UPGRADE-4.1.md b/UPGRADE-4.1.md deleted file mode 100644 index 8410c67f84e99..0000000000000 --- a/UPGRADE-4.1.md +++ /dev/null @@ -1,164 +0,0 @@ -UPGRADE FROM 4.0 to 4.1 -======================= - -Config ------- - - * Implementing `ParentNodeDefinitionInterface` without the `getChildNodeDefinitions()` method - is deprecated. - -Console -------- - - * Deprecated the `setCrossingChar()` method in favor of the `setDefaultCrossingChar()` method in `TableStyle`. - * The `Processor` class has been made final - * Deprecated the `setHorizontalBorderChar()` method in favor of the `setDefaultCrossingChars()` method in `TableStyle`. - * Deprecated the `getHorizontalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`. - * Deprecated the `setVerticalBorderChar()` method in favor of the `setVerticalBorderChars()` method in `TableStyle`. - * Deprecated the `getVerticalBorderChar()` method in favor of the `getBorderChars()` method in `TableStyle`. - * Added support for `iterable` messages in `write` and `writeln` methods of `Symfony\Component\Console\Output\OutputInterface`. - If you have a custom implementation of the interface, you should make sure it works with iterable as well. - -DependencyInjection -------------------- - - * Deprecated the `TypedReference::canBeAutoregistered()` and `TypedReference::getRequiringClass()` methods. - * Deprecated support for auto-discovered extension configuration class which does not implement `ConfigurationInterface`. - -EventDispatcher ---------------- - - * The `TraceableEventDispatcherInterface` has been deprecated. - -Form ----- - - * Deprecated the `ChoiceLoaderInterface` implementation in `CountryType`, - `LanguageType`, `LocaleType` and `CurrencyType`, use the `choice_loader` - option instead. - - Before: - ```php - class MyCountryType extends CountryType - { - public function loadChoiceList() - { - // override the method - } - } - ``` - - After: - ```php - class MyCountryType extends AbstractType - { - public function getParent() - { - return CountryType::class; - } - - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefault('choice_loader', ...); // override the option instead - } - } - ``` - - * Added `help` option to the form field. If you have custom Form extension for it, you should remove it. - Also remove it from the custom form theme. - -FrameworkBundle ---------------- - - * Deprecated `bundle:controller:action` and `service:action` syntaxes to reference controllers. Use `serviceOrFqcn::method` - instead where `serviceOrFqcn` is either the service ID when using controllers as services or the FQCN of the controller. - - Before: - - ```yml - bundle_controller: - path: / - defaults: - _controller: FrameworkBundle:Redirect:redirect - - service_controller: - path: / - defaults: - _controller: app.my_controller:myAction - ``` - - After: - - ```yml - bundle_controller: - path: / - defaults: - _controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction - - service_controller: - path: / - defaults: - _controller: app.my_controller::myAction - ``` - - * Deprecated `Symfony\Bundle\FrameworkBundle\Controller\ControllerNameParser` - * Warming up a router in `RouterCacheWarmer` that does not implement the `WarmableInterface` is deprecated and will not be - supported anymore in 5.0. - * The `RequestDataCollector` class has been deprecated. Use the `Symfony\Component\HttpKernel\DataCollector\RequestDataCollector` class instead. - -HttpFoundation --------------- - - * Passing the file size to the constructor of the `UploadedFile` class is deprecated. - * The `getClientSize()` method of the `UploadedFile` class is deprecated. Use `getSize()` instead. - * Deprecated `Symfony\Component\HttpFoundation\Request::getSession()` when no session has been set. Use `Symfony\Component\HttpFoundation\Request::hasSession()` instead. - -Security --------- - - * The `ContextListener::setLogoutOnUserChange()` method is deprecated. - * Using the `AdvancedUserInterface` is now deprecated. To use the existing - functionality, create a custom user-checker based on the - `Symfony\Component\Security\Core\User\UserChecker`. - * `AuthenticationUtils::getLastUsername()` now always returns a string. - * The `ExpressionVoter::addExpressionLanguageProvider()` method is deprecated. Register the provider directly on the injected ExpressionLanguage instance instead. - -SecurityBundle --------------- - - * The `logout_on_user_change` firewall option is deprecated. - * The `switch_user.stateless` firewall option is deprecated, use the `stateless` option instead. - * The `SecurityUserValueResolver` class is deprecated, use - `Symfony\Component\Security\Http\Controller\UserValueResolver` instead. - -Serializer ----------- - - * Decoding XML with `XmlEncoder` now ignores comment node types by default. - -Translation ------------ - - * The `FileDumper::setBackup()` method is deprecated. - * The `TranslationWriter::disableBackup()` method is deprecated. - -TwigBundle ----------- - - * Deprecated relying on the default value (`false`) of the `twig.strict_variables` configuration option. You should use `%kernel.debug%` explicitly instead, which will be the new default in 5.0. - -Validator --------- - - * The `Email::__construct()` 'strict' property is deprecated. Use 'mode'=>"strict" instead. - * Calling `EmailValidator::__construct()` method with a boolean parameter is deprecated, use `EmailValidator("strict")` instead. - * Deprecated the `checkDNS` and `dnsMessage` options of the `Url` constraint. - -Workflow --------- - - * Deprecated the `DefinitionBuilder::reset()` method, use the `clear()` one instead. - * Deprecated the `add` method in favor of the `addWorkflow` method in `Workflow\Registry`. - * Deprecated `SupportStrategyInterface` in favor of `WorkflowSupportStrategyInterface`. - * Deprecated the class `ClassInstanceSupportStrategy` in favor of the class `InstanceOfSupportStrategy`. - * Deprecated passing the workflow name as 4th parameter of `Event` constructor in favor of the workflow itself. diff --git a/UPGRADE-4.2.md b/UPGRADE-4.2.md deleted file mode 100644 index 8f7cc54411aa9..0000000000000 --- a/UPGRADE-4.2.md +++ /dev/null @@ -1,393 +0,0 @@ -UPGRADE FROM 4.1 to 4.2 -======================= - -BrowserKit ----------- - - * The `Client::submit()` method will have a new `$serverParameters` argument in version 5.0, not defining it is deprecated. - -Cache ------ - - * Deprecated `CacheItem::getPreviousTags()`, use `CacheItem::getMetadata()` instead. - -Config ------- - - * Deprecated constructing a `TreeBuilder` without passing root node information: - - Before: - ```php - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('my_config'); - ``` - - After: - ```php - $treeBuilder = new TreeBuilder('my_config'); - $rootNode = $treeBuilder->getRootNode(); - ``` - - * Deprecated `FileLoaderLoadException`, use `LoaderLoadException` instead. - -Console -------- - - * Deprecated passing a command as a string to `ProcessHelper::run()`, - pass the command as an array of arguments instead. - - Before: - ```php - $processHelper->run($output, 'ls -l'); - ``` - - After: - ```php - $processHelper->run($output, array('ls', '-l')); - - // alternatively, when a shell wrapper is required - $processHelper->run($output, Process::fromShellCommandline('ls -l')); - ``` - -DoctrineBridge --------------- - - * The `lazy` attribute on `doctrine.event_listener` tags was removed. - Listeners are now lazy by default. So any `lazy` attributes can safely be removed from those tags. - -DomCrawler ----------- - - * The `Crawler::children()` method will have a new `$selector` argument in version 5.0, not defining it is deprecated. - -Finder ------- - - * The `Finder::sortByName()` method will have a new `$useNaturalSort` argument in version 5.0, not defining it is deprecated. - -Form ----- - - * The `symfony/translation` dependency has been removed - run `composer require symfony/translation` if you need the component - * The `getExtendedType()` method of the `FormTypeExtensionInterface` is deprecated and will be removed in 5.0. Type - extensions must implement the static `getExtendedTypes()` method instead and return an iterable of extended types. - - Before: - - ```php - class FooTypeExtension extends AbstractTypeExtension - { - public function getExtendedType() - { - return FormType::class; - } - - // ... - } - ``` - - After: - - ```php - class FooTypeExtension extends AbstractTypeExtension - { - public static function getExtendedTypes(): iterable - { - return array(FormType::class); - } - - // ... - } - ``` - * The `scale` option of the `IntegerType` is deprecated. - * The `$scale` argument of the `IntegerToLocalizedStringTransformer` is deprecated. - * Deprecated calling `FormRenderer::searchAndRenderBlock` for fields which were already rendered. - Instead of expecting such calls to return empty strings, check if the field has already been rendered. - - Before: - ```twig - {% for field in fieldsWithPotentialDuplicates %} - {{ form_widget(field) }} - {% endfor %} - ``` - - After: - ```twig - {% for field in fieldsWithPotentialDuplicates if not field.rendered %} - {{ form_widget(field) }} - {% endfor %} - ``` - - * The `regions` option of the `TimezoneType` is deprecated. - -FrameworkBundle ---------------- - - * The following middleware service ids were renamed: - - `messenger.middleware.call_message_handler` becomes `messenger.middleware.handle_message` - - `messenger.middleware.route_messages` becomes `messenger.middleware.send_message` - - If you set `framework.messenger.buses.[bus_id].default_middleware` to `false`, - replace any of these names in the `framework.messenger.buses.[bus_id].middleware` list. - * The `allow_no_handler` middleware has been removed. Use `framework.messenger.buses.[bus_id].default_middleware` instead: - - Before: - ```yaml - framework: - messenger: - buses: - messenger.bus.events: - middleware: - - allow_no_handler - ``` - - After: - ```yaml - framework: - messenger: - buses: - messenger.bus.events: - default_middleware: allow_no_handlers - ``` - - * The `messenger:consume-messages` command expects a mandatory `--bus` option value if you have more than one bus configured. - * The `framework.router.utf8` configuration option has been added. If your app's charset - is UTF-8 (see kernel's `getCharset()` method), it is recommended to set it to `true`: - this will generate 404s for non-UTF-8 URLs, which are incompatible with you app anyway, - and will allow dumping optimized routers and using Unicode classes in requirements. - * Added support for the SameSite attribute for session cookies. It is highly recommended to set this setting (`framework.session.cookie_samesite`) to `lax` for increased security against CSRF attacks. - * The `Controller` class has been deprecated, use `AbstractController` instead. - * The Messenger encoder/decoder configuration has been changed for a unified Messenger serializer configuration. - - Before: - ```yaml - framework: - messenger: - encoder: your_encoder_service_id - decoder: your_decoder_service_id - ``` - - After: - ```yaml - framework: - messenger: - serializer: - id: your_messenger_service_id - ``` - * The `ContainerAwareCommand` class has been deprecated, use `Symfony\Component\Console\Command\Command` - with dependency injection instead. - * The `Templating\Helper\TranslatorHelper::transChoice()` method has been deprecated, use the `trans()` one instead with a `%count%` parameter. - * Deprecated support for legacy translations directories `src/Resources/translations/` and `src/Resources//translations/`, use `translations/` instead. - * Support for the legacy directory structure in `translation:update` and `debug:translation` commands has been deprecated. - -HttpFoundation --------------- - - * The default value of the `$secure` and `$samesite` arguments of Cookie's constructor - will respectively change from `false` to `null` and from `null` to `lax` in Symfony - 5.0, you should define their values explicitly or use `Cookie::create()` instead. - -HttpKernel ----------- - - * The `Kernel::getRootDir()` and the `kernel.root_dir` parameter have been deprecated - * The `KernelInterface::getName()` and the `kernel.name` parameter have been deprecated - * Deprecated the first and second constructor argument of `ConfigDataCollector` - * Deprecated `ConfigDataCollector::getApplicationName()` - * Deprecated `ConfigDataCollector::getApplicationVersion()` - -Messenger ---------- - - * The `MiddlewareInterface::handle()` and `SenderInterface::send()` methods must now return an `Envelope` instance. - * The return value of handlers isn't forwarded anymore by middleware and buses. - If you used to return a value, e.g in query bus handlers, you can either: - - get the result from the `HandledStamp` in the envelope returned by the bus. - - use the `HandleTrait` to leverage a message bus, expecting a single, synchronous message handling and returning its result. - - make your `Query` mutable to allow setting & getting a result: - ```php - // When dispatching: - $bus->dispatch($query = new Query()); - $result = $query->getResult(); - - // In your handler: - $query->setResult($yourResult); - ``` - * The `EnvelopeAwareInterface` was removed and the `MiddlewareInterface::handle()` method now requires an `Envelope` object - as first argument. When using built-in middleware with the provided `MessageBus`, you will not have to do anything. - If you use your own `MessageBusInterface` implementation, you must wrap the message in an `Envelope` before passing it to middleware. - If you created your own middleware, you must change the signature to always expect an `Envelope`. - * The `MiddlewareInterface::handle()` second argument (`callable $next`) has changed in favor of a `StackInterface` instance. - When using built-in middleware with the provided `MessageBus`, you will not have to do anything. - If you use your own `MessageBusInterface` implementation, you can use the `StackMiddleware` implementation. - If you created your own middleware, you must change the signature to always expect an `StackInterface` instance - and call `$stack->next()->handle($envelope, $stack)` instead of `$next` to call the next middleware: - - Before: - ```php - public function handle($message, callable $next): Envelope - { - // do something before - $message = $next($message); - // do something after - - return $message; - } - ``` - - After: - ```php - public function handle(Envelope $envelope, StackInterface $stack): Envelope - { - // do something before - $envelope = $stack->next()->handle($envelope, $stack); - // do something after - - return $envelope; - } - ``` - * `StampInterface` replaces `EnvelopeItemInterface` and doesn't extend `Serializable` anymore. - Built-in `ReceivedMessage`, `ValidationConfiguration` and `SerializerConfiguration` were renamed - respectively `ReceivedStamp`, `ValidationStamp`, `SerializerStamp` and moved to the `Stamp` namespace. - * `AllowNoHandlerMiddleware` has been removed in favor of a new constructor argument on `HandleMessageMiddleware` - * The `ConsumeMessagesCommand` class now takes an instance of `Psr\Container\ContainerInterface` - as first constructor argument, i.e a message bus locator. The CLI command now expects a mandatory - `--bus` option value if there is more than one bus in the locator. - * `MessageSubscriberInterface::getHandledMessages()` return value has changed. The value of an array item - needs to be an associative array or the method name. - - Before: - ```php - return [ - [FirstMessage::class, 0], - [SecondMessage::class, -10], - ]; - ``` - - After: - ```php - yield FirstMessage::class => ['priority' => 0]; - yield SecondMessage::class => ['priority' => -10]; - ``` - - Before: - ```php - return [ - SecondMessage::class => ['secondMessageMethod', 20], - ]; - ``` - - After: - ```php - yield SecondMessage::class => [ - 'method' => 'secondMessageMethod', - 'priority' => 20, - ]; - ``` - * The `EncoderInterface` and `DecoderInterface` interfaces have been replaced by a unified `Symfony\Component\Messenger\Transport\Serialization\SerializerInterface`. - Each interface method have been merged untouched into the `Serializer` interface, so you can simply merge your two implementations together and implement the new interface. - * The `HandlerLocator` class was replaced with `Symfony\Component\Messenger\Handler\HandlersLocator`. - - Before: - ```php - new HandlerLocator([ - YourMessage::class => $handlerCallable, - ]); - ``` - - After: - ```php - new HandlersLocator([ - YourMessage::class => [ - $handlerCallable, - ] - ]); - ``` - -Monolog -------- - - * The methods `DebugProcessor::getLogs()`, `DebugProcessor::countErrors()`, `Logger::getLogs()` and `Logger::countErrors()` will have a new `$request` argument in version 5.0, not defining it is deprecated. - -Process -------- - - * Deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods. - * Deprecated passing commands as strings when creating a `Process` instance. - - Before: - ```php - $process = new Process('ls -l'); - ``` - - After: - ```php - $process = new Process(array('ls', '-l')); - - // alternatively, when a shell wrapper is required - $process = Process::fromShellCommandline('ls -l'); - ``` - -Security --------- - - * Using the `has_role()` function in security expressions is deprecated, use the `is_granted()` function instead. - * Not returning an array of 3 elements from `FirewallMapInterface::getListeners()` is deprecated, the 3rd element - must be an instance of `LogoutListener` or `null`. - * Passing custom class names to the - `Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolver` to define - custom anonymous and remember me token classes is deprecated. To - use custom tokens, extend the existing `Symfony\Component\Security\Core\Authentication\Token\AnonymousToken` - or `Symfony\Component\Security\Core\Authentication\Token\RememberMeToken`. - * Accessing the user object that is not an instance of `UserInterface` from `Security::getUser()` is deprecated. - * `SimpleAuthenticatorInterface`, `SimpleFormAuthenticatorInterface`, `SimplePreAuthenticatorInterface`, - `SimpleAuthenticationProvider`, `SimpleAuthenticationHandler`, `SimpleFormAuthenticationListener` and - `SimplePreAuthenticationListener` have been deprecated. Use Guard instead. - * **BC break note**: Upgrade to this version will log out all logged in users. See bug #33473. - -SecurityBundle --------------- - - * Passing a `FirewallConfig` instance as 3rd argument to the `FirewallContext` constructor is deprecated, - pass a `LogoutListener` instance instead. - * Using the `security.authentication.trust_resolver.anonymous_class` and - `security.authentication.trust_resolver.rememberme_class` parameters to define - the token classes is deprecated. To use - custom tokens extend the existing AnonymousToken and RememberMeToken. - * The `simple_form` and `simple_preauth` authentication listeners have been deprecated, - use Guard instead. - * The `SimpleFormFactory` and `SimplePreAuthenticationFactory` classes have been deprecated, - use Guard instead. - -Serializer ----------- - - * Relying on the default value (false) of the "as_collection" option is deprecated. - You should set it to false explicitly instead as true will be the default value in 5.0. - * The `AbstractNormalizer::handleCircularReference()` method will have two new `$format` and `$context` arguments in version 5.0, not defining them is deprecated. - -Translation ------------ - - * The `TranslatorInterface` has been deprecated in favor of `Symfony\Contracts\Translation\TranslatorInterface` - * The `Translator::transChoice()` method has been deprecated in favor of using `Translator::trans()` with "%count%" as the parameter driving plurals - * The `MessageSelector`, `Interval` and `PluralizationRules` classes have been deprecated, use `IdentityTranslator` instead - * The `Translator::getFallbackLocales()` and `TranslationDataCollector::getFallbackLocales()` method have been marked as internal - -TwigBundle ----------- - - * The `transchoice` tag and filter have been deprecated, use the `trans` ones instead with a `%count%` parameter. - * Deprecated support for legacy templates directories `src/Resources/views/` and `src/Resources//views/`, use `templates/` and `templates/bundles//` instead. - -Validator ---------- - - * The `symfony/translation` dependency has been removed - run `composer require symfony/translation` if you need the component - * The `checkMX` and `checkHost` options of the `Email` constraint are deprecated - * The component is now decoupled from `symfony/translation` and uses `Symfony\Contracts\Translation\TranslatorInterface` instead - * The `ValidatorBuilderInterface` has been deprecated and `ValidatorBuilder::setTranslator()` has been made final - * Deprecated validating instances of `\DateTimeInterface` in `DateTimeValidator`, `DateValidator` and `TimeValidator`. Use `Type` instead or remove the constraint if the underlying model is type hinted to `\DateTimeInterface` already. - * Using the `Bic`, `Country`, `Currency`, `Language` and `Locale` constraints without `symfony/intl` is deprecated - * Using the `Email` constraint in strict mode without `egulias/email-validator` is deprecated - * Using the `Expression` constraint without `symfony/expression-language` is deprecated diff --git a/UPGRADE-4.3.md b/UPGRADE-4.3.md deleted file mode 100644 index 5093de27cb2dc..0000000000000 --- a/UPGRADE-4.3.md +++ /dev/null @@ -1,358 +0,0 @@ -UPGRADE FROM 4.2 to 4.3 -======================= - -BrowserKit ----------- - - * Renamed `Client` to `AbstractBrowser` - * Marked `Response` final. - * Deprecated `Response::buildHeader()` - * Deprecated `Response::getStatus()`, use `Response::getStatusCode()` instead - -Cache ------ - - * The `psr/simple-cache` dependency has been removed - run `composer require psr/simple-cache` if you need it. - * Deprecated all PSR-16 adapters, use `Psr16Cache` or `Symfony\Contracts\Cache\CacheInterface` implementations instead. - * Deprecated `SimpleCacheAdapter`, use `Psr16Adapter` instead. - -Config ------- - - * Deprecated using environment variables with `cannotBeEmpty()` if the value is validated with `validate()` - * Deprecated the `root()` method in `TreeBuilder`, pass the root node information to the constructor instead - -DependencyInjection -------------------- - - * Deprecated support for non-string default env() parameters - - Before: - ```yaml - parameters: - env(NAME): 1.5 - ``` - - After: - ```yaml - parameters: - env(NAME): '1.5' - ``` - -Doctrine Bridge ---------------- - - * Passing an `IdReader` to the `DoctrineChoiceLoader` when the query cannot be optimized with single id field has been deprecated, pass `null` instead - * Not passing an `IdReader` to the `DoctrineChoiceLoader` when the query can be optimized with single id field has been deprecated - -Dotenv ------- - - * First parameter of `Dotenv::__construct()` will be changed from `true` to `false` in Symfony 5.0. A deprecation warning - is triggered if no parameter is provided. Use `$usePutenv = true` to upgrade without breaking changes. - -EventDispatcher ---------------- - - * The signature of the `EventDispatcherInterface::dispatch()` method has been updated, consider using the new signature `dispatch($event, string $eventName = null)` instead of the old signature `dispatch($eventName, $event)` that is deprecated - - You have to swap arguments when calling `dispatch()`: - - Before: - ```php - $this->eventDispatcher->dispatch(Events::My_EVENT, $event); - ``` - - After: - ```php - $this->eventDispatcher->dispatch($event, Events::My_EVENT); - ``` - - If your bundle or package needs to provide compatibility with the previous way of using the dispatcher, you can use `Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy::decorate()` to ease upgrades: - - Before: - ```php - public function __construct(EventDispatcherInterface $eventDispatcher) { - $this->eventDispatcher = $eventDispatcher; - } - ``` - - After: - ```php - public function __construct(EventDispatcherInterface $eventDispatcher) { - $this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher); - } - ``` - - * The `Event` class has been deprecated, use `Symfony\Contracts\EventDispatcher\Event` instead - -Filesystem ----------- - - * Support for passing arrays to `Filesystem::dumpFile()` is deprecated. - * Support for passing arrays to `Filesystem::appendToFile()` is deprecated. - -Form ----- - - * Using the `format` option of `DateType` and `DateTimeType` when the `html5` option is enabled is deprecated. - * Using names for buttons that do not start with a letter, a digit, or an underscore is deprecated and will lead to an - exception in 5.0. - * Using names for buttons that do not contain only letters, digits, underscores, hyphens, and colons is deprecated and - will lead to an exception in 5.0. - * Using the `date_format`, `date_widget`, and `time_widget` options of the `DateTimeType` when the `widget` option is - set to `single_text` is deprecated. - -FrameworkBundle ---------------- - - * Deprecated the `framework.templating` option, configure the Twig bundle instead. - * Not passing the project directory to the constructor of the `AssetsInstallCommand` is deprecated. This argument will - be mandatory in 5.0. - * Deprecated the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead. - * The `generate()` method of the `UrlGenerator` class can return an empty string instead of null. - -HttpFoundation --------------- - - * The `MimeTypeGuesserInterface` and `ExtensionGuesserInterface` interfaces have been deprecated, - use `Symfony\Component\Mime\MimeTypesInterface` instead. - * The `MimeType` and `MimeTypeExtensionGuesser` classes have been deprecated, - use `Symfony\Component\Mime\MimeTypes` instead. - * The `FileBinaryMimeTypeGuesser` class has been deprecated, - use `Symfony\Component\Mime\FileBinaryMimeTypeGuesser` instead. - * The `FileinfoMimeTypeGuesser` class has been deprecated, - use `Symfony\Component\Mime\FileinfoMimeTypeGuesser` instead. - -HttpKernel ----------- - - * Renamed `Client` to `HttpKernelBrowser` - * Renamed `FilterControllerArgumentsEvent` to `ControllerArgumentsEvent` - * Renamed `FilterControllerEvent` to `ControllerEvent` - * Renamed `FilterResponseEvent` to `ResponseEvent` - * Renamed `GetResponseEvent` to `RequestEvent` - * Renamed `GetResponseForControllerResultEvent` to `ViewEvent` - * Renamed `GetResponseForExceptionEvent` to `ExceptionEvent` - * Renamed `PostResponseEvent` to `TerminateEvent` - * Deprecated `TranslatorListener` in favor of `LocaleAwareListener` - -Intl ----- - - * Deprecated `ResourceBundle` namespace - * Deprecated `Intl::getCurrencyBundle()`, use `Currencies` instead - * Deprecated `Intl::getLanguageBundle()`, use `Languages` or `Scripts` instead - * Deprecated `Intl::getLocaleBundle()`, use `Locales` instead - * Deprecated `Intl::getRegionBundle()`, use `Countries` instead - -Messenger ---------- - - * `Amqp` transport does not throw `\AMQPException` anymore, catch `TransportException` instead. - * Deprecated the `LoggingMiddleware` class, pass a logger to `SendMessageMiddleware` instead. - -Routing -------- - - * The `generator_base_class`, `generator_cache_class`, `matcher_base_class`, and `matcher_cache_class` router - options have been deprecated. - * `Serializable` implementing methods for `Route` and `CompiledRoute` are marked as `@internal` and `@final`. - Instead of overwriting them, use `__serialize` and `__unserialize` as extension points which are forward compatible - with the new serialization methods in PHP 7.4. - -Security --------- - - * The `Role` and `SwitchUserRole` classes are deprecated and will be removed in 5.0. Use strings for roles - instead. - * The `getReachableRoles()` method of the `RoleHierarchyInterface` is deprecated and will be removed in 5.0. - Role hierarchies must implement the `getReachableRoleNames()` method instead and return roles as strings. - * The `getRoles()` method of the `TokenInterface` is deprecated. Tokens must implement the `getRoleNames()` - method instead and return roles as strings. - * The `ListenerInterface` is deprecated, turn your listeners into callables instead. - * The `Firewall::handleRequest()` method is deprecated, use `Firewall::callListeners()` instead. - * The `AbstractToken::serialize()`, `AbstractToken::unserialize()`, - `AuthenticationException::serialize()` and `AuthenticationException::unserialize()` - methods are now final, use `__serialize()` and `__unserialize()` instead. - - Before: - ```php - public function serialize() - { - return [$this->myLocalVar, parent::serialize()]; - } - - public function unserialize($serialized) - { - [$this->myLocalVar, $parentSerialized] = unserialize($serialized); - parent::unserialize($parentSerialized); - } - ``` - - After: - ```php - public function __serialize(): array - { - return [$this->myLocalVar, parent::__serialize()]; - } - - public function __unserialize(array $data): void - { - [$this->myLocalVar, $parentData] = $data; - parent::__unserialize($parentData); - } - ``` - - * The `Argon2iPasswordEncoder` class has been deprecated, use `SodiumPasswordEncoder` instead. - * The `BCryptPasswordEncoder` class has been deprecated, use `NativePasswordEncoder` instead. - * Not implementing the methods `__serialize` and `__unserialize` in classes implementing - the `TokenInterface` is deprecated - -TwigBridge ----------- - - * deprecated the `$requestStack` and `$requestContext` arguments of the - `HttpFoundationExtension`, pass a `Symfony\Component\HttpFoundation\UrlHelper` - instance as the only argument instead - -Workflow --------- - - * `initial_place` is deprecated in favour of `initial_marking`. - - Before: - ```yaml - framework: - workflows: - article: - initial_place: draft - ``` - - After: - ```yaml - framework: - workflows: - article: - initial_marking: [draft] - ``` - - * `WorkflowInterface::apply()` will have a third argument in Symfony 5.0. - - Before: - ```php - class MyWorkflow implements WorkflowInterface - { - public function apply($subject, $transitionName) - { - } - } - ``` - - After: - ```php - class MyWorkflow implements WorkflowInterface - { - public function apply($subject, $transitionName, array $context = []) - { - } - } - ``` - - * `MarkingStoreInterface::setMarking()` will have a third argument in Symfony 5.0. - - Before: - ```php - class MyMarkingStore implements MarkingStoreInterface - { - public function setMarking($subject, Marking $marking) - { - } - } - ``` - - After: - ```php - class MyMarkingStore implements MarkingStoreInterface - { - public function setMarking($subject, Marking $marking , array $context = []) - { - } - } - ``` - - * `MultipleStateMarkingStore` is deprecated. Use `MethodMarkingStore` instead. - - Before: - ```yaml - framework: - workflows: - article: - type: workflow - marking_store: - type: multiple_state - arguments: states - ``` - - After: - ```yaml - framework: - workflows: - article: - type: workflow - marking_store: - type: method - property: states - ``` - - * `SingleStateMarkingStore` is deprecated. Use `MethodMarkingStore` instead. - - Before: - ```yaml - framework: - workflows: - article: - marking_store: - arguments: state - ``` - - After: - ```yaml - framework: - workflows: - article: - type: state_machine - marking_store: - type: method - property: state - ``` - - * Using a workflow with a single state marking is deprecated. Use a state machine instead. - - Before: - ```yaml - framework: - workflows: - article: - type: workflow - marking_store: - type: single_state - ``` - - After: - ```yaml - framework: - workflows: - article: - type: state_machine - marking_store: - # type: single_state # Since the single_state marking store is deprecated, use method instead - type: method - ``` - - * Using `DefinitionBuilder::setInitialPlace()` is deprecated, use `DefinitionBuilder::setInitialPlaces()` instead. - -Yaml ----- - - * Using a mapping inside a multi-line string is deprecated and will throw a `ParseException` in 5.0. diff --git a/UPGRADE-4.4.md b/UPGRADE-4.4.md deleted file mode 100644 index c0160192746c3..0000000000000 --- a/UPGRADE-4.4.md +++ /dev/null @@ -1,396 +0,0 @@ -UPGRADE FROM 4.3 to 4.4 -======================= - -Cache ------ - - * Added argument `$prefix` to `AdapterInterface::clear()` - * Marked the `CacheDataCollector` class as `@final`. - -Console -------- - - * Deprecated finding hidden commands using an abbreviation, use the full name instead - * Deprecated returning `null` from `Command::execute()`, return `0` instead - * Deprecated the `Application::renderException()` and `Application::doRenderException()` methods, - use `renderThrowable()` and `doRenderThrowable()` instead. - -Debug ------ - - * Deprecated the component in favor of the `ErrorHandler` component - * Replace uses of `Symfony\Component\Debug\Debug` by `Symfony\Component\ErrorHandler\Debug` - -Config ------- - - * Deprecated overriding the `FilerLoader::import()` method without declaring the optional `$exclude` argument - -DependencyInjection -------------------- - - * Made singly-implemented interfaces detection be scoped by file - * Deprecated support for short factories and short configurators in Yaml - - Before: - ```yaml - services: - my_service: - factory: factory_service:method - ``` - - After: - ```yaml - services: - my_service: - factory: ['@factory_service', method] - ``` - - * Passing an instance of `Symfony\Component\DependencyInjection\Parameter` as class name to `Symfony\Component\DependencyInjection\Definition` is deprecated. - - Before: - ```php - new Definition(new Parameter('my_class')); - ``` - - After: - ```php - new Definition('%my_class%'); - ``` - -DoctrineBridge --------------- - * Deprecated injecting `ClassMetadataFactory` in `DoctrineExtractor`, an instance of `EntityManagerInterface` should be - injected instead. - * Deprecated passing an `IdReader` to the `DoctrineChoiceLoader` when the query cannot be optimized with single id field. - * Deprecated not passing an `IdReader` to the `DoctrineChoiceLoader` when the query can be optimized with single id field. - * Deprecated `RegistryInterface`, use `Doctrine\Persistence\ManagerRegistry`. - * Added a new `getMetadataDriverClass` method to replace class parameters in `AbstractDoctrineExtension`. This method - will be abstract in Symfony 5 and must be declared in extending classes. - -Filesystem ----------- - - * Support for passing a `null` value to `Filesystem::isAbsolutePath()` is deprecated. - -Form ----- - - * Using different values for the "model_timezone" and "view_timezone" options of the `TimeType` without configuring a - reference date is deprecated. - * Using `int` or `float` as data for the `NumberType` when the `input` option is set to `string` is deprecated. - * Overriding the methods `FormIntegrationTestCase::setUp()`, `TypeTestCase::setUp()` and `TypeTestCase::tearDown()` without the `void` return-type is deprecated. - -FrameworkBundle ---------------- - - * Deprecated calling `WebTestCase::createClient()` while a kernel has been booted, ensure the kernel is shut down before calling the method - * Deprecated support for `templating` engine in `TemplateController`, use Twig instead - * The `$parser` argument of `ControllerResolver::__construct()` and `DelegatingLoader::__construct()` - has been deprecated. - * The `ControllerResolver` and `DelegatingLoader` classes have been marked as `final`. - * The `controller_name_converter` and `resolve_controller_name_subscriber` services have been deprecated. - * Deprecated `routing.loader.service`, use `routing.loader.container` instead. - * Not tagging service route loaders with `routing.route_loader` has been deprecated. - * Overriding the methods `KernelTestCase::tearDown()` and `WebTestCase::tearDown()` without the `void` return-type is deprecated. - * Marked the `RouterDataCollector` class as `@final`. - -HttpClient ----------- - - * Added method `cancel()` to `ResponseInterface` - -HttpFoundation --------------- - - * `ApacheRequest` is deprecated, use `Request` class instead. - * Passing a third argument to `HeaderBag::get()` is deprecated since Symfony 4.4, use method `all()` instead - * [BC BREAK] `PdoSessionHandler` with MySQL changed the type of the lifetime column, - make sure to run `ALTER TABLE sessions MODIFY sess_lifetime INTEGER UNSIGNED NOT NULL` to - update your database. - * `PdoSessionHandler` now precalculates the expiry timestamp in the lifetime column, - make sure to run `CREATE INDEX EXPIRY ON sessions (sess_lifetime)` to update your database - to speed up garbage collection of expired sessions. - -HttpKernel ----------- - - * The `DebugHandlersListener` class has been marked as `final` - * Added new Bundle directory convention consistent with standard skeletons: - - ``` - └── MyBundle/ - ├── config/ - ├── public/ - ├── src/ - │ └── MyBundle.php - ├── templates/ - └── translations/ - ``` - - To make this work properly, it is necessary to change the root path of the bundle: - - ```php - class MyBundle extends Bundle - { - public function getPath(): string - { - return \dirname(__DIR__); - } - } - ``` - - As many bundles must be compatible with a range of Symfony versions, the current - directory convention is not deprecated yet, but it will be in the future. - - * Deprecated the second and third argument of `KernelInterface::locateResource` - * Deprecated the second and third argument of `FileLocator::__construct` - * Deprecated loading resources from `%kernel.root_dir%/Resources` and `%kernel.root_dir%` as - fallback directories. Resources like service definitions are usually loaded relative to the - current directory or with a glob pattern. The fallback directories have never been advocated - so you likely do not use those in any app based on the SF Standard or Flex edition. - * Getting the container from a non-booted kernel is deprecated - * Marked the `AjaxDataCollector`, `ConfigDataCollector`, `EventDataCollector`, - `ExceptionDataCollector`, `LoggerDataCollector`, `MemoryDataCollector`, - `RequestDataCollector` and `TimeDataCollector` classes as `@final`. - * Marked the `RouterDataCollector::collect()` method as `@final`. - * The `DataCollectorInterface::collect()` and `Profiler::collect()` methods third parameter signature - will be `\Throwable $exception = null` instead of `\Exception $exception = null` in Symfony 5.0. - * Deprecated methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead - * Deprecated class `ExceptionListener`, use `ErrorListener` instead - -Lock ----- - - * Deprecated `Symfony\Component\Lock\StoreInterface` in favor of `Symfony\Component\Lock\BlockingStoreInterface` and - `Symfony\Component\Lock\PersistingStoreInterface`. - * `Factory` is deprecated, use `LockFactory` instead - * Deprecated services `lock.store.flock`, `lock.store.semaphore`, `lock.store.memcached.abstract` and `lock.store.redis.abstract`, - use `StoreFactory::createStore` instead. - -Mailer ------- - - * [BC BREAK] Changed the DSN to use for disabling delivery (using the `NullTransport`) from `smtp://null` to `null://null` (host doesn't matter). - * [BC BREAK] Renamed class `SmtpEnvelope` to `Envelope` and `DelayedSmtpEnvelope` to `DelayedEnvelope`. - * [BC BREAK] Added a required `string $transport` argument to `MessageEvent::__construct`. - -Messenger ---------- - - * [BC BREAK] Removed `SendersLocatorInterface::getSenderByAlias` added in 4.3. - * [BC BREAK] Removed `$retryStrategies` argument from `Worker::__construct`. - * [BC BREAK] Changed arguments of `ConsumeMessagesCommand::__construct`. - * [BC BREAK] Removed `$senderClassOrAlias` argument from `RedeliveryStamp::__construct`. - * [BC BREAK] Removed `UnknownSenderException`. - * [BC BREAK] Removed `WorkerInterface`. - * [BC BREAK] Removed `$onHandledCallback` of `Worker::run(array $options = [], callable $onHandledCallback = null)`. - * [BC BREAK] Removed `StopWhenMemoryUsageIsExceededWorker` in favor of `StopWorkerOnMemoryLimitListener`. - * [BC BREAK] Removed `StopWhenMessageCountIsExceededWorker` in favor of `StopWorkerOnMessageLimitListener`. - * [BC BREAK] Removed `StopWhenTimeLimitIsReachedWorker` in favor of `StopWorkerOnTimeLimitListener`. - * [BC BREAK] Removed `StopWhenRestartSignalIsReceived` in favor of `StopWorkerOnRestartSignalListener`. - * Marked the `MessengerDataCollector` class as `@final`. - -Mime ----- - - * Removed `NamedAddress`, use `Address` instead (which supports a name now) - -MonologBridge --------------- - - * The `RouteProcessor` has been marked final. - -Process -------- - - * Deprecated the `Process::inheritEnvironmentVariables()` method: env variables are always inherited. - -PropertyAccess --------------- - - * Deprecated passing `null` as 2nd argument of `PropertyAccessor::createCache()` method (`$defaultLifetime`), pass `0` instead. - -Routing -------- - - * Deprecated `ServiceRouterLoader` in favor of `ContainerLoader`. - * Deprecated `ObjectRouteLoader` in favor of `ObjectLoader`. - -Security --------- - - * The `LdapUserProvider` class has been deprecated, use `Symfony\Component\Ldap\Security\LdapUserProvider` instead. - * Implementations of `PasswordEncoderInterface` and `UserPasswordEncoderInterface` should add a new `needsRehash()` method - * Deprecated returning a non-boolean value when implementing `Guard\AuthenticatorInterface::checkCredentials()`. Please explicitly return `false` to indicate invalid credentials. - * The `ListenerInterface` is deprecated, extend `AbstractListener` instead. - * Deprecated passing more than one attribute to `AccessDecisionManager::decide()` and `AuthorizationChecker::isGranted()` (and indirectly the `is_granted()` Twig and ExpressionLanguage function) - - **Before** - ```php - if ($this->authorizationChecker->isGranted(['ROLE_USER', 'ROLE_ADMIN'])) { - // ... - } - ``` - - **After** - ```php - if ($this->authorizationChecker->isGranted(new Expression("is_granted('ROLE_USER') or is_granted('ROLE_ADMIN')"))) {} - - // or: - if ($this->authorizationChecker->isGranted('ROLE_USER') - || $this->authorizationChecker->isGranted('ROLE_ADMIN') - ) {} - ``` - -SecurityBundle --------------- - - * Marked the `SecurityDataCollector` class as `@final`. - -Serializer ----------- - - * Deprecated the `XmlEncoder::TYPE_CASE_ATTRIBUTES` constant. Use `XmlEncoder::TYPE_CAST_ATTRIBUTES` instead. - -Stopwatch ---------- - - * Deprecated passing `null` as 1st (`$id`) argument of `Section::get()` method, pass a valid child section identifier instead. - -Translation ------------ - - * Deprecated support for using `null` as the locale in `Translator`. - * Deprecated accepting STDIN implicitly when using the `lint:xliff` command, use `lint:xliff -` (append a dash) instead to make it explicit. - * Marked the `TranslationDataCollector` class as `@final`. - -TwigBridge ----------- - - * Deprecated to pass `$rootDir` and `$fileLinkFormatter` as 5th and 6th argument respectively to the - `DebugCommand::__construct()` method, swap the variables position. - * Deprecated accepting STDIN implicitly when using the `lint:twig` command, use `lint:twig -` (append a dash) instead to make it explicit. - * Marked the `TwigDataCollector` class as `@final`. - -TwigBundle ----------- - - * Deprecated `twig.exception_controller` configuration option. - - If you were not using this option previously, set it to `null`: - - After: - ```yaml - twig: - exception_controller: null - ``` - - If you were using this option previously, set it to `null` and use `framework.error_controller` instead: - - Before: - ```yaml - twig: - exception_controller: 'App\Controller\MyExceptionController' - ``` - - After: - ```yaml - twig: - exception_controller: null - - framework: - error_controller: 'App\Controller\MyExceptionController' - ``` - - The new default exception controller will also change the error response content according to - https://tools.ietf.org/html/rfc7807 for `json`, `xml`, `atom` and `txt` formats: - - Before (HTTP status code `200`): - ```json - { - "error": { - "code": 404, - "message": "Sorry, the page you are looking for could not be found" - } - } - ``` - - After (HTTP status code `404`): - ```json - { - "title": "Not Found", - "status": 404, - "detail": "Sorry, the page you are looking for could not be found" - } - ``` - - * Deprecated the `ExceptionController` and `PreviewErrorController` controllers, use `ErrorController` from the HttpKernel component instead - * Deprecated all built-in error templates, use the error renderer mechanism of the `ErrorHandler` component - * Deprecated loading custom error templates in non-html formats. Custom HTML error pages based on Twig keep working as before: - - Before (`templates/bundles/TwigBundle/Exception/error.json.twig`): - ```twig - { - "type": "https://example.com/error", - "title": "{{ status_text }}", - "status": {{ status_code }} - } - ``` - - After (`App\Serializer\ProblemJsonNormalizer`): - ```php - class ProblemJsonNormalizer implements NormalizerInterface - { - public function normalize($exception, $format = null, array $context = []) - { - return [ - 'type' => 'https://example.com/error', - 'title' => $exception->getStatusText(), - 'status' => $exception->getStatusCode(), - ]; - } - - public function supportsNormalization($data, $format = null) - { - return 'json' === $format && $data instanceof FlattenException; - } - } - ``` - -Validator ---------- - - * [BC BREAK] Using null as `$classValidatorRegexp` value in `DoctrineLoader::__construct` or `PropertyInfoLoader::__construct` will not enable auto-mapping for all classes anymore, use `'{.*}'` instead. - * Deprecated passing an `ExpressionLanguage` instance as the second argument of `ExpressionValidator::__construct()`. - * Deprecated using anything else than a `string` as the code of a `ConstraintViolation`, a `string` type-hint will - be added to the constructor of the `ConstraintViolation` class and to the `ConstraintViolationBuilder::setCode()` - method in 5.0. - * Deprecated passing an `ExpressionLanguage` instance as the second argument of `ExpressionValidator::__construct()`. - Pass it as the first argument instead. - * The `Length` constraint expects the `allowEmptyString` option to be defined - when the `min` option is used. - Set it to `true` to keep the current behavior and `false` to reject empty strings. - In 5.0, it'll become optional and will default to `false`. - * Overriding the methods `ConstraintValidatorTestCase::setUp()` and `ConstraintValidatorTestCase::tearDown()` without the `void` return-type is deprecated. - * deprecated `Symfony\Component\Validator\Mapping\Cache\CacheInterface` and all implementations in favor of PSR-6. - * deprecated `ValidatorBuilder::setMetadataCache`, use `ValidatorBuilder::setMappingCache` instead. - * The `Range` constraint has a new message option `notInRangeMessage` that is used when both `min` and `max` values are set. - In case you are using custom translations make sure to add one for this new message. - * Marked the `ValidatorDataCollector` class as `@final`. - -WebProfilerBundle ------------------ - - * Deprecated the `ExceptionController` class in favor of `ExceptionErrorController` - * Deprecated the `TemplateManager::templateExists()` method - -WebServerBundle ---------------- - - * The bundle is deprecated and will be removed in 5.0. - -Yaml ----- - - * Deprecated accepting STDIN implicitly when using the `lint:yaml` command, use `lint:yaml -` (append a dash) instead to make it explicit. diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 67b5ef02c3787..d8ecc8f0f818d 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -1,4 +1,4 @@ -UPGRADE FROM 4.x to 5.0 +UPGRADE FROM 4.4 to 5.0 ======================= BrowserKit @@ -237,7 +237,7 @@ FrameworkBundle * The `Templating\Helper\TranslatorHelper::transChoice()` method has been removed, use the `trans()` one instead with a `%count%` parameter. * Removed support for legacy translations directories `src/Resources/translations/` and `src/Resources//translations/`, use `translations/` instead. * Support for the legacy directory structure in `translation:update` and `debug:translation` commands has been removed. - * Removed the "Psr\SimpleCache\CacheInterface" / "cache.app.simple" service, use "Symfony\Contracts\Cache\CacheInterface" / "cache.app" instead. + * Removed the `Psr\SimpleCache\CacheInterface` / `cache.app.simple` service, use `Symfony\Contracts\Cache\CacheInterface` / `cache.app` instead. * Removed support for `templating` engine in `TemplateController`, use Twig instead * Removed `ResolveControllerNameSubscriber`. * Removed `routing.loader.service`. @@ -260,7 +260,7 @@ HttpFoundation * The `$size` argument of the `UploadedFile` constructor has been removed. * The `getClientSize()` method of the `UploadedFile` class has been removed. * The `getSession()` method of the `Request` class throws an exception when session is null. - * The default value of the "$secure" and "$samesite" arguments of Cookie's constructor + * The default value of the `$secure` and `$samesite` arguments of Cookie's constructor changed respectively from "false" to "null" and from "null" to "lax". * The `MimeTypeGuesserInterface` and `ExtensionGuesserInterface` interfaces have been removed, use `Symfony\Component\Mime\MimeTypesInterface` instead. @@ -561,7 +561,7 @@ TwigBridge ---------- * Removed argument `$rootDir` from the `DebugCommand::__construct()` method and the 5th argument must be an instance of `FileLinkFormatter` - * removed the `$requestStack` and `$requestContext` arguments of the + * Removed the `$requestStack` and `$requestContext` arguments of the `HttpFoundationExtension`, pass a `Symfony\Component\HttpFoundation\UrlHelper` instance as the only argument instead * Removed support for implicit STDIN usage in the `lint:twig` command, use `lint:twig -` (append a dash) instead to make it explicit. diff --git a/UPGRADE-5.1.md b/UPGRADE-5.1.md new file mode 100644 index 0000000000000..3143e173bd05e --- /dev/null +++ b/UPGRADE-5.1.md @@ -0,0 +1,191 @@ +UPGRADE FROM 5.0 to 5.1 +======================= + +Config +------ + + * The signature of method `NodeDefinition::setDeprecated()` has been updated to `NodeDefinition::setDeprecated(string $package, string $version, string $message)`. + * The signature of method `BaseNode::setDeprecated()` has been updated to `BaseNode::setDeprecated(string $package, string $version, string $message)`. + * Passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node is deprecated + * Deprecated `BaseNode::getDeprecationMessage()`, use `BaseNode::getDeprecation()` instead + +Console +------- + + * `Command::setHidden()` is final since Symfony 5.1 + +DependencyInjection +------------------- + + * The signature of method `Definition::setDeprecated()` has been updated to `Definition::setDeprecation(string $package, string $version, string $message)`. + * The signature of method `Alias::setDeprecated()` has been updated to `Alias::setDeprecation(string $package, string $version, string $message)`. + * The signature of method `DeprecateTrait::deprecate()` has been updated to `DeprecateTrait::deprecation(string $package, string $version, string $message)`. + * Deprecated the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service, + configure them explicitly instead. + * Deprecated `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead. + * Deprecated `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead. + * The `inline()` function from the PHP-DSL has been deprecated, use `inline_service()` instead + * The `ref()` function from the PHP-DSL has been deprecated, use `service()` instead + +Dotenv +------ + + * Deprecated passing `$usePutenv` argument to Dotenv's constructor, use `Dotenv::usePutenv()` instead. + +EventDispatcher +--------------- + + * Deprecated `LegacyEventDispatcherProxy`. Use the event dispatcher without the proxy. + +Form +---- + + * Not configuring the `rounding_mode` option of the `PercentType` is deprecated. It will default to `\NumberFormatter::ROUND_HALFUP` in Symfony 6. + * Not passing a rounding mode to the constructor of `PercentToLocalizedStringTransformer` is deprecated. It will default to `\NumberFormatter::ROUND_HALFUP` in Symfony 6. + * Implementing the `FormConfigInterface` without implementing the `getIsEmptyCallback()` method + is deprecated. The method will be added to the interface in 6.0. + * Implementing the `FormConfigBuilderInterface` without implementing the `setIsEmptyCallback()` method + is deprecated. The method will be added to the interface in 6.0. + * Added argument `callable|null $filter` to `ChoiceListFactoryInterface::createListFromChoices()` and `createListFromLoader()` - not defining them is deprecated. + * Using `Symfony\Component\Form\Extension\Validator\Util\ServerParams` class is deprecated, use its parent `Symfony\Component\Form\Util\ServerParams` instead. + * The `NumberToLocalizedStringTransformer::ROUND_*` constants have been deprecated, use `\NumberFormatter::ROUND_*` instead. + +FrameworkBundle +--------------- + + * Deprecated passing a `RouteCollectionBuilder` to `MicroKernelTrait::configureRoutes()`, type-hint `RoutingConfigurator` instead + * Deprecated *not* setting the "framework.router.utf8" configuration option as it will default to `true` in Symfony 6.0 + * Deprecated `session.attribute_bag` service and `session.flash_bag` service. + +HttpFoundation +-------------- + + * Deprecate `Response::create()`, `JsonResponse::create()`, + `RedirectResponse::create()`, and `StreamedResponse::create()` methods (use + `__construct()` instead) + * Made the Mime component an optional dependency + +HttpKernel +---------- + + * Made `WarmableInterface::warmUp()` return a list of classes or files to preload on PHP 7.4+ + not returning an array is deprecated + * Deprecated support for `service:action` syntax to reference controllers. Use `serviceOrFqcn::method` instead. + +Inflector +--------- + + * The component has been deprecated, use `EnglishInflector` from the String component instead. + +Mailer +------ + + * Deprecated passing Mailgun headers without their "h:" prefix. + * Deprecated the `SesApiTransport` class. It has been replaced by SesApiAsyncAwsTransport Run `composer require async-aws/ses` to use the new classes. + * Deprecated the `SesHttpTransport` class. It has been replaced by SesHttpAsyncAwsTransport Run `composer require async-aws/ses` to use the new classes. + +Messenger +--------- + + * Deprecated AmqpExt transport. It has moved to a separate package. Run `composer require symfony/amqp-messenger` to use the new classes. + * Deprecated Doctrine transport. It has moved to a separate package. Run `composer require symfony/doctrine-messenger` to use the new classes. + * Deprecated RedisExt transport. It has moved to a separate package. Run `composer require symfony/redis-messenger` to use the new classes. + * Deprecated use of invalid options in Redis and AMQP connections. + * Deprecated *not* declaring a `\Throwable` argument in `RetryStrategyInterface::isRetryable()` + * Deprecated *not* declaring a `\Throwable` argument in `RetryStrategyInterface::getWaitingTime()` + +Notifier +-------- + + * [BC BREAK] The `ChatMessage::fromNotification()` method's `$recipient` and `$transport` + arguments were removed. + * [BC BREAK] The `EmailMessage::fromNotification()` and `SmsMessage::fromNotification()` + methods' `$transport` argument was removed. + +OptionsResolver +--------------- + + * The signature of method `OptionsResolver::setDeprecated()` has been updated to `OptionsResolver::setDeprecated(string $option, string $package, string $version, $message)`. + * Deprecated `OptionsResolverIntrospector::getDeprecationMessage()`, use `OptionsResolverIntrospector::getDeprecation()` instead. + +PhpUnitBridge +------------- + + * Deprecated the `@expectedDeprecation` annotation, use the `ExpectDeprecationTrait::expectDeprecation()` method instead. + +Routing +------- + + * Deprecated `RouteCollectionBuilder` in favor of `RoutingConfigurator`. + * Added argument `$priority` to `RouteCollection::add()` + * Deprecated the `RouteCompiler::REGEX_DELIMITER` constant + +SecurityBundle +-------------- + + * Deprecated `anonymous: lazy` in favor of `lazy: true` + + *Before* + ```yaml + security: + firewalls: + main: + anonymous: lazy + ``` + + *After* + ```yaml + security: + firewalls: + main: + anonymous: true + lazy: true + ``` + * Marked the `AnonymousFactory`, `FormLoginFactory`, `FormLoginLdapFactory`, `GuardAuthenticationFactory`, + `HttpBasicFactory`, `HttpBasicLdapFactory`, `JsonLoginFactory`, `JsonLoginLdapFactory`, `RememberMeFactory`, `RemoteUserFactory` + and `X509Factory` as `@internal`. Instead of extending these classes, create your own implementation based on + `SecurityFactoryInterface`. + +Security +-------- + + * Deprecated `ROLE_PREVIOUS_ADMIN` role in favor of `IS_IMPERSONATOR` attribute. + + *before* + ```twig + {% if is_granted('ROLE_PREVIOUS_ADMIN') %} + Exit impersonation + {% endif %} + ``` + + *after* + ```twig + {% if is_granted('IS_IMPERSONATOR') %} + Exit impersonation + {% endif %} + ``` + + * Deprecated `LogoutSuccessHandlerInterface` and `LogoutHandlerInterface`, register a listener on the `LogoutEvent` event instead. + * Deprecated `DefaultLogoutSuccessHandler` in favor of `DefaultLogoutListener`. + * Deprecated `RememberMeServicesInterface` implementations without a `logout(Request $request, Response $response, TokenInterface $token)` method. + +Yaml +---- + + * Added support for parsing numbers prefixed with `0o` as octal numbers. + * Deprecated support for parsing numbers starting with `0` as octal numbers. They will be parsed as strings as of Symfony 6.0. Prefix numbers with `0o` + so that they are parsed as octal numbers. + + Before: + + ```yaml + Yaml::parse('072'); + ``` + + After: + + ```yaml + Yaml::parse('0o72'); + ``` + + * Deprecated using the `!php/object` and `!php/const` tags without a value. diff --git a/UPGRADE-5.2.md b/UPGRADE-5.2.md new file mode 100644 index 0000000000000..c49e55445e34d --- /dev/null +++ b/UPGRADE-5.2.md @@ -0,0 +1,176 @@ +UPGRADE FROM 5.1 to 5.2 +======================= + +DependencyInjection +------------------- + + * Deprecated `Definition::setPrivate()` and `Alias::setPrivate()`, use `setPublic()` instead + +FrameworkBundle +--------------- + + * Deprecated the public `form.factory`, `form.type.file`, `translator`, `security.csrf.token_manager`, `serializer`, + `cache_clearer`, `filesystem` and `validator` services to private. + * If you configured the `framework.cache.prefix_seed` option, you might want to add the `%kernel.environment%` to its value to + keep cache namespaces separated by environment of the app. The `%kernel.container_class%` (which includes the environment) + used to be added by default to the seed, which is not the case anymore. This allows sharing caches between + apps or different environments. + * Deprecated the `lock.RESOURCE_NAME` and `lock.RESOURCE_NAME.store` services and the `lock`, `LockInterface`, `lock.store` and `PersistingStoreInterface` aliases, use `lock.RESOURCE_NAME.factory`, `lock.factory` or `LockFactory` instead. + +Form +---- + + * Deprecated `PropertyPathMapper` in favor of `DataMapper` and `PropertyPathAccessor`. + + Before: + + ```php + use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper; + + $builder->setDataMapper(new PropertyPathMapper()); + ``` + + After: + + ```php + use Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor; + use Symfony\Component\Form\Extension\Core\DataMapper\DataMapper; + + $builder->setDataMapper(new DataMapper(new PropertyPathAccessor())); + ``` + +HttpFoundation +-------------- + + * Deprecated not passing a `Closure` together with `FILTER_CALLBACK` to `ParameterBag::filter()`; wrap your filter in a closure instead. + * Deprecated the `Request::HEADER_X_FORWARDED_ALL` constant, use either `Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO` or `Request::HEADER_X_FORWARDED_AWS_ELB` or `Request::HEADER_X_FORWARDED_TRAEFIK`constants instead. + * Deprecated `BinaryFileResponse::create()`, use `__construct()` instead + +Lock +---- + + * `MongoDbStore` does not implement `BlockingStoreInterface` anymore, typehint against `PersistingStoreInterface` instead. + * deprecated `NotSupportedException`, it shouldn't be thrown anymore. + * deprecated `RetryTillSaveStore`, logic has been moved in `Lock` and is not needed anymore. + +Mime +---- + + * Deprecated `Address::fromString()`, use `Address::create()` instead + +Monolog +------- + + * The `$actionLevel` constructor argument of `Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy` has been deprecated and replaced by the `$inner` one which expects an ActivationStrategyInterface to decorate instead. `Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy` will become final in 6.0. + * The `$actionLevel` constructor argument of `Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy` has been deprecated and replaced by the `$inner` one which expects an ActivationStrategyInterface to decorate instead. `Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy` will become final in 6.0 + +Notifier +-------- + + * [BC BREAK] The `TransportInterface::send()` and `AbstractTransport::doSend()` methods changed to return a `?SentMessage` instance instead of `void`. + * [BC BREAK] Changed the type-hint of the `$recipient` argument in the `as*Message()` method + of `EmailNotificationInterface` and `SmsNotificationInterface` to `EmailRecipientInterface` + and `SmsRecipientInterface`. + * [BC BREAK] Removed the `AdminRecipient`. + * [BC BREAK] Changed the type-hint of the `$recipient` argument in `NotifierInterface::send()`, + `Notifier::getChannels()`, `ChannelInterface::notifiy()` and `ChannelInterface::supports()` to + `RecipientInterface`. + +PropertyAccess +-------------- + + * Deprecated passing a boolean as the first argument of `PropertyAccessor::__construct()`. + Pass a combination of bitwise flags instead. + +PropertyInfo +------------ + + * Deprecated the `enable_magic_call_extraction` context option in `ReflectionExtractor::getWriteInfo()` and `ReflectionExtractor::getReadInfo()` in favor of `enable_magic_methods_extraction`. + +TwigBundle +---------- + + * Deprecated the public `twig` service to private. + +TwigBridge +---------- + + * Changed 2nd argument type of `TranslationExtension::__construct()` to `TranslationNodeVisitor` + +Validator +--------- + + * Deprecated the `allowEmptyString` option of the `Length` constraint. + + Before: + + ```php + use Symfony\Component\Validator\Constraints as Assert; + + /** + * @Assert\Length(min=5, allowEmptyString=true) + */ + ``` + + After: + + ```php + use Symfony\Component\Validator\Constraints as Assert; + + /** + * @Assert\AtLeastOneOf({ + * @Assert\Blank(), + * @Assert\Length(min=5) + * }) + */ + ``` + + * Deprecated the `NumberConstraintTrait` trait. + + * Deprecated setting a Doctrine annotation reader via `ValidatorBuilder::enableAnnotationMapping()` + + Before: + + ```php + $builder->enableAnnotationMapping($reader); + ``` + + After: + + ```php + $builder->enableAnnotationMapping(true) + ->setDoctrineAnnotationReader($reader); + ``` + + * Deprecated creating a Doctrine annotation reader via `ValidatorBuilder::enableAnnotationMapping()` + + Before: + + ```php + $builder->enableAnnotationMapping(); + ``` + + After: + + ```php + $builder->enableAnnotationMapping(true) + ->addDefaultDoctrineAnnotationReader(); + ``` + +Security +-------- + + * [BC break] In the experimental authenticator-based system, * `TokenInterface::getUser()` + returns `null` in case of unauthenticated session. + + * [BC break] `AccessListener::PUBLIC_ACCESS` has been removed in favor of + `AuthenticatedVoter::PUBLIC_ACCESS`. + + * Deprecated `setProviderKey()`/`getProviderKey()` in favor of `setFirewallName()/getFirewallName()` + in `PreAuthenticatedToken`, `RememberMeToken`, `SwitchUserToken`, `UsernamePasswordToken`, + `DefaultAuthenticationSuccessHandler`, the old methods will be removed in 6.0. + + * Deprecated the `AbstractRememberMeServices::$providerKey` property in favor of + `AbstractRememberMeServices::$firewallName`, the old property will be removed + in 6.0. + diff --git a/UPGRADE-6.0.md b/UPGRADE-6.0.md new file mode 100644 index 0000000000000..b0e52953dd672 --- /dev/null +++ b/UPGRADE-6.0.md @@ -0,0 +1,241 @@ +UPGRADE FROM 5.x to 6.0 +======================= + +Config +------ + + * The signature of method `NodeDefinition::setDeprecated()` has been updated to `NodeDefinition::setDeprecation(string $package, string $version, string $message)`. + * The signature of method `BaseNode::setDeprecated()` has been updated to `BaseNode::setDeprecation(string $package, string $version, string $message)`. + * Passing a null message to `BaseNode::setDeprecated()` to un-deprecate a node is not supported anymore. + * Removed `BaseNode::getDeprecationMessage()`, use `BaseNode::getDeprecation()` instead. + +Console +------- + + * `Command::setHidden()` has a default value (`true`) for `$hidden` parameter + +DependencyInjection +------------------- + + * The signature of method `Definition::setDeprecated()` has been updated to `Definition::setDeprecation(string $package, string $version, string $message)`. + * The signature of method `Alias::setDeprecated()` has been updated to `Alias::setDeprecation(string $package, string $version, string $message)`. + * The signature of method `DeprecateTrait::deprecate()` has been updated to `DeprecateTrait::deprecation(string $package, string $version, string $message)`. + * Removed the `Psr\Container\ContainerInterface` and `Symfony\Component\DependencyInjection\ContainerInterface` aliases of the `service_container` service, + configure them explicitly instead. + * Removed `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead. + * Removed `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead. + * The `inline()` function from the PHP-DSL has been removed, use `inline_service()` instead. + * The `ref()` function from the PHP-DSL has been removed, use `service()` instead. + * Removed `Definition::setPrivate()` and `Alias::setPrivate()`, use `setPublic()` instead + +Dotenv +------ + + * Removed argument `$usePutenv` from Dotenv's constructor, use `Dotenv::usePutenv()` instead. + +EventDispatcher +--------------- + + * Removed `LegacyEventDispatcherProxy`. Use the event dispatcher without the proxy. + +Form +---- + + * The default value of the `rounding_mode` option of the `PercentType` has been changed to `\NumberFormatter::ROUND_HALFUP`. + * The default rounding mode of the `PercentToLocalizedStringTransformer` has been changed to `\NumberFormatter::ROUND_HALFUP`. + * Added the `getIsEmptyCallback()` method to the `FormConfigInterface`. + * Added the `setIsEmptyCallback()` method to the `FormConfigBuilderInterface`. + * Added argument `callable|null $filter` to `ChoiceListFactoryInterface::createListFromChoices()` and `createListFromLoader()`. + * The `Symfony\Component\Form\Extension\Validator\Util\ServerParams` class has been removed, use its parent `Symfony\Component\Form\Util\ServerParams` instead. + * The `NumberToLocalizedStringTransformer::ROUND_*` constants have been removed, use `\NumberFormatter::ROUND_*` instead. + * Removed `PropertyPathMapper` in favor of `DataMapper` and `PropertyPathAccessor`. + +FrameworkBundle +--------------- + + * `MicroKernelTrait::configureRoutes()` is now always called with a `RoutingConfigurator` + * The "framework.router.utf8" configuration option defaults to `true` + * Removed `session.attribute_bag` service and `session.flash_bag` service. + * The `form.factory`, `form.type.file`, `translator`, `security.csrf.token_manager`, `serializer`, + `cache_clearer`, `filesystem` and `validator` services are now private. + * Removed the `lock.RESOURCE_NAME` and `lock.RESOURCE_NAME.store` services and the `lock`, `LockInterface`, `lock.store` and `PersistingStoreInterface` aliases, use `lock.RESOURCE_NAME.factory`, `lock.factory` or `LockFactory` instead. + +HttpFoundation +-------------- + + * Removed `Response::create()`, `JsonResponse::create()`, + `RedirectResponse::create()`, `StreamedResponse::create()` and + `BinaryFileResponse::create()` methods (use `__construct()` instead) + * Not passing a `Closure` together with `FILTER_CALLBACK` to `ParameterBag::filter()` throws an `InvalidArgumentException`; wrap your filter in a closure instead. + * Removed the `Request::HEADER_X_FORWARDED_ALL` constant, use either `Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO` or `Request::HEADER_X_FORWARDED_AWS_ELB` or `Request::HEADER_X_FORWARDED_TRAEFIK`constants instead. + +HttpKernel +---------- + + * Made `WarmableInterface::warmUp()` return a list of classes or files to preload on PHP 7.4+ + * Removed support for `service:action` syntax to reference controllers. Use `serviceOrFqcn::method` instead. + +Inflector +--------- + + * The component has been removed, use `EnglishInflector` from the String component instead. + +Lock +---- + + * Removed the `NotSupportedException`. It shouldn't be thrown anymore. + * Removed the `RetryTillSaveStore`. Logic has been moved in `Lock` and is not needed anymore. + +Mailer +------ + + * Removed the `SesApiTransport` class. Use `SesApiAsyncAwsTransport` instead. + * Removed the `SesHttpTransport` class. Use `SesHttpAsyncAwsTransport` instead. + +Messenger +--------- + + * Removed AmqpExt transport. Run `composer require symfony/amqp-messenger` to keep the transport in your application. + * Removed Doctrine transport. Run `composer require symfony/doctrine-messenger` to keep the transport in your application. + * Removed RedisExt transport. Run `composer require symfony/redis-messenger` to keep the transport in your application. + * Use of invalid options in Redis and AMQP connections now throws an error. + * The signature of method `RetryStrategyInterface::isRetryable()` has been updated to `RetryStrategyInterface::isRetryable(Envelope $message, \Throwable $throwable = null)`. + * The signature of method `RetryStrategyInterface::getWaitingTime()` has been updated to `RetryStrategyInterface::getWaitingTime(Envelope $message, \Throwable $throwable = null)`. + +Mime +---- + + * Removed `Address::fromString()`, use `Address::create()` instead + +Monolog +------- + + * The `$actionLevel` constructor argument of `Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy` has been replaced by the `$inner` one which expects an ActivationStrategyInterface to decorate instead. `Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy` is now final. + * The `$actionLevel` constructor argument of `Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy` has been replaced by the `$inner` one which expects an ActivationStrategyInterface to decorate instead. `Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy` is now final. + +OptionsResolver +--------------- + + * The signature of method `OptionsResolver::setDeprecated()` has been updated to `OptionsResolver::setDeprecated(string $option, string $package, string $version, $message)`. + * Removed `OptionsResolverIntrospector::getDeprecationMessage()`, use `OptionsResolverIntrospector::getDeprecation()` instead. + +PhpUnitBridge +------------- + + * Removed support for `@expectedDeprecation` annotations, use the `ExpectDeprecationTrait::expectDeprecation()` method instead. + +PropertyAccess +-------------- + + * Dropped support for booleans as the first argument of `PropertyAccessor::__construct()`. + Pass a combination of bitwise flags instead. + +PropertyInfo +------------ + + * Dropped the `enable_magic_call_extraction` context option in `ReflectionExtractor::getWriteInfo()` and `ReflectionExtractor::getReadInfo()` in favor of `enable_magic_methods_extraction`. + +Routing +------- + + * Removed `RouteCollectionBuilder`. + * Added argument `$priority` to `RouteCollection::add()` + * Removed the `RouteCompiler::REGEX_DELIMITER` constant + +Security +-------- + + * Removed `ROLE_PREVIOUS_ADMIN` role in favor of `IS_IMPERSONATOR` attribute + * Removed `LogoutSuccessHandlerInterface` and `LogoutHandlerInterface`, register a listener on the `LogoutEvent` event instead. + * Removed `DefaultLogoutSuccessHandler` in favor of `DefaultLogoutListener`. + * Added a `logout(Request $request, Response $response, TokenInterface $token)` method to the `RememberMeServicesInterface`. + * Removed `setProviderKey()`/`getProviderKey()` in favor of `setFirewallName()/getFirewallName()` + in `PreAuthenticatedToken`, `RememberMeToken`, `SwitchUserToken`, `UsernamePasswordToken`, + `DefaultAuthenticationSuccessHandler`. + * Removed the `AbstractRememberMeServices::$providerKey` property in favor of `AbstractRememberMeServices::$firewallName` + +TwigBundle +---------- + + * The `twig` service is now private. + +Validator +--------- + + * Removed the `allowEmptyString` option from the `Length` constraint. + + Before: + + ```php + use Symfony\Component\Validator\Constraints as Assert; + + /** + * @Assert\Length(min=5, allowEmptyString=true) + */ + ``` + + After: + + ```php + use Symfony\Component\Validator\Constraints as Assert; + + /** + * @Assert\AtLeastOneOf({ + * @Assert\Blank(), + * @Assert\Length(min=5) + * }) + */ + ``` + + * Removed the `NumberConstraintTrait` trait. + + * `ValidatorBuilder::enableAnnotationMapping()` does not accept a Doctrine annotation reader anymore. + + Before: + + ```php + $builder->enableAnnotationMapping($reader); + ``` + + After: + + ```php + $builder->enableAnnotationMapping(true) + ->setDoctrineAnnotationReader($reader); + ``` + + * `ValidatorBuilder::enableAnnotationMapping()` won't automatically setup a Doctrine annotation reader anymore. + + Before: + + ```php + $builder->enableAnnotationMapping(); + ``` + + After: + + ```php + $builder->enableAnnotationMapping(true) + ->addDefaultDoctrineAnnotationReader(); + ``` + +Yaml +---- + + * Added support for parsing numbers prefixed with `0o` as octal numbers. + * Removed support for parsing numbers starting with `0` as octal numbers. They will be parsed as strings. Prefix numbers with `0o` + so that they are parsed as octal numbers. + + Before: + + ```yaml + Yaml::parse('072'); + ``` + + After: + + ```yaml + Yaml::parse('0o72'); + ``` + + * Removed support for using the `!php/object` and `!php/const` tags without a value. diff --git a/composer.json b/composer.json index 737f767885da5..fcc78bf789953 100644 --- a/composer.json +++ b/composer.json @@ -26,30 +26,33 @@ "psr/log-implementation": "1.0", "psr/simple-cache-implementation": "1.0", "symfony/cache-implementation": "1.0|2.0", - "symfony/event-dispatcher-implementation": "1.1", - "symfony/http-client-implementation": "1.1|2.0", + "symfony/event-dispatcher-implementation": "2.0", + "symfony/http-client-implementation": "2.2", "symfony/service-implementation": "1.0|2.0", - "symfony/translation-implementation": "1.0|2.0" + "symfony/translation-implementation": "2.3" }, "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", "ext-xml": "*", "friendsofphp/proxy-manager-lts": "^1.0.2", "doctrine/event-manager": "~1.0", - "doctrine/persistence": "^1.3|^2", - "twig/twig": "^1.43|^2.13|^3.0.4", + "doctrine/persistence": "^2", + "twig/twig": "^2.13|^3.0.4", "psr/cache": "^1.0|^2.0", "psr/container": "^1.0", + "psr/event-dispatcher": "^1.0", "psr/link": "^1.0", "psr/log": "~1.0", - "symfony/contracts": "^1.1.8", + "symfony/contracts": "^2.1", "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-icu": "~1.0", "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php72": "~1.5", "symfony/polyfill-php73": "^1.11", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-uuid": "^1.15" }, "replace": { "symfony/asset": "self.version", @@ -60,7 +63,6 @@ "symfony/console": "self.version", "symfony/css-selector": "self.version", "symfony/dependency-injection": "self.version", - "symfony/debug": "self.version", "symfony/debug-bundle": "self.version", "symfony/doctrine-bridge": "self.version", "symfony/dom-crawler": "self.version", @@ -86,50 +88,59 @@ "symfony/messenger": "self.version", "symfony/mime": "self.version", "symfony/monolog-bridge": "self.version", + "symfony/notifier": "self.version", "symfony/options-resolver": "self.version", "symfony/postmark-mailer": "self.version", "symfony/process": "self.version", "symfony/property-access": "self.version", "symfony/property-info": "self.version", "symfony/proxy-manager-bridge": "self.version", + "symfony/rate-limiter": "self.version", "symfony/routing": "self.version", - "symfony/security": "self.version", + "symfony/security-bundle": "self.version", "symfony/security-core": "self.version", "symfony/security-csrf": "self.version", "symfony/security-guard": "self.version", "symfony/security-http": "self.version", - "symfony/security-bundle": "self.version", + "symfony/semaphore": "self.version", "symfony/sendgrid-mailer": "self.version", "symfony/serializer": "self.version", "symfony/stopwatch": "self.version", + "symfony/string": "self.version", "symfony/templating": "self.version", "symfony/translation": "self.version", "symfony/twig-bridge": "self.version", "symfony/twig-bundle": "self.version", + "symfony/uid": "self.version", "symfony/validator": "self.version", "symfony/var-dumper": "self.version", "symfony/var-exporter": "self.version", "symfony/web-link": "self.version", "symfony/web-profiler-bundle": "self.version", - "symfony/web-server-bundle": "self.version", "symfony/workflow": "self.version", "symfony/yaml": "self.version" }, "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "async-aws/ses": "^1.0", + "async-aws/sqs": "^1.0", "cache/integration-tests": "dev-master", "composer/package-versions-deprecated": "^1.8", "doctrine/annotations": "^1.10.4", "doctrine/cache": "~1.6", "doctrine/collections": "~1.0", "doctrine/data-fixtures": "^1.1", - "doctrine/dbal": "^2.6|^3.0", - "doctrine/orm": "^2.6.3", - "doctrine/doctrine-bundle": "^1.5|^2.0", + "doctrine/dbal": "^2.10|^3.0", + "doctrine/orm": "^2.7.3", + "doctrine/doctrine-bundle": "^2.0", "guzzlehttp/promises": "^1.4", "masterminds/html5": "^2.6", - "monolog/monolog": "^1.25.1", + "monolog/monolog": "^1.25.1|^2", "nyholm/psr7": "^1.0", "paragonie/sodium_compat": "^1.8", + "pda/pheanstalk": "^4.0", "php-http/httplug": "^1.0|^2.0", "predis/predis": "~1.1", "psr/http-client": "^1.0", @@ -143,11 +154,11 @@ "twig/markdown-extra": "^2.12|^3" }, "conflict": { + "doctrine/dbal": "<2.10", "egulias/email-validator": "~3.0.0", "masterminds/html5": "<2.6", - "monolog/monolog": ">=2", - "phpdocumentor/reflection-docblock": "<3.0|>=3.2.0,<3.2.2", - "phpdocumentor/type-resolver": "<0.3.0|1.3.*", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", "ocramius/proxy-manager": "<2.1", "phpunit/phpunit": "<5.4.3" }, @@ -160,6 +171,9 @@ "Symfony\\Bundle\\": "src/Symfony/Bundle/", "Symfony\\Component\\": "src/Symfony/Component/" }, + "files": [ + "src/Symfony/Component/String/Resources/functions.php" + ], "classmap": [ "src/Symfony/Component/Intl/Resources/stubs" ], @@ -168,7 +182,9 @@ ] }, "autoload-dev": { - "files": [ "src/Symfony/Component/VarDumper/Resources/functions/dump.php" ] + "files": [ + "src/Symfony/Component/VarDumper/Resources/functions/dump.php" + ] }, "repositories": [ { @@ -176,7 +192,7 @@ "url": "src/Symfony/Contracts", "options": { "versions": { - "symfony/contracts": "1.1.x-dev" + "symfony/contracts": "2.3.x-dev" } } } diff --git a/link b/link index 60cd84dc4b569..a56075840ebb9 100755 --- a/link +++ b/link @@ -47,7 +47,6 @@ $directories = array_merge(...array_values(array_map(function ($part) { }, $braces))); $directories[] = __DIR__.'/src/Symfony/Contracts'; - foreach ($directories as $dir) { if ($filesystem->exists($composer = "$dir/composer.json")) { $sfPackages[json_decode(file_get_contents($composer))->name] = $dir; diff --git a/phpunit b/phpunit index 3a18c4c782e1e..cdd9af8352881 100755 --- a/phpunit +++ b/phpunit @@ -8,9 +8,7 @@ if (!file_exists(__DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit')) { exit(1); } if (!getenv('SYMFONY_PHPUNIT_VERSION')) { - if (\PHP_VERSION_ID < 70200) { - putenv('SYMFONY_PHPUNIT_VERSION=7.5'); - } elseif (\PHP_VERSION_ID < 70300) { + if (\PHP_VERSION_ID < 70300) { putenv('SYMFONY_PHPUNIT_VERSION=8.5'); } else { putenv('SYMFONY_PHPUNIT_VERSION=9.5'); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d7f495fac7216..5bf27434011c1 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -21,6 +21,9 @@ + + + @@ -75,6 +78,7 @@ Symfony\Component\Cache\Traits Symfony\Component\Console Symfony\Component\HttpFoundation + Symfony\Component\Uid diff --git a/src/Symfony/Bridge/Doctrine/CHANGELOG.md b/src/Symfony/Bridge/Doctrine/CHANGELOG.md index 8fe8d410797fa..af0b9366a1b66 100644 --- a/src/Symfony/Bridge/Doctrine/CHANGELOG.md +++ b/src/Symfony/Bridge/Doctrine/CHANGELOG.md @@ -1,6 +1,20 @@ CHANGELOG ========= +5.2.0 +----- + + * added support for symfony/uid as `UlidType` and `UuidType` as Doctrine types + * added `UlidGenerator`, `UuidV1Generator`, `UuidV4Generator` and `UuidV6Generator` + +5.0.0 +----- + + * the `getMetadataDriverClass()` method is abstract and must be implemented by class extending `AbstractDoctrineExtension` + * passing an `IdReader` to the `DoctrineChoiceLoader` when the query cannot be optimized with single id field, throws an exception; pass `null` instead + * not explicitly passing an instance of `IdReader` to `DoctrineChoiceLoader` when it can optimize single id field, will not apply any optimization + * `DoctrineExtractor` now requires an `EntityManagerInterface` on instantiation + 4.4.0 ----- diff --git a/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php b/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php index 24cf25be59f3d..bca2ea2c170da 100644 --- a/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php +++ b/src/Symfony/Bridge/Doctrine/CacheWarmer/ProxyCacheWarmer.php @@ -43,9 +43,12 @@ public function isOptional() /** * {@inheritdoc} + * + * @return string[] A list of files to preload on PHP 7.4+ */ - public function warmUp($cacheDir) + public function warmUp(string $cacheDir) { + $files = []; foreach ($this->registry->getManagers() as $em) { // we need the directory no matter the proxy cache generation strategy if (!is_dir($proxyCacheDir = $em->getConfiguration()->getProxyDir())) { @@ -64,6 +67,14 @@ public function warmUp($cacheDir) $classes = $em->getMetadataFactory()->getAllMetadata(); $em->getProxyFactory()->generateProxyClasses($classes); + + foreach (scandir($proxyCacheDir) as $file) { + if (!is_dir($file = $proxyCacheDir.'/'.$file)) { + $files[] = $file; + } + } } + + return $files; } } diff --git a/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php b/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php index d259e4123976a..8e292cf36b8d7 100644 --- a/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php +++ b/src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php @@ -46,20 +46,16 @@ public function __construct(ManagerRegistry $registry) /** * Adds the stack logger for a connection. - * - * @param string $name */ - public function addLogger($name, DebugStack $logger) + public function addLogger(string $name, DebugStack $logger) { $this->loggers[$name] = $logger; } /** * {@inheritdoc} - * - * @param \Throwable|null $exception */ - public function collect(Request $request, Response $response/*, \Throwable $exception = null*/) + public function collect(Request $request, Response $response, \Throwable $exception = null) { $queries = []; foreach ($this->loggers as $name => $logger) { diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php index f67ecd35c9f5b..00652bb71612a 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/AbstractDoctrineExtension.php @@ -100,11 +100,8 @@ protected function loadMappingInformation(array $objectManager, ContainerBuilder * Register the alias for this mapping driver. * * Aliases can be used in the Query languages of all the Doctrine object managers to simplify writing tasks. - * - * @param array $mappingConfig - * @param string $mappingName */ - protected function setMappingDriverAlias($mappingConfig, $mappingName) + protected function setMappingDriverAlias(array $mappingConfig, string $mappingName) { if (isset($mappingConfig['alias'])) { $this->aliasMap[$mappingConfig['alias']] = $mappingConfig['prefix']; @@ -116,11 +113,9 @@ protected function setMappingDriverAlias($mappingConfig, $mappingName) /** * Register the mapping driver configuration for later use with the object managers metadata driver chain. * - * @param string $mappingName - * * @throws \InvalidArgumentException */ - protected function setMappingDriverConfig(array $mappingConfig, $mappingName) + protected function setMappingDriverConfig(array $mappingConfig, string $mappingName) { $mappingDirectory = $mappingConfig['dir']; if (!is_dir($mappingDirectory)) { @@ -169,10 +164,8 @@ protected function getMappingDriverBundleConfigDefaults(array $bundleConfig, \Re /** * Register all the collected mapping information with the object manager by registering the appropriate mapping drivers. - * - * @param array $objectManager */ - protected function registerMappingDrivers($objectManager, ContainerBuilder $container) + protected function registerMappingDrivers(array $objectManager, ContainerBuilder $container) { // configure metadata driver for each bundle based on the type of mapping files found if ($container->hasDefinition($this->getObjectManagerElementName($objectManager['name'].'_metadata_driver'))) { @@ -226,11 +219,9 @@ protected function registerMappingDrivers($objectManager, ContainerBuilder $cont /** * Assertion if the specified mapping information is valid. * - * @param string $objectManagerName - * * @throws \InvalidArgumentException */ - protected function assertValidMappingConfiguration(array $mappingConfig, $objectManagerName) + protected function assertValidMappingConfiguration(array $mappingConfig, string $objectManagerName) { if (!$mappingConfig['type'] || !$mappingConfig['dir'] || !$mappingConfig['prefix']) { throw new \InvalidArgumentException(sprintf('Mapping definitions for Doctrine manager "%s" require at least the "type", "dir" and "prefix" options.', $objectManagerName)); @@ -248,11 +239,9 @@ protected function assertValidMappingConfiguration(array $mappingConfig, $object /** * Detects what metadata driver to use for the supplied directory. * - * @param string $dir A directory path - * * @return string|null A metadata driver short name, if one can be detected */ - protected function detectMetadataDriver($dir, ContainerBuilder $container) + protected function detectMetadataDriver(string $dir, ContainerBuilder $container) { $configPath = $this->getMappingResourceConfigDirectory(); $extension = $this->getMappingResourceExtension(); @@ -281,12 +270,9 @@ protected function detectMetadataDriver($dir, ContainerBuilder $container) /** * Loads a configured object manager metadata, query or result cache driver. * - * @param array $objectManager A configured object manager - * @param string $cacheName - * * @throws \InvalidArgumentException in case of unknown driver type */ - protected function loadObjectManagerCacheDriver(array $objectManager, ContainerBuilder $container, $cacheName) + protected function loadObjectManagerCacheDriver(array $objectManager, ContainerBuilder $container, string $cacheName) { $this->loadCacheDriver($cacheName, $objectManager['name'], $objectManager[$cacheName.'_driver'], $container); } @@ -294,15 +280,11 @@ protected function loadObjectManagerCacheDriver(array $objectManager, ContainerB /** * Loads a cache driver. * - * @param string $cacheName The cache driver name - * @param string $objectManagerName The object manager name - * @param array $cacheDriver The cache driver mapping - * * @return string * * @throws \InvalidArgumentException */ - protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheDriver, ContainerBuilder $container) + protected function loadCacheDriver(string $cacheName, string $objectManagerName, array $cacheDriver, ContainerBuilder $container) { $cacheDriverServiceId = $this->getObjectManagerElementName($objectManagerName.'_'.$cacheName); @@ -318,7 +300,6 @@ protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheD $memcachedPort = !empty($cacheDriver['port']) ? $cacheDriver['port'] : '%'.$this->getObjectManagerElementName('cache.memcached_port').'%'; $cacheDef = new Definition($memcachedClass); $memcachedInstance = new Definition($memcachedInstanceClass); - $memcachedInstance->setPrivate(true); $memcachedInstance->addMethodCall('addServer', [ $memcachedHost, $memcachedPort, ]); @@ -332,7 +313,6 @@ protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheD $redisPort = !empty($cacheDriver['port']) ? $cacheDriver['port'] : '%'.$this->getObjectManagerElementName('cache.redis_port').'%'; $cacheDef = new Definition($redisClass); $redisInstance = new Definition($redisInstanceClass); - $redisInstance->setPrivate(true); $redisInstance->addMethodCall('connect', [ $redisHost, $redisPort, ]); @@ -356,11 +336,12 @@ protected function loadCacheDriver($cacheName, $objectManagerName, array $cacheD if (!isset($cacheDriver['namespace'])) { // generate a unique namespace for the given application if ($container->hasParameter('cache.prefix.seed')) { - $seed = '.'.$container->getParameterBag()->resolveValue($container->getParameter('cache.prefix.seed')); + $seed = $container->getParameterBag()->resolveValue($container->getParameter('cache.prefix.seed')); } else { $seed = '_'.$container->getParameter('kernel.project_dir'); + $seed .= '.'.$container->getParameter('kernel.container_class'); } - $seed .= '.'.$container->getParameter('kernel.container_class'); + $namespace = 'sf_'.$this->getMappingResourceExtension().'_'.$objectManagerName.'_'.ContainerBuilder::hash($seed); $cacheDriver['namespace'] = $namespace; @@ -405,11 +386,9 @@ protected function fixManagersAutoMappings(array $managerConfigs, array $bundles * * @example $name is 'entity_manager' then the result would be 'doctrine.orm.entity_manager' * - * @param string $name - * * @return string */ - abstract protected function getObjectManagerElementName($name); + abstract protected function getObjectManagerElementName(string $name); /** * Noun that describes the mapped objects such as Entity or Document. @@ -437,12 +416,7 @@ abstract protected function getMappingResourceExtension(); /** * The class name used by the various mapping drivers. */ - protected function getMetadataDriverClass(string $driverType): string - { - @trigger_error(sprintf('Not declaring the "%s" method in class "%s" is deprecated since Symfony 4.4. This method will be abstract in Symfony 5.0.', __METHOD__, static::class), \E_USER_DEPRECATED); - - return '%'.$this->getObjectManagerElementName('metadata.'.$driverType.'.class').'%'; - } + abstract protected function getMetadataDriverClass(string $driverType): string; /** * Search for a manager that is declared as 'auto_mapping' = true. diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterUidTypePass.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterUidTypePass.php new file mode 100644 index 0000000000000..95a74533ba0f5 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/CompilerPass/RegisterUidTypePass.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass; + +use Symfony\Bridge\Doctrine\Types\UlidType; +use Symfony\Bridge\Doctrine\Types\UuidType; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Uid\AbstractUid; + +final class RegisterUidTypePass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if (!class_exists(AbstractUid::class)) { + return; + } + + if (!$container->hasParameter('doctrine.dbal.connection_factory.types')) { + return; + } + + $typeDefinition = $container->getParameter('doctrine.dbal.connection_factory.types'); + + if (!isset($typeDefinition['uuid'])) { + $typeDefinition['uuid'] = ['class' => UuidType::class]; + } + + if (!isset($typeDefinition['ulid'])) { + $typeDefinition['ulid'] = ['class' => UlidType::class]; + } + + $container->setParameter('doctrine.dbal.connection_factory.types', $typeDefinition); + } +} diff --git a/src/Symfony/Bridge/Doctrine/DependencyInjection/Security/UserProvider/EntityFactory.php b/src/Symfony/Bridge/Doctrine/DependencyInjection/Security/UserProvider/EntityFactory.php index 352bf79bfbc7e..aae6a8643868a 100644 --- a/src/Symfony/Bridge/Doctrine/DependencyInjection/Security/UserProvider/EntityFactory.php +++ b/src/Symfony/Bridge/Doctrine/DependencyInjection/Security/UserProvider/EntityFactory.php @@ -33,7 +33,7 @@ public function __construct(string $key, string $providerId) $this->providerId = $providerId; } - public function create(ContainerBuilder $container, $id, $config) + public function create(ContainerBuilder $container, string $id, array $config) { $container ->setDefinition($id, new ChildDefinition($this->providerId)) @@ -52,7 +52,11 @@ public function addConfiguration(NodeDefinition $node) { $node ->children() - ->scalarNode('class')->isRequired()->cannotBeEmpty()->end() + ->scalarNode('class') + ->isRequired() + ->info('The full entity class name of your user class.') + ->cannotBeEmpty() + ->end() ->scalarNode('property')->defaultNull()->end() ->scalarNode('manager_name')->defaultNull()->end() ->end() diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php index c5ba42d471c35..99be884f34b04 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/DoctrineChoiceLoader.php @@ -12,27 +12,20 @@ namespace Symfony\Bridge\Doctrine\Form\ChoiceList; use Doctrine\Persistence\ObjectManager; -use Symfony\Component\Form\ChoiceList\ArrayChoiceList; -use Symfony\Component\Form\ChoiceList\ChoiceListInterface; -use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; +use Symfony\Component\Form\ChoiceList\Loader\AbstractChoiceLoader; /** * Loads choices using a Doctrine object manager. * * @author Bernhard Schussek */ -class DoctrineChoiceLoader implements ChoiceLoaderInterface +class DoctrineChoiceLoader extends AbstractChoiceLoader { private $manager; private $class; private $idReader; private $objectLoader; - /** - * @var ChoiceListInterface - */ - private $choiceList; - /** * Creates a new choice loader. * @@ -47,20 +40,7 @@ public function __construct(ObjectManager $manager, string $class, IdReader $idR $classMetadata = $manager->getClassMetadata($class); if ($idReader && !$idReader->isSingleId()) { - @trigger_error(sprintf('Passing an instance of "%s" to "%s" with an entity class "%s" that has a composite id is deprecated since Symfony 4.3 and will throw an exception in 5.0.', IdReader::class, __CLASS__, $class), \E_USER_DEPRECATED); - - // In Symfony 5.0 - // throw new \InvalidArgumentException(sprintf('The second argument `$idReader` of "%s" must be null when the query cannot be optimized because of composite id fields.', __METHOD__)); - } - - if ((5 > \func_num_args() || false !== func_get_arg(4)) && null === $idReader) { - $idReader = new IdReader($manager, $classMetadata); - - if ($idReader->isSingleId()) { - @trigger_error(sprintf('Not explicitly passing an instance of "%s" to "%s" when it can optimize single id entity "%s" has been deprecated in 4.3 and will not apply any optimization in 5.0.', IdReader::class, __CLASS__, $class), \E_USER_DEPRECATED); - } else { - $idReader = null; - } + throw new \InvalidArgumentException(sprintf('The second argument `$idReader` of "%s" must be null when the query cannot be optimized because of composite id fields.', __METHOD__)); } $this->manager = $manager; @@ -72,81 +52,57 @@ public function __construct(ObjectManager $manager, string $class, IdReader $idR /** * {@inheritdoc} */ - public function loadChoiceList($value = null) + protected function loadChoices(): iterable { - if ($this->choiceList) { - return $this->choiceList; - } - - $objects = $this->objectLoader + return $this->objectLoader ? $this->objectLoader->getEntities() : $this->manager->getRepository($this->class)->findAll(); - - return $this->choiceList = new ArrayChoiceList($objects, $value); } /** - * {@inheritdoc} + * @internal to be remove in Symfony 6 */ - public function loadValuesForChoices(array $choices, $value = null) + protected function doLoadValuesForChoices(array $choices): array { - // Performance optimization - if (empty($choices)) { - return []; - } - // Optimize performance for single-field identifiers. We already // know that the IDs are used as values - $optimize = $this->idReader && (null === $value || \is_array($value) && $value[0] === $this->idReader); - // Attention: This optimization does not check choices for existence - if ($optimize && !$this->choiceList && $this->idReader->isSingleId()) { - $values = []; - + if ($this->idReader) { + trigger_deprecation('symfony/doctrine-bridge', '5.1', 'Not defining explicitly the IdReader as value callback when query can be optimized is deprecated. Don\'t pass the IdReader to "%s" or define the "choice_value" option instead.', __CLASS__); // Maintain order and indices of the given objects + $values = []; foreach ($choices as $i => $object) { if ($object instanceof $this->class) { - // Make sure to convert to the right format - $values[$i] = (string) $this->idReader->getIdValue($object); + $values[$i] = $this->idReader->getIdValue($object); } } return $values; } - return $this->loadChoiceList($value)->getValuesForChoices($choices); + return parent::doLoadValuesForChoices($choices); } - /** - * {@inheritdoc} - */ - public function loadChoicesForValues(array $values, $value = null) + protected function doLoadChoicesForValues(array $values, ?callable $value): array { - // Performance optimization - // Also prevents the generation of "WHERE id IN ()" queries through the - // object loader. At least with MySQL and on the development machine - // this was tested on, no exception was thrown for such invalid - // statements, consequently no test fails when this code is removed. - // https://github.com/symfony/symfony/pull/8981#issuecomment-24230557 - if (empty($values)) { - return []; + $legacy = $this->idReader && null === $value; + + if ($legacy) { + trigger_deprecation('symfony/doctrine-bridge', '5.1', 'Not defining explicitly the IdReader as value callback when query can be optimized is deprecated. Don\'t pass the IdReader to "%s" or define the "choice_value" option instead.', __CLASS__); } // Optimize performance in case we have an object loader and // a single-field identifier - $optimize = $this->idReader && (null === $value || \is_array($value) && $this->idReader === $value[0]); - - if ($optimize && !$this->choiceList && $this->objectLoader && $this->idReader->isSingleId()) { - $unorderedObjects = $this->objectLoader->getEntitiesByIds($this->idReader->getIdField(), $values); - $objectsById = []; + if (($legacy || \is_array($value) && $this->idReader === $value[0]) && $this->objectLoader) { $objects = []; + $objectsById = []; // Maintain order and indices from the given $values // An alternative approach to the following loop is to add the // "INDEX BY" clause to the Doctrine query in the loader, // but I'm not sure whether that's doable in a generic fashion. - foreach ($unorderedObjects as $object) { - $objectsById[(string) $this->idReader->getIdValue($object)] = $object; + foreach ($this->objectLoader->getEntitiesByIds($this->idReader->getIdField(), $values) as $object) { + $objectsById[$this->idReader->getIdValue($object)] = $object; } foreach ($values as $i => $id) { @@ -158,6 +114,6 @@ public function loadChoicesForValues(array $values, $value = null) return $objects; } - return $this->loadChoiceList($value)->getChoicesForValues($values); + return parent::doLoadChoicesForValues($values, $value); } } diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityLoaderInterface.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityLoaderInterface.php index e36043af63cb8..8eb5a84484503 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityLoaderInterface.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/EntityLoaderInterface.php @@ -28,12 +28,7 @@ public function getEntities(); /** * Returns an array of entities matching the given identifiers. * - * @param string $identifier The identifier field of the object. This method - * is not applicable for fields with multiple - * identifiers. - * @param array $values The values of the identifiers - * * @return array The entities */ - public function getEntitiesByIds($identifier, array $values); + public function getEntitiesByIds(string $identifier, array $values); } diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php index f56193e81062f..0625e5175ce08 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/IdReader.php @@ -84,18 +84,16 @@ public function isIntId(): bool * * This method assumes that the object has a single-column ID. * - * @param object $object The object - * - * @return mixed The ID value + * @return string The ID value */ - public function getIdValue($object) + public function getIdValue(object $object = null) { if (!$object) { - return null; + return ''; } if (!$this->om->contains($object)) { - throw new RuntimeException(sprintf('Entity of type "%s" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?', \get_class($object))); + throw new RuntimeException(sprintf('Entity of type "%s" passed to the choice field must be managed. Maybe you forget to persist it in the entity manager?', get_debug_type($object))); } $this->om->initializeObject($object); @@ -106,7 +104,7 @@ public function getIdValue($object) $idValue = $this->associationIdReader->getIdValue($idValue); } - return $idValue; + return (string) $idValue; } /** diff --git a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php index a96a543a60a12..e38a7268be623 100644 --- a/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php +++ b/src/Symfony/Bridge/Doctrine/Form/ChoiceList/ORMQueryBuilderLoader.php @@ -12,7 +12,10 @@ namespace Symfony\Bridge\Doctrine\Form\ChoiceList; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Type; use Doctrine\ORM\QueryBuilder; +use Symfony\Component\Form\Exception\TransformationFailedException; /** * Loads entities using a {@link QueryBuilder} instance. @@ -48,7 +51,7 @@ public function getEntities() /** * {@inheritdoc} */ - public function getEntitiesByIds($identifier, array $values) + public function getEntitiesByIds(string $identifier, array $values) { if (null !== $this->queryBuilder->getMaxResults() || null !== $this->queryBuilder->getFirstResult()) { // an offset or a limit would apply on results including the where clause with submitted id values @@ -74,7 +77,7 @@ public function getEntitiesByIds($identifier, array $values) // Guess type $entity = current($qb->getRootEntities()); $metadata = $qb->getEntityManager()->getClassMetadata($entity); - if (\in_array($metadata->getTypeOfField($identifier), ['integer', 'bigint', 'smallint'])) { + if (\in_array($type = $metadata->getTypeOfField($identifier), ['integer', 'bigint', 'smallint'])) { $parameterType = Connection::PARAM_INT_ARRAY; // Filter out non-integer values (e.g. ""). If we don't, some @@ -82,13 +85,27 @@ public function getEntitiesByIds($identifier, array $values) $values = array_values(array_filter($values, function ($v) { return (string) $v === (string) (int) $v || ctype_digit($v); })); - } elseif (\in_array($metadata->getTypeOfField($identifier), ['uuid', 'guid'])) { + } elseif (\in_array($type, ['ulid', 'uuid', 'guid'])) { $parameterType = Connection::PARAM_STR_ARRAY; // Like above, but we just filter out empty strings. $values = array_values(array_filter($values, function ($v) { return '' !== (string) $v; })); + + // Convert values into right type + if (Type::hasType($type)) { + $doctrineType = Type::getType($type); + $platform = $qb->getEntityManager()->getConnection()->getDatabasePlatform(); + foreach ($values as &$value) { + try { + $value = $doctrineType->convertToDatabaseValue($value, $platform); + } catch (ConversionException $e) { + throw new TransformationFailedException(sprintf('Failed to transform "%s" into "%s".', $value, $type), 0, $e); + } + } + unset($value); + } } else { $parameterType = Connection::PARAM_STR_ARRAY; } diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php index 944c305ab70a7..231b50640f040 100644 --- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php +++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php @@ -11,7 +11,6 @@ namespace Symfony\Bridge\Doctrine\Form; -use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\Mapping\MappingException as LegacyMappingException; @@ -29,21 +28,15 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface private $cache = []; - private static $useDeprecatedConstants; - public function __construct(ManagerRegistry $registry) { $this->registry = $registry; - - if (null === self::$useDeprecatedConstants) { - self::$useDeprecatedConstants = !class_exists(Types::class); - } } /** * {@inheritdoc} */ - public function guessType($class, $property) + public function guessType(string $class, string $property) { if (!$ret = $this->getMetadata($class)) { return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::LOW_CONFIDENCE); @@ -59,44 +52,39 @@ public function guessType($class, $property) } switch ($metadata->getTypeOfField($property)) { - case self::$useDeprecatedConstants ? Type::TARRAY : Types::ARRAY: - // no break - case self::$useDeprecatedConstants ? Type::SIMPLE_ARRAY : Types::SIMPLE_ARRAY: + case Types::ARRAY: + case Types::SIMPLE_ARRAY: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CollectionType', [], Guess::MEDIUM_CONFIDENCE); - case self::$useDeprecatedConstants ? Type::BOOLEAN : Types::BOOLEAN: + case Types::BOOLEAN: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\CheckboxType', [], Guess::HIGH_CONFIDENCE); - case self::$useDeprecatedConstants ? Type::DATETIME : Types::DATETIME_MUTABLE: - // no break - case self::$useDeprecatedConstants ? Type::DATETIMETZ : Types::DATETIMETZ_MUTABLE: - // no break + case Types::DATETIME_MUTABLE: + case Types::DATETIMETZ_MUTABLE: case 'vardatetime': return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', [], Guess::HIGH_CONFIDENCE); - case 'datetime_immutable': - case 'datetimetz_immutable': + case Types::DATETIME_IMMUTABLE: + case Types::DATETIMETZ_IMMUTABLE: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', ['input' => 'datetime_immutable'], Guess::HIGH_CONFIDENCE); - case 'dateinterval': + case Types::DATEINTERVAL: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateIntervalType', [], Guess::HIGH_CONFIDENCE); - case self::$useDeprecatedConstants ? Type::DATE : Types::DATE_MUTABLE: + case Types::DATE_MUTABLE: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateType', [], Guess::HIGH_CONFIDENCE); - case 'date_immutable': + case Types::DATE_IMMUTABLE: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateType', ['input' => 'datetime_immutable'], Guess::HIGH_CONFIDENCE); - case self::$useDeprecatedConstants ? Type::TIME : Types::TIME_MUTABLE: + case Types::TIME_MUTABLE: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TimeType', [], Guess::HIGH_CONFIDENCE); - case 'time_immutable': + case Types::TIME_IMMUTABLE: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TimeType', ['input' => 'datetime_immutable'], Guess::HIGH_CONFIDENCE); - case self::$useDeprecatedConstants ? Type::DECIMAL : Types::DECIMAL: + case Types::DECIMAL: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\NumberType', ['input' => 'string'], Guess::MEDIUM_CONFIDENCE); - case self::$useDeprecatedConstants ? Type::FLOAT : Types::FLOAT: + case Types::FLOAT: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\NumberType', [], Guess::MEDIUM_CONFIDENCE); - case self::$useDeprecatedConstants ? Type::INTEGER : Types::INTEGER: - // no break - case self::$useDeprecatedConstants ? Type::BIGINT : Types::BIGINT: - // no break - case self::$useDeprecatedConstants ? Type::SMALLINT : Types::SMALLINT: + case Types::INTEGER: + case Types::BIGINT: + case Types::SMALLINT: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\IntegerType', [], Guess::MEDIUM_CONFIDENCE); - case self::$useDeprecatedConstants ? Type::STRING : Types::STRING: + case Types::STRING: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::MEDIUM_CONFIDENCE); - case self::$useDeprecatedConstants ? Type::TEXT : Types::TEXT: + case Types::TEXT: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextareaType', [], Guess::MEDIUM_CONFIDENCE); default: return new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TextType', [], Guess::LOW_CONFIDENCE); @@ -106,7 +94,7 @@ public function guessType($class, $property) /** * {@inheritdoc} */ - public function guessRequired($class, $property) + public function guessRequired(string $class, string $property) { $classMetadatas = $this->getMetadata($class); @@ -119,7 +107,7 @@ public function guessRequired($class, $property) // Check whether the field exists and is nullable or not if (isset($classMetadata->fieldMappings[$property])) { - if (!$classMetadata->isNullable($property) && (self::$useDeprecatedConstants ? Type::BOOLEAN : Types::BOOLEAN) !== $classMetadata->getTypeOfField($property)) { + if (!$classMetadata->isNullable($property) && Types::BOOLEAN !== $classMetadata->getTypeOfField($property)) { return new ValueGuess(true, Guess::HIGH_CONFIDENCE); } @@ -146,7 +134,7 @@ public function guessRequired($class, $property) /** * {@inheritdoc} */ - public function guessMaxLength($class, $property) + public function guessMaxLength(string $class, string $property) { $ret = $this->getMetadata($class); if ($ret && isset($ret[0]->fieldMappings[$property]) && !$ret[0]->hasAssociation($property)) { @@ -156,7 +144,7 @@ public function guessMaxLength($class, $property) return new ValueGuess($mapping['length'], Guess::HIGH_CONFIDENCE); } - if (\in_array($ret[0]->getTypeOfField($property), self::$useDeprecatedConstants ? [Type::DECIMAL, Type::FLOAT] : [Types::DECIMAL, Types::FLOAT])) { + if (\in_array($ret[0]->getTypeOfField($property), [Types::DECIMAL, Types::FLOAT])) { return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); } } @@ -167,11 +155,11 @@ public function guessMaxLength($class, $property) /** * {@inheritdoc} */ - public function guessPattern($class, $property) + public function guessPattern(string $class, string $property) { $ret = $this->getMetadata($class); if ($ret && isset($ret[0]->fieldMappings[$property]) && !$ret[0]->hasAssociation($property)) { - if (\in_array($ret[0]->getTypeOfField($property), self::$useDeprecatedConstants ? [Type::DECIMAL, Type::FLOAT] : [Types::DECIMAL, Types::FLOAT])) { + if (\in_array($ret[0]->getTypeOfField($property), [Types::DECIMAL, Types::FLOAT])) { return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE); } } @@ -179,7 +167,7 @@ public function guessPattern($class, $property) return null; } - protected function getMetadata($class) + protected function getMetadata(string $class) { // normalize class name $class = self::getRealClass(ltrim($class, '\\')); diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php index 3a77e74c560b0..b6a699287b8c8 100644 --- a/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php +++ b/src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php @@ -20,6 +20,7 @@ use Symfony\Bridge\Doctrine\Form\DataTransformer\CollectionToArrayTransformer; use Symfony\Bridge\Doctrine\Form\EventListener\MergeDoctrineCollectionListener; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\ChoiceList\ChoiceList; use Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator; use Symfony\Component\Form\Exception\RuntimeException; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; @@ -41,21 +42,19 @@ abstract class DoctrineType extends AbstractType implements ResetInterface private $idReaders = []; /** - * @var DoctrineChoiceLoader[] + * @var EntityLoaderInterface[] */ - private $choiceLoaders = []; + private $entityLoaders = []; /** * Creates the label for a choice. * * For backwards compatibility, objects are cast to strings by default. * - * @param object $choice The object - * * @internal This method is public to be usable as callback. It should not * be used in user code. */ - public static function createChoiceLabel($choice): string + public static function createChoiceLabel(object $choice): string { return (string) $choice; } @@ -67,15 +66,14 @@ public static function createChoiceLabel($choice): string * a single-column integer ID. In that case, the value of the field is * the ID of the object. That ID is also used as field name. * - * @param object $choice The object - * @param int|string $key The choice key - * @param string $value The choice value. Corresponds to the object's - * ID here. + * @param int|string $key The choice key + * @param string $value The choice value. Corresponds to the object's + * ID here. * * @internal This method is public to be usable as callback. It should not * be used in user code. */ - public static function createChoiceName($choice, $key, $value): string + public static function createChoiceName(object $choice, $key, string $value): string { return str_replace('-', '_', (string) $value); } @@ -119,44 +117,26 @@ public function configureOptions(OptionsResolver $resolver) $choiceLoader = function (Options $options) { // Unless the choices are given explicitly, load them on demand if (null === $options['choices']) { - $hash = null; - $qbParts = null; + // If there is no QueryBuilder we can safely cache + $vary = [$options['em'], $options['class']]; - // If there is no QueryBuilder we can safely cache DoctrineChoiceLoader, // also if concrete Type can return important QueryBuilder parts to generate - // hash key we go for it as well - if (!$options['query_builder'] || null !== $qbParts = $this->getQueryBuilderPartsForCachingHash($options['query_builder'])) { - $hash = CachingFactoryDecorator::generateHash([ - $options['em'], - $options['class'], - $qbParts, - ]); - - if (isset($this->choiceLoaders[$hash])) { - return $this->choiceLoaders[$hash]; - } + // hash key we go for it as well, otherwise fallback on the instance + if ($options['query_builder']) { + $vary[] = $this->getQueryBuilderPartsForCachingHash($options['query_builder']) ?? $options['query_builder']; } - if (null !== $options['query_builder']) { - $entityLoader = $this->getLoader($options['em'], $options['query_builder'], $options['class']); - } else { - $queryBuilder = $options['em']->getRepository($options['class'])->createQueryBuilder('e'); - $entityLoader = $this->getLoader($options['em'], $queryBuilder, $options['class']); - } - - $doctrineChoiceLoader = new DoctrineChoiceLoader( + return ChoiceList::loader($this, new DoctrineChoiceLoader( $options['em'], $options['class'], $options['id_reader'], - $entityLoader, - false - ); - - if (null !== $hash) { - $this->choiceLoaders[$hash] = $doctrineChoiceLoader; - } - - return $doctrineChoiceLoader; + $this->getCachedEntityLoader( + $options['em'], + $options['query_builder'] ?? $options['em']->getRepository($options['class'])->createQueryBuilder('e'), + $options['class'], + $vary + ) + ), $vary); } return null; @@ -167,7 +147,7 @@ public function configureOptions(OptionsResolver $resolver) // field name. We can only use numeric IDs as names, as we cannot // guarantee that a non-numeric ID contains a valid form name if ($options['id_reader'] instanceof IdReader && $options['id_reader']->isIntId()) { - return [__CLASS__, 'createChoiceName']; + return ChoiceList::fieldName($this, [__CLASS__, 'createChoiceName']); } // Otherwise, an incrementing integer is used as name automatically @@ -181,7 +161,7 @@ public function configureOptions(OptionsResolver $resolver) $choiceValue = function (Options $options) { // If the entity has a single-column ID, use that ID as value if ($options['id_reader'] instanceof IdReader && $options['id_reader']->isSingleId()) { - return [$options['id_reader'], 'getIdValue']; + return ChoiceList::value($this, [$options['id_reader'], 'getIdValue'], $options['id_reader']); } // Otherwise, an incrementing integer is used as value automatically @@ -219,27 +199,13 @@ public function configureOptions(OptionsResolver $resolver) // Set the "id_reader" option via the normalizer. This option is not // supposed to be set by the user. $idReaderNormalizer = function (Options $options) { - $hash = CachingFactoryDecorator::generateHash([ - $options['em'], - $options['class'], - ]); - // The ID reader is a utility that is needed to read the object IDs // when generating the field values. The callback generating the // field values has no access to the object manager or the class // of the field, so we store that information in the reader. // The reader is cached so that two choice lists for the same class // (and hence with the same reader) can successfully be cached. - if (!isset($this->idReaders[$hash])) { - $classMetadata = $options['em']->getClassMetadata($options['class']); - $this->idReaders[$hash] = new IdReader($options['em'], $classMetadata); - } - - if ($this->idReaders[$hash]->isSingleId()) { - return $this->idReaders[$hash]; - } - - return null; + return $this->getCachedIdReader($options['em'], $options['class']); }; $resolver->setDefaults([ @@ -247,7 +213,7 @@ public function configureOptions(OptionsResolver $resolver) 'query_builder' => null, 'choices' => null, 'choice_loader' => $choiceLoader, - 'choice_label' => [__CLASS__, 'createChoiceLabel'], + 'choice_label' => ChoiceList::label($this, [__CLASS__, 'createChoiceLabel']), 'choice_name' => $choiceName, 'choice_value' => $choiceValue, 'id_reader' => null, // internal @@ -266,12 +232,11 @@ public function configureOptions(OptionsResolver $resolver) /** * Return the default loader object. * - * @param mixed $queryBuilder - * @param string $class + * @param mixed $queryBuilder * * @return EntityLoaderInterface */ - abstract public function getLoader(ObjectManager $manager, $queryBuilder, $class); + abstract public function getLoader(ObjectManager $manager, $queryBuilder, string $class); public function getParent() { @@ -281,8 +246,27 @@ public function getParent() public function reset() { $this->idReaders = []; - $this->choiceLoaders = []; + $this->entityLoaders = []; } -} -interface_exists(ObjectManager::class); + private function getCachedIdReader(ObjectManager $manager, string $class): ?IdReader + { + $hash = CachingFactoryDecorator::generateHash([$manager, $class]); + + if (isset($this->idReaders[$hash])) { + return $this->idReaders[$hash]; + } + + $idReader = new IdReader($manager, $manager->getClassMetadata($class)); + + // don't cache the instance for composite ids that cannot be optimized + return $this->idReaders[$hash] = $idReader->isSingleId() ? $idReader : null; + } + + private function getCachedEntityLoader(ObjectManager $manager, $queryBuilder, string $class, array $vary): EntityLoaderInterface + { + $hash = CachingFactoryDecorator::generateHash($vary); + + return $this->entityLoaders[$hash] ?? ($this->entityLoaders[$hash] = $this->getLoader($manager, $queryBuilder, $class)); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php b/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php index 69c92c0b08389..6627630675b53 100644 --- a/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php +++ b/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php @@ -47,14 +47,13 @@ public function configureOptions(OptionsResolver $resolver) * Return the default loader object. * * @param QueryBuilder $queryBuilder - * @param string $class * * @return ORMQueryBuilderLoader */ - public function getLoader(ObjectManager $manager, $queryBuilder, $class) + public function getLoader(ObjectManager $manager, $queryBuilder, string $class) { if (!$queryBuilder instanceof QueryBuilder) { - throw new \TypeError(sprintf('Expected an instance of "%s", but got "%s".', QueryBuilder::class, \is_object($queryBuilder) ? \get_class($queryBuilder) : \gettype($queryBuilder))); + throw new \TypeError(sprintf('Expected an instance of "%s", but got "%s".', QueryBuilder::class, get_debug_type($queryBuilder))); } return new ORMQueryBuilderLoader($queryBuilder); @@ -80,7 +79,7 @@ public function getBlockPrefix() public function getQueryBuilderPartsForCachingHash($queryBuilder): ?array { if (!$queryBuilder instanceof QueryBuilder) { - throw new \TypeError(sprintf('Expected an instance of "%s", but got "%s".', QueryBuilder::class, \is_object($queryBuilder) ? \get_class($queryBuilder) : \gettype($queryBuilder))); + throw new \TypeError(sprintf('Expected an instance of "%s", but got "%s".', QueryBuilder::class, get_debug_type($queryBuilder))); } return [ @@ -97,5 +96,3 @@ private function parameterToArray(Parameter $parameter): array return [$parameter->getName(), $parameter->getType(), $parameter->getValue()]; } } - -interface_exists(ObjectManager::class); diff --git a/src/Symfony/Bridge/Doctrine/IdGenerator/UlidGenerator.php b/src/Symfony/Bridge/Doctrine/IdGenerator/UlidGenerator.php new file mode 100644 index 0000000000000..364bf3b3acb96 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/IdGenerator/UlidGenerator.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\IdGenerator; + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Id\AbstractIdGenerator; +use Symfony\Component\Uid\Ulid; + +/** + * @experimental in 5.2 + */ +final class UlidGenerator extends AbstractIdGenerator +{ + public function generate(EntityManager $em, $entity): Ulid + { + return new Ulid(); + } +} diff --git a/src/Symfony/Bridge/Doctrine/IdGenerator/UuidV1Generator.php b/src/Symfony/Bridge/Doctrine/IdGenerator/UuidV1Generator.php new file mode 100644 index 0000000000000..55f6eb1eb2113 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/IdGenerator/UuidV1Generator.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\IdGenerator; + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Id\AbstractIdGenerator; +use Symfony\Component\Uid\UuidV1; + +/** + * @experimental in 5.2 + */ +final class UuidV1Generator extends AbstractIdGenerator +{ + public function generate(EntityManager $em, $entity): UuidV1 + { + return new UuidV1(); + } +} diff --git a/src/Symfony/Bridge/Doctrine/IdGenerator/UuidV4Generator.php b/src/Symfony/Bridge/Doctrine/IdGenerator/UuidV4Generator.php new file mode 100644 index 0000000000000..8731daa641032 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/IdGenerator/UuidV4Generator.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\IdGenerator; + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Id\AbstractIdGenerator; +use Symfony\Component\Uid\UuidV4; + +/** + * @experimental in 5.2 + */ +final class UuidV4Generator extends AbstractIdGenerator +{ + public function generate(EntityManager $em, $entity): UuidV4 + { + return new UuidV4(); + } +} diff --git a/src/Symfony/Bridge/Doctrine/IdGenerator/UuidV6Generator.php b/src/Symfony/Bridge/Doctrine/IdGenerator/UuidV6Generator.php new file mode 100644 index 0000000000000..cdcd908e93647 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/IdGenerator/UuidV6Generator.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\IdGenerator; + +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Id\AbstractIdGenerator; +use Symfony\Component\Uid\UuidV6; + +/** + * @experimental in 5.2 + */ +final class UuidV6Generator extends AbstractIdGenerator +{ + public function generate(EntityManager $em, $entity): UuidV6 + { + return new UuidV6(); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php b/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php index f7d2ae00e5df9..4c385ef070a6c 100644 --- a/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php +++ b/src/Symfony/Bridge/Doctrine/Logger/DbalLogger.php @@ -62,11 +62,8 @@ public function stopQuery() /** * Logs a message. - * - * @param string $message A message to log - * @param array $params The context */ - protected function log($message, array $params) + protected function log(string $message, array $params) { $this->logger->debug($message, $params); } diff --git a/src/Symfony/Bridge/Doctrine/ManagerRegistry.php b/src/Symfony/Bridge/Doctrine/ManagerRegistry.php index 2139562dedbaf..7a2ad9a8d9cd0 100644 --- a/src/Symfony/Bridge/Doctrine/ManagerRegistry.php +++ b/src/Symfony/Bridge/Doctrine/ManagerRegistry.php @@ -55,17 +55,13 @@ protected function resetService($name) } $manager->setProxyInitializer(\Closure::bind( function (&$wrappedInstance, LazyLoadingInterface $manager) use ($name) { - if (isset($this->normalizedIds[$normalizedId = strtolower($name)])) { // BC with DI v3.4 - $name = $this->normalizedIds[$normalizedId]; - } if (isset($this->aliases[$name])) { $name = $this->aliases[$name]; } if (isset($this->fileMap[$name])) { $wrappedInstance = $this->load($this->fileMap[$name]); } else { - $method = $this->methodMap[$name] ?? 'get'.strtr($name, $this->underscoreMap).'Service'; // BC with DI v3.4 - $wrappedInstance = $this->{$method}(false); + $wrappedInstance = $this->{$this->methodMap[$name]}(false); } $manager->setProxyInitializer(null); diff --git a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php index a0459aa970903..f031eeb172340 100644 --- a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php +++ b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php @@ -11,13 +11,11 @@ namespace Symfony\Bridge\Doctrine\PropertyInfo; -use Doctrine\DBAL\Types\Type as DBALType; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\Mapping\MappingException as OrmMappingException; -use Doctrine\Persistence\Mapping\ClassMetadataFactory; use Doctrine\Persistence\Mapping\MappingException; use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface; use Symfony\Component\PropertyInfo\PropertyListExtractorInterface; @@ -34,31 +32,15 @@ class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeE private $entityManager; private $classMetadataFactory; - private static $useDeprecatedConstants; - - /** - * @param EntityManagerInterface $entityManager - */ - public function __construct($entityManager) + public function __construct(EntityManagerInterface $entityManager) { - if ($entityManager instanceof EntityManagerInterface) { - $this->entityManager = $entityManager; - } elseif ($entityManager instanceof ClassMetadataFactory) { - @trigger_error(sprintf('Injecting an instance of "%s" in "%s" is deprecated since Symfony 4.2, inject an instance of "%s" instead.', ClassMetadataFactory::class, __CLASS__, EntityManagerInterface::class), \E_USER_DEPRECATED); - $this->classMetadataFactory = $entityManager; - } else { - throw new \TypeError(sprintf('$entityManager must be an instance of "%s", "%s" given.', EntityManagerInterface::class, \is_object($entityManager) ? \get_class($entityManager) : \gettype($entityManager))); - } - - if (null === self::$useDeprecatedConstants) { - self::$useDeprecatedConstants = !class_exists(Types::class); - } + $this->entityManager = $entityManager; } /** * {@inheritdoc} */ - public function getProperties($class, array $context = []) + public function getProperties(string $class, array $context = []) { if (null === $metadata = $this->getMetadata($class)) { return null; @@ -80,7 +62,7 @@ public function getProperties($class, array $context = []) /** * {@inheritdoc} */ - public function getTypes($class, $property, array $context = []) + public function getTypes(string $class, string $property, array $context = []) { if (null === $metadata = $this->getMetadata($class)) { return null; @@ -163,35 +145,31 @@ public function getTypes($class, $property, array $context = []) switch ($builtinType) { case Type::BUILTIN_TYPE_OBJECT: switch ($typeOfField) { - case self::$useDeprecatedConstants ? DBALType::DATE : Types::DATE_MUTABLE: - // no break - case self::$useDeprecatedConstants ? DBALType::DATETIME : Types::DATETIME_MUTABLE: - // no break - case self::$useDeprecatedConstants ? DBALType::DATETIMETZ : Types::DATETIMETZ_MUTABLE: - // no break + case Types::DATE_MUTABLE: + case Types::DATETIME_MUTABLE: + case Types::DATETIMETZ_MUTABLE: case 'vardatetime': - case self::$useDeprecatedConstants ? DBALType::TIME : Types::TIME_MUTABLE: + case Types::TIME_MUTABLE: return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTime')]; - case 'date_immutable': - case 'datetime_immutable': - case 'datetimetz_immutable': - case 'time_immutable': + case Types::DATE_IMMUTABLE: + case Types::DATETIME_IMMUTABLE: + case Types::DATETIMETZ_IMMUTABLE: + case Types::TIME_IMMUTABLE: return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateTimeImmutable')]; - case 'dateinterval': + case Types::DATEINTERVAL: return [new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, 'DateInterval')]; } break; case Type::BUILTIN_TYPE_ARRAY: switch ($typeOfField) { - case self::$useDeprecatedConstants ? DBALType::TARRAY : Types::ARRAY: - // no break - case 'json_array': + case Types::ARRAY: + case Types::JSON_ARRAY: return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true)]; - case self::$useDeprecatedConstants ? DBALType::SIMPLE_ARRAY : Types::SIMPLE_ARRAY: + case Types::SIMPLE_ARRAY: return [new Type(Type::BUILTIN_TYPE_ARRAY, $nullable, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_STRING))]; } } @@ -205,7 +183,7 @@ public function getTypes($class, $property, array $context = []) /** * {@inheritdoc} */ - public function isReadable($class, $property, array $context = []) + public function isReadable(string $class, string $property, array $context = []) { return null; } @@ -213,7 +191,7 @@ public function isReadable($class, $property, array $context = []) /** * {@inheritdoc} */ - public function isWritable($class, $property, array $context = []) + public function isWritable(string $class, string $property, array $context = []) { if ( null === ($metadata = $this->getMetadata($class)) @@ -266,56 +244,43 @@ private function isAssociationNullable(array $associationMapping): bool private function getPhpType(string $doctrineType): ?string { switch ($doctrineType) { - case self::$useDeprecatedConstants ? DBALType::SMALLINT : Types::SMALLINT: - // no break - case self::$useDeprecatedConstants ? DBALType::INTEGER : Types::INTEGER: + case Types::SMALLINT: + case Types::INTEGER: return Type::BUILTIN_TYPE_INT; - case self::$useDeprecatedConstants ? DBALType::FLOAT : Types::FLOAT: + case Types::FLOAT: return Type::BUILTIN_TYPE_FLOAT; - case self::$useDeprecatedConstants ? DBALType::BIGINT : Types::BIGINT: - // no break - case self::$useDeprecatedConstants ? DBALType::STRING : Types::STRING: - // no break - case self::$useDeprecatedConstants ? DBALType::TEXT : Types::TEXT: - // no break - case self::$useDeprecatedConstants ? DBALType::GUID : Types::GUID: - // no break - case self::$useDeprecatedConstants ? DBALType::DECIMAL : Types::DECIMAL: + case Types::BIGINT: + case Types::STRING: + case Types::TEXT: + case Types::GUID: + case Types::DECIMAL: return Type::BUILTIN_TYPE_STRING; - case self::$useDeprecatedConstants ? DBALType::BOOLEAN : Types::BOOLEAN: + case Types::BOOLEAN: return Type::BUILTIN_TYPE_BOOL; - case self::$useDeprecatedConstants ? DBALType::BLOB : Types::BLOB: - // no break - case 'binary': + case Types::BLOB: + case Types::BINARY: return Type::BUILTIN_TYPE_RESOURCE; - case self::$useDeprecatedConstants ? DBALType::OBJECT : Types::OBJECT: - // no break - case self::$useDeprecatedConstants ? DBALType::DATE : Types::DATE_MUTABLE: - // no break - case self::$useDeprecatedConstants ? DBALType::DATETIME : Types::DATETIME_MUTABLE: - // no break - case self::$useDeprecatedConstants ? DBALType::DATETIMETZ : Types::DATETIMETZ_MUTABLE: - // no break + case Types::OBJECT: + case Types::DATE_MUTABLE: + case Types::DATETIME_MUTABLE: + case Types::DATETIMETZ_MUTABLE: case 'vardatetime': - case self::$useDeprecatedConstants ? DBALType::TIME : Types::TIME_MUTABLE: - // no break - case 'date_immutable': - case 'datetime_immutable': - case 'datetimetz_immutable': - case 'time_immutable': - case 'dateinterval': + case Types::TIME_MUTABLE: + case Types::DATE_IMMUTABLE: + case Types::DATETIME_IMMUTABLE: + case Types::DATETIMETZ_IMMUTABLE: + case Types::TIME_IMMUTABLE: + case Types::DATEINTERVAL: return Type::BUILTIN_TYPE_OBJECT; - case self::$useDeprecatedConstants ? DBALType::TARRAY : Types::ARRAY: - // no break - case self::$useDeprecatedConstants ? DBALType::SIMPLE_ARRAY : Types::SIMPLE_ARRAY: - // no break - case 'json_array': + case Types::ARRAY: + case Types::SIMPLE_ARRAY: + case Types::JSON_ARRAY: return Type::BUILTIN_TYPE_ARRAY; } diff --git a/src/Symfony/Bridge/Doctrine/RegistryInterface.php b/src/Symfony/Bridge/Doctrine/RegistryInterface.php deleted file mode 100644 index e62b3ba49ca23..0000000000000 --- a/src/Symfony/Bridge/Doctrine/RegistryInterface.php +++ /dev/null @@ -1,96 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\Doctrine; - -use Doctrine\ORM\EntityManager; -use Doctrine\Persistence\ManagerRegistry; - -/** - * References Doctrine connections and entity managers. - * - * @deprecated since Symfony 4.4, use Doctrine\Persistence\ManagerRegistry instead - * - * @author Fabien Potencier - */ -interface RegistryInterface extends ManagerRegistry -{ - /** - * Gets the default entity manager name. - * - * @return string The default entity manager name - */ - public function getDefaultEntityManagerName(); - - /** - * Gets a named entity manager. - * - * @param string $name The entity manager name (null for the default one) - * - * @return EntityManager - */ - public function getEntityManager($name = null); - - /** - * Gets an array of all registered entity managers. - * - * @return array An array of EntityManager instances - */ - public function getEntityManagers(); - - /** - * Resets a named entity manager. - * - * This method is useful when an entity manager has been closed - * because of a rollbacked transaction AND when you think that - * it makes sense to get a new one to replace the closed one. - * - * Be warned that you will get a brand new entity manager as - * the existing one is not usable anymore. This means that any - * other object with a dependency on this entity manager will - * hold an obsolete reference. You can inject the registry instead - * to avoid this problem. - * - * @param string $name The entity manager name (null for the default one) - * - * @return EntityManager - */ - public function resetEntityManager($name = null); - - /** - * Resolves a registered namespace alias to the full namespace. - * - * This method looks for the alias in all registered entity managers. - * - * @param string $alias The alias - * - * @return string The full namespace - * - * @see Configuration::getEntityNamespace - */ - public function getEntityNamespace($alias); - - /** - * Gets all connection names. - * - * @return array An array of connection names - */ - public function getEntityManagerNames(); - - /** - * Gets the entity manager associated with a given class. - * - * @param string $class A Doctrine Entity class name - * - * @return EntityManager|null - */ - public function getEntityManagerForClass($class); -} diff --git a/src/Symfony/Bridge/Doctrine/SchemaListener/MessengerTransportDoctrineSchemaSubscriber.php b/src/Symfony/Bridge/Doctrine/SchemaListener/MessengerTransportDoctrineSchemaSubscriber.php new file mode 100644 index 0000000000000..5b3798eb3918a --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/SchemaListener/MessengerTransportDoctrineSchemaSubscriber.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\SchemaListener; + +use Doctrine\Common\EventSubscriber; +use Doctrine\DBAL\Event\SchemaCreateTableEventArgs; +use Doctrine\DBAL\Events; +use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; +use Doctrine\ORM\Tools\ToolEvents; +use Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransport; +use Symfony\Component\Messenger\Transport\TransportInterface; + +/** + * Automatically adds any required database tables to the Doctrine Schema. + * + * @author Ryan Weaver + */ +final class MessengerTransportDoctrineSchemaSubscriber implements EventSubscriber +{ + private const PROCESSING_TABLE_FLAG = self::class.':processing'; + + private $transports; + + /** + * @param iterable|TransportInterface[] $transports + */ + public function __construct(iterable $transports) + { + $this->transports = $transports; + } + + public function postGenerateSchema(GenerateSchemaEventArgs $event): void + { + $dbalConnection = $event->getEntityManager()->getConnection(); + foreach ($this->transports as $transport) { + if (!$transport instanceof DoctrineTransport) { + continue; + } + + $transport->configureSchema($event->getSchema(), $dbalConnection); + } + } + + public function onSchemaCreateTable(SchemaCreateTableEventArgs $event): void + { + $table = $event->getTable(); + + // if this method triggers a nested create table below, allow Doctrine to work like normal + if ($table->hasOption(self::PROCESSING_TABLE_FLAG)) { + return; + } + + foreach ($this->transports as $transport) { + if (!$transport instanceof DoctrineTransport) { + continue; + } + + if (!$extraSql = $transport->getExtraSetupSqlForTable($table)) { + continue; + } + + // avoid this same listener from creating a loop on this table + $table->addOption(self::PROCESSING_TABLE_FLAG, true); + $createTableSql = $event->getPlatform()->getCreateTableSQL($table); + + /* + * Add all the SQL needed to create the table and tell Doctrine + * to "preventDefault" so that only our SQL is used. This is + * the only way to inject some extra SQL. + */ + $event->addSql($createTableSql); + foreach ($extraSql as $sql) { + $event->addSql($sql); + } + $event->preventDefault(); + + return; + } + } + + public function getSubscribedEvents(): array + { + $subscribedEvents = []; + + if (class_exists(ToolEvents::class)) { + $subscribedEvents[] = ToolEvents::postGenerateSchema; + } + + if (class_exists(Events::class)) { + $subscribedEvents[] = Events::onSchemaCreateTable; + } + + return $subscribedEvents; + } +} diff --git a/src/Symfony/Bridge/Doctrine/SchemaListener/PdoCacheAdapterDoctrineSchemaSubscriber.php b/src/Symfony/Bridge/Doctrine/SchemaListener/PdoCacheAdapterDoctrineSchemaSubscriber.php new file mode 100644 index 0000000000000..527b055b28078 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/SchemaListener/PdoCacheAdapterDoctrineSchemaSubscriber.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\SchemaListener; + +use Doctrine\Common\EventSubscriber; +use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; +use Doctrine\ORM\Tools\ToolEvents; +use Symfony\Component\Cache\Adapter\PdoAdapter; + +/** + * Automatically adds the cache table needed for the PdoAdapter. + * + * @author Ryan Weaver + */ +final class PdoCacheAdapterDoctrineSchemaSubscriber implements EventSubscriber +{ + private $pdoAdapters; + + /** + * @param iterable|PdoAdapter[] $pdoAdapters + */ + public function __construct(iterable $pdoAdapters) + { + $this->pdoAdapters = $pdoAdapters; + } + + public function postGenerateSchema(GenerateSchemaEventArgs $event): void + { + $dbalConnection = $event->getEntityManager()->getConnection(); + foreach ($this->pdoAdapters as $pdoAdapter) { + $pdoAdapter->configureSchema($event->getSchema(), $dbalConnection); + } + } + + public function getSubscribedEvents(): array + { + if (!class_exists(ToolEvents::class)) { + return []; + } + + return [ + ToolEvents::postGenerateSchema, + ]; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php b/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php index 4b63652ae8058..4116a6c9c6cb8 100644 --- a/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/RememberMe/DoctrineTokenProvider.php @@ -14,7 +14,6 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver\Result as DriverResult; use Doctrine\DBAL\Result; -use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Types; use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentTokenInterface; @@ -43,21 +42,15 @@ class DoctrineTokenProvider implements TokenProviderInterface { private $conn; - private static $useDeprecatedConstants; - public function __construct(Connection $conn) { $this->conn = $conn; - - if (null === self::$useDeprecatedConstants) { - self::$useDeprecatedConstants = !class_exists(Types::class); - } } /** * {@inheritdoc} */ - public function loadTokenBySeries($series) + public function loadTokenBySeries(string $series) { // the alias for lastUsed works around case insensitivity in PostgreSQL $sql = 'SELECT class, username, value, lastUsed AS last_used' @@ -77,7 +70,7 @@ public function loadTokenBySeries($series) /** * {@inheritdoc} */ - public function deleteTokenBySeries($series) + public function deleteTokenBySeries(string $series) { $sql = 'DELETE FROM rememberme_token WHERE series=:series'; $paramValues = ['series' => $series]; @@ -92,7 +85,7 @@ public function deleteTokenBySeries($series) /** * {@inheritdoc} */ - public function updateToken($series, $tokenValue, \DateTime $lastUsed) + public function updateToken(string $series, string $tokenValue, \DateTime $lastUsed) { $sql = 'UPDATE rememberme_token SET value=:value, lastUsed=:lastUsed' .' WHERE series=:series'; @@ -103,7 +96,7 @@ public function updateToken($series, $tokenValue, \DateTime $lastUsed) ]; $paramTypes = [ 'value' => \PDO::PARAM_STR, - 'lastUsed' => self::$useDeprecatedConstants ? Type::DATETIME : Types::DATETIME_MUTABLE, + 'lastUsed' => Types::DATETIME_MUTABLE, 'series' => \PDO::PARAM_STR, ]; if (method_exists($this->conn, 'executeStatement')) { @@ -136,7 +129,7 @@ public function createNewToken(PersistentTokenInterface $token) 'username' => \PDO::PARAM_STR, 'series' => \PDO::PARAM_STR, 'value' => \PDO::PARAM_STR, - 'lastUsed' => self::$useDeprecatedConstants ? Type::DATETIME : Types::DATETIME_MUTABLE, + 'lastUsed' => Types::DATETIME_MUTABLE, ]; if (method_exists($this->conn, 'executeStatement')) { $this->conn->executeStatement($sql, $paramValues, $paramTypes); diff --git a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php index 5dd3889e8eb15..1763631d61f9c 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/EntityUserProvider.php @@ -48,14 +48,14 @@ public function __construct(ManagerRegistry $registry, string $classOrAlias, str /** * {@inheritdoc} */ - public function loadUserByUsername($username) + public function loadUserByUsername(string $username) { $repository = $this->getRepository(); if (null !== $this->property) { $user = $repository->findOneBy([$this->property => $username]); } else { if (!$repository instanceof UserLoaderInterface) { - throw new \InvalidArgumentException(sprintf('You must either make the "%s" entity Doctrine Repository ("%s") implement "Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface" or set the "property" option in the corresponding entity provider configuration.', $this->classOrAlias, \get_class($repository))); + throw new \InvalidArgumentException(sprintf('You must either make the "%s" entity Doctrine Repository ("%s") implement "Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface" or set the "property" option in the corresponding entity provider configuration.', $this->classOrAlias, get_debug_type($repository))); } $user = $repository->loadUserByUsername($username); @@ -78,7 +78,7 @@ public function refreshUser(UserInterface $user) { $class = $this->getClass(); if (!$user instanceof $class) { - throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', \get_class($user))); + throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user))); } $repository = $this->getRepository(); @@ -108,7 +108,7 @@ public function refreshUser(UserInterface $user) /** * {@inheritdoc} */ - public function supportsClass($class) + public function supportsClass(string $class) { return $class === $this->getClass() || is_subclass_of($class, $this->getClass()); } @@ -120,7 +120,7 @@ public function upgradePassword(UserInterface $user, string $newEncodedPassword) { $class = $this->getClass(); if (!$user instanceof $class) { - throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', \get_class($user))); + throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_debug_type($user))); } $repository = $this->getRepository(); @@ -159,6 +159,3 @@ private function getClassMetadata(): ClassMetadata return $this->getObjectManager()->getClassMetadata($this->classOrAlias); } } - -interface_exists(ObjectManager::class); -interface_exists(ObjectRepository::class); diff --git a/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php index 452939fa7934a..d996f71702291 100644 --- a/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php +++ b/src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php @@ -31,9 +31,7 @@ interface UserLoaderInterface * * This method must return null if the user is not found. * - * @param string $username The username - * * @return UserInterface|null */ - public function loadUserByUsername($username); + public function loadUserByUsername(string $username); } diff --git a/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php b/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php index e9d260ec26608..c77c13e59fecb 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php @@ -199,7 +199,7 @@ class MyListener public $calledByInvokeCount = 0; public $calledByEventNameCount = 0; - public function __invoke(): void + public function __invoke() { ++$this->calledByInvokeCount; } diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterUidTypePassTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterUidTypePassTest.php new file mode 100644 index 0000000000000..9b87c051702ee --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/CompilerPass/RegisterUidTypePassTest.php @@ -0,0 +1,34 @@ +setParameter('doctrine.dbal.connection_factory.types', ['foo' => 'bar']); + (new RegisterUidTypePass())->process($container); + + $expected = [ + 'foo' => 'bar', + 'uuid' => ['class' => UuidType::class], + 'ulid' => ['class' => UlidType::class], + ]; + $this->assertSame($expected, $container->getParameter('doctrine.dbal.connection_factory.types')); + } + + public function testRegisteredDontFail() + { + $container = new ContainerBuilder(); + (new RegisterUidTypePass())->process($container); + + $this->expectNotToPerformAssertions(); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php index 4fb8a0a4437d6..085a37fbff73f 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php @@ -38,6 +38,7 @@ protected function setUp(): void 'getObjectManagerElementName', 'getMappingObjectDefaultName', 'getMappingResourceExtension', + 'getMetadataDriverClass', 'load', ]) ->getMock() @@ -263,6 +264,7 @@ protected function createContainer(array $data = []): ContainerBuilder return new ContainerBuilder(new ParameterBag(array_merge([ 'kernel.bundles' => ['FrameworkBundle' => 'Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle'], 'kernel.cache_dir' => __DIR__, + 'kernel.build_dir' => __DIR__, 'kernel.container_class' => 'kernel', 'kernel.project_dir' => __DIR__, ], $data))); diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/BaseUser.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/BaseUser.php index aa24cd68943dd..416d5b20bf7b1 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/BaseUser.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/BaseUser.php @@ -2,9 +2,6 @@ namespace Symfony\Bridge\Doctrine\Tests\Fixtures; -use Symfony\Component\Validator\Constraints as Assert; -use Symfony\Component\Validator\Mapping\ClassMetadata; - /** * Class BaseUser. */ @@ -40,15 +37,4 @@ public function getUsername(): string { return $this->username; } - - public static function loadValidatorMetadata(ClassMetadata $metadata): void - { - $allowEmptyString = property_exists(Assert\Length::class, 'allowEmptyString') ? ['allowEmptyString' => true] : []; - - $metadata->addPropertyConstraint('username', new Assert\Length([ - 'min' => 2, - 'max' => 120, - 'groups' => ['Registration'], - ] + $allowEmptyString)); - } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEntity.php index 06f8674e56d66..d6aee2d18b0b1 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEntity.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoctrineLoaderEntity.php @@ -14,7 +14,6 @@ use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Validator\Constraints as Assert; -use Symfony\Component\Validator\Mapping\ClassMetadata; /** * @ORM\Entity @@ -37,11 +36,13 @@ class DoctrineLoaderEntity extends DoctrineLoaderParentEntity /** * @ORM\Column(length=20) + * @Assert\Length(min=5) */ public $mergedMaxLength; /** * @ORM\Column(length=20) + * @Assert\Length(min=1, max=10) */ public $alreadyMappedMaxLength; @@ -74,12 +75,4 @@ class DoctrineLoaderEntity extends DoctrineLoaderParentEntity * @Assert\DisableAutoMapping */ public $noAutoMapping; - - public static function loadValidatorMetadata(ClassMetadata $metadata): void - { - $allowEmptyString = property_exists(Assert\Length::class, 'allowEmptyString') ? ['allowEmptyString' => true] : []; - - $metadata->addPropertyConstraint('mergedMaxLength', new Assert\Length(['min' => 5] + $allowEmptyString)); - $metadata->addPropertyConstraint('alreadyMappedMaxLength', new Assert\Length(['min' => 1, 'max' => 10] + $allowEmptyString)); - } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/UlidIdEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/UlidIdEntity.php new file mode 100644 index 0000000000000..3ee909fe4bfc5 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/UlidIdEntity.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; + +/** @Entity */ +class UlidIdEntity +{ + /** @Id @Column(type="ulid") */ + protected $id; + + public function __construct($id) + { + $this->id = $id; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/DoctrineChoiceLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/DoctrineChoiceLoaderTest.php index afe595c7d3e19..76b6f4bdfd77e 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/DoctrineChoiceLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/DoctrineChoiceLoaderTest.php @@ -19,7 +19,7 @@ use Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader; use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityLoaderInterface; use Symfony\Bridge\Doctrine\Form\ChoiceList\IdReader; -use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Form\ChoiceList\ArrayChoiceList; use Symfony\Component\Form\ChoiceList\Factory\ChoiceListFactoryInterface; @@ -28,6 +28,8 @@ */ class DoctrineChoiceLoaderTest extends TestCase { + use ExpectDeprecationTrait; + /** * @var ChoiceListFactoryInterface|MockObject */ @@ -99,6 +101,10 @@ protected function setUp(): void ->method('getClassMetadata') ->with($this->class) ->willReturn(new ClassMetadata($this->class)); + $this->repository->expects($this->any()) + ->method('findAll') + ->willReturn([$this->obj1, $this->obj2, $this->obj3]) + ; } public function testLoadChoiceList() @@ -185,8 +191,12 @@ public function testLoadValuesForChoicesDoesNotLoadIfEmptyChoices() $this->assertSame([], $loader->loadValuesForChoices([])); } + /** + * @group legacy + */ public function testLoadValuesForChoicesDoesNotLoadIfSingleIntId() { + $this->expectDeprecation('Since symfony/doctrine-bridge 5.1: Not defining explicitly the IdReader as value callback when query can be optimized is deprecated. Don\'t pass the IdReader to "Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader" or define the "choice_value" option instead.'); $loader = new DoctrineChoiceLoader( $this->om, $this->class, @@ -204,7 +214,7 @@ public function testLoadValuesForChoicesDoesNotLoadIfSingleIntId() $this->assertSame(['2'], $loader->loadValuesForChoices([$this->obj2])); } - public function testLoadValuesForChoicesLoadsIfSingleIntIdAndValueGiven() + public function testLoadValuesForChoicesDoesNotLoadIfSingleIntIdAndValueGiven() { $loader = new DoctrineChoiceLoader( $this->om, @@ -215,7 +225,7 @@ public function testLoadValuesForChoicesLoadsIfSingleIntIdAndValueGiven() $choices = [$this->obj1, $this->obj2, $this->obj3]; $value = function (\stdClass $object) { return $object->name; }; - $this->repository->expects($this->once()) + $this->repository->expects($this->never()) ->method('findAll') ->willReturn($choices); @@ -253,8 +263,7 @@ public function testLoadChoicesForValues() { $loader = new DoctrineChoiceLoader( $this->om, - $this->class, - $this->idReader + $this->class ); $choices = [$this->obj1, $this->obj2, $this->obj3]; @@ -284,8 +293,12 @@ public function testLoadChoicesForValuesDoesNotLoadIfEmptyValues() $this->assertSame([], $loader->loadChoicesForValues([])); } - public function testLoadChoicesForValuesLoadsOnlyChoicesIfSingleIntId() + /** + * @group legacy + */ + public function legacyTestLoadChoicesForValuesLoadsOnlyChoicesIfValueUseIdReader() { + $this->expectDeprecation('Not defining explicitly the IdReader as value callback when query can be optimized has been deprecated in 5.1. Don\'t pass the IdReader to "Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader" or define the choice_value instead.'); $loader = new DoctrineChoiceLoader( $this->om, $this->class, @@ -320,6 +333,42 @@ public function testLoadChoicesForValuesLoadsOnlyChoicesIfSingleIntId() )); } + public function testLoadChoicesForValuesLoadsOnlyChoicesIfValueUseIdReader() + { + $loader = new DoctrineChoiceLoader( + $this->om, + $this->class, + $this->idReader, + $this->objectLoader + ); + + $choices = [$this->obj2, $this->obj3]; + + $this->idReader->expects($this->any()) + ->method('getIdField') + ->willReturn('idField'); + + $this->repository->expects($this->never()) + ->method('findAll'); + + $this->objectLoader->expects($this->once()) + ->method('getEntitiesByIds') + ->with('idField', [4 => '3', 7 => '2']) + ->willReturn($choices); + + $this->idReader->expects($this->any()) + ->method('getIdValue') + ->willReturnMap([ + [$this->obj2, '2'], + [$this->obj3, '3'], + ]); + + $this->assertSame( + [4 => $this->obj3, 7 => $this->obj2], + $loader->loadChoicesForValues([4 => '3', 7 => '2'], [$this->idReader, 'getIdValue'] + )); + } + public function testLoadChoicesForValuesLoadsAllIfSingleIntIdAndValueGiven() { $loader = new DoctrineChoiceLoader( @@ -375,87 +424,17 @@ public function testLoadChoicesForValuesLoadsOnlyChoicesIfValueIsIdReader() $this->assertSame([$this->obj2], $loader->loadChoicesForValues(['2'], $value)); } - /** - * @group legacy - * - * @expectedDeprecation Not explicitly passing an instance of "Symfony\Bridge\Doctrine\Form\ChoiceList\IdReader" to "Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader" when it can optimize single id entity "%s" has been deprecated in 4.3 and will not apply any optimization in 5.0. - */ - public function testLoaderWithoutIdReaderCanBeOptimized() - { - $obj1 = new SingleIntIdEntity('1', 'one'); - $obj2 = new SingleIntIdEntity('2', 'two'); - - $metadata = $this->createMock(ClassMetadata::class); - $metadata->expects($this->once()) - ->method('getIdentifierFieldNames') - ->willReturn(['idField']) - ; - $metadata->expects($this->any()) - ->method('getIdentifierValues') - ->willReturnCallback(function ($obj) use ($obj1, $obj2) { - if ($obj === $obj1) { - return ['idField' => '1']; - } - if ($obj === $obj2) { - return ['idField' => '2']; - } - - return null; - }) - ; - - $this->om = $this->createMock(ObjectManager::class); - $this->om->expects($this->once()) - ->method('getClassMetadata') - ->with(SingleIntIdEntity::class) - ->willReturn($metadata) - ; - $this->om->expects($this->any()) - ->method('contains') - ->with($this->isInstanceOf(SingleIntIdEntity::class)) - ->willReturn(true) - ; - - $loader = new DoctrineChoiceLoader( - $this->om, - SingleIntIdEntity::class, - null, - $this->objectLoader - ); - - $choices = [$obj1, $obj2]; - - $this->repository->expects($this->never()) - ->method('findAll'); - - $this->objectLoader->expects($this->once()) - ->method('getEntitiesByIds') - ->with('idField', ['1']) - ->willReturn($choices); - - $this->assertSame([$obj1], $loader->loadChoicesForValues(['1'])); - } - - /** - * @group legacy - * - * @deprecationMessage Passing an instance of "Symfony\Bridge\Doctrine\Form\ChoiceList\IdReader" to "Symfony\Bridge\Doctrine\Form\ChoiceList\DoctrineChoiceLoader" with an entity class "stdClass" that has a composite id is deprecated since Symfony 4.3 and will throw an exception in 5.0. - */ public function testPassingIdReaderWithoutSingleIdEntity() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('The second argument `$idReader` of "Symfony\\Bridge\\Doctrine\\Form\\ChoiceList\\DoctrineChoiceLoader::__construct" must be null when the query cannot be optimized because of composite id fields.'); + $idReader = $this->createMock(IdReader::class); $idReader->expects($this->once()) ->method('isSingleId') ->willReturn(false) ; - $loader = new DoctrineChoiceLoader( - $this->om, - $this->class, - $idReader, - $this->objectLoader - ); - - $this->assertInstanceOf(DoctrineChoiceLoader::class, $loader); + new DoctrineChoiceLoader($this->om, $this->class, $idReader, $this->objectLoader); } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php index 8bb0f256977a5..1ac6640d9950c 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/ChoiceList/ORMQueryBuilderLoaderTest.php @@ -12,13 +12,26 @@ namespace Symfony\Bridge\Doctrine\Tests\Form\ChoiceList; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Types\GuidType; +use Doctrine\DBAL\Types\Type; use Doctrine\ORM\Version; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Doctrine\Form\ChoiceList\ORMQueryBuilderLoader; use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper; +use Symfony\Bridge\Doctrine\Types\UlidType; +use Symfony\Bridge\Doctrine\Types\UuidType; +use Symfony\Component\Form\Exception\TransformationFailedException; +use Symfony\Component\Uid\Uuid; class ORMQueryBuilderLoaderTest extends TestCase { + protected function tearDown(): void + { + if (Type::hasType('uuid')) { + Type::overrideType('uuid', GuidType::class); + } + } + public function testIdentifierTypeIsStringArray() { $this->checkIdentifierType('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity', Connection::PARAM_STR_ARRAY); @@ -131,6 +144,86 @@ public function testFilterEmptyUuids($entityClass) $loader->getEntitiesByIds('id', ['71c5fd46-3f16-4abb-bad7-90ac1e654a2d', '', 'b98e8e11-2897-44df-ad24-d2627eb7f499']); } + /** + * @dataProvider provideUidEntityClasses + */ + public function testFilterUid($entityClass) + { + if (Type::hasType('uuid')) { + Type::overrideType('uuid', UuidType::class); + } else { + Type::addType('uuid', UuidType::class); + } + if (!Type::hasType('ulid')) { + Type::addType('ulid', UlidType::class); + } + + $em = DoctrineTestHelper::createTestEntityManager(); + + $query = $this->getMockBuilder(\QueryMock::class) + ->setMethods(['setParameter', 'getResult', 'getSql', '_doExecute']) + ->getMock(); + + $query + ->method('getResult') + ->willReturn([]); + + $query->expects($this->once()) + ->method('setParameter') + ->with('ORMQueryBuilderLoader_getEntitiesByIds_id', [Uuid::fromString('71c5fd46-3f16-4abb-bad7-90ac1e654a2d')->toBinary(), Uuid::fromString('b98e8e11-2897-44df-ad24-d2627eb7f499')->toBinary()], Connection::PARAM_STR_ARRAY) + ->willReturn($query); + + $qb = $this->getMockBuilder(\Doctrine\ORM\QueryBuilder::class) + ->setConstructorArgs([$em]) + ->setMethods(['getQuery']) + ->getMock(); + + $qb->expects($this->once()) + ->method('getQuery') + ->willReturn($query); + + $qb->select('e') + ->from($entityClass, 'e'); + + $loader = new ORMQueryBuilderLoader($qb); + $loader->getEntitiesByIds('id', ['71c5fd46-3f16-4abb-bad7-90ac1e654a2d', '', 'b98e8e11-2897-44df-ad24-d2627eb7f499']); + } + + /** + * @dataProvider provideUidEntityClasses + */ + public function testUidThrowProperException($entityClass) + { + if (Type::hasType('uuid')) { + Type::overrideType('uuid', UuidType::class); + } else { + Type::addType('uuid', UuidType::class); + } + if (!Type::hasType('ulid')) { + Type::addType('ulid', UlidType::class); + } + + $em = DoctrineTestHelper::createTestEntityManager(); + + $qb = $this->getMockBuilder(\Doctrine\ORM\QueryBuilder::class) + ->setConstructorArgs([$em]) + ->setMethods(['getQuery']) + ->getMock(); + + $qb->expects($this->never()) + ->method('getQuery'); + + $qb->select('e') + ->from($entityClass, 'e'); + + $loader = new ORMQueryBuilderLoader($qb); + + $this->expectException(TransformationFailedException::class); + $this->expectExceptionMessageMatches('/^Failed to transform "hello" into "(uuid|ulid)"\.$/'); + + $loader->getEntitiesByIds('id', ['hello']); + } + public function testEmbeddedIdentifierName() { if (Version::compare('2.5.0') > 0) { @@ -176,4 +269,12 @@ public function provideGuidEntityClasses() ['Symfony\Bridge\Doctrine\Tests\Fixtures\UuidIdEntity'], ]; } + + public function provideUidEntityClasses() + { + return [ + ['Symfony\Bridge\Doctrine\Tests\Fixtures\UuidIdEntity'], + ['Symfony\Bridge\Doctrine\Tests\Fixtures\UlidIdEntity'], + ]; + } } diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/DoctrineOrmTypeGuesserTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/DoctrineOrmTypeGuesserTest.php index e003a20ee6b56..652f9d67ebe18 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/DoctrineOrmTypeGuesserTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/DoctrineOrmTypeGuesserTest.php @@ -11,16 +11,44 @@ namespace Symfony\Bridge\Doctrine\Tests\Form; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ObjectManager; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser; use Symfony\Component\Form\Guess\Guess; +use Symfony\Component\Form\Guess\TypeGuess; use Symfony\Component\Form\Guess\ValueGuess; class DoctrineOrmTypeGuesserTest extends TestCase { + /** + * @dataProvider requiredType + */ + public function testTypeGuesser(string $type, $expected) + { + $classMetadata = $this->createMock(ClassMetadata::class); + $classMetadata->fieldMappings['field'] = true; + $classMetadata->expects($this->once())->method('getTypeOfField')->with('field')->willReturn($type); + + $this->assertEquals($expected, $this->getGuesser($classMetadata)->guessType('TestEntity', 'field')); + } + + public function requiredType() + { + yield [Types::DATE_IMMUTABLE, new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateType', ['input' => 'datetime_immutable'], Guess::HIGH_CONFIDENCE)]; + yield [Types::DATE_MUTABLE, new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateType', [], Guess::HIGH_CONFIDENCE)]; + + yield [Types::TIME_IMMUTABLE, new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TimeType', ['input' => 'datetime_immutable'], Guess::HIGH_CONFIDENCE)]; + yield [Types::TIME_MUTABLE, new TypeGuess('Symfony\Component\Form\Extension\Core\Type\TimeType', [], Guess::HIGH_CONFIDENCE)]; + + yield [Types::DATETIME_IMMUTABLE, new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', ['input' => 'datetime_immutable'], Guess::HIGH_CONFIDENCE)]; + yield [Types::DATETIMETZ_IMMUTABLE, new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', ['input' => 'datetime_immutable'], Guess::HIGH_CONFIDENCE)]; + yield [Types::DATETIME_MUTABLE, new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', [], Guess::HIGH_CONFIDENCE)]; + yield [Types::DATETIMETZ_MUTABLE, new TypeGuess('Symfony\Component\Form\Extension\Core\Type\DateTimeType', [], Guess::HIGH_CONFIDENCE)]; + } + /** * @dataProvider requiredProvider */ diff --git a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php index d082ba5492b17..bd6b2f156280d 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Form/Type/EntityTypeTest.php @@ -29,7 +29,7 @@ use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringCastableIdEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity; -use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface; +use Symfony\Component\Form\ChoiceList\LazyChoiceList; use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView; use Symfony\Component\Form\ChoiceList\View\ChoiceView; use Symfony\Component\Form\Exception\RuntimeException; @@ -1243,13 +1243,13 @@ public function testLoaderCaching() 'property3' => 2, ]); - $choiceLoader1 = $form->get('property1')->getConfig()->getOption('choice_loader'); - $choiceLoader2 = $form->get('property2')->getConfig()->getOption('choice_loader'); - $choiceLoader3 = $form->get('property3')->getConfig()->getOption('choice_loader'); + $choiceList1 = $form->get('property1')->getConfig()->getAttribute('choice_list'); + $choiceList2 = $form->get('property2')->getConfig()->getAttribute('choice_list'); + $choiceList3 = $form->get('property3')->getConfig()->getAttribute('choice_list'); - $this->assertInstanceOf(ChoiceLoaderInterface::class, $choiceLoader1); - $this->assertSame($choiceLoader1, $choiceLoader2); - $this->assertSame($choiceLoader1, $choiceLoader3); + $this->assertInstanceOf(LazyChoiceList::class, $choiceList1); + $this->assertSame($choiceList1, $choiceList2); + $this->assertSame($choiceList1, $choiceList3); } public function testLoaderCachingWithParameters() @@ -1303,13 +1303,13 @@ public function testLoaderCachingWithParameters() 'property3' => 2, ]); - $choiceLoader1 = $form->get('property1')->getConfig()->getOption('choice_loader'); - $choiceLoader2 = $form->get('property2')->getConfig()->getOption('choice_loader'); - $choiceLoader3 = $form->get('property3')->getConfig()->getOption('choice_loader'); + $choiceList1 = $form->get('property1')->getConfig()->getAttribute('choice_list'); + $choiceList2 = $form->get('property2')->getConfig()->getAttribute('choice_list'); + $choiceList3 = $form->get('property3')->getConfig()->getAttribute('choice_list'); - $this->assertInstanceOf(ChoiceLoaderInterface::class, $choiceLoader1); - $this->assertSame($choiceLoader1, $choiceLoader2); - $this->assertSame($choiceLoader1, $choiceLoader3); + $this->assertInstanceOf(LazyChoiceList::class, $choiceList1); + $this->assertSame($choiceList1, $choiceList2); + $this->assertSame($choiceList1, $choiceList3); } protected function createRegistryMock($name, $em) diff --git a/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/EntityManager.php b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/EntityManager.php new file mode 100644 index 0000000000000..22667a6daad4d --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/EntityManager.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\IdGenerator; + +use Doctrine\ORM\EntityManager as DoctrineEntityManager; + +class EntityManager extends DoctrineEntityManager +{ + public function __construct() + { + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UlidGeneratorTest.php b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UlidGeneratorTest.php new file mode 100644 index 0000000000000..c4373554e2b6b --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UlidGeneratorTest.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\IdGenerator; + +use Doctrine\ORM\Mapping\Entity; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator; +use Symfony\Component\Uid\AbstractUid; +use Symfony\Component\Uid\Ulid; + +class UlidGeneratorTest extends TestCase +{ + public function testUlidCanBeGenerated() + { + $em = new EntityManager(); + $generator = new UlidGenerator(); + $ulid = $generator->generate($em, new Entity()); + + $this->assertInstanceOf(AbstractUid::class, $ulid); + $this->assertInstanceOf(Ulid::class, $ulid); + $this->assertTrue(Ulid::isValid($ulid)); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UuidV1GeneratorTest.php b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UuidV1GeneratorTest.php new file mode 100644 index 0000000000000..b9010afe417ef --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UuidV1GeneratorTest.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\IdGenerator; + +use Doctrine\ORM\Mapping\Entity; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\IdGenerator\UuidV1Generator; +use Symfony\Component\Uid\AbstractUid; +use Symfony\Component\Uid\UuidV1; + +class UuidV1GeneratorTest extends TestCase +{ + public function testUuidv1CanBeGenerated() + { + $em = new EntityManager(); + $generator = new UuidV1Generator(); + + $uuid = $generator->generate($em, new Entity()); + + $this->assertInstanceOf(AbstractUid::class, $uuid); + $this->assertInstanceOf(UuidV1::class, $uuid); + $this->assertTrue(UuidV1::isValid($uuid)); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UuidV4GeneratorTest.php b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UuidV4GeneratorTest.php new file mode 100644 index 0000000000000..cc87f74428d84 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UuidV4GeneratorTest.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\IdGenerator; + +use Doctrine\ORM\Mapping\Entity; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\IdGenerator\UuidV4Generator; +use Symfony\Component\Uid\AbstractUid; +use Symfony\Component\Uid\UuidV4; + +class UuidV4GeneratorTest extends TestCase +{ + public function testUuidv4CanBeGenerated() + { + $em = new EntityManager(); + $generator = new UuidV4Generator(); + + $uuid = $generator->generate($em, new Entity()); + + $this->assertInstanceOf(AbstractUid::class, $uuid); + $this->assertInstanceOf(UuidV4::class, $uuid); + $this->assertTrue(UuidV4::isValid($uuid)); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UuidV6GeneratorTest.php b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UuidV6GeneratorTest.php new file mode 100644 index 0000000000000..f0697b272c981 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/IdGenerator/UuidV6GeneratorTest.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\IdGenerator; + +use Doctrine\ORM\Mapping\Entity; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\IdGenerator\UuidV6Generator; +use Symfony\Component\Uid\AbstractUid; +use Symfony\Component\Uid\UuidV6; + +class UuidV6GeneratorTest extends TestCase +{ + public function testUuidv6CanBeGenerated() + { + $em = new EntityManager(); + $generator = new UuidV6Generator(); + + $uuid = $generator->generate($em, new Entity()); + + $this->assertInstanceOf(AbstractUid::class, $uuid); + $this->assertInstanceOf(UuidV6::class, $uuid); + $this->assertTrue(UuidV6::isValid($uuid)); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php index 7e256eb77e2d8..3b9419d174a60 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/DoctrineExtractorTest.php @@ -13,12 +13,11 @@ use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Type as DBALType; -use Doctrine\DBAL\Types\Types; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\Setup; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor; -use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy210; +use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy; use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineGeneratedValue; use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineRelation; use Symfony\Component\PropertyInfo\Type; @@ -28,7 +27,7 @@ */ class DoctrineExtractorTest extends TestCase { - private function createExtractor(bool $legacy = false) + private function createExtractor() { $config = Setup::createAnnotationMetadataConfiguration([__DIR__.\DIRECTORY_SEPARATOR.'Fixtures'], true); $entityManager = EntityManager::create(['driver' => 'pdo_sqlite'], $config); @@ -38,20 +37,10 @@ private function createExtractor(bool $legacy = false) $entityManager->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('custom_foo', 'foo'); } - return new DoctrineExtractor($legacy ? $entityManager->getMetadataFactory() : $entityManager); + return new DoctrineExtractor($entityManager); } public function testGetProperties() - { - $this->doTestGetProperties(false); - } - - public function testLegacyGetProperties() - { - $this->doTestGetProperties(true); - } - - private function doTestGetProperties(bool $legacy) { // Fields $expected = [ @@ -68,12 +57,9 @@ private function doTestGetProperties(bool $legacy) 'binary', 'customFoo', 'bigint', + 'json', ]; - if (class_exists(Types::class)) { - $expected[] = 'json'; - } - // Associations $expected = array_merge($expected, [ 'foo', @@ -90,21 +76,11 @@ private function doTestGetProperties(bool $legacy) $this->assertEquals( $expected, - $this->createExtractor($legacy)->getProperties(!class_exists(Types::class) ? 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy' : DoctrineDummy210::class) + $this->createExtractor()->getProperties(DoctrineDummy::class) ); } public function testTestGetPropertiesWithEmbedded() - { - $this->doTestGetPropertiesWithEmbedded(false); - } - - public function testLegacyTestGetPropertiesWithEmbedded() - { - $this->doTestGetPropertiesWithEmbedded(true); - } - - private function doTestGetPropertiesWithEmbedded(bool $legacy) { if (!class_exists(\Doctrine\ORM\Mapping\Embedded::class)) { $this->markTestSkipped('@Embedded is not available in Doctrine ORM lower than 2.5.'); @@ -115,7 +91,7 @@ private function doTestGetPropertiesWithEmbedded(bool $legacy) 'id', 'embedded', ], - $this->createExtractor($legacy)->getProperties('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineWithEmbedded') + $this->createExtractor()->getProperties('Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineWithEmbedded') ); } @@ -124,33 +100,10 @@ private function doTestGetPropertiesWithEmbedded(bool $legacy) */ public function testExtract($property, array $type = null) { - $this->doTestExtract(false, $property, $type); - } - - /** - * @dataProvider typesProvider - */ - public function testLegacyExtract($property, array $type = null) - { - $this->doTestExtract(true, $property, $type); - } - - private function doTestExtract(bool $legacy, $property, array $type = null) - { - $this->assertEquals($type, $this->createExtractor($legacy)->getTypes(!class_exists(Types::class) ? 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineDummy' : DoctrineDummy210::class, $property, [])); + $this->assertEquals($type, $this->createExtractor()->getTypes(DoctrineDummy::class, $property, [])); } public function testExtractWithEmbedded() - { - $this->doTestExtractWithEmbedded(false); - } - - public function testLegacyExtractWithEmbedded() - { - $this->doTestExtractWithEmbedded(true); - } - - private function doTestExtractWithEmbedded(bool $legacy) { if (!class_exists(\Doctrine\ORM\Mapping\Embedded::class)) { $this->markTestSkipped('@Embedded is not available in Doctrine ORM lower than 2.5.'); @@ -162,7 +115,7 @@ private function doTestExtractWithEmbedded(bool $legacy) 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineEmbeddable' )]; - $actualTypes = $this->createExtractor($legacy)->getTypes( + $actualTypes = $this->createExtractor()->getTypes( 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineWithEmbedded', 'embedded', [] @@ -257,41 +210,17 @@ public function typesProvider() ['json', null], ]; - if (class_exists(Types::class)) { - $provider[] = ['json', null]; - } - return $provider; } public function testGetPropertiesCatchException() { - $this->doTestGetPropertiesCatchException(false); - } - - public function testLegacyGetPropertiesCatchException() - { - $this->doTestGetPropertiesCatchException(true); - } - - private function doTestGetPropertiesCatchException(bool $legacy) - { - $this->assertNull($this->createExtractor($legacy)->getProperties('Not\Exist')); + $this->assertNull($this->createExtractor()->getProperties('Not\Exist')); } public function testGetTypesCatchException() { - return $this->doTestGetTypesCatchException(false); - } - - public function testLegacyGetTypesCatchException() - { - return $this->doTestGetTypesCatchException(true); - } - - private function doTestGetTypesCatchException(bool $legacy) - { - $this->assertNull($this->createExtractor($legacy)->getTypes('Not\Exist', 'baz')); + $this->assertNull($this->createExtractor()->getTypes('Not\Exist', 'baz')); } public function testGeneratedValueNotWritable() diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php index 67d61f2abfd3d..8190540e27566 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy.php @@ -138,6 +138,11 @@ class DoctrineDummy */ protected $indexedBuz; + /** + * @Column(type="json", nullable=true) + */ + private $json; + /** * @OneToMany(targetEntity="DoctrineRelation", mappedBy="dummyRelation", indexBy="gen_value_col_id", orphanRemoval=true) */ diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy210.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy210.php deleted file mode 100644 index d3916143deab7..0000000000000 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineDummy210.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures; - -use Doctrine\ORM\Mapping\Column; -use Doctrine\ORM\Mapping\Entity; -use Doctrine\ORM\Mapping\Id; -use Doctrine\ORM\Mapping\ManyToMany; -use Doctrine\ORM\Mapping\ManyToOne; -use Doctrine\ORM\Mapping\OneToMany; - -/** - * @Entity - */ -final class DoctrineDummy210 extends DoctrineDummy -{ - /** - * @Column(type="json", nullable=true) - */ - private $json; -} diff --git a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php index d7dbb1eeb41f9..7c09108fde562 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php +++ b/src/Symfony/Bridge/Doctrine/Tests/PropertyInfo/Fixtures/DoctrineFooType.php @@ -52,7 +52,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform) return null; } if (!$value instanceof Foo) { - throw new ConversionException(sprintf('Expected "%s", got "%s"', 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\Foo', \gettype($value))); + throw new ConversionException(sprintf('Expected "%s", got "%s"', 'Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\Foo', get_debug_type($value))); } return $foo->bar; diff --git a/src/Symfony/Bridge/Doctrine/Tests/Resources/validator/BaseUser.xml b/src/Symfony/Bridge/Doctrine/Tests/Resources/validator/BaseUser.xml index ddb8a13bc1fcc..bf64b92ca484d 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Resources/validator/BaseUser.xml +++ b/src/Symfony/Bridge/Doctrine/Tests/Resources/validator/BaseUser.xml @@ -9,6 +9,11 @@ + + + + + diff --git a/src/Symfony/Bridge/Doctrine/Tests/SchemaListener/MessengerTransportDoctrineSchemaSubscriberTest.php b/src/Symfony/Bridge/Doctrine/Tests/SchemaListener/MessengerTransportDoctrineSchemaSubscriberTest.php new file mode 100644 index 0000000000000..ff4ab2c27a19c --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/SchemaListener/MessengerTransportDoctrineSchemaSubscriberTest.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\SchemaListener; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Event\SchemaCreateTableEventArgs; +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Schema\Schema; +use Doctrine\DBAL\Schema\Table; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\SchemaListener\MessengerTransportDoctrineSchemaSubscriber; +use Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransport; +use Symfony\Component\Messenger\Transport\TransportInterface; + +class MessengerTransportDoctrineSchemaSubscriberTest extends TestCase +{ + public function testPostGenerateSchema() + { + $schema = new Schema(); + $dbalConnection = $this->createMock(Connection::class); + $entityManager = $this->createMock(EntityManagerInterface::class); + $entityManager->expects($this->once()) + ->method('getConnection') + ->willReturn($dbalConnection); + $event = new GenerateSchemaEventArgs($entityManager, $schema); + + $doctrineTransport = $this->createMock(DoctrineTransport::class); + $doctrineTransport->expects($this->once()) + ->method('configureSchema') + ->with($schema, $dbalConnection); + $otherTransport = $this->createMock(TransportInterface::class); + $otherTransport->expects($this->never()) + ->method($this->anything()); + + $subscriber = new MessengerTransportDoctrineSchemaSubscriber([$doctrineTransport, $otherTransport]); + $subscriber->postGenerateSchema($event); + } + + public function testOnSchemaCreateTable() + { + $platform = $this->createMock(AbstractPlatform::class); + $table = new Table('queue_table'); + $event = new SchemaCreateTableEventArgs($table, [], [], $platform); + + $otherTransport = $this->createMock(TransportInterface::class); + $otherTransport->expects($this->never()) + ->method($this->anything()); + + $doctrineTransport = $this->createMock(DoctrineTransport::class); + $doctrineTransport->expects($this->once()) + ->method('getExtraSetupSqlForTable') + ->with($table) + ->willReturn(['ALTER TABLE pizza ADD COLUMN extra_cheese boolean']); + + // we use the platform to generate the full create table sql + $platform->expects($this->once()) + ->method('getCreateTableSQL') + ->with($table) + ->willReturn('CREATE TABLE pizza (id integer NOT NULL)'); + + $subscriber = new MessengerTransportDoctrineSchemaSubscriber([$otherTransport, $doctrineTransport]); + $subscriber->onSchemaCreateTable($event); + $this->assertTrue($event->isDefaultPrevented()); + $this->assertSame([ + 'CREATE TABLE pizza (id integer NOT NULL)', + 'ALTER TABLE pizza ADD COLUMN extra_cheese boolean', + ], $event->getSql()); + } + + public function testOnSchemaCreateTableNoExtraSql() + { + $platform = $this->createMock(AbstractPlatform::class); + $table = new Table('queue_table'); + $event = new SchemaCreateTableEventArgs($table, [], [], $platform); + + $doctrineTransport = $this->createMock(DoctrineTransport::class); + $doctrineTransport->expects($this->once()) + ->method('getExtraSetupSqlForTable') + ->willReturn([]); + + $platform->expects($this->never()) + ->method('getCreateTableSQL'); + + $subscriber = new MessengerTransportDoctrineSchemaSubscriber([$doctrineTransport]); + $subscriber->onSchemaCreateTable($event); + $this->assertFalse($event->isDefaultPrevented()); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/SchemaListener/PdoCacheAdapterDoctrineSchemaSubscriberTest.php b/src/Symfony/Bridge/Doctrine/Tests/SchemaListener/PdoCacheAdapterDoctrineSchemaSubscriberTest.php new file mode 100644 index 0000000000000..9cf70e943ed25 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/SchemaListener/PdoCacheAdapterDoctrineSchemaSubscriberTest.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\SchemaListener; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Schema\Schema; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\SchemaListener\PdoCacheAdapterDoctrineSchemaSubscriber; +use Symfony\Component\Cache\Adapter\PdoAdapter; + +class PdoCacheAdapterDoctrineSchemaSubscriberTest extends TestCase +{ + public function testPostGenerateSchema() + { + $schema = new Schema(); + $dbalConnection = $this->createMock(Connection::class); + $entityManager = $this->createMock(EntityManagerInterface::class); + $entityManager->expects($this->once()) + ->method('getConnection') + ->willReturn($dbalConnection); + $event = new GenerateSchemaEventArgs($entityManager, $schema); + + $pdoAdapter = $this->createMock(PdoAdapter::class); + $pdoAdapter->expects($this->once()) + ->method('configureSchema') + ->with($schema, $dbalConnection); + + $subscriber = new PdoCacheAdapterDoctrineSchemaSubscriber([$pdoAdapter]); + $subscriber->postGenerateSchema($event); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Types/UlidTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Types/UlidTypeTest.php new file mode 100644 index 0000000000000..fde2341bc9ebe --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Types/UlidTypeTest.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Type; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\Types\UlidType; +use Symfony\Component\Uid\AbstractUid; +use Symfony\Component\Uid\Ulid; + +final class UlidTypeTest extends TestCase +{ + private const DUMMY_ULID = '01EEDQEK6ZAZE93J8KG5B4MBJC'; + + /** @var AbstractPlatform */ + private $platform; + + /** @var UlidType */ + private $type; + + public static function setUpBeforeClass(): void + { + if (Type::hasType('ulid')) { + Type::overrideType('ulid', UlidType::class); + } else { + Type::addType('ulid', UlidType::class); + } + } + + protected function setUp(): void + { + $this->platform = $this->createMock(AbstractPlatform::class); + $this->platform + ->method('hasNativeGuidType') + ->willReturn(true); + $this->platform + ->method('getGuidTypeDeclarationSQL') + ->willReturn('DUMMYVARCHAR()'); + + $this->type = Type::getType('ulid'); + } + + public function testUlidConvertsToDatabaseValue() + { + $ulid = Ulid::fromString(self::DUMMY_ULID); + + $expected = $ulid->toRfc4122(); + $actual = $this->type->convertToDatabaseValue($ulid, $this->platform); + + $this->assertEquals($expected, $actual); + } + + public function testUlidInterfaceConvertsToDatabaseValue() + { + $ulid = $this->createMock(AbstractUid::class); + + $ulid + ->expects($this->once()) + ->method('toRfc4122') + ->willReturn('foo'); + + $actual = $this->type->convertToDatabaseValue($ulid, $this->platform); + + $this->assertEquals('foo', $actual); + } + + public function testUlidStringConvertsToDatabaseValue() + { + $actual = $this->type->convertToDatabaseValue(self::DUMMY_ULID, $this->platform); + $ulid = Ulid::fromString(self::DUMMY_ULID); + + $expected = $ulid->toRfc4122(); + + $this->assertEquals($expected, $actual); + } + + public function testNotSupportedTypeConversionForDatabaseValue() + { + $this->expectException(ConversionException::class); + + $this->type->convertToDatabaseValue(new \stdClass(), $this->platform); + } + + public function testNullConversionForDatabaseValue() + { + $this->assertNull($this->type->convertToDatabaseValue(null, $this->platform)); + } + + public function testUlidInterfaceConvertsToPHPValue() + { + $ulid = $this->createMock(AbstractUid::class); + $actual = $this->type->convertToPHPValue($ulid, $this->platform); + + $this->assertSame($ulid, $actual); + } + + public function testUlidConvertsToPHPValue() + { + $ulid = $this->type->convertToPHPValue(self::DUMMY_ULID, $this->platform); + + $this->assertInstanceOf(Ulid::class, $ulid); + $this->assertEquals(self::DUMMY_ULID, $ulid->__toString()); + } + + public function testInvalidUlidConversionForPHPValue() + { + $this->expectException(ConversionException::class); + + $this->type->convertToPHPValue('abcdefg', $this->platform); + } + + public function testNullConversionForPHPValue() + { + $this->assertNull($this->type->convertToPHPValue(null, $this->platform)); + } + + public function testReturnValueIfUlidForPHPValue() + { + $ulid = new Ulid(); + + $this->assertSame($ulid, $this->type->convertToPHPValue($ulid, $this->platform)); + } + + public function testGetName() + { + $this->assertEquals('ulid', $this->type->getName()); + } + + public function testGetGuidTypeDeclarationSQL() + { + $this->assertEquals('DUMMYVARCHAR()', $this->type->getSqlDeclaration(['length' => 36], $this->platform)); + } + + public function testRequiresSQLCommentHint() + { + $this->assertTrue($this->type->requiresSQLCommentHint($this->platform)); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Types/UuidTypeTest.php b/src/Symfony/Bridge/Doctrine/Tests/Types/UuidTypeTest.php new file mode 100644 index 0000000000000..d6bf714627a1d --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Types/UuidTypeTest.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Type; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\Types\UuidType; +use Symfony\Component\Uid\AbstractUid; +use Symfony\Component\Uid\Uuid; + +final class UuidTypeTest extends TestCase +{ + private const DUMMY_UUID = '9f755235-5a2d-4aba-9605-e9962b312e50'; + + /** @var AbstractPlatform */ + private $platform; + + /** @var UuidType */ + private $type; + + public static function setUpBeforeClass(): void + { + if (Type::hasType('uuid')) { + Type::overrideType('uuid', UuidType::class); + } else { + Type::addType('uuid', UuidType::class); + } + } + + protected function setUp(): void + { + $this->platform = $this->createMock(AbstractPlatform::class); + $this->platform + ->method('hasNativeGuidType') + ->willReturn(true); + $this->platform + ->method('getGuidTypeDeclarationSQL') + ->willReturn('DUMMYVARCHAR()'); + + $this->type = Type::getType('uuid'); + } + + public function testUuidConvertsToDatabaseValue() + { + $uuid = Uuid::fromString(self::DUMMY_UUID); + + $expected = $uuid->__toString(); + $actual = $this->type->convertToDatabaseValue($uuid, $this->platform); + + $this->assertEquals($expected, $actual); + } + + public function testUuidInterfaceConvertsToDatabaseValue() + { + $uuid = $this->createMock(AbstractUid::class); + + $uuid + ->expects($this->once()) + ->method('toRfc4122') + ->willReturn('foo'); + + $actual = $this->type->convertToDatabaseValue($uuid, $this->platform); + + $this->assertEquals('foo', $actual); + } + + public function testUuidStringConvertsToDatabaseValue() + { + $actual = $this->type->convertToDatabaseValue(self::DUMMY_UUID, $this->platform); + + $this->assertEquals(self::DUMMY_UUID, $actual); + } + + public function testNotSupportedTypeConversionForDatabaseValue() + { + $this->expectException(ConversionException::class); + + $this->type->convertToDatabaseValue(new \stdClass(), $this->platform); + } + + public function testNullConversionForDatabaseValue() + { + $this->assertNull($this->type->convertToDatabaseValue(null, $this->platform)); + } + + public function testUuidInterfaceConvertsToPHPValue() + { + $uuid = $this->createMock(AbstractUid::class); + $actual = $this->type->convertToPHPValue($uuid, $this->platform); + + $this->assertSame($uuid, $actual); + } + + public function testUuidConvertsToPHPValue() + { + $uuid = $this->type->convertToPHPValue(self::DUMMY_UUID, $this->platform); + + $this->assertInstanceOf(Uuid::class, $uuid); + $this->assertEquals(self::DUMMY_UUID, $uuid->__toString()); + } + + public function testInvalidUuidConversionForPHPValue() + { + $this->expectException(ConversionException::class); + + $this->type->convertToPHPValue('abcdefg', $this->platform); + } + + public function testNullConversionForPHPValue() + { + $this->assertNull($this->type->convertToPHPValue(null, $this->platform)); + } + + public function testReturnValueIfUuidForPHPValue() + { + $uuid = Uuid::v4(); + + $this->assertSame($uuid, $this->type->convertToPHPValue($uuid, $this->platform)); + } + + public function testGetName() + { + $this->assertEquals('uuid', $this->type->getName()); + } + + public function testGetGuidTypeDeclarationSQL() + { + $this->assertEquals('DUMMYVARCHAR()', $this->type->getSqlDeclaration(['length' => 36], $this->platform)); + } + + public function testRequiresSQLCommentHint() + { + $this->assertTrue($this->type->requiresSQLCommentHint($this->platform)); + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityTest.php new file mode 100644 index 0000000000000..2c9c3815654ba --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Validator\Constraints; + +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; +use Symfony\Component\Validator\Mapping\ClassMetadata; +use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader; + +/** + * @requires PHP 8 + */ +class UniqueEntityTest extends TestCase +{ + public function testAttributeWithDefaultProperty() + { + $metadata = new ClassMetadata(UniqueEntityDummyOne::class); + $loader = new AnnotationLoader(); + self::assertTrue($loader->loadClassMetadata($metadata)); + + /** @var UniqueEntity $constraint */ + [$constraint] = $metadata->getConstraints(); + self::assertSame(['email'], $constraint->fields); + self::assertTrue($constraint->ignoreNull); + self::assertSame('doctrine.orm.validator.unique', $constraint->validatedBy()); + self::assertSame(['Default', 'UniqueEntityDummyOne'], $constraint->groups); + } + + public function testAttributeWithCustomizedService() + { + $metadata = new ClassMetadata(UniqueEntityDummyTwo::class); + $loader = new AnnotationLoader(); + self::assertTrue($loader->loadClassMetadata($metadata)); + + /** @var UniqueEntity $constraint */ + [$constraint] = $metadata->getConstraints(); + self::assertSame(['isbn'], $constraint->fields); + self::assertSame('my_own_validator', $constraint->validatedBy()); + self::assertSame('my_own_entity_manager', $constraint->em); + self::assertSame('App\Entity\MyEntity', $constraint->entityClass); + self::assertSame('fetchDifferently', $constraint->repositoryMethod); + } + + public function testAttributeWithGroupsAndPaylod() + { + $metadata = new ClassMetadata(UniqueEntityDummyThree::class); + $loader = new AnnotationLoader(); + self::assertTrue($loader->loadClassMetadata($metadata)); + + /** @var UniqueEntity $constraint */ + [$constraint] = $metadata->getConstraints(); + self::assertSame('uuid', $constraint->fields); + self::assertSame('id', $constraint->errorPath); + self::assertSame('some attached data', $constraint->payload); + self::assertSame(['some_group'], $constraint->groups); + } +} + +#[UniqueEntity(['email'], message: 'myMessage')] +class UniqueEntityDummyOne +{ + private $email; +} + +#[UniqueEntity(fields: ['isbn'], service: 'my_own_validator', em: 'my_own_entity_manager', entityClass: 'App\Entity\MyEntity', repositoryMethod: 'fetchDifferently')] +class UniqueEntityDummyTwo +{ + private $isbn; +} + +#[UniqueEntity('uuid', ignoreNull: false, errorPath: 'id', payload: 'some attached data', groups: ['some_group'])] +class UniqueEntityDummyThree +{ + private $id; + private $uuid; +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 05faff5872dd8..268dc29b6ece0 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -155,15 +155,11 @@ private function createSchema($em) /** * This is a functional test as there is a large integration necessary to get the validator working. + * + * @dataProvider provideUniquenessConstraints */ - public function testValidateUniqueness() + public function testValidateUniqueness(UniqueEntity $constraint) { - $constraint = new UniqueEntity([ - 'message' => 'myMessage', - 'fields' => ['name'], - 'em' => self::EM_NAME, - ]); - $entity1 = new SingleIntIdEntity(1, 'Foo'); $entity2 = new SingleIntIdEntity(2, 'Foo'); @@ -189,15 +185,24 @@ public function testValidateUniqueness() ->assertRaised(); } - public function testValidateCustomErrorPath() + public function provideUniquenessConstraints(): iterable { - $constraint = new UniqueEntity([ + yield 'Doctrine style' => [new UniqueEntity([ 'message' => 'myMessage', 'fields' => ['name'], 'em' => self::EM_NAME, - 'errorPath' => 'bar', - ]); + ])]; + + if (\PHP_VERSION_ID >= 80000) { + yield 'Named arguments' => [eval('return new \Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity(message: "myMessage", fields: ["name"], em: "foo");')]; + } + } + /** + * @dataProvider provideConstraintsWithCustomErrorPath + */ + public function testValidateCustomErrorPath(UniqueEntity $constraint) + { $entity1 = new SingleIntIdEntity(1, 'Foo'); $entity2 = new SingleIntIdEntity(2, 'Foo'); @@ -215,14 +220,25 @@ public function testValidateCustomErrorPath() ->assertRaised(); } - public function testValidateUniquenessWithNull() + public function provideConstraintsWithCustomErrorPath(): iterable { - $constraint = new UniqueEntity([ + yield 'Doctrine style' => [new UniqueEntity([ 'message' => 'myMessage', 'fields' => ['name'], 'em' => self::EM_NAME, - ]); + 'errorPath' => 'bar', + ])]; + if (\PHP_VERSION_ID >= 80000) { + yield 'Named arguments' => [eval('return new \Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity(message: "myMessage", fields: ["name"], em: "foo", errorPath: "bar");')]; + } + } + + /** + * @dataProvider provideUniquenessConstraints + */ + public function testValidateUniquenessWithNull(UniqueEntity $constraint) + { $entity1 = new SingleIntIdEntity(1, null); $entity2 = new SingleIntIdEntity(2, null); @@ -235,15 +251,11 @@ public function testValidateUniquenessWithNull() $this->assertNoViolation(); } - public function testValidateUniquenessWithIgnoreNullDisabled() + /** + * @dataProvider provideConstraintsWithIgnoreNullDisabled + */ + public function testValidateUniquenessWithIgnoreNullDisabled(UniqueEntity $constraint) { - $constraint = new UniqueEntity([ - 'message' => 'myMessage', - 'fields' => ['name', 'name2'], - 'em' => self::EM_NAME, - 'ignoreNull' => false, - ]); - $entity1 = new DoubleNameEntity(1, 'Foo', null); $entity2 = new DoubleNameEntity(2, 'Foo', null); @@ -269,30 +281,36 @@ public function testValidateUniquenessWithIgnoreNullDisabled() ->assertRaised(); } - public function testAllConfiguredFieldsAreCheckedOfBeingMappedByDoctrineWithIgnoreNullEnabled() + public function provideConstraintsWithIgnoreNullDisabled(): iterable { - $this->expectException(ConstraintDefinitionException::class); - $constraint = new UniqueEntity([ + yield 'Doctrine style' => [new UniqueEntity([ 'message' => 'myMessage', 'fields' => ['name', 'name2'], 'em' => self::EM_NAME, - 'ignoreNull' => true, - ]); + 'ignoreNull' => false, + ])]; + if (\PHP_VERSION_ID >= 80000) { + yield 'Named arguments' => [eval('return new \Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity(message: "myMessage", fields: ["name", "name2"], em: "foo", ignoreNull: false);')]; + } + } + + /** + * @dataProvider provideConstraintsWithIgnoreNullEnabled + */ + public function testAllConfiguredFieldsAreCheckedOfBeingMappedByDoctrineWithIgnoreNullEnabled(UniqueEntity $constraint) + { $entity1 = new SingleIntIdEntity(1, null); + $this->expectException(\Symfony\Component\Validator\Exception\ConstraintDefinitionException::class); $this->validator->validate($entity1, $constraint); } - public function testNoValidationIfFirstFieldIsNullAndNullValuesAreIgnored() + /** + * @dataProvider provideConstraintsWithIgnoreNullEnabled + */ + public function testNoValidationIfFirstFieldIsNullAndNullValuesAreIgnored(UniqueEntity $constraint) { - $constraint = new UniqueEntity([ - 'message' => 'myMessage', - 'fields' => ['name', 'name2'], - 'em' => self::EM_NAME, - 'ignoreNull' => true, - ]); - $entity1 = new DoubleNullableNameEntity(1, null, 'Foo'); $entity2 = new DoubleNullableNameEntity(2, null, 'Foo'); @@ -312,6 +330,20 @@ public function testNoValidationIfFirstFieldIsNullAndNullValuesAreIgnored() $this->assertNoViolation(); } + public function provideConstraintsWithIgnoreNullEnabled(): iterable + { + yield 'Doctrine style' => [new UniqueEntity([ + 'message' => 'myMessage', + 'fields' => ['name', 'name2'], + 'em' => self::EM_NAME, + 'ignoreNull' => true, + ])]; + + if (\PHP_VERSION_ID >= 80000) { + yield 'Named arguments' => [eval('return new \Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity(message: "myMessage", fields: ["name", "name2"], em: "foo", ignoreNull: true);')]; + } + } + public function testValidateUniquenessWithValidCustomErrorPath() { $constraint = new UniqueEntity([ @@ -346,15 +378,11 @@ public function testValidateUniquenessWithValidCustomErrorPath() ->assertRaised(); } - public function testValidateUniquenessUsingCustomRepositoryMethod() + /** + * @dataProvider provideConstraintsWithCustomRepositoryMethod + */ + public function testValidateUniquenessUsingCustomRepositoryMethod(UniqueEntity $constraint) { - $constraint = new UniqueEntity([ - 'message' => 'myMessage', - 'fields' => ['name'], - 'em' => self::EM_NAME, - 'repositoryMethod' => 'findByCustom', - ]); - $repository = $this->createRepositoryMock(); $repository->expects($this->once()) ->method('findByCustom') @@ -372,15 +400,11 @@ public function testValidateUniquenessUsingCustomRepositoryMethod() $this->assertNoViolation(); } - public function testValidateUniquenessWithUnrewoundArray() + /** + * @dataProvider provideConstraintsWithCustomRepositoryMethod + */ + public function testValidateUniquenessWithUnrewoundArray(UniqueEntity $constraint) { - $constraint = new UniqueEntity([ - 'message' => 'myMessage', - 'fields' => ['name'], - 'em' => self::EM_NAME, - 'repositoryMethod' => 'findByCustom', - ]); - $entity = new SingleIntIdEntity(1, 'foo'); $repository = $this->createRepositoryMock(); @@ -407,6 +431,20 @@ function () use ($entity) { $this->assertNoViolation(); } + public function provideConstraintsWithCustomRepositoryMethod(): iterable + { + yield 'Doctrine style' => [new UniqueEntity([ + 'message' => 'myMessage', + 'fields' => ['name'], + 'em' => self::EM_NAME, + 'repositoryMethod' => 'findByCustom', + ])]; + + if (\PHP_VERSION_ID >= 80000) { + yield 'Named arguments' => [eval('return new \Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity(message: "myMessage", fields: ["name"], em: "foo", repositoryMethod: "findByCustom");')]; + } + } + /** * @dataProvider resultTypesProvider */ diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php index db691401cef8d..31129a8c615d0 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php @@ -46,8 +46,8 @@ protected function setUp(): void public function testLoadClassMetadata() { $validator = Validation::createValidatorBuilder() - ->addMethodMapping('loadValidatorMetadata') - ->enableAnnotationMapping() + ->enableAnnotationMapping(true) + ->addDefaultDoctrineAnnotationReader() ->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{^Symfony\\\\Bridge\\\\Doctrine\\\\Tests\\\\Fixtures\\\\DoctrineLoader}')) ->getValidator() ; @@ -152,8 +152,8 @@ public function testLoadClassMetadata() public function testFieldMappingsConfiguration() { $validator = Validation::createValidatorBuilder() - ->addMethodMapping('loadValidatorMetadata') - ->enableAnnotationMapping() + ->enableAnnotationMapping(true) + ->addDefaultDoctrineAnnotationReader() ->addXmlMappings([__DIR__.'/../Resources/validator/BaseUser.xml']) ->addLoader( new DoctrineLoader( @@ -194,7 +194,8 @@ public function regexpProvider() public function testClassNoAutoMapping() { $validator = Validation::createValidatorBuilder() - ->enableAnnotationMapping() + ->enableAnnotationMapping(true) + ->addDefaultDoctrineAnnotationReader() ->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{.*}')) ->getValidator(); diff --git a/src/Symfony/Bridge/Doctrine/Types/AbstractUidType.php b/src/Symfony/Bridge/Doctrine/Types/AbstractUidType.php new file mode 100644 index 0000000000000..ec0c6ef6f8078 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Types/AbstractUidType.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\ConversionException; +use Doctrine\DBAL\Types\Type; +use Symfony\Component\Uid\AbstractUid; + +abstract class AbstractUidType extends Type +{ + abstract protected function getUidClass(): string; + + /** + * {@inheritdoc} + */ + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string + { + if ($platform->hasNativeGuidType()) { + return $platform->getGuidTypeDeclarationSQL($column); + } + + return $platform->getBinaryTypeDeclarationSQL([ + 'length' => '16', + 'fixed' => true, + ]); + } + + /** + * {@inheritdoc} + * + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?AbstractUid + { + if ($value instanceof AbstractUid || null === $value) { + return $value; + } + + if (!\is_string($value)) { + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'string', AbstractUid::class]); + } + + try { + return $this->getUidClass()::fromString($value); + } catch (\InvalidArgumentException $e) { + throw ConversionException::conversionFailed($value, $this->getName(), $e); + } + } + + /** + * {@inheritdoc} + * + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + $toString = $platform->hasNativeGuidType() ? 'toRfc4122' : 'toBinary'; + + if ($value instanceof AbstractUid) { + return $value->$toString(); + } + + if (null === $value || '' === $value) { + return null; + } + + if (!\is_string($value)) { + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'string', AbstractUid::class]); + } + + try { + return $this->getUidClass()::fromString($value)->$toString(); + } catch (\InvalidArgumentException $e) { + throw ConversionException::conversionFailed($value, $this->getName()); + } + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform): bool + { + return true; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Types/UlidType.php b/src/Symfony/Bridge/Doctrine/Types/UlidType.php new file mode 100644 index 0000000000000..809317b222005 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Types/UlidType.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Types; + +use Symfony\Component\Uid\Ulid; + +final class UlidType extends AbstractUidType +{ + public function getName(): string + { + return 'ulid'; + } + + protected function getUidClass(): string + { + return Ulid::class; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Types/UuidType.php b/src/Symfony/Bridge/Doctrine/Types/UuidType.php new file mode 100644 index 0000000000000..bbf0394034a06 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Types/UuidType.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Types; + +use Symfony\Component\Uid\Uuid; + +final class UuidType extends AbstractUidType +{ + public function getName(): string + { + return 'uuid'; + } + + protected function getUidClass(): string + { + return Uuid::class; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php index 3839f14f35330..dc848c143ca9e 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php @@ -21,6 +21,7 @@ * * @author Benjamin Eberlei */ +#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)] class UniqueEntity extends Constraint { public const NOT_UNIQUE_ERROR = '23bd9dbf-6b9b-41cd-a99e-4844bcf3077f'; @@ -38,6 +39,41 @@ class UniqueEntity extends Constraint self::NOT_UNIQUE_ERROR => 'NOT_UNIQUE_ERROR', ]; + /** + * {@inheritdoc} + * + * @param array|string $fields the combination of fields that must contain unique values or a set of options + */ + public function __construct( + $fields, + string $message = null, + string $service = null, + string $em = null, + string $entityClass = null, + string $repositoryMethod = null, + string $errorPath = null, + bool $ignoreNull = null, + array $groups = null, + $payload = null, + array $options = [] + ) { + if (\is_array($fields) && \is_string(key($fields))) { + $options = array_merge($fields, $options); + } elseif (null !== $fields) { + $options['fields'] = $fields; + } + + parent::__construct($options, $groups, $payload); + + $this->message = $message ?? $this->message; + $this->service = $service ?? $this->service; + $this->em = $em ?? $this->em; + $this->entityClass = $entityClass ?? $this->entityClass; + $this->repositoryMethod = $repositoryMethod ?? $this->repositoryMethod; + $this->errorPath = $errorPath ?? $this->errorPath; + $this->ignoreNull = $ignoreNull ?? $this->ignoreNull; + } + public function getRequiredOptions() { return ['fields']; diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index 399a18d90c7fe..bed785cbd88c9 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -71,7 +71,7 @@ public function validate($entity, Constraint $constraint) $em = $this->registry->getManagerForClass(\get_class($entity)); if (!$em) { - throw new ConstraintDefinitionException(sprintf('Unable to find the object manager associated with an entity of class "%s".', \get_class($entity))); + throw new ConstraintDefinitionException(sprintf('Unable to find the object manager associated with an entity of class "%s".', get_debug_type($entity))); } } diff --git a/src/Symfony/Bridge/Doctrine/Validator/DoctrineInitializer.php b/src/Symfony/Bridge/Doctrine/Validator/DoctrineInitializer.php index 659bd8569759d..28d5fccc7459c 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/DoctrineInitializer.php +++ b/src/Symfony/Bridge/Doctrine/Validator/DoctrineInitializer.php @@ -28,7 +28,7 @@ public function __construct(ManagerRegistry $registry) $this->registry = $registry; } - public function initialize($object) + public function initialize(object $object) { $manager = $this->registry->getManagerForClass(\get_class($object)); if (null !== $manager) { diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index 68fbcef8c7b53..5a58adf607189 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -16,44 +16,52 @@ } ], "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", "doctrine/event-manager": "~1.0", - "doctrine/persistence": "^1.3|^2", + "doctrine/persistence": "^2", + "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.15", "symfony/service-contracts": "^1.1|^2" }, "require-dev": { "composer/package-versions-deprecated": "^1.8", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/config": "^4.2|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/form": "^4.4.11|^5.0.11", - "symfony/http-kernel": "^4.3.7", + "symfony/stopwatch": "^4.4|^5.0", + "symfony/cache": "^5.1", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/form": "^5.1.3", + "symfony/http-kernel": "^5.0", "symfony/messenger": "^4.4|^5.0", - "symfony/property-access": "^3.4|^4.0|^5.0", - "symfony/property-info": "^3.4|^4.0|^5.0", - "symfony/proxy-manager-bridge": "^3.4|^4.0|^5.0", - "symfony/security-core": "^4.4|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/validator": "^4.4.2|^5.0.2", - "symfony/var-dumper": "^3.4|^4.0|^5.0", - "symfony/translation": "^3.4|^4.0|^5.0", + "symfony/doctrine-messenger": "^5.1", + "symfony/property-access": "^4.4|^5.0", + "symfony/property-info": "^5.0", + "symfony/proxy-manager-bridge": "^4.4|^5.0", + "symfony/security-core": "^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/uid": "^5.1", + "symfony/validator": "^5.2", + "symfony/translation": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0", "doctrine/annotations": "^1.10.4", "doctrine/cache": "~1.6", "doctrine/collections": "~1.0", "doctrine/data-fixtures": "^1.1", - "doctrine/dbal": "^2.6|^3.0", - "doctrine/orm": "^2.6.3" + "doctrine/dbal": "^2.10|^3.0", + "doctrine/orm": "^2.7.3" }, "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/dependency-injection": "<3.4", - "symfony/form": "<4.4", - "symfony/http-kernel": "<4.3.7", - "symfony/messenger": "<4.3", - "symfony/security-core": "<4.4", - "symfony/validator": "<4.4.2|<5.0.2,>=5.0" + "doctrine/dbal": "<2.10", + "phpunit/phpunit": "<5.4.3", + "symfony/dependency-injection": "<4.4", + "symfony/form": "<5.1", + "symfony/http-kernel": "<5", + "symfony/messenger": "<4.4", + "symfony/property-info": "<5", + "symfony/security-bundle": "<5", + "symfony/security-core": "<5", + "symfony/validator": "<5.2" }, "suggest": { "symfony/form": "", diff --git a/src/Symfony/Bridge/Monolog/CHANGELOG.md b/src/Symfony/Bridge/Monolog/CHANGELOG.md index 61ab0b3c6f899..1a7e11615e7d0 100644 --- a/src/Symfony/Bridge/Monolog/CHANGELOG.md +++ b/src/Symfony/Bridge/Monolog/CHANGELOG.md @@ -1,6 +1,23 @@ CHANGELOG ========= +5.2.0 +----- + + * The `$actionLevel` constructor argument of `Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy` has been deprecated and replaced by the `$inner` one which expects an ActivationStrategyInterface to decorate instead. `Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy` will become final in 6.0. + * The `$actionLevel` constructor argument of `Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy` has been deprecated and replaced by the `$inner` one which expects an ActivationStrategyInterface to decorate instead. `Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy` will become final in 6.0 + +5.1.0 +----- + + * Added `MailerHandler` + +5.0.0 +----- + + * The methods `DebugProcessor::getLogs()`, `DebugProcessor::countErrors()`, `Logger::getLogs()` and `Logger::countErrors()` have a new `$request` argument. + * Added support for Monolog 2. + 4.4.0 ----- diff --git a/src/Symfony/Bridge/Monolog/Handler/ChromePhpHandler.php b/src/Symfony/Bridge/Monolog/Handler/ChromePhpHandler.php index 4d722c46ecfcf..e7049c4b614cc 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ChromePhpHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ChromePhpHandler.php @@ -13,14 +13,14 @@ use Monolog\Handler\ChromePHPHandler as BaseChromePhpHandler; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\Event\ResponseEvent; /** * ChromePhpHandler. * * @author Christophe Coevoet * - * @final since Symfony 4.3 + * @final */ class ChromePhpHandler extends BaseChromePhpHandler { @@ -34,7 +34,7 @@ class ChromePhpHandler extends BaseChromePhpHandler /** * Adds the headers to the response once it's created. */ - public function onKernelResponse(FilterResponseEvent $event) + public function onKernelResponse(ResponseEvent $event) { if (!$event->isMasterRequest()) { return; @@ -57,7 +57,7 @@ public function onKernelResponse(FilterResponseEvent $event) /** * {@inheritdoc} */ - protected function sendHeader($header, $content) + protected function sendHeader($header, $content): void { if (!self::$sendHeaders) { return; @@ -72,10 +72,8 @@ protected function sendHeader($header, $content) /** * Override default behavior since we check it in onKernelResponse. - * - * @return bool */ - protected function headersAccepted() + protected function headersAccepted(): bool { return true; } diff --git a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php index 2a02905d24e21..17d3c2f28d227 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php @@ -74,20 +74,16 @@ public function __construct(OutputInterface $output = null, bool $bubble = true, /** * {@inheritdoc} - * - * @return bool */ - public function isHandling(array $record) + public function isHandling(array $record): bool { return $this->updateLevel() && parent::isHandling($record); } /** * {@inheritdoc} - * - * @return bool */ - public function handle(array $record) + public function handle(array $record): bool { // we have to update the logging level each time because the verbosity of the // console output might have changed in the meantime (it is not immutable) @@ -105,7 +101,7 @@ public function setOutput(OutputInterface $output) /** * Disables the output. */ - public function close() + public function close(): void { $this->output = null; @@ -147,10 +143,8 @@ public static function getSubscribedEvents() /** * {@inheritdoc} - * - * @return void */ - protected function write(array $record) + protected function write(array $record): void { // at this point we've determined for sure that we want to output the record, so use the output's own verbosity $this->output->write((string) $record['formatted'], false, $this->output->getVerbosity()); @@ -158,10 +152,8 @@ protected function write(array $record) /** * {@inheritdoc} - * - * @return FormatterInterface */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { if (!class_exists(CliDumper::class)) { return new LineFormatter(); diff --git a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php index 84f61ce9bf706..e87b8677cec6d 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php +++ b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/HttpCodeActivationStrategy.php @@ -11,6 +11,7 @@ namespace Symfony\Bridge\Monolog\Handler\FingersCrossed; +use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -19,17 +20,29 @@ * Activation strategy that ignores certain HTTP codes. * * @author Shaun Simmons + * @author Pierrick Vignand + * + * @final */ -class HttpCodeActivationStrategy extends ErrorLevelActivationStrategy +class HttpCodeActivationStrategy extends ErrorLevelActivationStrategy implements ActivationStrategyInterface { + private $inner; private $exclusions; private $requestStack; /** - * @param array $exclusions each exclusion must have a "code" and "urls" keys + * @param array $exclusions each exclusion must have a "code" and "urls" keys + * @param ActivationStrategyInterface|int|string $inner an ActivationStrategyInterface to decorate */ - public function __construct(RequestStack $requestStack, array $exclusions, $actionLevel) + public function __construct(RequestStack $requestStack, array $exclusions, $inner) { + if (!$inner instanceof ActivationStrategyInterface) { + trigger_deprecation('symfony/monolog-bridge', '5.2', 'Passing an actionLevel (int|string) as constructor\'s 3rd argument of "%s" is deprecated, "%s" expected.', __CLASS__, ActivationStrategyInterface::class); + + $actionLevel = $inner; + $inner = new ErrorLevelActivationStrategy($actionLevel); + } + foreach ($exclusions as $exclusion) { if (!\array_key_exists('code', $exclusion)) { throw new \LogicException('An exclusion must have a "code" key.'); @@ -39,18 +52,14 @@ public function __construct(RequestStack $requestStack, array $exclusions, $acti } } - parent::__construct($actionLevel); - + $this->inner = $inner; $this->requestStack = $requestStack; $this->exclusions = $exclusions; } - /** - * @return bool - */ - public function isHandlerActivated(array $record) + public function isHandlerActivated(array $record): bool { - $isActivated = parent::isHandlerActivated($record); + $isActivated = $this->inner->isHandlerActivated($record); if ( $isActivated diff --git a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php index a404f39db3cab..a9806d7e92ea6 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php +++ b/src/Symfony/Bridge/Monolog/Handler/FingersCrossed/NotFoundActivationStrategy.php @@ -11,6 +11,7 @@ namespace Symfony\Bridge\Monolog\Handler\FingersCrossed; +use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Exception\HttpException; @@ -20,26 +21,36 @@ * * @author Jordi Boggiano * @author Fabien Potencier + * @author Pierrick Vignand + * + * @final */ -class NotFoundActivationStrategy extends ErrorLevelActivationStrategy +class NotFoundActivationStrategy extends ErrorLevelActivationStrategy implements ActivationStrategyInterface { + private $inner; private $exclude; private $requestStack; - public function __construct(RequestStack $requestStack, array $excludedUrls, $actionLevel) + /** + * @param ActivationStrategyInterface|int|string $inner an ActivationStrategyInterface to decorate + */ + public function __construct(RequestStack $requestStack, array $excludedUrls, $inner) { - parent::__construct($actionLevel); + if (!$inner instanceof ActivationStrategyInterface) { + trigger_deprecation('symfony/monolog-bridge', '5.2', 'Passing an actionLevel (int|string) as constructor\'s 3rd argument of "%s" is deprecated, "%s" expected.', __CLASS__, ActivationStrategyInterface::class); + $actionLevel = $inner; + $inner = new ErrorLevelActivationStrategy($actionLevel); + } + + $this->inner = $inner; $this->requestStack = $requestStack; $this->exclude = '{('.implode('|', $excludedUrls).')}i'; } - /** - * @return bool - */ - public function isHandlerActivated(array $record) + public function isHandlerActivated(array $record): bool { - $isActivated = parent::isHandlerActivated($record); + $isActivated = $this->inner->isHandlerActivated($record); if ( $isActivated diff --git a/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php b/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php index f006118223cba..0a9a6965db4a9 100644 --- a/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/FirePHPHandler.php @@ -13,14 +13,14 @@ use Monolog\Handler\FirePHPHandler as BaseFirePHPHandler; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\Event\ResponseEvent; /** * FirePHPHandler. * * @author Jordi Boggiano * - * @final since Symfony 4.3 + * @final */ class FirePHPHandler extends BaseFirePHPHandler { @@ -34,7 +34,7 @@ class FirePHPHandler extends BaseFirePHPHandler /** * Adds the headers to the response once it's created. */ - public function onKernelResponse(FilterResponseEvent $event) + public function onKernelResponse(ResponseEvent $event) { if (!$event->isMasterRequest()) { return; @@ -59,7 +59,7 @@ public function onKernelResponse(FilterResponseEvent $event) /** * {@inheritdoc} */ - protected function sendHeader($header, $content) + protected function sendHeader($header, $content): void { if (!self::$sendHeaders) { return; @@ -74,10 +74,8 @@ protected function sendHeader($header, $content) /** * Override default behavior since we check the user agent in onKernelResponse. - * - * @return bool */ - protected function headersAccepted() + protected function headersAccepted(): bool { return true; } diff --git a/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php b/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php new file mode 100644 index 0000000000000..cf59f45ef388f --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Handler/MailerHandler.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Monolog\Handler; + +use Monolog\Formatter\FormatterInterface; +use Monolog\Formatter\HtmlFormatter; +use Monolog\Formatter\LineFormatter; +use Monolog\Handler\AbstractProcessingHandler; +use Monolog\Logger; +use Symfony\Component\Mailer\MailerInterface; +use Symfony\Component\Mime\Email; + +/** + * @author Alexander Borisov + */ +class MailerHandler extends AbstractProcessingHandler +{ + private $mailer; + + private $messageTemplate; + + /** + * @param callable|Email $messageTemplate + * @param string|int $level The minimum logging level at which this handler will be triggered + */ + public function __construct(MailerInterface $mailer, $messageTemplate, $level = Logger::DEBUG, bool $bubble = true) + { + parent::__construct($level, $bubble); + + $this->mailer = $mailer; + $this->messageTemplate = $messageTemplate; + } + + /** + * {@inheritdoc} + */ + public function handleBatch(array $records): void + { + $messages = []; + + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + $messages[] = $this->processRecord($record); + } + + if (!empty($messages)) { + $this->send((string) $this->getFormatter()->formatBatch($messages), $messages); + } + } + + /** + * {@inheritdoc} + */ + protected function write(array $record): void + { + $this->send((string) $record['formatted'], [$record]); + } + + /** + * Send a mail with the given content. + * + * @param string $content formatted email body to be sent + * @param array $records the array of log records that formed this content + */ + protected function send(string $content, array $records) + { + $this->mailer->send($this->buildMessage($content, $records)); + } + + /** + * Gets the formatter for the Message subject. + * + * @param string $format The format of the subject + */ + protected function getSubjectFormatter(string $format): FormatterInterface + { + return new LineFormatter($format); + } + + /** + * Creates instance of Message to be sent. + * + * @param string $content formatted email body to be sent + * @param array $records Log records that formed the content + */ + protected function buildMessage(string $content, array $records): Email + { + $message = null; + if ($this->messageTemplate instanceof Email) { + $message = clone $this->messageTemplate; + } elseif (\is_callable($this->messageTemplate)) { + $message = \call_user_func($this->messageTemplate, $content, $records); + if (!$message instanceof Email) { + throw new \InvalidArgumentException(sprintf('Could not resolve message from a callable. Instance of "%s" is expected.', Email::class)); + } + } else { + throw new \InvalidArgumentException('Could not resolve message as instance of Email or a callable returning it.'); + } + + if ($records) { + $subjectFormatter = $this->getSubjectFormatter($message->getSubject()); + $message->subject($subjectFormatter->format($this->getHighestRecord($records))); + } + + if ($this->getFormatter() instanceof HtmlFormatter) { + if ($message->getHtmlCharset()) { + $message->html($content, $message->getHtmlCharset()); + } else { + $message->html($content); + } + } else { + if ($message->getTextCharset()) { + $message->text($content, $message->getTextCharset()); + } else { + $message->text($content); + } + } + + return $message; + } + + protected function getHighestRecord(array $records): array + { + $highestRecord = null; + foreach ($records as $record) { + if (null === $highestRecord || $highestRecord['level'] < $record['level']) { + $highestRecord = $record; + } + } + + return $highestRecord; + } +} diff --git a/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php b/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php new file mode 100644 index 0000000000000..be60c7dcbf234 --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Handler/NotifierHandler.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Monolog\Handler; + +use Monolog\Handler\AbstractHandler; +use Monolog\Logger; +use Symfony\Component\Notifier\Notification\Notification; +use Symfony\Component\Notifier\Notifier; +use Symfony\Component\Notifier\NotifierInterface; + +/** + * Uses Notifier as a log handler. + * + * @author Fabien Potencier + */ +class NotifierHandler extends AbstractHandler +{ + private $notifier; + + /** + * @param string|int $level The minimum logging level at which this handler will be triggered + */ + public function __construct(NotifierInterface $notifier, $level = Logger::ERROR, bool $bubble = true) + { + $this->notifier = $notifier; + + parent::__construct(Logger::toMonologLevel($level) < Logger::ERROR ? Logger::ERROR : $level, $bubble); + } + + public function handle(array $record): bool + { + if (!$this->isHandling($record)) { + return false; + } + + $this->notify([$record]); + + return !$this->bubble; + } + + public function handleBatch(array $records): void + { + if ($records = array_filter($records, [$this, 'isHandling'])) { + $this->notify($records); + } + } + + private function notify(array $records): void + { + $record = $this->getHighestRecord($records); + if (($record['context']['exception'] ?? null) instanceof \Throwable) { + $notification = Notification::fromThrowable($record['context']['exception']); + } else { + $notification = new Notification($record['message']); + } + + $notification->importanceFromLogLevelName(Logger::getLevelName($record['level'])); + + $this->notifier->send($notification, ...$this->notifier->getAdminRecipients()); + } + + private function getHighestRecord(array $records) + { + $highestRecord = null; + foreach ($records as $record) { + if (null === $highestRecord || $highestRecord['level'] < $record['level']) { + $highestRecord = $record; + } + } + + return $highestRecord; + } +} diff --git a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php index 4b92b088f7dac..056b4ab9a9bb8 100644 --- a/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/ServerLogHandler.php @@ -12,14 +12,43 @@ namespace Symfony\Bridge\Monolog\Handler; use Monolog\Formatter\FormatterInterface; -use Monolog\Handler\AbstractHandler; +use Monolog\Handler\AbstractProcessingHandler; +use Monolog\Handler\FormattableHandlerTrait; use Monolog\Logger; use Symfony\Bridge\Monolog\Formatter\VarDumperFormatter; +if (trait_exists(FormattableHandlerTrait::class)) { + class ServerLogHandler extends AbstractProcessingHandler + { + use ServerLogHandlerTrait; + + /** + * {@inheritdoc} + */ + protected function getDefaultFormatter(): FormatterInterface + { + return new VarDumperFormatter(); + } + } +} else { + class ServerLogHandler extends AbstractProcessingHandler + { + use ServerLogHandlerTrait; + + /** + * {@inheritdoc} + */ + protected function getDefaultFormatter() + { + return new VarDumperFormatter(); + } + } +} + /** * @author Grégoire Pineau */ -class ServerLogHandler extends AbstractHandler +trait ServerLogHandlerTrait { private $host; private $context; @@ -42,10 +71,8 @@ public function __construct(string $host, $level = Logger::DEBUG, bool $bubble = /** * {@inheritdoc} - * - * @return bool */ - public function handle(array $record) + public function handle(array $record): bool { if (!$this->isHandling($record)) { return false; @@ -61,6 +88,11 @@ public function handle(array $record) restore_error_handler(); } + return parent::handle($record); + } + + protected function write(array $record): void + { $recordFormatted = $this->formatRecord($record); set_error_handler(self::class.'::nullErrorHandler'); @@ -77,16 +109,12 @@ public function handle(array $record) } finally { restore_error_handler(); } - - return false === $this->bubble; } /** * {@inheritdoc} - * - * @return FormatterInterface */ - protected function getDefaultFormatter() + protected function getDefaultFormatter(): FormatterInterface { return new VarDumperFormatter(); } @@ -108,13 +136,7 @@ private function createSocket() private function formatRecord(array $record): string { - if ($this->processors) { - foreach ($this->processors as $processor) { - $record = $processor($record); - } - } - - $recordFormatted = $this->getFormatter()->format($record); + $recordFormatted = $record['formatted']; foreach (['log_uuid', 'uuid', 'uid'] as $key) { if (isset($record['extra'][$key])) { diff --git a/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php b/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php index 1143c0668093c..d5470c6b18916 100644 --- a/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php +++ b/src/Symfony/Bridge/Monolog/Handler/SwiftMailerHandler.php @@ -13,14 +13,14 @@ use Monolog\Handler\SwiftMailerHandler as BaseSwiftMailerHandler; use Symfony\Component\Console\Event\ConsoleTerminateEvent; -use Symfony\Component\HttpKernel\Event\PostResponseEvent; +use Symfony\Component\HttpKernel\Event\TerminateEvent; /** * Extended SwiftMailerHandler that flushes mail queue if necessary. * * @author Philipp Kräutli * - * @final since Symfony 4.3 + * @final */ class SwiftMailerHandler extends BaseSwiftMailerHandler { @@ -36,7 +36,7 @@ public function setTransport(\Swift_Transport $transport) /** * After the kernel has been terminated we will always flush messages. */ - public function onKernelTerminate(PostResponseEvent $event) + public function onKernelTerminate(TerminateEvent $event) { $this->instantFlush = true; } @@ -52,7 +52,7 @@ public function onCliTerminate(ConsoleTerminateEvent $event) /** * {@inheritdoc} */ - protected function send($content, array $records) + protected function send($content, array $records): void { parent::send($content, $records); @@ -64,7 +64,7 @@ protected function send($content, array $records) /** * {@inheritdoc} */ - public function reset() + public function reset(): void { $this->flushMemorySpool(); } diff --git a/src/Symfony/Bridge/Monolog/Logger.php b/src/Symfony/Bridge/Monolog/Logger.php index 336d2e7f0dc33..4643f5b6d7598 100644 --- a/src/Symfony/Bridge/Monolog/Logger.php +++ b/src/Symfony/Bridge/Monolog/Logger.php @@ -24,17 +24,11 @@ class Logger extends BaseLogger implements DebugLoggerInterface, ResetInterface { /** * {@inheritdoc} - * - * @param Request|null $request */ - public function getLogs(/* Request $request = null */) + public function getLogs(Request $request = null) { - if (\func_num_args() < 1 && __CLASS__ !== static::class && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface && !$this instanceof \Mockery\MockInterface) { - @trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), \E_USER_DEPRECATED); - } - if ($logger = $this->getDebugLogger()) { - return $logger->getLogs(...\func_get_args()); + return $logger->getLogs($request); } return []; @@ -42,17 +36,11 @@ public function getLogs(/* Request $request = null */) /** * {@inheritdoc} - * - * @param Request|null $request */ - public function countErrors(/* Request $request = null */) + public function countErrors(Request $request = null) { - if (\func_num_args() < 1 && __CLASS__ !== static::class && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface && !$this instanceof \Mockery\MockInterface) { - @trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), \E_USER_DEPRECATED); - } - if ($logger = $this->getDebugLogger()) { - return $logger->countErrors(...\func_get_args()); + return $logger->countErrors($request); } return 0; @@ -71,7 +59,7 @@ public function clear() /** * {@inheritdoc} */ - public function reset() + public function reset(): void { $this->clear(); diff --git a/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php new file mode 100644 index 0000000000000..ed37c94b81c00 --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Processor/AbstractTokenProcessor.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Monolog\Processor; + +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +/** + * The base class for security token processors. + * + * @author Dany Maillard + * @author Igor Timoshenko + */ +abstract class AbstractTokenProcessor +{ + /** + * @var TokenStorageInterface + */ + protected $tokenStorage; + + public function __construct(TokenStorageInterface $tokenStorage) + { + $this->tokenStorage = $tokenStorage; + } + + abstract protected function getKey(): string; + + abstract protected function getToken(): ?TokenInterface; + + public function __invoke(array $record): array + { + $record['extra'][$this->getKey()] = null; + + if (null !== $token = $this->getToken()) { + $record['extra'][$this->getKey()] = [ + 'username' => $token->getUsername(), + 'authenticated' => $token->isAuthenticated(), + 'roles' => $token->getRoleNames(), + ]; + } + + return $record; + } +} diff --git a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php index 11f075fe3a26e..7b7bf23c1a219 100644 --- a/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php @@ -58,16 +58,10 @@ public function __invoke(array $record) /** * {@inheritdoc} - * - * @param Request|null $request */ - public function getLogs(/* Request $request = null */) + public function getLogs(Request $request = null) { - if (\func_num_args() < 1 && __CLASS__ !== static::class && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface && !$this instanceof \Mockery\MockInterface) { - @trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), \E_USER_DEPRECATED); - } - - if (1 <= \func_num_args() && null !== $request = func_get_arg(0)) { + if (null !== $request) { return $this->records[spl_object_hash($request)] ?? []; } @@ -80,16 +74,10 @@ public function getLogs(/* Request $request = null */) /** * {@inheritdoc} - * - * @param Request|null $request */ - public function countErrors(/* Request $request = null */) + public function countErrors(Request $request = null) { - if (\func_num_args() < 1 && __CLASS__ !== static::class && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface && !$this instanceof \Mockery\MockInterface) { - @trigger_error(sprintf('The "%s()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), \E_USER_DEPRECATED); - } - - if (1 <= \func_num_args() && null !== $request = func_get_arg(0)) { + if (null !== $request) { return $this->errorCount[spl_object_hash($request)] ?? 0; } diff --git a/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php b/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php index 09507b55e7fb2..23b95d9b8512c 100644 --- a/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/RouteProcessor.php @@ -13,7 +13,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Contracts\Service\ResetInterface; @@ -22,7 +22,7 @@ * * @author Piotr Stankowski * - * @final since Symfony 4.4 + * @final */ class RouteProcessor implements EventSubscriberInterface, ResetInterface { @@ -35,7 +35,7 @@ public function __construct(bool $includeParams = true) $this->reset(); } - public function __invoke(array $records) + public function __invoke(array $records): array { if ($this->routeData && !isset($records['extra']['requests'])) { $records['extra']['requests'] = array_values($this->routeData); @@ -49,7 +49,7 @@ public function reset() $this->routeData = []; } - public function addRouteData(GetResponseEvent $event) + public function addRouteData(RequestEvent $event) { if ($event->isMasterRequest()) { $this->reset(); @@ -78,7 +78,7 @@ public function removeRouteData(FinishRequestEvent $event) unset($this->routeData[$requestId]); } - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => ['addRouteData', 1], diff --git a/src/Symfony/Bridge/Monolog/Processor/SwitchUserTokenProcessor.php b/src/Symfony/Bridge/Monolog/Processor/SwitchUserTokenProcessor.php new file mode 100644 index 0000000000000..76aa7e479d0e5 --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Processor/SwitchUserTokenProcessor.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Monolog\Processor; + +use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + +/** + * Adds the original security token to the log entry. + * + * @author Igor Timoshenko + */ +class SwitchUserTokenProcessor extends AbstractTokenProcessor +{ + /** + * {@inheritdoc} + */ + protected function getKey(): string + { + return 'impersonator_token'; + } + + /** + * {@inheritdoc} + */ + protected function getToken(): ?TokenInterface + { + $token = $this->tokenStorage->getToken(); + + if ($token instanceof SwitchUserToken) { + return $token->getOriginalToken(); + } + + return null; + } +} diff --git a/src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php b/src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php index 7613d01361962..7ca212eb29770 100644 --- a/src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php @@ -11,39 +11,29 @@ namespace Symfony\Bridge\Monolog\Processor; -use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; /** * Adds the current security token to the log entry. * * @author Dany Maillard + * @author Igor Timoshenko */ -class TokenProcessor +class TokenProcessor extends AbstractTokenProcessor { - private $tokenStorage; - - public function __construct(TokenStorageInterface $tokenStorage) + /** + * {@inheritdoc} + */ + protected function getKey(): string { - $this->tokenStorage = $tokenStorage; + return 'token'; } - public function __invoke(array $records) + /** + * {@inheritdoc} + */ + protected function getToken(): ?TokenInterface { - $records['extra']['token'] = null; - if (null !== $token = $this->tokenStorage->getToken()) { - if (method_exists($token, 'getRoleNames')) { - $roles = $token->getRoleNames(); - } else { - $roles = array_map(function ($role) { return $role->getRole(); }, $token->getRoles(false)); - } - - $records['extra']['token'] = [ - 'username' => $token->getUsername(), - 'authenticated' => $token->isAuthenticated(), - 'roles' => $roles, - ]; - } - - return $records; + return $this->tokenStorage->getToken(); } } diff --git a/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php b/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php index 71bf71a816327..98ec10ca6dcb4 100644 --- a/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php +++ b/src/Symfony/Bridge/Monolog/Processor/WebProcessor.php @@ -13,7 +13,7 @@ use Monolog\Processor\WebProcessor as BaseWebProcessor; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents; /** @@ -21,7 +21,7 @@ * * @author Jordi Boggiano * - * @final since Symfony 4.3 + * @final */ class WebProcessor extends BaseWebProcessor implements EventSubscriberInterface { @@ -31,7 +31,7 @@ public function __construct(array $extraFields = null) parent::__construct([], $extraFields); } - public function onKernelRequest(GetResponseEvent $event) + public function onKernelRequest(RequestEvent $event) { if ($event->isMasterRequest()) { $this->serverData = $event->getRequest()->server->all(); @@ -39,7 +39,7 @@ public function onKernelRequest(GetResponseEvent $event) } } - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { return [ KernelEvents::REQUEST => ['onKernelRequest', 4096], diff --git a/src/Symfony/Bridge/Monolog/Tests/ClassThatInheritLogger.php b/src/Symfony/Bridge/Monolog/Tests/ClassThatInheritLogger.php index 31c62e3e75591..e258c7942a20a 100644 --- a/src/Symfony/Bridge/Monolog/Tests/ClassThatInheritLogger.php +++ b/src/Symfony/Bridge/Monolog/Tests/ClassThatInheritLogger.php @@ -12,16 +12,17 @@ namespace Symfony\Bridge\Monolog\Tests; use Symfony\Bridge\Monolog\Logger; +use Symfony\Component\HttpFoundation\Request; class ClassThatInheritLogger extends Logger { - public function getLogs(): array + public function getLogs(Request $request = null): array { - return parent::getLogs(); + return parent::getLogs($request); } - public function countErrors(): int + public function countErrors(Request $request = null): int { - return parent::countErrors(); + return parent::countErrors($request); } } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php index 3d84cb3552c0d..073f3eee1f86f 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/HttpCodeActivationStrategyTest.php @@ -11,6 +11,7 @@ namespace Symfony\Bridge\Monolog\Tests\Handler\FingersCrossed; +use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Monolog\Logger; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy; @@ -20,13 +21,19 @@ class HttpCodeActivationStrategyTest extends TestCase { - public function testExclusionsWithoutCode() + /** + * @group legacy + */ + public function testExclusionsWithoutCodeLegacy() { $this->expectException(\LogicException::class); new HttpCodeActivationStrategy(new RequestStack(), [['urls' => []]], Logger::WARNING); } - public function testExclusionsWithoutUrls() + /** + * @group legacy + */ + public function testExclusionsWithoutUrlsLegacy() { $this->expectException(\LogicException::class); new HttpCodeActivationStrategy(new RequestStack(), [['code' => 404]], Logger::WARNING); @@ -34,8 +41,10 @@ public function testExclusionsWithoutUrls() /** * @dataProvider isActivatedProvider + * + * @group legacy */ - public function testIsActivated($url, $record, $expected) + public function testIsActivatedLegacy($url, $record, $expected) { $requestStack = new RequestStack(); $requestStack->push(Request::create($url)); @@ -51,10 +60,44 @@ public function testIsActivated($url, $record, $expected) Logger::WARNING ); - $this->assertEquals($expected, $strategy->isHandlerActivated($record)); + self::assertEquals($expected, $strategy->isHandlerActivated($record)); + } + + public function testExclusionsWithoutCode() + { + $this->expectException(\LogicException::class); + new HttpCodeActivationStrategy(new RequestStack(), [['urls' => []]], new ErrorLevelActivationStrategy(Logger::WARNING)); + } + + public function testExclusionsWithoutUrls() + { + $this->expectException(\LogicException::class); + new HttpCodeActivationStrategy(new RequestStack(), [['code' => 404]], new ErrorLevelActivationStrategy(Logger::WARNING)); + } + + /** + * @dataProvider isActivatedProvider + */ + public function testIsActivated($url, $record, $expected) + { + $requestStack = new RequestStack(); + $requestStack->push(Request::create($url)); + + $strategy = new HttpCodeActivationStrategy( + $requestStack, + [ + ['code' => 403, 'urls' => []], + ['code' => 404, 'urls' => []], + ['code' => 405, 'urls' => []], + ['code' => 400, 'urls' => ['^/400/a', '^/400/b']], + ], + new ErrorLevelActivationStrategy(Logger::WARNING) + ); + + self::assertEquals($expected, $strategy->isHandlerActivated($record)); } - public function isActivatedProvider() + public function isActivatedProvider(): array { return [ ['/test', ['level' => Logger::ERROR], true], @@ -70,7 +113,7 @@ public function isActivatedProvider() ]; } - protected function getContextException($code) + private function getContextException(int $code): array { return ['exception' => new HttpException($code)]; } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php index b04678106c96e..a60cc450c7236 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/FingersCrossed/NotFoundActivationStrategyTest.php @@ -11,6 +11,7 @@ namespace Symfony\Bridge\Monolog\Tests\Handler\FingersCrossed; +use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Monolog\Logger; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy; @@ -22,18 +23,33 @@ class NotFoundActivationStrategyTest extends TestCase { /** * @dataProvider isActivatedProvider + * + * @group legacy */ - public function testIsActivated($url, $record, $expected) + public function testIsActivatedLegacy(string $url, array $record, bool $expected) { $requestStack = new RequestStack(); $requestStack->push(Request::create($url)); $strategy = new NotFoundActivationStrategy($requestStack, ['^/foo', 'bar'], Logger::WARNING); - $this->assertEquals($expected, $strategy->isHandlerActivated($record)); + self::assertEquals($expected, $strategy->isHandlerActivated($record)); } - public function isActivatedProvider() + /** + * @dataProvider isActivatedProvider + */ + public function testIsActivated(string $url, array $record, bool $expected) + { + $requestStack = new RequestStack(); + $requestStack->push(Request::create($url)); + + $strategy = new NotFoundActivationStrategy($requestStack, ['^/foo', 'bar'], new ErrorLevelActivationStrategy(Logger::WARNING)); + + self::assertEquals($expected, $strategy->isHandlerActivated($record)); + } + + public function isActivatedProvider(): array { return [ ['/test', ['level' => Logger::DEBUG], false], @@ -48,7 +64,7 @@ public function isActivatedProvider() ]; } - protected function getContextException($code) + protected function getContextException(int $code): array { return ['exception' => new HttpException($code)]; } diff --git a/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php b/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php new file mode 100644 index 0000000000000..24aaa6b95cdd9 --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Tests/Handler/MailerHandlerTest.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Monolog\Tests\Handler; + +use Monolog\Formatter\HtmlFormatter; +use Monolog\Formatter\LineFormatter; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Monolog\Handler\MailerHandler; +use Symfony\Bridge\Monolog\Logger; +use Symfony\Component\Mailer\MailerInterface; +use Symfony\Component\Mime\Email; + +class MailerHandlerTest extends TestCase +{ + /** @var MockObject|MailerInterface */ + private $mailer = null; + + protected function setUp(): void + { + $this->mailer = $this->createMock(MailerInterface::class); + } + + public function testHandle() + { + $handler = new MailerHandler($this->mailer, (new Email())->subject('Alert: %level_name% %message%')); + $handler->setFormatter(new LineFormatter()); + $this->mailer + ->expects($this->once()) + ->method('send') + ->with($this->callback(function (Email $email) { + return 'Alert: WARNING message' === $email->getSubject() && null === $email->getHtmlBody(); + })) + ; + $handler->handle($this->getRecord(Logger::WARNING, 'message')); + } + + public function testHandleBatch() + { + $handler = new MailerHandler($this->mailer, (new Email())->subject('Alert: %level_name% %message%')); + $handler->setFormatter(new LineFormatter()); + $this->mailer + ->expects($this->once()) + ->method('send') + ->with($this->callback(function (Email $email) { + return 'Alert: ERROR error' === $email->getSubject() && null === $email->getHtmlBody(); + })) + ; + $handler->handleBatch($this->getMultipleRecords()); + } + + public function testMessageCreationIsLazyWhenUsingCallback() + { + $this->mailer + ->expects($this->never()) + ->method('send') + ; + + $callback = function () { + throw new \RuntimeException('Email creation callback should not have been called in this test'); + }; + $handler = new MailerHandler($this->mailer, $callback, Logger::ALERT); + + $records = [ + $this->getRecord(Logger::DEBUG), + $this->getRecord(Logger::INFO), + ]; + $handler->handleBatch($records); + } + + public function testHtmlContent() + { + $handler = new MailerHandler($this->mailer, (new Email())->subject('Alert: %level_name% %message%')); + $handler->setFormatter(new HtmlFormatter()); + $this->mailer + ->expects($this->once()) + ->method('send') + ->with($this->callback(function (Email $email) { + return 'Alert: WARNING message' === $email->getSubject() && null === $email->getTextBody(); + })) + ; + $handler->handle($this->getRecord(Logger::WARNING, 'message')); + } + + /** + * @return array Record + */ + protected function getRecord($level = Logger::WARNING, $message = 'test', $context = []) + { + return [ + 'message' => $message, + 'context' => $context, + 'level' => $level, + 'level_name' => Logger::getLevelName($level), + 'channel' => 'test', + 'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true))), + 'extra' => [], + ]; + } + + /** + * @return array + */ + protected function getMultipleRecords() + { + return [ + $this->getRecord(Logger::DEBUG, 'debug message 1'), + $this->getRecord(Logger::DEBUG, 'debug message 2'), + $this->getRecord(Logger::INFO, 'information'), + $this->getRecord(Logger::WARNING, 'warning'), + $this->getRecord(Logger::ERROR, 'error'), + ]; + } +} diff --git a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php index 12b687e115cdb..e862d780e7eb9 100644 --- a/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/LoggerTest.php @@ -125,15 +125,15 @@ public function testReset() } } - /** - * @group legacy - * @expectedDeprecation The "Symfony\Bridge\Monolog\Logger::getLogs()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2. - * @expectedDeprecation The "Symfony\Bridge\Monolog\Logger::countErrors()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2. - */ - public function testInheritedClassWithoutArgument() + public function testInheritedClassCallGetLogsWithoutArgument() { $loggerChild = new ClassThatInheritLogger('test'); - $loggerChild->getLogs(); - $loggerChild->countErrors(); + $this->assertSame([], $loggerChild->getLogs()); + } + + public function testInheritedClassCallCountErrorsWithoutArgument() + { + $loggerChild = new ClassThatInheritLogger('test'); + $this->assertEquals(0, $loggerChild->countErrors()); } } diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/ClassThatInheritDebugProcessor.php b/src/Symfony/Bridge/Monolog/Tests/Processor/ClassThatInheritDebugProcessor.php index 1f15bd9f764b2..bc87c724c9d31 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/ClassThatInheritDebugProcessor.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/ClassThatInheritDebugProcessor.php @@ -12,16 +12,17 @@ namespace Symfony\Bridge\Monolog\Tests\Processor; use Symfony\Bridge\Monolog\Processor\DebugProcessor; +use Symfony\Component\HttpFoundation\Request; class ClassThatInheritDebugProcessor extends DebugProcessor { - public function getLogs(): array + public function getLogs(Request $request = null): array { - return parent::getLogs(); + return parent::getLogs($request); } - public function countErrors(): int + public function countErrors(Request $request = null): int { - return parent::countErrors(); + return parent::countErrors($request); } } diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php index 4ac41c978ec4e..6adec38a0c7f0 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/DebugProcessorTest.php @@ -87,16 +87,16 @@ public function testWithRequestStack() $this->assertSame(0, $processor->countErrors(new Request())); } - /** - * @group legacy - * @expectedDeprecation The "Symfony\Bridge\Monolog\Processor\DebugProcessor::getLogs()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2. - * @expectedDeprecation The "Symfony\Bridge\Monolog\Processor\DebugProcessor::countErrors()" method will have a new "Request $request = null" argument in version 5.0, not defining it is deprecated since Symfony 4.2. - */ - public function testInheritedClassWithoutArgument() + public function testInheritedClassCallGetLogsWithoutArgument() + { + $debugProcessorChild = new ClassThatInheritDebugProcessor(); + $this->assertSame([], $debugProcessorChild->getLogs()); + } + + public function testInheritedClassCallCountErrorsWithoutArgument() { $debugProcessorChild = new ClassThatInheritDebugProcessor(); - $debugProcessorChild->getLogs(); - $debugProcessorChild->countErrors(); + $this->assertEquals(0, $debugProcessorChild->countErrors()); } private function getRecord($level = Logger::WARNING, $message = 'test'): array diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php new file mode 100644 index 0000000000000..7107993b9c849 --- /dev/null +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/SwitchUserTokenProcessorTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Monolog\Tests\Processor; + +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\Monolog\Processor\SwitchUserTokenProcessor; +use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; + +/** + * Tests the SwitchUserTokenProcessor. + * + * @author Igor Timoshenko + */ +class SwitchUserTokenProcessorTest extends TestCase +{ + public function testProcessor() + { + $originalToken = new UsernamePasswordToken('original_user', 'password', 'provider', ['ROLE_SUPER_ADMIN']); + $switchUserToken = new SwitchUserToken('user', 'passsword', 'provider', ['ROLE_USER'], $originalToken); + $tokenStorage = $this->createMock(TokenStorageInterface::class); + $tokenStorage->method('getToken')->willReturn($switchUserToken); + + $processor = new SwitchUserTokenProcessor($tokenStorage); + $record = ['extra' => []]; + $record = $processor($record); + + $expected = [ + 'impersonator_token' => [ + 'username' => 'original_user', + 'authenticated' => true, + 'roles' => ['ROLE_SUPER_ADMIN'], + ], + ]; + $this->assertSame($expected, $record['extra']); + } +} diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php index 73cb964d9ab6c..905e6efb617dd 100644 --- a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php +++ b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php @@ -38,7 +38,7 @@ public function testUsesRequestServerData() public function testUseRequestClientIp() { - Request::setTrustedProxies(['192.168.0.1'], Request::HEADER_X_FORWARDED_ALL); + Request::setTrustedProxies(['192.168.0.1'], Request::HEADER_X_FORWARDED_FOR); [$event, $server] = $this->createRequestEvent(['X_FORWARDED_FOR' => '192.168.0.2']); $processor = new WebProcessor(); diff --git a/src/Symfony/Bridge/Monolog/composer.json b/src/Symfony/Bridge/Monolog/composer.json index fee9fe256ab73..ee48ea0330d9f 100644 --- a/src/Symfony/Bridge/Monolog/composer.json +++ b/src/Symfony/Bridge/Monolog/composer.json @@ -16,20 +16,23 @@ } ], "require": { - "php": ">=7.1.3", - "monolog/monolog": "^1.25.1", + "php": ">=7.2.5", + "monolog/monolog": "^1.25.1|^2", "symfony/service-contracts": "^1.1|^2", - "symfony/http-kernel": "^4.3" + "symfony/http-kernel": "^4.4|^5.0", + "symfony/deprecation-contracts": "^2.1" }, "require-dev": { - "symfony/console": "^3.4|^4.0|^5.0", + "symfony/console": "^4.4|^5.0", "symfony/http-client": "^4.4|^5.0", - "symfony/security-core": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^3.4|^4.0|^5.0" + "symfony/security-core": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0", + "symfony/mailer": "^4.4|^5.0", + "symfony/mime": "^4.4|^5.0" }, "conflict": { - "symfony/console": "<3.4", - "symfony/http-foundation": "<3.4" + "symfony/console": "<4.4", + "symfony/http-foundation": "<4.4" }, "suggest": { "symfony/http-kernel": "For using the debugging handlers together with the response life cycle of the HTTP kernel.", diff --git a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md index e9fc8f43c6e86..2808ad0c50903 100644 --- a/src/Symfony/Bridge/PhpUnit/CHANGELOG.md +++ b/src/Symfony/Bridge/PhpUnit/CHANGELOG.md @@ -1,6 +1,19 @@ CHANGELOG ========= +5.1.0 +----- + + * ignore verbosity settings when the build fails because of deprecations + * added per-group verbosity + * added `ExpectDeprecationTrait` to be able to define an expected deprecation from inside a test + * deprecated the `@expectedDeprecation` annotation, use the `ExpectDeprecationTrait::expectDeprecation()` method instead + +5.0.0 +----- + + * removed `weak_vendor` mode, use `max[self]=0` instead + 4.4.0 ----- diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php index 19c6691dbec3e..feabafb760bde 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php @@ -15,6 +15,7 @@ use PHPUnit\Util\ErrorHandler; use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Configuration; use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Deprecation; +use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\DeprecationGroup; use Symfony\Component\ErrorHandler\DebugClassLoader; /** @@ -24,41 +25,33 @@ */ class DeprecationErrorHandler { - /** - * @deprecated since Symfony 4.3, use max[self]=0 instead - */ - const MODE_WEAK_VENDORS = 'weak_vendors'; - const MODE_DISABLED = 'disabled'; const MODE_WEAK = 'max[total]=999999&verbose=0'; const MODE_STRICT = 'max[total]=0'; private $mode; private $configuration; - private $deprecations = [ - 'unsilencedCount' => 0, - 'remaining selfCount' => 0, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 0, - 'remaining indirectCount' => 0, - 'unsilenced' => [], - 'remaining self' => [], - 'legacy' => [], - 'other' => [], - 'remaining direct' => [], - 'remaining indirect' => [], - ]; + + /** + * @var DeprecationGroup[] + */ + private $deprecationGroups = []; private static $isRegistered = false; private static $isAtLeastPhpUnit83; + public function __construct() + { + $this->resetDeprecationGroups(); + } + /** * Registers and configures the deprecation handler. * * The mode is a query string with options: - * - "disabled" to disable the deprecation handler + * - "disabled" to enable/disable the deprecation handler * - "verbose" to enable/disable displaying the deprecation report + * - "quiet" to disable displaying the deprecation report only for some groups (i.e. quiet[]=other) * - "max" to configure the number of deprecations to allow before exiting with a non-zero * status code; it's an array with keys "total", "self", "direct" and "indirect" * @@ -142,6 +135,9 @@ public function handleError($type, $msg, $file, $line, $context = []) if ($deprecation->isMuted()) { return null; } + if ($this->getConfiguration()->isBaselineDeprecation($deprecation)) { + return null; + } $msg = $deprecation->getMessage(); @@ -151,9 +147,9 @@ public function handleError($type, $msg, $file, $line, $context = []) $group = 'legacy'; } else { $group = [ - Deprecation::TYPE_SELF => 'remaining self', - Deprecation::TYPE_DIRECT => 'remaining direct', - Deprecation::TYPE_INDIRECT => 'remaining indirect', + Deprecation::TYPE_SELF => 'self', + Deprecation::TYPE_DIRECT => 'direct', + Deprecation::TYPE_INDIRECT => 'indirect', Deprecation::TYPE_UNDETERMINED => 'other', ][$deprecation->getType()]; } @@ -164,20 +160,16 @@ public function handleError($type, $msg, $file, $line, $context = []) exit(1); } - if ('legacy' !== $group) { - $ref = &$this->deprecations[$group][$msg]['count']; - ++$ref; - - if ($deprecation->originatesFromAnObject()) { - $class = $deprecation->originatingClass(); - $method = $deprecation->originatingMethod(); - $ref = &$this->deprecations[$group][$msg][$class.'::'.$method]; - ++$ref; - } + if ('legacy' === $group) { + $this->deprecationGroups[$group]->addNotice(); + } else if ($deprecation->originatesFromAnObject()) { + $class = $deprecation->originatingClass(); + $method = $deprecation->originatingMethod(); + $this->deprecationGroups[$group]->addNoticeFromObject($msg, $class, $method); + } else { + $this->deprecationGroups[$group]->addNoticeFromProceduralCode($msg); } - ++$this->deprecations[$group.'Count']; - return null; } @@ -202,34 +194,48 @@ public function shutdown() echo "\n", self::colorize('THE ERROR HANDLER HAS CHANGED!', true), "\n"; } - $groups = ['unsilenced', 'remaining self', 'remaining direct', 'remaining indirect', 'legacy', 'other']; - - $this->displayDeprecations($groups, $configuration); + $groups = array_keys($this->deprecationGroups); // store failing status - $isFailing = !$configuration->tolerates($this->deprecations); + $isFailing = !$configuration->tolerates($this->deprecationGroups); - // reset deprecations array - foreach ($this->deprecations as $group => $arrayOrInt) { - $this->deprecations[$group] = \is_int($arrayOrInt) ? 0 : []; - } + $this->displayDeprecations($groups, $configuration, $isFailing); + + $this->resetDeprecationGroups(); register_shutdown_function(function () use ($isFailing, $groups, $configuration) { - foreach ($this->deprecations as $group => $arrayOrInt) { - if (0 < (\is_int($arrayOrInt) ? $arrayOrInt : \count($arrayOrInt))) { + foreach ($this->deprecationGroups as $group) { + if ($group->count() > 0) { echo "Shutdown-time deprecations:\n"; break; } } - $this->displayDeprecations($groups, $configuration); + $isFailingAtShutdown = !$configuration->tolerates($this->deprecationGroups); + $this->displayDeprecations($groups, $configuration, $isFailingAtShutdown); - if ($isFailing || !$configuration->tolerates($this->deprecations)) { + if ($configuration->isGeneratingBaseline()) { + $configuration->writeBaseline(); + } + + if ($isFailing || $isFailingAtShutdown) { exit(1); } }); } + private function resetDeprecationGroups() + { + $this->deprecationGroups = [ + 'unsilenced' => new DeprecationGroup(), + 'self' => new DeprecationGroup(), + 'direct' => new DeprecationGroup(), + 'indirect' => new DeprecationGroup(), + 'legacy' => new DeprecationGroup(), + 'other' => new DeprecationGroup(), + ]; + } + private function getConfiguration() { if (null !== $this->configuration) { @@ -253,13 +259,6 @@ private function getConfiguration() if ('weak' === $mode) { return $this->configuration = Configuration::inWeakMode(); } - if (self::MODE_WEAK_VENDORS === $mode) { - ++$this->deprecations['remaining directCount']; - $msg = sprintf('Setting SYMFONY_DEPRECATIONS_HELPER to "%s" is deprecated in favor of "max[self]=0"', $mode); - $ref = &$this->deprecations['remaining direct'][$msg]['count']; - ++$ref; - $mode = 'max[self]=0'; - } if (isset($mode[0]) && '/' === $mode[0]) { return $this->configuration = Configuration::fromRegex($mode); } @@ -295,31 +294,38 @@ private static function colorize($str, $red) /** * @param string[] $groups * @param Configuration $configuration + * @param bool $isFailing */ - private function displayDeprecations($groups, $configuration) + private function displayDeprecations($groups, $configuration, $isFailing) { $cmp = function ($a, $b) { - return $b['count'] - $a['count']; + return $b->count() - $a->count(); }; foreach ($groups as $group) { - if ($this->deprecations[$group.'Count']) { + if ($this->deprecationGroups[$group]->count()) { echo "\n", self::colorize( - sprintf('%s deprecation notices (%d)', ucfirst($group), $this->deprecations[$group.'Count']), - 'legacy' !== $group && 'remaining indirect' !== $group + sprintf( + '%s deprecation notices (%d)', + \in_array($group, ['direct', 'indirect', 'self'], true) ? "Remaining $group" : ucfirst($group), + $this->deprecationGroups[$group]->count() + ), + 'legacy' !== $group && 'indirect' !== $group ), "\n"; - if (!$configuration->verboseOutput()) { + if ('legacy' !== $group && !$configuration->verboseOutput($group) && !$isFailing) { continue; } - uasort($this->deprecations[$group], $cmp); + $notices = $this->deprecationGroups[$group]->notices(); + uasort($notices, $cmp); - foreach ($this->deprecations[$group] as $msg => $notices) { - echo "\n ", $notices['count'], 'x: ', $msg, "\n"; + foreach ($notices as $msg => $notice) { + echo "\n ", $notice->count(), 'x: ', $msg, "\n"; - arsort($notices); + $countsByCaller = $notice->getCountsByCaller(); + arsort($countsByCaller); - foreach ($notices as $method => $count) { + foreach ($countsByCaller as $method => $count) { if ('count' !== $method) { echo ' ', $count, 'x in ', preg_replace('/(.*)\\\\(.*?::.*?)$/', '$2 from $1', $method), "\n"; } diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php index d26ffc45de692..20ffd9651b8ed 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Configuration.php @@ -31,18 +31,34 @@ class Configuration */ private $enabled = true; + /** + * @var bool[] + */ + private $verboseOutput; + /** * @var bool */ - private $verboseOutput = true; + private $generateBaseline = false; + + /** + * @var string + */ + private $baselineFile = ''; /** - * @param int[] $thresholds A hash associating groups to thresholds - * @param string $regex Will be matched against messages, to decide - * whether to display a stack trace - * @param bool $verboseOutput + * @var array */ - private function __construct(array $thresholds = [], $regex = '', $verboseOutput = true) + private $baselineDeprecations = []; + + /** + * @param int[] $thresholds A hash associating groups to thresholds + * @param string $regex Will be matched against messages, to decide whether to display a stack trace + * @param bool[] $verboseOutput Keyed by groups + * @param bool $generateBaseline Whether to generate or update the baseline file + * @param string $baselineFile The path to the baseline file + */ + private function __construct(array $thresholds = [], $regex = '', $verboseOutput = [], $generateBaseline = false, $baselineFile = '') { $groups = ['total', 'indirect', 'direct', 'self']; @@ -72,7 +88,37 @@ private function __construct(array $thresholds = [], $regex = '', $verboseOutput } } $this->regex = $regex; - $this->verboseOutput = $verboseOutput; + + $this->verboseOutput = [ + 'unsilenced' => true, + 'direct' => true, + 'indirect' => true, + 'self' => true, + 'other' => true, + ]; + + foreach ($verboseOutput as $group => $status) { + if (!isset($this->verboseOutput[$group])) { + throw new \InvalidArgumentException(sprintf('Unsupported verbosity group "%s", expected one of "%s".', $group, implode('", "', array_keys($this->verboseOutput)))); + } + $this->verboseOutput[$group] = (bool) $status; + } + + if ($generateBaseline && !$baselineFile) { + throw new \InvalidArgumentException('You cannot use the "generateBaseline" configuration option without providing a "baselineFile" configuration option.'); + } + $this->generateBaseline = $generateBaseline; + $this->baselineFile = $baselineFile; + if ($this->baselineFile && !$this->generateBaseline) { + if (is_file($this->baselineFile)) { + $map = json_decode(file_get_contents($this->baselineFile)); + foreach ($map as $baseline_deprecation) { + $this->baselineDeprecations[$baseline_deprecation->location][$baseline_deprecation->message] = $baseline_deprecation->count; + } + } else { + throw new \InvalidArgumentException(sprintf('The baselineFile "%s" does not exist.', $this->baselineFile)); + } + } } /** @@ -84,24 +130,26 @@ public function isEnabled() } /** - * @param mixed[] $deprecations + * @param DeprecationGroup[] $deprecationGroups * * @return bool */ - public function tolerates(array $deprecations) + public function tolerates(array $deprecationGroups) { - $deprecationCounts = []; - foreach ($deprecations as $key => $deprecation) { - if (false !== strpos($key, 'Count') && false === strpos($key, 'legacy')) { - $deprecationCounts[$key] = $deprecation; + $grandTotal = 0; + + foreach ($deprecationGroups as $name => $group) { + if ('legacy' !== $name) { + $grandTotal += $group->count(); } } - if (array_sum($deprecationCounts) > $this->thresholds['total']) { + if ($grandTotal > $this->thresholds['total']) { return false; } + foreach (['self', 'direct', 'indirect'] as $deprecationType) { - if ($deprecationCounts['remaining '.$deprecationType.'Count'] > $this->thresholds[$deprecationType]) { + if ($deprecationGroups[$deprecationType]->count() > $this->thresholds[$deprecationType]) { return false; } } @@ -109,6 +157,61 @@ public function tolerates(array $deprecations) return true; } + /** + * @return bool + */ + public function isBaselineDeprecation(Deprecation $deprecation) + { + if ($deprecation->originatesFromAnObject()) { + $location = $deprecation->originatingClass().'::'.$deprecation->originatingMethod(); + } else { + $location = 'procedural code'; + } + + $message = $deprecation->getMessage(); + $result = isset($this->baselineDeprecations[$location][$message]) && $this->baselineDeprecations[$location][$message] > 0; + if ($this->generateBaseline) { + if ($result) { + ++$this->baselineDeprecations[$location][$message]; + } else { + $this->baselineDeprecations[$location][$message] = 1; + $result = true; + } + } elseif ($result) { + --$this->baselineDeprecations[$location][$message]; + } + + return $result; + } + + /** + * @return bool + */ + public function isGeneratingBaseline() + { + return $this->generateBaseline; + } + + public function getBaselineFile() + { + return $this->baselineFile; + } + + public function writeBaseline() + { + $map = []; + foreach ($this->baselineDeprecations as $location => $messages) { + foreach ($messages as $message => $count) { + $map[] = [ + 'location' => $location, + 'message' => $message, + 'count' => $count, + ]; + } + } + file_put_contents($this->baselineFile, json_encode($map, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)); + } + /** * @param string $message * @@ -130,9 +233,9 @@ public function isInRegexMode() /** * @return bool */ - public function verboseOutput() + public function verboseOutput($group) { - return $this->verboseOutput; + return $this->verboseOutput[$group]; } /** @@ -145,24 +248,41 @@ public static function fromUrlEncodedString($serializedConfiguration) { parse_str($serializedConfiguration, $normalizedConfiguration); foreach (array_keys($normalizedConfiguration) as $key) { - if (!\in_array($key, ['max', 'disabled', 'verbose'], true)) { + if (!\in_array($key, ['max', 'disabled', 'verbose', 'quiet', 'generateBaseline', 'baselineFile'], true)) { throw new \InvalidArgumentException(sprintf('Unknown configuration option "%s".', $key)); } } - if (isset($normalizedConfiguration['disabled'])) { + $normalizedConfiguration += [ + 'max' => [], + 'disabled' => false, + 'verbose' => true, + 'quiet' => [], + 'generateBaseline' => false, + 'baselineFile' => '', + ]; + + if ('' === $normalizedConfiguration['disabled'] || filter_var($normalizedConfiguration['disabled'], \FILTER_VALIDATE_BOOLEAN)) { return self::inDisabledMode(); } - $verboseOutput = true; - if (isset($normalizedConfiguration['verbose'])) { - $verboseOutput = (bool) $normalizedConfiguration['verbose']; + $verboseOutput = []; + foreach (['unsilenced', 'direct', 'indirect', 'self', 'other'] as $group) { + $verboseOutput[$group] = filter_var($normalizedConfiguration['verbose'], \FILTER_VALIDATE_BOOLEAN); + } + + if (\is_array($normalizedConfiguration['quiet'])) { + foreach ($normalizedConfiguration['quiet'] as $shushedGroup) { + $verboseOutput[$shushedGroup] = false; + } } return new self( isset($normalizedConfiguration['max']) ? $normalizedConfiguration['max'] : [], '', - $verboseOutput + $verboseOutput, + filter_var($normalizedConfiguration['generateBaseline'], \FILTER_VALIDATE_BOOLEAN), + $normalizedConfiguration['baselineFile'] ); } @@ -190,7 +310,12 @@ public static function inStrictMode() */ public static function inWeakMode() { - return new self([], '', false); + $verboseOutput = []; + foreach (['unsilenced', 'direct', 'indirect', 'self', 'other'] as $group) { + $verboseOutput[$group] = false; + } + + return new self([], '', $verboseOutput); } /** diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php index fdc898a9316f5..b4d79e7ba46d7 100644 --- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php @@ -56,6 +56,11 @@ class Deprecation */ public function __construct($message, array $trace, $file) { + if (isset($trace[2]['function']) && 'trigger_deprecation' === $trace[2]['function']) { + $file = $trace[2]['file']; + array_splice($trace, 1, 1); + } + $this->trace = $trace; $this->message = $message; @@ -93,6 +98,27 @@ public function __construct($message, array $trace, $file) return; } + set_error_handler(function () {}); + $parsedMsg = unserialize($this->message); + restore_error_handler(); + if ($parsedMsg && isset($parsedMsg['deprecation'])) { + $this->message = $parsedMsg['deprecation']; + $this->originClass = $parsedMsg['class']; + $this->originMethod = $parsedMsg['method']; + if (isset($parsedMsg['files_stack'])) { + $this->originalFilesStack = $parsedMsg['files_stack']; + } + // If the deprecation has been triggered via + // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() + // then we need to use the serialized information to determine + // if the error has been triggered from vendor code. + if (isset($parsedMsg['triggering_file'])) { + $this->triggeringFile = $parsedMsg['triggering_file']; + } + + return; + } + if (!isset($line['class'], $trace[$i - 2]['function']) || 0 !== strpos($line['class'], SymfonyTestsListenerFor::class)) { $this->originClass = isset($line['object']) ? \get_class($line['object']) : $line['class']; $this->originMethod = $line['function']; @@ -108,23 +134,6 @@ public function __construct($message, array $trace, $file) return; } - - set_error_handler(function () {}); - $parsedMsg = unserialize($this->message); - restore_error_handler(); - $this->message = $parsedMsg['deprecation']; - $this->originClass = $parsedMsg['class']; - $this->originMethod = $parsedMsg['method']; - if (isset($parsedMsg['files_stack'])) { - $this->originalFilesStack = $parsedMsg['files_stack']; - } - // If the deprecation has been triggered via - // \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest() - // then we need to use the serialized information to determine - // if the error has been triggered from vendor code. - if (isset($parsedMsg['triggering_file'])) { - $this->triggeringFile = $parsedMsg['triggering_file']; - } } /** diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationGroup.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationGroup.php new file mode 100644 index 0000000000000..f2b0323135dd4 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationGroup.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\DeprecationErrorHandler; + +/** + * @internal + */ +final class DeprecationGroup +{ + private $count = 0; + + /** + * @var DeprecationNotice[] keys are messages + */ + private $deprecationNotices = []; + + /** + * @param string $message + * @param string $class + * @param string $method + */ + public function addNoticeFromObject($message, $class, $method) + { + $this->deprecationNotice($message)->addObjectOccurrence($class, $method); + $this->addNotice(); + } + + /** + * @param string $message + */ + public function addNoticeFromProceduralCode($message) + { + $this->deprecationNotice($message)->addProceduralOccurrence(); + $this->addNotice(); + } + + public function addNotice() + { + ++$this->count; + } + + /** + * @param string $message + * + * @return DeprecationNotice + */ + private function deprecationNotice($message) + { + if (!isset($this->deprecationNotices[$message])) { + $this->deprecationNotices[$message] = new DeprecationNotice(); + } + + return $this->deprecationNotices[$message]; + } + + public function count() + { + return $this->count; + } + + public function notices() + { + return $this->deprecationNotices; + } +} diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationNotice.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationNotice.php new file mode 100644 index 0000000000000..854bbd4d26333 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/DeprecationNotice.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\DeprecationErrorHandler; + +/** + * @internal + */ +final class DeprecationNotice +{ + private $count = 0; + + /** + * @var int[] + */ + private $countsByCaller = []; + + public function addObjectOccurrence($class, $method) + { + if (!isset($this->countsByCaller["$class::$method"])) { + $this->countsByCaller["$class::$method"] = 0; + } + ++$this->countsByCaller["$class::$method"]; + ++$this->count; + } + + public function addProceduralOccurrence() + { + ++$this->count; + } + + public function getCountsByCaller() + { + return $this->countsByCaller; + } + + public function count() + { + return $this->count; + } +} diff --git a/src/Symfony/Bridge/PhpUnit/ExpectDeprecationTrait.php b/src/Symfony/Bridge/PhpUnit/ExpectDeprecationTrait.php new file mode 100644 index 0000000000000..fd7f2c80b84f9 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/ExpectDeprecationTrait.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit; + +use Symfony\Bridge\PhpUnit\Legacy\ExpectDeprecationTraitBeforeV8_4; +use Symfony\Bridge\PhpUnit\Legacy\ExpectDeprecationTraitForV8_4; + +if (version_compare(\PHPUnit\Runner\Version::id(), '8.4.0', '<')) { + trait ExpectDeprecationTrait + { + use ExpectDeprecationTraitBeforeV8_4; + } +} else { + /** + * @method void expectDeprecation(string $message) + */ + trait ExpectDeprecationTrait + { + use ExpectDeprecationTraitForV8_4; + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/ExpectDeprecationTraitBeforeV8_4.php b/src/Symfony/Bridge/PhpUnit/Legacy/ExpectDeprecationTraitBeforeV8_4.php new file mode 100644 index 0000000000000..03368b5597fbe --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Legacy/ExpectDeprecationTraitBeforeV8_4.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Legacy; + +/** + * @internal, use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait instead. + */ +trait ExpectDeprecationTraitBeforeV8_4 +{ + /** + * @param string $message + * + * @return void + */ + protected function expectDeprecation($message) + { + // Expected deprecations set by isolated tests need to be written to a file + // so that the test running process can take account of them. + if ($file = getenv('SYMFONY_EXPECTED_DEPRECATIONS_SERIALIZE')) { + $this->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything(false); + $expectedDeprecations = file_get_contents($file); + if ($expectedDeprecations) { + $expectedDeprecations = array_merge(unserialize($expectedDeprecations), [$message]); + } else { + $expectedDeprecations = [$message]; + } + file_put_contents($file, serialize($expectedDeprecations)); + + return; + } + + if (!SymfonyTestsListenerTrait::$previousErrorHandler) { + SymfonyTestsListenerTrait::$previousErrorHandler = set_error_handler([SymfonyTestsListenerTrait::class, 'handleError']); + } + + SymfonyTestsListenerTrait::$expectedDeprecations[] = $message; + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/ExpectDeprecationTraitForV8_4.php b/src/Symfony/Bridge/PhpUnit/Legacy/ExpectDeprecationTraitForV8_4.php new file mode 100644 index 0000000000000..d15963520d6f2 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Legacy/ExpectDeprecationTraitForV8_4.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Legacy; + +/** + * @internal use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait instead + */ +trait ExpectDeprecationTraitForV8_4 +{ + /** + * @param string $message + */ + public function expectDeprecation(): void + { + if (1 > \func_num_args() || !\is_string($message = func_get_arg(0))) { + throw new \InvalidArgumentException(sprintf('The "%s()" method requires the string $message argument.', __FUNCTION__)); + } + + // Expected deprecations set by isolated tests need to be written to a file + // so that the test running process can take account of them. + if ($file = getenv('SYMFONY_EXPECTED_DEPRECATIONS_SERIALIZE')) { + $this->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything(false); + $expectedDeprecations = file_get_contents($file); + if ($expectedDeprecations) { + $expectedDeprecations = array_merge(unserialize($expectedDeprecations), [$message]); + } else { + $expectedDeprecations = [$message]; + } + file_put_contents($file, serialize($expectedDeprecations)); + + return; + } + + if (!SymfonyTestsListenerTrait::$previousErrorHandler) { + SymfonyTestsListenerTrait::$previousErrorHandler = set_error_handler([SymfonyTestsListenerTrait::class, 'handleError']); + } + + SymfonyTestsListenerTrait::$expectedDeprecations[] = $message; + } + + /** + * @internal use expectDeprecation() instead + */ + public function expectDeprecationMessage(string $message): void + { + throw new \BadMethodCallException(sprintf('The "%s()" method is not supported by Symfony\'s PHPUnit Bridge ExpectDeprecationTrait, pass the message to expectDeprecation() instead.', __FUNCTION__)); + } + + /** + * @internal use expectDeprecation() instead + */ + public function expectDeprecationMessageMatches(string $regularExpression): void + { + throw new \BadMethodCallException(sprintf('The "%s()" method is not supported by Symfony\'s PHPUnit Bridge ExpectDeprecationTrait.', __FUNCTION__)); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php index 0f9238bdd9c1c..44723f06ec937 100644 --- a/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php +++ b/src/Symfony/Bridge/PhpUnit/Legacy/SymfonyTestsListenerTrait.php @@ -13,6 +13,7 @@ use Doctrine\Common\Annotations\AnnotationRegistry; use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\RiskyTestError; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestSuite; use PHPUnit\Runner\BaseTestRunner; @@ -21,6 +22,7 @@ use PHPUnit\Util\Test; use Symfony\Bridge\PhpUnit\ClockMock; use Symfony\Bridge\PhpUnit\DnsMock; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader; use Symfony\Component\ErrorHandler\DebugClassLoader; @@ -33,16 +35,16 @@ */ class SymfonyTestsListenerTrait { + public static $expectedDeprecations = []; + public static $previousErrorHandler; + private static $gatheredDeprecations = []; private static $globallyEnabled = false; private $state = -1; private $skippedFile = false; private $wasSkipped = []; private $isSkipped = []; - private $expectedDeprecations = []; - private $gatheredDeprecations = []; - private $previousErrorHandler; - private $error; private $runsInSeparateProcess = false; + private $checkNumAssertions = false; /** * @param array $mockedNamespaces List of namespaces, indexed by mocked features (time-sensitive or dns-sensitive) @@ -205,6 +207,7 @@ public function startTest($test) if ($this->willBeIsolated($test)) { $this->runsInSeparateProcess = tempnam(sys_get_temp_dir(), 'deprec'); putenv('SYMFONY_DEPRECATIONS_SERIALIZE='.$this->runsInSeparateProcess); + putenv('SYMFONY_EXPECTED_DEPRECATIONS_SERIALIZE='.tempnam(sys_get_temp_dir(), 'expectdeprec')); } $groups = Test::getGroups(\get_class($test), $test->getName(false)); @@ -228,21 +231,35 @@ public function startTest($test) if (isset($annotations['class']['expectedDeprecation'])) { $test->getTestResultObject()->addError($test, new AssertionFailedError('`@expectedDeprecation` annotations are not allowed at the class level.'), 0); } - if (isset($annotations['method']['expectedDeprecation'])) { - if (!\in_array('legacy', $groups, true)) { - $this->error = new AssertionFailedError('Only tests with the `@group legacy` annotation can have `@expectedDeprecation`.'); + if (isset($annotations['method']['expectedDeprecation']) || $this->checkNumAssertions = method_exists($test, 'expectDeprecation') && (new \ReflectionMethod($test, 'expectDeprecation'))->getFileName() === (new \ReflectionMethod(ExpectDeprecationTrait::class, 'expectDeprecation'))->getFileName()) { + if (isset($annotations['method']['expectedDeprecation'])) { + self::$expectedDeprecations = $annotations['method']['expectedDeprecation']; + self::$previousErrorHandler = set_error_handler([self::class, 'handleError']); + @trigger_error('Since symfony/phpunit-bridge 5.1: Using "@expectedDeprecation" annotations in tests is deprecated, use the "ExpectDeprecationTrait::expectDeprecation()" method instead.', \E_USER_DEPRECATED); } - $test->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything(false); + if ($this->checkNumAssertions) { + $this->checkNumAssertions = $test->getTestResultObject()->isStrictAboutTestsThatDoNotTestAnything() && !$test->doesNotPerformAssertions(); + } - $this->expectedDeprecations = $annotations['method']['expectedDeprecation']; - $this->previousErrorHandler = set_error_handler([$this, 'handleError']); + $test->getTestResultObject()->beStrictAboutTestsThatDoNotTestAnything(false); } } } public function endTest($test, $time) { + if ($file = getenv('SYMFONY_EXPECTED_DEPRECATIONS_SERIALIZE')) { + putenv('SYMFONY_EXPECTED_DEPRECATIONS_SERIALIZE'); + $expectedDeprecations = file_get_contents($file); + if ($expectedDeprecations) { + self::$expectedDeprecations = array_merge(self::$expectedDeprecations, unserialize($expectedDeprecations)); + if (!self::$previousErrorHandler) { + self::$previousErrorHandler = set_error_handler([self::class, 'handleError']); + } + } + } + if (class_exists(DebugClassLoader::class, false)) { DebugClassLoader::checkClasses(); } @@ -250,9 +267,12 @@ public function endTest($test, $time) $className = \get_class($test); $groups = Test::getGroups($className, $test->getName(false)); - if ($errored = null !== $this->error) { - $test->getTestResultObject()->addError($test, $this->error, 0); - $this->error = null; + if ($this->checkNumAssertions) { + if (!self::$expectedDeprecations && !$test->getNumAssertions() && $test->getTestResultObject()->noneSkipped()) { + $test->getTestResultObject()->addFailure($test, new RiskyTestError('This test did not perform any assertions'), $time); + } + + $this->checkNumAssertions = false; } if ($this->runsInSeparateProcess) { @@ -271,24 +291,26 @@ public function endTest($test, $time) $this->runsInSeparateProcess = false; } - if ($this->expectedDeprecations) { + if (self::$expectedDeprecations) { if (!\in_array($test->getStatus(), [BaseTestRunner::STATUS_SKIPPED, BaseTestRunner::STATUS_INCOMPLETE], true)) { - $test->addToAssertionCount(\count($this->expectedDeprecations)); + $test->addToAssertionCount(\count(self::$expectedDeprecations)); } restore_error_handler(); - if (!$errored && !\in_array($test->getStatus(), [BaseTestRunner::STATUS_SKIPPED, BaseTestRunner::STATUS_INCOMPLETE, BaseTestRunner::STATUS_FAILURE, BaseTestRunner::STATUS_ERROR], true)) { + if (!\in_array('legacy', $groups, true)) { + $test->getTestResultObject()->addError($test, new AssertionFailedError('Only tests with the `@group legacy` annotation can expect a deprecation.'), 0); + } elseif (!\in_array($test->getStatus(), [BaseTestRunner::STATUS_SKIPPED, BaseTestRunner::STATUS_INCOMPLETE, BaseTestRunner::STATUS_FAILURE, BaseTestRunner::STATUS_ERROR], true)) { try { $prefix = "@expectedDeprecation:\n"; - $test->assertStringMatchesFormat($prefix.'%A '.implode("\n%A ", $this->expectedDeprecations)."\n%A", $prefix.' '.implode("\n ", $this->gatheredDeprecations)."\n"); + $test->assertStringMatchesFormat($prefix.'%A '.implode("\n%A ", self::$expectedDeprecations)."\n%A", $prefix.' '.implode("\n ", self::$gatheredDeprecations)."\n"); } catch (AssertionFailedError $e) { $test->getTestResultObject()->addFailure($test, $e, $time); } } - $this->expectedDeprecations = $this->gatheredDeprecations = []; - $this->previousErrorHandler = null; + self::$expectedDeprecations = self::$gatheredDeprecations = []; + self::$previousErrorHandler = null; } if (!$this->runsInSeparateProcess && -2 < $this->state && ($test instanceof \PHPUnit_Framework_TestCase || $test instanceof TestCase)) { if (\in_array('time-sensitive', $groups, true)) { @@ -300,10 +322,10 @@ public function endTest($test, $time) } } - public function handleError($type, $msg, $file, $line, $context = []) + public static function handleError($type, $msg, $file, $line, $context = []) { if (\E_USER_DEPRECATED !== $type && \E_DEPRECATED !== $type) { - $h = $this->previousErrorHandler; + $h = self::$previousErrorHandler; return $h ? $h($type, $msg, $file, $line, $context) : false; } @@ -316,7 +338,7 @@ public function handleError($type, $msg, $file, $line, $context = []) if (error_reporting() & $type) { $msg = 'Unsilenced deprecation: '.$msg; } - $this->gatheredDeprecations[] = $msg; + self::$gatheredDeprecations[] = $msg; return null; } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php index 39e792cd3a2cb..5d36a43bff54f 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/ConfigurationTest.php @@ -13,9 +13,13 @@ use PHPUnit\Framework\TestCase; use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Configuration; +use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\Deprecation; +use Symfony\Bridge\PhpUnit\DeprecationErrorHandler\DeprecationGroup; class ConfigurationTest extends TestCase { + private $files; + public function testItThrowsOnStringishValue() { $this->expectException(\InvalidArgumentException::class); @@ -47,122 +51,122 @@ public function testItThrowsOnStringishThreshold() public function testItNoticesExceededTotalThreshold() { $configuration = Configuration::fromUrlEncodedString('max[total]=3'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 1, - 'remaining selfCount' => 0, - 'legacyCount' => 1, - 'otherCount' => 0, - 'remaining directCount' => 1, - 'remaining indirectCount' => 1, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 1, - 'remaining selfCount' => 1, - 'legacyCount' => 1, - 'otherCount' => 0, - 'remaining directCount' => 1, - 'remaining indirectCount' => 1, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1, + 'self' => 0, + 'legacy' => 1, + 'other' => 0, + 'direct' => 1, + 'indirect' => 1, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1, + 'self' => 1, + 'legacy' => 1, + 'other' => 0, + 'direct' => 1, + 'indirect' => 1, + ]))); } public function testItNoticesExceededSelfThreshold() { $configuration = Configuration::fromUrlEncodedString('max[self]=1'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 1, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 124, - 'remaining indirectCount' => 3244, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 2, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 124, - 'remaining indirectCount' => 3244, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 1, + 'legacy' => 23, + 'other' => 13, + 'direct' => 124, + 'indirect' => 3244, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 2, + 'legacy' => 23, + 'other' => 13, + 'direct' => 124, + 'indirect' => 3244, + ]))); } public function testItNoticesExceededDirectThreshold() { $configuration = Configuration::fromUrlEncodedString('max[direct]=1&max[self]=999999'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 123, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 1, - 'remaining indirectCount' => 3244, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 124, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 2, - 'remaining indirectCount' => 3244, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 123, + 'legacy' => 23, + 'other' => 13, + 'direct' => 1, + 'indirect' => 3244, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 124, + 'legacy' => 23, + 'other' => 13, + 'direct' => 2, + 'indirect' => 3244, + ]))); } public function testItNoticesExceededIndirectThreshold() { $configuration = Configuration::fromUrlEncodedString('max[indirect]=1&max[direct]=999999&max[self]=999999'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 123, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 1234, - 'remaining indirectCount' => 1, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 1234, - 'remaining selfCount' => 124, - 'legacyCount' => 23, - 'otherCount' => 13, - 'remaining directCount' => 2324, - 'remaining indirectCount' => 2, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 123, + 'legacy' => 23, + 'other' => 13, + 'direct' => 1234, + 'indirect' => 1, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 1234, + 'self' => 124, + 'legacy' => 23, + 'other' => 13, + 'direct' => 2324, + 'indirect' => 2, + ]))); } public function testIndirectThresholdIsUsedAsADefaultForDirectAndSelfThreshold() { $configuration = Configuration::fromUrlEncodedString('max[indirect]=1'); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 0, - 'remaining selfCount' => 1, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 0, - 'remaining indirectCount' => 0, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 0, - 'remaining selfCount' => 2, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 0, - 'remaining indirectCount' => 0, - ])); - $this->assertTrue($configuration->tolerates([ - 'unsilencedCount' => 0, - 'remaining selfCount' => 0, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 1, - 'remaining indirectCount' => 0, - ])); - $this->assertFalse($configuration->tolerates([ - 'unsilencedCount' => 0, - 'remaining selfCount' => 0, - 'legacyCount' => 0, - 'otherCount' => 0, - 'remaining directCount' => 2, - 'remaining indirectCount' => 0, - ])); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 0, + 'self' => 1, + 'legacy' => 0, + 'other' => 0, + 'direct' => 0, + 'indirect' => 0, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 0, + 'self' => 2, + 'legacy' => 0, + 'other' => 0, + 'direct' => 0, + 'indirect' => 0, + ]))); + $this->assertTrue($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 0, + 'self' => 0, + 'legacy' => 0, + 'other' => 0, + 'direct' => 1, + 'indirect' => 0, + ]))); + $this->assertFalse($configuration->tolerates($this->buildGroups([ + 'unsilenced' => 0, + 'self' => 0, + 'legacy' => 0, + 'other' => 0, + 'direct' => 2, + 'indirect' => 0, + ]))); } public function testItCanTellWhetherToDisplayAStackTrace() @@ -175,21 +179,237 @@ public function testItCanTellWhetherToDisplayAStackTrace() $this->assertTrue($configuration->shouldDisplayStackTrace('interesting')); } - public function testItCanBeDisabled() + public function provideItCanBeDisabled(): array + { + return [ + ['disabled', false], + ['disabled=1', false], + ['disabled=0', true], + ]; + } + + /** + * @dataProvider provideItCanBeDisabled + */ + public function testItCanBeDisabled(string $encodedString, bool $expectedEnabled) { - $configuration = Configuration::fromUrlEncodedString('disabled'); - $this->assertFalse($configuration->isEnabled()); + $configuration = Configuration::fromUrlEncodedString($encodedString); + $this->assertSame($expectedEnabled, $configuration->isEnabled()); } public function testItCanBeShushed() { $configuration = Configuration::fromUrlEncodedString('verbose'); - $this->assertFalse($configuration->verboseOutput()); + $this->assertFalse($configuration->verboseOutput('unsilenced')); + $this->assertFalse($configuration->verboseOutput('direct')); + $this->assertFalse($configuration->verboseOutput('indirect')); + $this->assertFalse($configuration->verboseOutput('self')); + $this->assertFalse($configuration->verboseOutput('other')); + } + + public function testItCanBePartiallyShushed() + { + $configuration = Configuration::fromUrlEncodedString('quiet[]=unsilenced&quiet[]=indirect&quiet[]=other'); + $this->assertFalse($configuration->verboseOutput('unsilenced')); + $this->assertTrue($configuration->verboseOutput('direct')); + $this->assertFalse($configuration->verboseOutput('indirect')); + $this->assertTrue($configuration->verboseOutput('self')); + $this->assertFalse($configuration->verboseOutput('other')); + } + + public function testItThrowsOnUnknownVerbosityGroup() + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('made-up'); + Configuration::fromUrlEncodedString('quiet[]=made-up'); } public function testOutputIsNotVerboseInWeakMode() { $configuration = Configuration::inWeakMode(); - $this->assertFalse($configuration->verboseOutput()); + $this->assertFalse($configuration->verboseOutput('unsilenced')); + $this->assertFalse($configuration->verboseOutput('direct')); + $this->assertFalse($configuration->verboseOutput('indirect')); + $this->assertFalse($configuration->verboseOutput('self')); + $this->assertFalse($configuration->verboseOutput('other')); + } + + private function buildGroups($counts) + { + $groups = []; + foreach ($counts as $name => $count) { + $groups[$name] = new DeprecationGroup(); + $i = 0; + while ($i++ < $count) { + $groups[$name]->addNotice(); + } + } + + return $groups; + } + + public function testBaselineGenerationEmptyFile() + { + $filename = $this->createFile(); + $configuration = Configuration::fromUrlEncodedString('generateBaseline=true&baselineFile='.urlencode($filename)); + $this->assertTrue($configuration->isGeneratingBaseline()); + $trace = debug_backtrace(); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, ''))); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 2', $trace, ''))); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, ''))); + $configuration->writeBaseline(); + $this->assertEquals($filename, $configuration->getBaselineFile()); + $expected_baseline = [ + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 1', + 'count' => 2, + ], + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 2', + 'count' => 1, + ], + ]; + $this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); + } + + public function testBaselineGenerationNoFile() + { + $filename = $this->createFile(); + $configuration = Configuration::fromUrlEncodedString('generateBaseline=true&baselineFile='.urlencode($filename)); + $this->assertTrue($configuration->isGeneratingBaseline()); + $trace = debug_backtrace(); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, ''))); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 2', $trace, ''))); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 2', $trace, ''))); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, ''))); + $configuration->writeBaseline(); + $this->assertEquals($filename, $configuration->getBaselineFile()); + $expected_baseline = [ + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 1', + 'count' => 2, + ], + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 2', + 'count' => 2, + ], + ]; + $this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); + } + + public function testExistingBaseline() + { + $filename = $this->createFile(); + $baseline = [ + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 1', + 'count' => 1, + ], + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 2', + 'count' => 1, + ], + ]; + file_put_contents($filename, json_encode($baseline)); + + $configuration = Configuration::fromUrlEncodedString('baselineFile='.urlencode($filename)); + $this->assertFalse($configuration->isGeneratingBaseline()); + $trace = debug_backtrace(); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 1', $trace, ''))); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 2', $trace, ''))); + $this->assertFalse($configuration->isBaselineDeprecation(new Deprecation('Test message 3', $trace, ''))); + $this->assertEquals($filename, $configuration->getBaselineFile()); + } + + public function testExistingBaselineAndGeneration() + { + $filename = $this->createFile(); + $baseline = [ + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 1', + 'count' => 1, + ], + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 2', + 'count' => 1, + ], + ]; + file_put_contents($filename, json_encode($baseline)); + $configuration = Configuration::fromUrlEncodedString('generateBaseline=true&baselineFile='.urlencode($filename)); + $this->assertTrue($configuration->isGeneratingBaseline()); + $trace = debug_backtrace(); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 2', $trace, ''))); + $this->assertTrue($configuration->isBaselineDeprecation(new Deprecation('Test message 3', $trace, ''))); + $configuration->writeBaseline(); + $this->assertEquals($filename, $configuration->getBaselineFile()); + $expected_baseline = [ + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 2', + 'count' => 1, + ], + [ + 'location' => 'Symfony\Bridge\PhpUnit\Tests\DeprecationErrorHandler\ConfigurationTest::runTest', + 'message' => 'Test message 3', + 'count' => 1, + ], + ]; + $this->assertEquals(json_encode($expected_baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES), file_get_contents($filename)); + } + + public function testBaselineArgumentException() + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('You cannot use the "generateBaseline" configuration option without providing a "baselineFile" configuration option.'); + Configuration::fromUrlEncodedString('generateBaseline=true'); + } + + public function testBaselineFileException() + { + $filename = $this->createFile(); + unlink($filename); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage(sprintf('The baselineFile "%s" does not exist.', $filename)); + Configuration::fromUrlEncodedString('baselineFile='.urlencode($filename)); + } + + public function testBaselineFileWriteError() + { + $filename = $this->createFile(); + chmod($filename, 0444); + $this->expectError(); + $this->expectErrorMessageMatches('/[Ff]ailed to open stream: Permission denied/'); + $configuration = Configuration::fromUrlEncodedString('generateBaseline=true&baselineFile='.urlencode($filename)); + $configuration->writeBaseline(); + } + + protected function setUp(): void + { + $this->files = []; + } + + protected function tearDown(): void + { + foreach ($this->files as $file) { + if (file_exists($file)) { + @unlink($file); + } + } + } + + private function createFile() + { + $filename = tempnam(sys_get_temp_dir(), 'sf-'); + $this->files[] = $filename; + + return $filename; } } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationGroupTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationGroupTest.php new file mode 100644 index 0000000000000..df746e5e38907 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationGroupTest.php @@ -0,0 +1,30 @@ +addNoticeFromObject( + 'Calling sfContext::getInstance() is deprecated', + 'MonsterController', + 'get5klocMethod' + ); + $group->addNoticeFromProceduralCode('Calling sfContext::getInstance() is deprecated'); + $this->assertCount(1, $group->notices()); + $this->assertSame(2, $group->count()); + } + + public function testItAllowsAddingANoticeWithoutClutteringTheMemory() + { + // this is useful for notices in the legacy group + $group = new DeprecationGroup(); + $group->addNotice(); + $this->assertSame(1, $group->count()); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationNoticeTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationNoticeTest.php new file mode 100644 index 0000000000000..c0a88c443b4d7 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationNoticeTest.php @@ -0,0 +1,35 @@ +addObjectOccurrence('MyAction', '__invoke'); + $notice->addObjectOccurrence('MyAction', '__invoke'); + $notice->addObjectOccurrence('MyOtherAction', '__invoke'); + + $countsByCaller = $notice->getCountsByCaller(); + + $this->assertCount(2, $countsByCaller); + $this->assertArrayHasKey('MyAction::__invoke', $countsByCaller); + $this->assertArrayHasKey('MyOtherAction::__invoke', $countsByCaller); + $this->assertSame(2, $countsByCaller['MyAction::__invoke']); + $this->assertSame(1, $countsByCaller['MyOtherAction::__invoke']); + } + + public function testItCountsBothTypesOfOccurrences() + { + $notice = new DeprecationNotice(); + $notice->addObjectOccurrence('MyAction', '__invoke'); + $this->assertSame(1, $notice->count()); + + $notice->addProceduralOccurrence(); + $this->assertSame(2, $notice->count()); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/baseline.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/baseline.phpt new file mode 100644 index 0000000000000..533912c106cbd --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/baseline.phpt @@ -0,0 +1,80 @@ +--TEST-- +Test DeprecationErrorHandler in baseline mode +--FILE-- + 'FooTestCase::testLegacyFoo', + 'message' => 'silenced foo deprecation', + 'count' => 1, +], +[ + 'location' => 'FooTestCase::testNonLegacyBar', + 'message' => 'silenced bar deprecation', + 'count' => 1, +], +[ + 'location' => 'procedural code', + 'message' => 'root deprecation', + 'count' => 1, +]]; +file_put_contents($filename, json_encode($baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)); + +$k = 'SYMFONY_DEPRECATIONS_HELPER'; +unset($_SERVER[$k], $_ENV[$k]); +putenv($k.'='.$_SERVER[$k] = $_ENV[$k] = 'baselineFile=' . urlencode($filename)); +putenv('ANSICON'); +putenv('ConEmuANSI'); +putenv('TERM'); + +$vendor = __DIR__; +while (!file_exists($vendor.'/vendor')) { + $vendor = dirname($vendor); +} +define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php'); +require PHPUNIT_COMPOSER_INSTALL; +require_once __DIR__.'/../../bootstrap.php'; + +@trigger_error('root deprecation', E_USER_DEPRECATED); + +eval(<<<'EOPHP' +namespace PHPUnit\Util; + +class Test +{ + public static function getGroups() + { + return array(); + } +} +EOPHP +); + +class PHPUnit_Util_Test +{ + public static function getGroups() + { + return array(); + } +} + +class FooTestCase +{ + public function testLegacyFoo() + { + @trigger_error('silenced foo deprecation', E_USER_DEPRECATED); + } + + public function testNonLegacyBar() + { + @trigger_error('silenced bar deprecation', E_USER_DEPRECATED); + } +} + +$foo = new FooTestCase(); +$foo->testLegacyFoo(); +$foo->testNonLegacyBar(); +print "Cannot test baselineFile contents because it is generated in a shutdown function registered by another shutdown function." +?> +--EXPECT-- +Cannot test baselineFile contents because it is generated in a shutdown function registered by another shutdown function. diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/baseline2.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/baseline2.phpt new file mode 100644 index 0000000000000..f520912694a1e --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/baseline2.phpt @@ -0,0 +1,74 @@ +--TEST-- +Test DeprecationErrorHandler in baseline mode +--FILE-- + 'FooTestCase::testLegacyFoo', + 'message' => 'silenced foo deprecation', + 'count' => 1, +]]; +file_put_contents($filename, json_encode($baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)); + +$k = 'SYMFONY_DEPRECATIONS_HELPER'; +unset($_SERVER[$k], $_ENV[$k]); +putenv($k.'='.$_SERVER[$k] = $_ENV[$k] = 'baselineFile=' . urlencode($filename)); +putenv('ANSICON'); +putenv('ConEmuANSI'); +putenv('TERM'); + +$vendor = __DIR__; +while (!file_exists($vendor.'/vendor')) { + $vendor = dirname($vendor); +} +define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php'); +require PHPUNIT_COMPOSER_INSTALL; +require_once __DIR__.'/../../bootstrap.php'; + +@trigger_error('root deprecation', E_USER_DEPRECATED); + +eval(<<<'EOPHP' +namespace PHPUnit\Util; + +class Test +{ + public static function getGroups() + { + return array(); + } +} +EOPHP +); + +class PHPUnit_Util_Test +{ + public static function getGroups() + { + return array(); + } +} + +class FooTestCase +{ + public function testLegacyFoo() + { + @trigger_error('silenced foo deprecation', E_USER_DEPRECATED); + } + + public function testNonLegacyBar() + { + @trigger_error('silenced bar deprecation', E_USER_DEPRECATED); + } +} + +$foo = new FooTestCase(); +$foo->testLegacyFoo(); +$foo->testNonLegacyBar(); +?> +--EXPECTF-- +Other deprecation notices (2) + + 1x: root deprecation + + 1x: silenced bar deprecation + 1x in FooTestCase::testNonLegacyBar diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/baseline3.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/baseline3.phpt new file mode 100644 index 0000000000000..28d1a74ffd427 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/baseline3.phpt @@ -0,0 +1,79 @@ +--TEST-- +Test DeprecationErrorHandler in baseline mode +--FILE-- + 'FooTestCase::testLegacyFoo', + 'message' => 'silenced foo deprecation', + 'count' => 1, +]]; +file_put_contents($filename, json_encode($baseline, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)); + +$k = 'SYMFONY_DEPRECATIONS_HELPER'; +unset($_SERVER[$k], $_ENV[$k]); +putenv($k.'='.$_SERVER[$k] = $_ENV[$k] = 'baselineFile=' . urlencode($filename)); +putenv('ANSICON'); +putenv('ConEmuANSI'); +putenv('TERM'); + +$vendor = __DIR__; +while (!file_exists($vendor.'/vendor')) { + $vendor = dirname($vendor); +} +define('PHPUNIT_COMPOSER_INSTALL', $vendor.'/vendor/autoload.php'); +require PHPUNIT_COMPOSER_INSTALL; +require_once __DIR__.'/../../bootstrap.php'; + +@trigger_error('root deprecation', E_USER_DEPRECATED); + +eval(<<<'EOPHP' +namespace PHPUnit\Util; + +class Test +{ + public static function getGroups() + { + return array(); + } +} +EOPHP +); + +class PHPUnit_Util_Test +{ + public static function getGroups() + { + return array(); + } +} + +class FooTestCase +{ + public function testLegacyFoo() + { + @trigger_error('silenced foo deprecation', E_USER_DEPRECATED); + // This will cause a deprecation because the baseline only expects 1 + // deprecation. + @trigger_error('silenced foo deprecation', E_USER_DEPRECATED); + } + + public function testNonLegacyBar() + { + @trigger_error('silenced bar deprecation', E_USER_DEPRECATED); + } +} + +$foo = new FooTestCase(); +$foo->testLegacyFoo(); +$foo->testNonLegacyBar(); +?> +--EXPECTF-- +Legacy deprecation notices (1) + +Other deprecation notices (2) + + 1x: root deprecation + + 1x: silenced bar deprecation + 1x in FooTestCase::testNonLegacyBar diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_1.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_1.phpt new file mode 100644 index 0000000000000..acb5f096306d0 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/disabled_1.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test DeprecationErrorHandler in default mode +--FILE-- + +--EXPECTREGEX-- +.{0} diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/AppService.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/AppService.php index 2e5ccf3c78811..2b6cb316af143 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/AppService.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_app/AppService.php @@ -7,6 +7,37 @@ final class AppService { + public function directDeprecationsTwoVendors() + { + $service1 = new SomeService(); + $service1->deprecatedApi(); + + $service2 = new SomeOtherService(); + $service2->deprecatedApi(); + } + + public function selfDeprecation(bool $useContracts = false) + { + $args = [__FUNCTION__, __FUNCTION__]; + if ($useContracts) { + trigger_deprecation('App', '3.0', sprintf('%s is deprecated, use %s_new instead.', ...$args)); + } else { + @trigger_error(sprintf('Since App 3.0: %s is deprecated, use %s_new instead.', ...$args), \E_USER_DEPRECATED); + } + } + + public function directDeprecation(bool $useContracts = false) + { + $service = new SomeService(); + $service->deprecatedApi($useContracts); + } + + public function indirectDeprecation(bool $useContracts = false) + { + $service = new SomeService(); + $service->indirectDeprecatedApi($useContracts); + } + public function directDeprecations() { $service1 = new SomeService(); diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/SomeService.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/SomeService.php index d18cfbd3319bd..cc237e6146c23 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/SomeService.php +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/acme/lib/SomeService.php @@ -2,13 +2,22 @@ namespace acme\lib; +use bar\lib\AnotherService; + class SomeService { - public function deprecatedApi() + public function deprecatedApi(bool $useContracts = false) + { + $args = [__FUNCTION__, __FUNCTION__]; + if ($useContracts) { + trigger_deprecation('acme/lib', '3.0', sprintf('%s is deprecated, use %s_new instead.', ...$args)); + } else { + @trigger_error(sprintf('Since acme/lib 3.0: %s is deprecated, use %s_new instead.', ...$args), \E_USER_DEPRECATED); + } + } + + public function indirectDeprecatedApi(bool $useContracts = false) { - @trigger_error( - __FUNCTION__.' is deprecated! You should stop relying on it!', - \E_USER_DEPRECATED - ); + (new AnotherService())->deprecatedApi($useContracts); } } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/bar/lib/AnotherService.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/bar/lib/AnotherService.php new file mode 100644 index 0000000000000..2e2f0f9b6b4b5 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/bar/lib/AnotherService.php @@ -0,0 +1,16 @@ + [__DIR__.'/../../fake_app/'], 'acme\\lib\\' => [__DIR__.'/../acme/lib/'], + 'bar\\lib\\' => [__DIR__.'/../bar/lib/'], 'fcy\\lib\\' => [__DIR__.'/../fcy/lib/'], ]; } diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/generate_baseline.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/generate_baseline.phpt new file mode 100644 index 0000000000000..112a02b4c41a0 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/generate_baseline.phpt @@ -0,0 +1,64 @@ +--TEST-- +Test DeprecationErrorHandler in baseline generation mode +--FILE-- +testLegacyFoo(); +$foo->testNonLegacyBar(); +print "Cannot test baselineFile contents because it is generated in a shutdown function registered by another shutdown function." +?> +--EXPECT-- +Cannot test baselineFile contents because it is generated in a shutdown function registered by another shutdown function. diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/lagging_vendor.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/lagging_vendor.phpt index 2f7686fd98819..b5253df4299e4 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/lagging_vendor.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/lagging_vendor.phpt @@ -35,5 +35,5 @@ require __DIR__.'/fake_vendor/acme/outdated-lib/outdated_file.php'; --EXPECTF-- Remaining indirect deprecation notices (1) - 1x: deprecatedApi is deprecated! You should stop relying on it! + 1x: Since acme/lib 3.0: deprecatedApi is deprecated, use deprecatedApi_new instead. 1x in SomeService::deprecatedApi from acme\lib diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/multiple_autoloads.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/multiple_autoloads.phpt index 336001f500113..edf9f4f6f3731 100644 --- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/multiple_autoloads.phpt +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/multiple_autoloads.phpt @@ -38,7 +38,7 @@ require __DIR__.'/fake_vendor_bis/autoload.php'; --EXPECTF-- Remaining direct deprecation notices (2) - 1x: deprecatedApi is deprecated! You should stop relying on it! + 1x: Since acme/lib 3.0: deprecatedApi is deprecated, use deprecatedApi_new instead. 1x in AppService::directDeprecations from App\Services 1x: deprecatedApi from foo is deprecated! You should stop relying on it! diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt new file mode 100644 index 0000000000000..83b135b34bab7 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test DeprecationErrorHandler quiet on everything but indirect deprecations +--FILE-- + +--EXPECTF-- +Unsilenced deprecation notices (3) + +Remaining direct deprecation notices (2) + +Remaining indirect deprecation notices (1) + + 1x: Since acme/lib 3.0: deprecatedApi is deprecated, use deprecatedApi_new instead. + 1x in SomeService::deprecatedApi from acme\lib + +Legacy deprecation notices (2) + diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/quiet_but_failing.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/quiet_but_failing.phpt new file mode 100644 index 0000000000000..8d8f8b4ff490d --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/quiet_but_failing.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test DeprecationErrorHandler when failing and not verbose +--FILE-- + +--EXPECTF-- +Remaining indirect deprecation notices (1) + + 1x: Since acme/lib 3.0: deprecatedApi is deprecated, use deprecatedApi_new instead. + 1x in SomeService::deprecatedApi from acme\lib diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/trigger_deprecation_types.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/trigger_deprecation_types.phpt new file mode 100644 index 0000000000000..261b6ec83f675 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/trigger_deprecation_types.phpt @@ -0,0 +1,58 @@ +--TEST-- +Test deprecation types with trigger_deprecation +--FILE-- +selfDeprecation(true); +(new \App\Services\AppService())->directDeprecation(true); +(new \App\Services\AppService())->indirectDeprecation(true); +trigger_deprecation('foo/bar', '2.0', 'func is deprecated, use new instead.'); +?> +--EXPECTF-- +Remaining self deprecation notices (1) + + 1x: Since App 3.0: selfDeprecation is deprecated, use selfDeprecation_new instead. + 1x in AppService::selfDeprecation from App\Services + +Remaining direct deprecation notices (1) + + 1x: Since acme/lib 3.0: deprecatedApi is deprecated, use deprecatedApi_new instead. + 1x in AppService::directDeprecation from App\Services + +Remaining indirect deprecation notices (1) + + 1x: Since bar/lib 3.0: deprecatedApi is deprecated, use deprecatedApi_new instead. + 1x in AppService::indirectDeprecation from App\Services + +Other deprecation notices (1) + + 1x: Since foo/bar 2.0: func is deprecated, use new instead. diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/trigger_error_types.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/trigger_error_types.phpt new file mode 100644 index 0000000000000..4dd6bdaed9f0b --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/trigger_error_types.phpt @@ -0,0 +1,58 @@ +--TEST-- +Test deprecation types with trigger_error +--FILE-- +selfDeprecation(); +(new \App\Services\AppService())->directDeprecation(); +(new \App\Services\AppService())->indirectDeprecation(); +@trigger_error('Since foo/bar 2.0: func is deprecated, use new instead.', E_USER_DEPRECATED); +?> +--EXPECTF-- +Remaining self deprecation notices (1) + + 1x: Since App 3.0: selfDeprecation is deprecated, use selfDeprecation_new instead. + 1x in AppService::selfDeprecation from App\Services + +Remaining direct deprecation notices (1) + + 1x: Since acme/lib 3.0: deprecatedApi is deprecated, use deprecatedApi_new instead. + 1x in AppService::directDeprecation from App\Services + +Remaining indirect deprecation notices (1) + + 1x: Since bar/lib 3.0: deprecatedApi is deprecated, use deprecatedApi_new instead. + 1x in AppService::indirectDeprecation from App\Services + +Other deprecation notices (1) + + 1x: Since foo/bar 2.0: func is deprecated, use new instead. diff --git a/src/Symfony/Bridge/PhpUnit/Tests/ExpectDeprecationTraitTest.php b/src/Symfony/Bridge/PhpUnit/Tests/ExpectDeprecationTraitTest.php new file mode 100644 index 0000000000000..5e6350e673101 --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/ExpectDeprecationTraitTest.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; + +final class ExpectDeprecationTraitTest extends TestCase +{ + use ExpectDeprecationTrait; + + /** + * Do not remove this test in the next major version. + * + * @group legacy + */ + public function testOne() + { + $this->expectDeprecation('foo'); + @trigger_error('foo', \E_USER_DEPRECATED); + } + + /** + * Do not remove this test in the next major version. + * + * @group legacy + * @runInSeparateProcess + */ + public function testOneInIsolation() + { + $this->expectDeprecation('foo'); + @trigger_error('foo', \E_USER_DEPRECATED); + } + + /** + * Do not remove this test in the next major version. + * + * @group legacy + */ + public function testMany() + { + $this->expectDeprecation('foo'); + $this->expectDeprecation('bar'); + @trigger_error('foo', \E_USER_DEPRECATED); + @trigger_error('bar', \E_USER_DEPRECATED); + } + + /** + * Do not remove this test in the next major version. + * + * @group legacy + * + * @expectedDeprecation foo + */ + public function testOneWithAnnotation() + { + $this->expectDeprecation('bar'); + @trigger_error('foo', \E_USER_DEPRECATED); + @trigger_error('bar', \E_USER_DEPRECATED); + } + + /** + * Do not remove this test in the next major version. + * + * @group legacy + * + * @expectedDeprecation foo + * @expectedDeprecation bar + */ + public function testManyWithAnnotation() + { + $this->expectDeprecation('ccc'); + $this->expectDeprecation('fcy'); + @trigger_error('foo', \E_USER_DEPRECATED); + @trigger_error('bar', \E_USER_DEPRECATED); + @trigger_error('ccc', \E_USER_DEPRECATED); + @trigger_error('fcy', \E_USER_DEPRECATED); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Tests/FailTests/ExpectDeprecationTraitTestFail.php b/src/Symfony/Bridge/PhpUnit/Tests/FailTests/ExpectDeprecationTraitTestFail.php new file mode 100644 index 0000000000000..ba35b268deebe --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/FailTests/ExpectDeprecationTraitTestFail.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\PhpUnit\Tests\FailTests; + +use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; + +/** + * Class ExpectDeprecationTraitTestFail. + * + * This class is deliberately suffixed with *TestFail.php so that it is ignored + * by PHPUnit. This test is designed to fail. See ../expectdeprecationfail.phpt. + */ +final class ExpectDeprecationTraitTestFail extends TestCase +{ + use ExpectDeprecationTrait; + + /** + * Do not remove this test in the next major version. + * + * @group legacy + */ + public function testOne() + { + $this->expectDeprecation('foo'); + @trigger_error('bar', \E_USER_DEPRECATED); + } + + /** + * Do not remove this test in the next major version. + * + * @group legacy + * @runInSeparateProcess + */ + public function testOneInIsolation() + { + $this->expectDeprecation('foo'); + @trigger_error('bar', \E_USER_DEPRECATED); + } +} diff --git a/src/Symfony/Bridge/PhpUnit/Tests/expectdeprecationfail.phpt b/src/Symfony/Bridge/PhpUnit/Tests/expectdeprecationfail.phpt new file mode 100644 index 0000000000000..9f9bf8c17508e --- /dev/null +++ b/src/Symfony/Bridge/PhpUnit/Tests/expectdeprecationfail.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test ExpectDeprecationTrait failing tests +--FILE-- + +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +%ATesting Symfony\Bridge\PhpUnit\Tests\FailTests\ExpectDeprecationTraitTestFail +FF 2 / 2 (100%) + +Time: %s, Memory: %s + +There were 2 failures: + +1) Symfony\Bridge\PhpUnit\Tests\FailTests\ExpectDeprecationTraitTestFail::testOne +Failed asserting that string matches format description. +--- Expected ++++ Actual +@@ @@ + @expectedDeprecation: +-%A foo ++ bar + +2) Symfony\Bridge\PhpUnit\Tests\FailTests\ExpectDeprecationTraitTestFail::testOneInIsolation +Failed asserting that string matches format description. +--- Expected ++++ Actual +@@ @@ + @expectedDeprecation: +-%A foo ++ bar + +FAILURES! +Tests: 2, Assertions: 2, Failures: 2. diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php index 4dba98105762c..a28ee544787d4 100644 --- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php +++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php @@ -113,6 +113,12 @@ $PHPUNIT_VERSION = '4.8'; } +$MAX_PHPUNIT_VERSION = $getEnvVar('SYMFONY_MAX_PHPUNIT_VERSION', false); + +if ($MAX_PHPUNIT_VERSION && version_compare($MAX_PHPUNIT_VERSION, $PHPUNIT_VERSION, '<')) { + $PHPUNIT_VERSION = $MAX_PHPUNIT_VERSION; +} + $PHPUNIT_REMOVE_RETURN_TYPEHINT = filter_var($getEnvVar('SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT', '0'), \FILTER_VALIDATE_BOOLEAN); $COMPOSER_JSON = getenv('COMPOSER') ?: 'composer.json'; @@ -137,6 +143,7 @@ 'COMPOSER' => 'composer.json', 'COMPOSER_VENDOR_DIR' => 'vendor', 'COMPOSER_BIN_DIR' => 'bin', + 'SYMFONY_SIMPLE_PHPUNIT_BIN_DIR' => __DIR__, ]; foreach ($defaultEnvs as $envName => $envValue) { diff --git a/src/Symfony/Bridge/PhpUnit/composer.json b/src/Symfony/Bridge/PhpUnit/composer.json index 54cb26cf70164..2d7c04040127f 100644 --- a/src/Symfony/Bridge/PhpUnit/composer.json +++ b/src/Symfony/Bridge/PhpUnit/composer.json @@ -21,6 +21,7 @@ "php": ">=5.5.9" }, "require-dev": { + "symfony/deprecation-contracts": "^2.1", "symfony/error-handler": "^4.4|^5.0" }, "suggest": { diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php index 7f5aa8ab51d86..75fa047741638 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/Instantiator/RuntimeInstantiator.php @@ -38,7 +38,7 @@ public function __construct() /** * {@inheritdoc} */ - public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator) + public function instantiateProxy(ContainerInterface $container, Definition $definition, string $id, callable $realInstantiator) { return $this->factory->createProxy( $this->factory->getGenerator()->getProxifiedClass($definition), diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index 599fa7c6ec404..a4ce339a7c5f5 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -47,7 +47,7 @@ public function isProxyCandidate(Definition $definition): bool /** * {@inheritdoc} */ - public function getProxyFactoryCode(Definition $definition, $id, $factoryCode = null): string + public function getProxyFactoryCode(Definition $definition, string $id, string $factoryCode): string { $instantiation = 'return'; @@ -55,10 +55,6 @@ public function getProxyFactoryCode(Definition $definition, $id, $factoryCode = $instantiation .= sprintf(' $this->%s[%s] =', $definition->isPublic() && !$definition->isPrivate() ? 'services' : 'privates', var_export($id, true)); } - if (null === $factoryCode) { - throw new \InvalidArgumentException(sprintf('Missing factory code to construct the service "%s".', $id)); - } - $proxyClass = $this->getProxyClassName($definition); return <<expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Missing factory code to construct the service "foo".'); - $definition = new Definition(__CLASS__); - $definition->setLazy(true); - $this->dumper->getProxyFactoryCode($definition, 'foo'); - } - public function testGetProxyFactoryCodeForInterface() { $class = DummyClass::class; diff --git a/src/Symfony/Bridge/ProxyManager/composer.json b/src/Symfony/Bridge/ProxyManager/composer.json index c96e2b7b772fc..145ac6880f828 100644 --- a/src/Symfony/Bridge/ProxyManager/composer.json +++ b/src/Symfony/Bridge/ProxyManager/composer.json @@ -16,13 +16,13 @@ } ], "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", "composer/package-versions-deprecated": "^1.8", "friendsofphp/proxy-manager-lts": "^1.0.2", - "symfony/dependency-injection": "^4.0|^5.0" + "symfony/dependency-injection": "^5.0" }, "require-dev": { - "symfony/config": "^3.4|^4.0|^5.0" + "symfony/config": "^4.4|^5.0" }, "autoload": { "psr-4": { "Symfony\\Bridge\\ProxyManager\\": "" }, diff --git a/src/Symfony/Bridge/Twig/AppVariable.php b/src/Symfony/Bridge/Twig/AppVariable.php index 4a22265908b42..f5a6494ed29bc 100644 --- a/src/Symfony/Bridge/Twig/AppVariable.php +++ b/src/Symfony/Bridge/Twig/AppVariable.php @@ -39,14 +39,14 @@ public function setRequestStack(RequestStack $requestStack) $this->requestStack = $requestStack; } - public function setEnvironment($environment) + public function setEnvironment(string $environment) { $this->environment = $environment; } - public function setDebug($debug) + public function setDebug(bool $debug) { - $this->debug = (bool) $debug; + $this->debug = $debug; } /** diff --git a/src/Symfony/Bridge/Twig/CHANGELOG.md b/src/Symfony/Bridge/Twig/CHANGELOG.md index 71a30ae880d78..d44edb22fc923 100644 --- a/src/Symfony/Bridge/Twig/CHANGELOG.md +++ b/src/Symfony/Bridge/Twig/CHANGELOG.md @@ -1,12 +1,33 @@ CHANGELOG ========= +5.2.0 +----- + + * added the `impersonation_exit_url()` and `impersonation_exit_path()` functions. They return a URL that allows to switch back to the original user. + * added the `workflow_transition()` function to easily retrieve a specific transition object + * added support for translating `TranslatableInterface` objects + * added the `t()` function to easily create `TranslatableMessage` objects + * Added support for extracting messages from the `t()` function + * Added `field_*` Twig functions to access string values from Form fields + * changed the `importance` context option of `NotificationEmail` to allow `null` + +5.0.0 +----- + + * removed `TwigEngine` class, use `\Twig\Environment` instead. + * removed `transChoice` filter and token + * `HttpFoundationExtension` requires a `UrlHelper` on instantiation + * removed support for implicit STDIN usage in the `lint:twig` command, use `lint:twig -` (append a dash) instead to make it explicit. + * added form theme for Foundation 6 + * added support for Foundation 6 switches: add the `switch-input` class to the attributes of a `CheckboxType` + 4.4.0 ----- * added a new `TwigErrorRenderer` for `html` format, integrated with the `ErrorHandler` component * marked all classes extending twig as `@final` - * deprecated to pass `$rootDir` and `$fileLinkFormatter` as 5th and 6th argument respectively to the + * deprecated to pass `$rootDir` and `$fileLinkFormatter` as 5th and 6th argument respectively to the `DebugCommand::__construct()` method, swap the variables position. * the `LintCommand` lints all the templates stored in all configured Twig paths if none argument is provided * deprecated accepting STDIN implicitly when using the `lint:twig` command, use `lint:twig -` (append a dash) instead to make it explicit. @@ -19,7 +40,7 @@ CHANGELOG * added the `form_parent()` function that allows to reliably retrieve the parent form in Twig templates * added the `workflow_transition_blockers()` function - * deprecated the `$requestStack` and `$requestContext` arguments of the + * deprecated the `$requestStack` and `$requestContext` arguments of the `HttpFoundationExtension`, pass a `Symfony\Component\HttpFoundation\UrlHelper` instance as the only argument instead diff --git a/src/Symfony/Bridge/Twig/Command/DebugCommand.php b/src/Symfony/Bridge/Twig/Command/DebugCommand.php index 966532b422f43..1b1bf7a7c34b2 100644 --- a/src/Symfony/Bridge/Twig/Command/DebugCommand.php +++ b/src/Symfony/Bridge/Twig/Command/DebugCommand.php @@ -38,15 +38,10 @@ class DebugCommand extends Command private $projectDir; private $bundlesMetadata; private $twigDefaultPath; - private $rootDir; private $filesystemLoaders; private $fileLinkFormatter; - /** - * @param FileLinkFormatter|null $fileLinkFormatter - * @param string|null $rootDir - */ - public function __construct(Environment $twig, string $projectDir = null, array $bundlesMetadata = [], string $twigDefaultPath = null, $fileLinkFormatter = null, $rootDir = null) + public function __construct(Environment $twig, string $projectDir = null, array $bundlesMetadata = [], string $twigDefaultPath = null, FileLinkFormatter $fileLinkFormatter = null) { parent::__construct(); @@ -54,16 +49,7 @@ public function __construct(Environment $twig, string $projectDir = null, array $this->projectDir = $projectDir; $this->bundlesMetadata = $bundlesMetadata; $this->twigDefaultPath = $twigDefaultPath; - - if (\is_string($fileLinkFormatter) || $rootDir instanceof FileLinkFormatter) { - @trigger_error(sprintf('Passing a string as "$fileLinkFormatter" 5th argument or an instance of FileLinkFormatter as "$rootDir" 6th argument of the "%s()" method is deprecated since Symfony 4.4, swap the variables position.', __METHOD__), \E_USER_DEPRECATED); - - $this->rootDir = $fileLinkFormatter; - $this->fileLinkFormatter = $rootDir; - } else { - $this->fileLinkFormatter = $fileLinkFormatter; - $this->rootDir = $rootDir; - } + $this->fileLinkFormatter = $fileLinkFormatter; } protected function configure() @@ -405,22 +391,6 @@ private function findWrongBundleOverrides(): array $alternatives = []; $bundleNames = []; - if ($this->rootDir && $this->projectDir) { - $folders = glob($this->rootDir.'/Resources/*/views', \GLOB_ONLYDIR); - $relativePath = ltrim(substr($this->rootDir.\DIRECTORY_SEPARATOR.'Resources/', \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); - $bundleNames = array_reduce($folders, function ($carry, $absolutePath) use ($relativePath) { - if (0 === strpos($absolutePath, $this->projectDir)) { - $name = basename(\dirname($absolutePath)); - $path = ltrim($relativePath.$name, \DIRECTORY_SEPARATOR); - $carry[$name] = $path; - - @trigger_error(sprintf('Loading Twig templates from the "%s" directory is deprecated since Symfony 4.2, use "%s" instead.', $absolutePath, $this->twigDefaultPath.'/bundles/'.$name), \E_USER_DEPRECATED); - } - - return $carry; - }, $bundleNames); - } - if ($this->twigDefaultPath && $this->projectDir) { $folders = glob($this->twigDefaultPath.'/bundles/*', \GLOB_ONLYDIR); $relativePath = ltrim(substr($this->twigDefaultPath.'/bundles/', \strlen($this->projectDir)), \DIRECTORY_SEPARATOR); diff --git a/src/Symfony/Bridge/Twig/Command/LintCommand.php b/src/Symfony/Bridge/Twig/Command/LintCommand.php index 9dcbf4964e228..2e3befb5aa0e2 100644 --- a/src/Symfony/Bridge/Twig/Command/LintCommand.php +++ b/src/Symfony/Bridge/Twig/Command/LintCommand.php @@ -85,13 +85,6 @@ protected function execute(InputInterface $input, OutputInterface $output) } if (!$filenames) { - // @deprecated to be removed in 5.0 - if (0 === ftell(\STDIN)) { - @trigger_error('Piping content from STDIN to the "lint:twig" command without passing the dash symbol "-" as argument is deprecated since Symfony 4.4.', \E_USER_DEPRECATED); - - return $this->display($input, $output, $io, [$this->validate(file_get_contents('php://stdin'), uniqid('sf_', true))]); - } - $loader = $this->twig->getLoader(); if ($loader instanceof FilesystemLoader) { $paths = []; @@ -144,7 +137,7 @@ private function getFilesInfo(array $filenames): array return $filesInfo; } - protected function findFiles($filename) + protected function findFiles(string $filename) { if (is_file($filename)) { return [$filename]; diff --git a/src/Symfony/Bridge/Twig/DataCollector/TwigDataCollector.php b/src/Symfony/Bridge/Twig/DataCollector/TwigDataCollector.php index fd6bc2d1e2663..be432838ff45a 100644 --- a/src/Symfony/Bridge/Twig/DataCollector/TwigDataCollector.php +++ b/src/Symfony/Bridge/Twig/DataCollector/TwigDataCollector.php @@ -26,7 +26,7 @@ * * @author Fabien Potencier * - * @final since Symfony 4.4 + * @final */ class TwigDataCollector extends DataCollector implements LateDataCollectorInterface { @@ -42,10 +42,8 @@ public function __construct(Profile $profile, Environment $twig = null) /** * {@inheritdoc} - * - * @param \Throwable|null $exception */ - public function collect(Request $request, Response $response/*, \Throwable $exception = null*/) + public function collect(Request $request, Response $response, \Throwable $exception = null) { } diff --git a/src/Symfony/Bridge/Twig/ErrorRenderer/TwigErrorRenderer.php b/src/Symfony/Bridge/Twig/ErrorRenderer/TwigErrorRenderer.php index 1f5caee4ee5c7..b0ccd684e8b6f 100644 --- a/src/Symfony/Bridge/Twig/ErrorRenderer/TwigErrorRenderer.php +++ b/src/Symfony/Bridge/Twig/ErrorRenderer/TwigErrorRenderer.php @@ -16,8 +16,6 @@ use Symfony\Component\ErrorHandler\Exception\FlattenException; use Symfony\Component\HttpFoundation\RequestStack; use Twig\Environment; -use Twig\Error\LoaderError; -use Twig\Loader\ExistsLoaderInterface; /** * Provides the ability to render custom Twig-based HTML error pages @@ -37,7 +35,7 @@ class TwigErrorRenderer implements ErrorRendererInterface public function __construct(Environment $twig, HtmlErrorRenderer $fallbackErrorRenderer = null, $debug = false) { if (!\is_bool($debug) && !\is_callable($debug)) { - throw new \TypeError(sprintf('Argument 3 passed to "%s()" must be a boolean or a callable, "%s" given.', __METHOD__, \is_object($debug) ? \get_class($debug) : \gettype($debug))); + throw new \TypeError(sprintf('Argument 3 passed to "%s()" must be a boolean or a callable, "%s" given.', __METHOD__, get_debug_type($debug))); } $this->twig = $twig; @@ -58,7 +56,6 @@ public function render(\Throwable $exception): FlattenException } return $exception->setAsString($this->twig->render($template, [ - 'legacy' => false, // to be removed in 5.0 'exception' => $exception, 'status_code' => $exception->getStatusCode(), 'status_text' => $exception->getStatusText(), @@ -79,39 +76,15 @@ public static function isDebug(RequestStack $requestStack, bool $debug): \Closur private function findTemplate(int $statusCode): ?string { $template = sprintf('@Twig/Exception/error%s.html.twig', $statusCode); - if ($this->templateExists($template)) { + if ($this->twig->getLoader()->exists($template)) { return $template; } $template = '@Twig/Exception/error.html.twig'; - if ($this->templateExists($template)) { + if ($this->twig->getLoader()->exists($template)) { return $template; } return null; } - - /** - * To be removed in 5.0. - * - * Use instead: - * - * $this->twig->getLoader()->exists($template) - */ - private function templateExists(string $template): bool - { - $loader = $this->twig->getLoader(); - if ($loader instanceof ExistsLoaderInterface || method_exists($loader, 'exists')) { - return $loader->exists($template); - } - - try { - $loader->getSourceContext($template); - - return true; - } catch (LoaderError $e) { - } - - return false; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/AssetExtension.php b/src/Symfony/Bridge/Twig/Extension/AssetExtension.php index 62e7b91cb2db6..694821f7bf6b8 100644 --- a/src/Symfony/Bridge/Twig/Extension/AssetExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/AssetExtension.php @@ -19,10 +19,8 @@ * Twig extension for the Symfony Asset component. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class AssetExtension extends AbstractExtension +final class AssetExtension extends AbstractExtension { private $packages; @@ -33,10 +31,8 @@ public function __construct(Packages $packages) /** * {@inheritdoc} - * - * @return TwigFunction[] */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('asset', [$this, 'getAssetUrl']), @@ -49,37 +45,17 @@ public function getFunctions() * * If the package used to generate the path is an instance of * UrlPackage, you will always get a URL and not a path. - * - * @param string $path A public path - * @param string $packageName The name of the asset package to use - * - * @return string The public path of the asset */ - public function getAssetUrl($path, $packageName = null) + public function getAssetUrl(string $path, string $packageName = null): string { return $this->packages->getUrl($path, $packageName); } /** * Returns the version of an asset. - * - * @param string $path A public path - * @param string $packageName The name of the asset package to use - * - * @return string The asset version */ - public function getAssetVersion($path, $packageName = null) + public function getAssetVersion(string $path, string $packageName = null): string { return $this->packages->getVersion($path, $packageName); } - - /** - * Returns the name of the extension. - * - * @return string The extension name - */ - public function getName() - { - return 'asset'; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php index 7f60b542bff40..7acf75fb9c17a 100644 --- a/src/Symfony/Bridge/Twig/Extension/CodeExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/CodeExtension.php @@ -19,10 +19,8 @@ * Twig extension relate to PHP code and used by the profiler and the default exception templates. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class CodeExtension extends AbstractExtension +final class CodeExtension extends AbstractExtension { private $fileLinkFormat; private $charset; @@ -30,8 +28,6 @@ class CodeExtension extends AbstractExtension /** * @param string|FileLinkFormatter $fileLinkFormat The format for links to source files - * @param string $projectDir The project directory - * @param string $charset The charset */ public function __construct($fileLinkFormat, string $projectDir, string $charset) { @@ -42,10 +38,8 @@ public function __construct($fileLinkFormat, string $projectDir, string $charset /** * {@inheritdoc} - * - * @return TwigFilter[] */ - public function getFilters() + public function getFilters(): array { return [ new TwigFilter('abbr_class', [$this, 'abbrClass'], ['is_safe' => ['html']]), @@ -61,7 +55,7 @@ public function getFilters() ]; } - public function abbrClass($class) + public function abbrClass(string $class): string { $parts = explode('\\', $class); $short = array_pop($parts); @@ -69,7 +63,7 @@ public function abbrClass($class) return sprintf('%s', $class, $short); } - public function abbrMethod($method) + public function abbrMethod(string $method): string { if (false !== strpos($method, '::')) { [$class, $method] = explode('::', $method, 2); @@ -85,12 +79,8 @@ public function abbrMethod($method) /** * Formats an array as a string. - * - * @param array $args The argument array - * - * @return string */ - public function formatArgs($args) + public function formatArgs(array $args): string { $result = []; foreach ($args as $key => $item) { @@ -118,26 +108,16 @@ public function formatArgs($args) /** * Formats an array as a string. - * - * @param array $args The argument array - * - * @return string */ - public function formatArgsAsText($args) + public function formatArgsAsText(array $args): string { return strip_tags($this->formatArgs($args)); } /** * Returns an excerpt of a code file around the given line number. - * - * @param string $file A file path - * @param int $line The selected line number - * @param int $srcContext The number of displayed lines around or -1 for the whole file - * - * @return string An HTML string */ - public function fileExcerpt($file, $line, $srcContext = 3) + public function fileExcerpt(string $file, int $line, int $srcContext = 3): ?string { if (is_file($file) && is_readable($file)) { // highlight_file could throw warnings @@ -168,14 +148,8 @@ public function fileExcerpt($file, $line, $srcContext = 3) /** * Formats a file path. - * - * @param string $file An absolute file path - * @param int $line The line number - * @param string $text Use this text for the link rather than the file path - * - * @return string */ - public function formatFile($file, $line, $text = null) + public function formatFile(string $file, int $line, string $text = null): string { $file = trim($file); @@ -201,12 +175,9 @@ public function formatFile($file, $line, $text = null) /** * Returns the link for a given file/line pair. * - * @param string $file An absolute file path - * @param int $line The line number - * * @return string|false A link or false */ - public function getFileLink($file, $line) + public function getFileLink(string $file, int $line) { if ($fmt = $this->fileLinkFormat) { return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : $fmt->format($file, $line); @@ -226,7 +197,7 @@ public function getFileRelative(string $file): ?string return null; } - public function formatFileFromText($text) + public function formatFileFromText(string $text): string { return preg_replace_callback('/in ("|")?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) { return 'in '.$this->formatFile($match[2], $match[3]); @@ -254,15 +225,7 @@ public function formatLogMessage(string $message, array $context): string return htmlspecialchars($message, \ENT_COMPAT | \ENT_SUBSTITUTE, $this->charset); } - /** - * {@inheritdoc} - */ - public function getName() - { - return 'code'; - } - - protected static function fixCodeMarkup($line) + protected static function fixCodeMarkup(string $line): string { // ending tag from previous line $opening = strpos($line, ' * @author Titouan Galopin - * - * @final since Symfony 4.4 */ -class CsrfExtension extends AbstractExtension +final class CsrfExtension extends AbstractExtension { /** * {@inheritdoc} diff --git a/src/Symfony/Bridge/Twig/Extension/CsrfRuntime.php b/src/Symfony/Bridge/Twig/Extension/CsrfRuntime.php index ea857c7ed583b..c3d5da6470c25 100644 --- a/src/Symfony/Bridge/Twig/Extension/CsrfRuntime.php +++ b/src/Symfony/Bridge/Twig/Extension/CsrfRuntime.php @@ -16,10 +16,8 @@ /** * @author Christian Flothmann * @author Titouan Galopin - * - * @final since Symfony 4.4 */ -class CsrfRuntime +final class CsrfRuntime { private $csrfTokenManager; diff --git a/src/Symfony/Bridge/Twig/Extension/DumpExtension.php b/src/Symfony/Bridge/Twig/Extension/DumpExtension.php index 8937c890e3a99..46ad8eaf679c2 100644 --- a/src/Symfony/Bridge/Twig/Extension/DumpExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/DumpExtension.php @@ -17,17 +17,14 @@ use Twig\Environment; use Twig\Extension\AbstractExtension; use Twig\Template; -use Twig\TokenParser\TokenParserInterface; use Twig\TwigFunction; /** * Provides integration of the dump() function with Twig. * * @author Nicolas Grekas - * - * @final since Symfony 4.4 */ -class DumpExtension extends AbstractExtension +final class DumpExtension extends AbstractExtension { private $cloner; private $dumper; @@ -39,9 +36,9 @@ public function __construct(ClonerInterface $cloner, HtmlDumper $dumper = null) } /** - * @return TwigFunction[] + * {@inheritdoc} */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('dump', [$this, 'dump'], ['is_safe' => ['html'], 'needs_context' => true, 'needs_environment' => true]), @@ -49,19 +46,14 @@ public function getFunctions() } /** - * @return TokenParserInterface[] + * {@inheritdoc} */ - public function getTokenParsers() + public function getTokenParsers(): array { return [new DumpTokenParser()]; } - public function getName() - { - return 'dump'; - } - - public function dump(Environment $env, $context) + public function dump(Environment $env, array $context): ?string { if (!$env->isDebug()) { return null; diff --git a/src/Symfony/Bridge/Twig/Extension/ExpressionExtension.php b/src/Symfony/Bridge/Twig/Extension/ExpressionExtension.php index af7be97c4f9bd..8d2a35c99f682 100644 --- a/src/Symfony/Bridge/Twig/Extension/ExpressionExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/ExpressionExtension.php @@ -19,35 +19,21 @@ * ExpressionExtension gives a way to create Expressions from a template. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class ExpressionExtension extends AbstractExtension +final class ExpressionExtension extends AbstractExtension { /** * {@inheritdoc} - * - * @return TwigFunction[] */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('expression', [$this, 'createExpression']), ]; } - public function createExpression($expression) + public function createExpression(string $expression): Expression { return new Expression($expression); } - - /** - * Returns the name of the extension. - * - * @return string The extension name - */ - public function getName() - { - return 'expression'; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/FormExtension.php b/src/Symfony/Bridge/Twig/Extension/FormExtension.php index 174a5cc3fe4bb..7f0b1ed597e36 100644 --- a/src/Symfony/Bridge/Twig/Extension/FormExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/FormExtension.php @@ -12,10 +12,12 @@ namespace Symfony\Bridge\Twig\Extension; use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser; +use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView; use Symfony\Component\Form\ChoiceList\View\ChoiceView; +use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormView; +use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Extension\AbstractExtension; -use Twig\TokenParser\TokenParserInterface; use Twig\TwigFilter; use Twig\TwigFunction; use Twig\TwigTest; @@ -25,17 +27,20 @@ * * @author Fabien Potencier * @author Bernhard Schussek - * - * @final since Symfony 4.4 */ -class FormExtension extends AbstractExtension +final class FormExtension extends AbstractExtension { + private $translator; + + public function __construct(TranslatorInterface $translator = null) + { + $this->translator = $translator; + } + /** * {@inheritdoc} - * - * @return TokenParserInterface[] */ - public function getTokenParsers() + public function getTokenParsers(): array { return [ // {% form_theme form "SomeBundle::widgets.twig" %} @@ -45,10 +50,8 @@ public function getTokenParsers() /** * {@inheritdoc} - * - * @return TwigFunction[] */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('form_widget', null, ['node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', 'is_safe' => ['html']]), @@ -62,15 +65,19 @@ public function getFunctions() new TwigFunction('form_end', null, ['node_class' => 'Symfony\Bridge\Twig\Node\RenderBlockNode', 'is_safe' => ['html']]), new TwigFunction('csrf_token', ['Symfony\Component\Form\FormRenderer', 'renderCsrfToken']), new TwigFunction('form_parent', 'Symfony\Bridge\Twig\Extension\twig_get_form_parent'), + new TwigFunction('field_name', [$this, 'getFieldName']), + new TwigFunction('field_value', [$this, 'getFieldValue']), + new TwigFunction('field_label', [$this, 'getFieldLabel']), + new TwigFunction('field_help', [$this, 'getFieldHelp']), + new TwigFunction('field_errors', [$this, 'getFieldErrors']), + new TwigFunction('field_choices', [$this, 'getFieldChoices']), ]; } /** * {@inheritdoc} - * - * @return TwigFilter[] */ - public function getFilters() + public function getFilters(): array { return [ new TwigFilter('humanize', ['Symfony\Component\Form\FormRenderer', 'humanize']), @@ -80,10 +87,8 @@ public function getFilters() /** * {@inheritdoc} - * - * @return TwigTest[] */ - public function getTests() + public function getTests(): array { return [ new TwigTest('selectedchoice', 'Symfony\Bridge\Twig\Extension\twig_is_selected_choice'), @@ -91,12 +96,91 @@ public function getTests() ]; } + public function getFieldName(FormView $view): string + { + $view->setRendered(); + + return $view->vars['full_name']; + } + /** - * {@inheritdoc} + * @return string|array */ - public function getName() + public function getFieldValue(FormView $view) { - return 'form'; + return $view->vars['value']; + } + + public function getFieldLabel(FormView $view): ?string + { + if (false === $label = $view->vars['label']) { + return null; + } + + if (!$label && $labelFormat = $view->vars['label_format']) { + $label = str_replace(['%id%', '%name%'], [$view->vars['id'], $view->vars['name']], $labelFormat); + } elseif (!$label) { + $label = ucfirst(strtolower(trim(preg_replace(['/([A-Z])/', '/[_\s]+/'], ['_$1', ' '], $view->vars['name'])))); + } + + return $this->createFieldTranslation( + $label, + $view->vars['label_translation_parameters'] ?: [], + $view->vars['translation_domain'] + ); + } + + public function getFieldHelp(FormView $view): ?string + { + return $this->createFieldTranslation( + $view->vars['help'], + $view->vars['help_translation_parameters'] ?: [], + $view->vars['translation_domain'] + ); + } + + /** + * @return string[] + */ + public function getFieldErrors(FormView $view): iterable + { + /** @var FormError $error */ + foreach ($view->vars['errors'] as $error) { + yield $error->getMessage(); + } + } + + /** + * @return string[]|string[][] + */ + public function getFieldChoices(FormView $view): iterable + { + yield from $this->createFieldChoicesList($view->vars['choices'], $view->vars['choice_translation_domain']); + } + + private function createFieldChoicesList(iterable $choices, $translationDomain): iterable + { + foreach ($choices as $choice) { + $translatableLabel = $this->createFieldTranslation($choice->label, [], $translationDomain); + + if ($choice instanceof ChoiceGroupView) { + yield $translatableLabel => $this->createFieldChoicesList($choice, $translationDomain); + + continue; + } + + /* @var ChoiceView $choice */ + yield $translatableLabel => $choice->value; + } + } + + private function createFieldTranslation(?string $value, array $parameters, $domain): ?string + { + if (!$this->translator || !$value || false === $domain) { + return $value; + } + + return $this->translator->trans($value, $parameters, $domain); } } @@ -107,8 +191,6 @@ public function getName() * * @param string|array $selectedValue The selected value to compare * - * @return bool Whether the choice is selected - * * @see ChoiceView::isSelected() */ function twig_is_selected_choice(ChoiceView $choice, $selectedValue): bool diff --git a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php index f3c42482f9d1d..a9ee05c4d0093 100644 --- a/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php @@ -12,9 +12,7 @@ namespace Symfony\Bridge\Twig\Extension; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\UrlHelper; -use Symfony\Component\Routing\RequestContext; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; @@ -22,47 +20,20 @@ * Twig extension for the Symfony HttpFoundation component. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class HttpFoundationExtension extends AbstractExtension +final class HttpFoundationExtension extends AbstractExtension { private $urlHelper; - /** - * @param UrlHelper $urlHelper - */ - public function __construct($urlHelper) + public function __construct(UrlHelper $urlHelper) { - if ($urlHelper instanceof UrlHelper) { - $this->urlHelper = $urlHelper; - - return; - } - - if (!$urlHelper instanceof RequestStack) { - throw new \TypeError(sprintf('The first argument must be an instance of "%s" or an instance of "%s".', UrlHelper::class, RequestStack::class)); - } - - @trigger_error(sprintf('Passing a "%s" instance as the first argument to the "%s" constructor is deprecated since Symfony 4.3, pass a "%s" instance instead.', RequestStack::class, __CLASS__, UrlHelper::class), \E_USER_DEPRECATED); - - $requestContext = null; - if (2 === \func_num_args()) { - $requestContext = func_get_arg(1); - if (null !== $requestContext && !$requestContext instanceof RequestContext) { - throw new \TypeError(sprintf('The second argument must be an instance of "%s".', RequestContext::class)); - } - } - - $this->urlHelper = new UrlHelper($urlHelper, $requestContext); + $this->urlHelper = $urlHelper; } /** * {@inheritdoc} - * - * @return TwigFunction[] */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('absolute_url', [$this, 'generateAbsoluteUrl']), @@ -75,13 +46,9 @@ public function getFunctions() * * This method returns the path unchanged if no request is available. * - * @param string $path The path - * - * @return string The absolute URL - * * @see Request::getUriForPath() */ - public function generateAbsoluteUrl($path) + public function generateAbsoluteUrl(string $path): string { return $this->urlHelper->getAbsoluteUrl($path); } @@ -91,24 +58,10 @@ public function generateAbsoluteUrl($path) * * This method returns the path unchanged if no request is available. * - * @param string $path The path - * - * @return string The relative path - * * @see Request::getRelativeUriForPath() */ - public function generateRelativePath($path) + public function generateRelativePath(string $path): string { return $this->urlHelper->getRelativePath($path); } - - /** - * Returns the name of the extension. - * - * @return string The extension name - */ - public function getName() - { - return 'request'; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php b/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php index 286bc420c66c5..f4b3e4b66953c 100644 --- a/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php @@ -19,15 +19,13 @@ * Provides integration with the HttpKernel component. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class HttpKernelExtension extends AbstractExtension +final class HttpKernelExtension extends AbstractExtension { /** - * @return TwigFunction[] + * {@inheritdoc} */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('render', [HttpKernelRuntime::class, 'renderFragment'], ['is_safe' => ['html']]), @@ -36,16 +34,8 @@ public function getFunctions() ]; } - public static function controller($controller, $attributes = [], $query = []) + public static function controller(string $controller, array $attributes = [], array $query = []): ControllerReference { return new ControllerReference($controller, $attributes, $query); } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'http_kernel'; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/HttpKernelRuntime.php b/src/Symfony/Bridge/Twig/Extension/HttpKernelRuntime.php index edcf8a4dc0e6f..ebc9e4469b558 100644 --- a/src/Symfony/Bridge/Twig/Extension/HttpKernelRuntime.php +++ b/src/Symfony/Bridge/Twig/Extension/HttpKernelRuntime.php @@ -18,10 +18,8 @@ * Provides integration with the HttpKernel component. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class HttpKernelRuntime +final class HttpKernelRuntime { private $handler; @@ -33,14 +31,11 @@ public function __construct(FragmentHandler $handler) /** * Renders a fragment. * - * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance - * @param array $options An array of options - * - * @return string The fragment content + * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance * * @see FragmentHandler::render() */ - public function renderFragment($uri, $options = []) + public function renderFragment($uri, array $options = []): string { $strategy = $options['strategy'] ?? 'inline'; unset($options['strategy']); @@ -51,15 +46,11 @@ public function renderFragment($uri, $options = []) /** * Renders a fragment. * - * @param string $strategy A strategy name - * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance - * @param array $options An array of options - * - * @return string The fragment content + * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance * * @see FragmentHandler::render() */ - public function renderFragmentStrategy($strategy, $uri, $options = []) + public function renderFragmentStrategy(string $strategy, $uri, array $options = []): string { return $this->handler->render($uri, $strategy, $options); } diff --git a/src/Symfony/Bridge/Twig/Extension/LogoutUrlExtension.php b/src/Symfony/Bridge/Twig/Extension/LogoutUrlExtension.php index a6648dc072db1..071b9ff247f1d 100644 --- a/src/Symfony/Bridge/Twig/Extension/LogoutUrlExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/LogoutUrlExtension.php @@ -19,10 +19,8 @@ * LogoutUrlHelper provides generator functions for the logout URL to Twig. * * @author Jeremy Mikola - * - * @final since Symfony 4.4 */ -class LogoutUrlExtension extends AbstractExtension +final class LogoutUrlExtension extends AbstractExtension { private $generator; @@ -33,10 +31,8 @@ public function __construct(LogoutUrlGenerator $generator) /** * {@inheritdoc} - * - * @return TwigFunction[] */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('logout_url', [$this, 'getLogoutUrl']), @@ -48,10 +44,8 @@ public function getFunctions() * Generates the relative logout URL for the firewall. * * @param string|null $key The firewall key or null to use the current firewall key - * - * @return string The relative logout URL */ - public function getLogoutPath($key = null) + public function getLogoutPath(string $key = null): string { return $this->generator->getLogoutPath($key); } @@ -60,19 +54,9 @@ public function getLogoutPath($key = null) * Generates the absolute logout URL for the firewall. * * @param string|null $key The firewall key or null to use the current firewall key - * - * @return string The absolute logout URL */ - public function getLogoutUrl($key = null) + public function getLogoutUrl(string $key = null): string { return $this->generator->getLogoutUrl($key); } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'logout_url'; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/ProfilerExtension.php b/src/Symfony/Bridge/Twig/Extension/ProfilerExtension.php index a46f2cdbb8936..fcc4396f1c9a1 100644 --- a/src/Symfony/Bridge/Twig/Extension/ProfilerExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/ProfilerExtension.php @@ -17,10 +17,8 @@ /** * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class ProfilerExtension extends BaseProfilerExtension +final class ProfilerExtension extends BaseProfilerExtension { private $stopwatch; private $events; @@ -33,10 +31,7 @@ public function __construct(Profile $profile, Stopwatch $stopwatch = null) $this->events = new \SplObjectStorage(); } - /** - * @return void - */ - public function enter(Profile $profile) + public function enter(Profile $profile): void { if ($this->stopwatch && $profile->isTemplate()) { $this->events[$profile] = $this->stopwatch->start($profile->getName(), 'template'); @@ -45,10 +40,7 @@ public function enter(Profile $profile) parent::enter($profile); } - /** - * @return void - */ - public function leave(Profile $profile) + public function leave(Profile $profile): void { parent::leave($profile); @@ -57,12 +49,4 @@ public function leave(Profile $profile) unset($this->events[$profile]); } } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'native_profiler'; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php b/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php index 1ba528546d6d2..800c22f6d4c2c 100644 --- a/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/RoutingExtension.php @@ -22,10 +22,8 @@ * Provides integration of the Routing component with Twig. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class RoutingExtension extends AbstractExtension +final class RoutingExtension extends AbstractExtension { private $generator; @@ -36,10 +34,8 @@ public function __construct(UrlGeneratorInterface $generator) /** * {@inheritdoc} - * - * @return TwigFunction[] */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('url', [$this, 'getUrl'], ['is_safe_callback' => [$this, 'isUrlGenerationSafe']]), @@ -47,26 +43,12 @@ public function getFunctions() ]; } - /** - * @param string $name - * @param array $parameters - * @param bool $relative - * - * @return string - */ - public function getPath($name, $parameters = [], $relative = false) + public function getPath(string $name, array $parameters = [], bool $relative = false): string { return $this->generator->generate($name, $parameters, $relative ? UrlGeneratorInterface::RELATIVE_PATH : UrlGeneratorInterface::ABSOLUTE_PATH); } - /** - * @param string $name - * @param array $parameters - * @param bool $schemeRelative - * - * @return string - */ - public function getUrl($name, $parameters = [], $schemeRelative = false) + public function getUrl(string $name, array $parameters = [], bool $schemeRelative = false): string { return $this->generator->generate($name, $parameters, $schemeRelative ? UrlGeneratorInterface::NETWORK_PATH : UrlGeneratorInterface::ABSOLUTE_URL); } @@ -92,8 +74,6 @@ public function getUrl($name, $parameters = [], $schemeRelative = false) * @param Node $argsNode The arguments of the path/url function * * @return array An array with the contexts the URL is safe - * - * @final */ public function isUrlGenerationSafe(Node $argsNode): array { @@ -110,12 +90,4 @@ public function isUrlGenerationSafe(Node $argsNode): array return []; } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'routing'; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php b/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php index 4acd7bbf9cc72..0e58fc0ec66e4 100644 --- a/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php @@ -14,6 +14,7 @@ use Symfony\Component\Security\Acl\Voter\FieldVote; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException; +use Symfony\Component\Security\Http\Impersonate\ImpersonateUrlGenerator; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; @@ -21,19 +22,23 @@ * SecurityExtension exposes security context features. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class SecurityExtension extends AbstractExtension +final class SecurityExtension extends AbstractExtension { private $securityChecker; - public function __construct(AuthorizationCheckerInterface $securityChecker = null) + private $impersonateUrlGenerator; + + public function __construct(AuthorizationCheckerInterface $securityChecker = null, ImpersonateUrlGenerator $impersonateUrlGenerator = null) { $this->securityChecker = $securityChecker; + $this->impersonateUrlGenerator = $impersonateUrlGenerator; } - public function isGranted($role, $object = null, $field = null) + /** + * @param mixed $object + */ + public function isGranted($role, $object = null, string $field = null): bool { if (null === $this->securityChecker) { return false; @@ -50,23 +55,33 @@ public function isGranted($role, $object = null, $field = null) } } - /** - * {@inheritdoc} - * - * @return TwigFunction[] - */ - public function getFunctions() + public function getImpersonateExitUrl(string $exitTo = null): string { - return [ - new TwigFunction('is_granted', [$this, 'isGranted']), - ]; + if (null === $this->impersonateUrlGenerator) { + return ''; + } + + return $this->impersonateUrlGenerator->generateExitUrl($exitTo); + } + + public function getImpersonateExitPath(string $exitTo = null): string + { + if (null === $this->impersonateUrlGenerator) { + return ''; + } + + return $this->impersonateUrlGenerator->generateExitPath($exitTo); } /** * {@inheritdoc} */ - public function getName() + public function getFunctions(): array { - return 'security'; + return [ + new TwigFunction('is_granted', [$this, 'isGranted']), + new TwigFunction('impersonation_exit_url', [$this, 'getImpersonateExitUrl']), + new TwigFunction('impersonation_exit_path', [$this, 'getImpersonateExitPath']), + ]; } } diff --git a/src/Symfony/Bridge/Twig/Extension/StopwatchExtension.php b/src/Symfony/Bridge/Twig/Extension/StopwatchExtension.php index f4b9a24ced5cd..80a25a949bdb5 100644 --- a/src/Symfony/Bridge/Twig/Extension/StopwatchExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/StopwatchExtension.php @@ -20,10 +20,8 @@ * Twig extension for the stopwatch helper. * * @author Wouter J - * - * @final since Symfony 4.4 */ -class StopwatchExtension extends AbstractExtension +final class StopwatchExtension extends AbstractExtension { private $stopwatch; private $enabled; @@ -34,7 +32,7 @@ public function __construct(Stopwatch $stopwatch = null, bool $enabled = true) $this->enabled = $enabled; } - public function getStopwatch() + public function getStopwatch(): Stopwatch { return $this->stopwatch; } @@ -42,7 +40,7 @@ public function getStopwatch() /** * @return TokenParserInterface[] */ - public function getTokenParsers() + public function getTokenParsers(): array { return [ /* @@ -53,9 +51,4 @@ public function getTokenParsers() new StopwatchTokenParser(null !== $this->stopwatch && $this->enabled), ]; } - - public function getName() - { - return 'stopwatch'; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php b/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php index 96df106307da7..c2797d837aa7f 100644 --- a/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/TranslationExtension.php @@ -13,16 +13,15 @@ use Symfony\Bridge\Twig\NodeVisitor\TranslationDefaultDomainNodeVisitor; use Symfony\Bridge\Twig\NodeVisitor\TranslationNodeVisitor; -use Symfony\Bridge\Twig\TokenParser\TransChoiceTokenParser; use Symfony\Bridge\Twig\TokenParser\TransDefaultDomainTokenParser; use Symfony\Bridge\Twig\TokenParser\TransTokenParser; -use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; +use Symfony\Component\Translation\TranslatableMessage; +use Symfony\Contracts\Translation\TranslatableInterface; use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorTrait; use Twig\Extension\AbstractExtension; -use Twig\NodeVisitor\NodeVisitorInterface; -use Twig\TokenParser\AbstractTokenParser; use Twig\TwigFilter; +use Twig\TwigFunction; // Help opcache.preload discover always-needed symbols class_exists(TranslatorInterface::class); @@ -32,30 +31,19 @@ class_exists(TranslatorTrait::class); * Provides integration of the Translation component with Twig. * * @author Fabien Potencier - * - * @final since Symfony 4.2 */ -class TranslationExtension extends AbstractExtension +final class TranslationExtension extends AbstractExtension { private $translator; private $translationNodeVisitor; - /** - * @param TranslatorInterface|null $translator - */ - public function __construct($translator = null, NodeVisitorInterface $translationNodeVisitor = null) + public function __construct(TranslatorInterface $translator = null, TranslationNodeVisitor $translationNodeVisitor = null) { - if (null !== $translator && !$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) { - throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be an instance of "%s", "%s" given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator))); - } $this->translator = $translator; $this->translationNodeVisitor = $translationNodeVisitor; } - /** - * @return TranslatorInterface|null - */ - public function getTranslator() + public function getTranslator(): TranslatorInterface { if (null === $this->translator) { if (!interface_exists(TranslatorInterface::class)) { @@ -72,33 +60,33 @@ public function getTranslator() /** * {@inheritdoc} - * - * @return TwigFilter[] */ - public function getFilters() + public function getFunctions(): array + { + return [ + new TwigFunction('t', [$this, 'createTranslatable']), + ]; + } + + /** + * {@inheritdoc} + */ + public function getFilters(): array { return [ new TwigFilter('trans', [$this, 'trans']), - new TwigFilter('transchoice', [$this, 'transchoice'], ['deprecated' => '4.2', 'alternative' => 'trans" with parameter "%count%']), ]; } /** - * Returns the token parser instance to add to the existing list. - * - * @return AbstractTokenParser[] + * {@inheritdoc} */ - public function getTokenParsers() + public function getTokenParsers(): array { return [ // {% trans %}Symfony is great!{% endtrans %} new TransTokenParser(), - // {% transchoice count %} - // {0} There is no apples|{1} There is one apple|]1,Inf] There is {{ count }} apples - // {% endtranschoice %} - new TransChoiceTokenParser(), - // {% trans_default_domain "foobar" %} new TransDefaultDomainTokenParser(), ]; @@ -106,21 +94,39 @@ public function getTokenParsers() /** * {@inheritdoc} - * - * @return NodeVisitorInterface[] */ - public function getNodeVisitors() + public function getNodeVisitors(): array { return [$this->getTranslationNodeVisitor(), new TranslationDefaultDomainNodeVisitor()]; } - public function getTranslationNodeVisitor() + public function getTranslationNodeVisitor(): TranslationNodeVisitor { return $this->translationNodeVisitor ?: $this->translationNodeVisitor = new TranslationNodeVisitor(); } - public function trans($message, array $arguments = [], $domain = null, $locale = null, $count = null) + /** + * @param string|\Stringable|TranslatableInterface|null $message + * @param array|string $arguments Can be the locale as a string when $message is a TranslatableInterface + */ + public function trans($message, $arguments = [], string $domain = null, string $locale = null, int $count = null): string { + if ($message instanceof TranslatableInterface) { + if ([] !== $arguments && !\is_string($arguments)) { + throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be a locale passed as a string when the message is a "%s", "%s" given.', __METHOD__, TranslatableInterface::class, get_debug_type($arguments))); + } + + return $message->trans($this->getTranslator(), $locale ?? (\is_string($arguments) ? $arguments : null)); + } + + if (!\is_array($arguments)) { + throw new \TypeError(sprintf('Unless the message is a "%s", argument 2 passed to "%s()" must be an array of parameters, "%s" given.', TranslatableInterface::class, __METHOD__, get_debug_type($arguments))); + } + + if ('' === $message = (string) $message) { + return ''; + } + if (null !== $count) { $arguments['%count%'] = $count; } @@ -128,25 +134,12 @@ public function trans($message, array $arguments = [], $domain = null, $locale = return $this->getTranslator()->trans($message, $arguments, $domain, $locale); } - /** - * @deprecated since Symfony 4.2, use the trans() method instead with a %count% parameter - */ - public function transchoice($message, $count, array $arguments = [], $domain = null, $locale = null) + public function createTranslatable(string $message, array $parameters = [], string $domain = null): TranslatableMessage { - $translator = $this->getTranslator(); - - if ($translator instanceof TranslatorInterface) { - return $translator->trans($message, array_merge(['%count%' => $count], $arguments), $domain, $locale); + if (!class_exists(TranslatableMessage::class)) { + throw new \LogicException(sprintf('You cannot use the "%s" as the Translation Component is not installed. Try running "composer require symfony/translation".', __CLASS__)); } - return $translator->transChoice($message, $count, array_merge(['%count%' => $count], $arguments), $domain, $locale); - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'translator'; + return new TranslatableMessage($message, $parameters, $domain); } } diff --git a/src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php b/src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php index c2c6f8ba8fcf6..4b8217d932f4e 100644 --- a/src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php @@ -21,10 +21,8 @@ * Twig extension for the Symfony WebLink component. * * @author Kévin Dunglas - * - * @final since Symfony 4.4 */ -class WebLinkExtension extends AbstractExtension +final class WebLinkExtension extends AbstractExtension { private $requestStack; @@ -35,10 +33,8 @@ public function __construct(RequestStack $requestStack) /** * {@inheritdoc} - * - * @return TwigFunction[] */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('link', [$this, 'link']), @@ -53,13 +49,12 @@ public function getFunctions() /** * Adds a "Link" HTTP header. * - * @param string $uri The relation URI * @param string $rel The relation type (e.g. "preload", "prefetch", "prerender" or "dns-prefetch") * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]") * * @return string The relation URI */ - public function link($uri, $rel, array $attributes = []) + public function link(string $uri, string $rel, array $attributes = []): string { if (!$request = $this->requestStack->getMasterRequest()) { return $uri; @@ -79,12 +74,11 @@ public function link($uri, $rel, array $attributes = []) /** * Preloads a resource. * - * @param string $uri A public path - * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['crossorigin' => 'use-credentials']") + * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['crossorigin' => 'use-credentials']") * * @return string The path of the asset */ - public function preload($uri, array $attributes = []) + public function preload(string $uri, array $attributes = []): string { return $this->link($uri, 'preload', $attributes); } @@ -92,12 +86,11 @@ public function preload($uri, array $attributes = []) /** * Resolves a resource origin as early as possible. * - * @param string $uri A public path - * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]") + * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]") * * @return string The path of the asset */ - public function dnsPrefetch($uri, array $attributes = []) + public function dnsPrefetch(string $uri, array $attributes = []): string { return $this->link($uri, 'dns-prefetch', $attributes); } @@ -105,12 +98,11 @@ public function dnsPrefetch($uri, array $attributes = []) /** * Initiates a early connection to a resource (DNS resolution, TCP handshake, TLS negotiation). * - * @param string $uri A public path - * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]") + * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]") * * @return string The path of the asset */ - public function preconnect($uri, array $attributes = []) + public function preconnect(string $uri, array $attributes = []): string { return $this->link($uri, 'preconnect', $attributes); } @@ -118,12 +110,11 @@ public function preconnect($uri, array $attributes = []) /** * Indicates to the client that it should prefetch this resource. * - * @param string $uri A public path - * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]") + * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]") * * @return string The path of the asset */ - public function prefetch($uri, array $attributes = []) + public function prefetch(string $uri, array $attributes = []): string { return $this->link($uri, 'prefetch', $attributes); } @@ -131,12 +122,11 @@ public function prefetch($uri, array $attributes = []) /** * Indicates to the client that it should prerender this resource . * - * @param string $uri A public path - * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]") + * @param array $attributes The attributes of this link (e.g. "['as' => true]", "['pr' => 0.5]") * * @return string The path of the asset */ - public function prerender($uri, array $attributes = []) + public function prerender(string $uri, array $attributes = []): string { return $this->link($uri, 'prerender', $attributes); } diff --git a/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php b/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php index b5f3badea88fd..ea7cd17a8fc10 100644 --- a/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php @@ -21,10 +21,9 @@ * WorkflowExtension. * * @author Grégoire Pineau - * - * @final since Symfony 4.4 + * @author Carlos Pereira De Amorim */ -class WorkflowExtension extends AbstractExtension +final class WorkflowExtension extends AbstractExtension { private $workflowRegistry; @@ -34,13 +33,14 @@ public function __construct(Registry $workflowRegistry) } /** - * @return TwigFunction[] + * {@inheritdoc} */ - public function getFunctions() + public function getFunctions(): array { return [ new TwigFunction('workflow_can', [$this, 'canTransition']), new TwigFunction('workflow_transitions', [$this, 'getEnabledTransitions']), + new TwigFunction('workflow_transition', [$this, 'getEnabledTransition']), new TwigFunction('workflow_has_marked_place', [$this, 'hasMarkedPlace']), new TwigFunction('workflow_marked_places', [$this, 'getMarkedPlaces']), new TwigFunction('workflow_metadata', [$this, 'getMetadata']), @@ -50,14 +50,8 @@ public function getFunctions() /** * Returns true if the transition is enabled. - * - * @param object $subject A subject - * @param string $transitionName A transition - * @param string $name A workflow name - * - * @return bool true if the transition is enabled */ - public function canTransition($subject, $transitionName, $name = null) + public function canTransition(object $subject, string $transitionName, string $name = null): bool { return $this->workflowRegistry->get($subject, $name)->can($subject, $transitionName); } @@ -65,26 +59,22 @@ public function canTransition($subject, $transitionName, $name = null) /** * Returns all enabled transitions. * - * @param object $subject A subject - * @param string $name A workflow name - * * @return Transition[] All enabled transitions */ - public function getEnabledTransitions($subject, $name = null) + public function getEnabledTransitions(object $subject, string $name = null): array { return $this->workflowRegistry->get($subject, $name)->getEnabledTransitions($subject); } + public function getEnabledTransition(object $subject, string $transition, string $name = null): ?Transition + { + return $this->workflowRegistry->get($subject, $name)->getEnabledTransition($subject, $transition); + } + /** * Returns true if the place is marked. - * - * @param object $subject A subject - * @param string $placeName A place name - * @param string $name A workflow name - * - * @return bool true if the transition is enabled */ - public function hasMarkedPlace($subject, $placeName, $name = null) + public function hasMarkedPlace(object $subject, string $placeName, string $name = null): bool { return $this->workflowRegistry->get($subject, $name)->getMarking($subject)->has($placeName); } @@ -92,13 +82,9 @@ public function hasMarkedPlace($subject, $placeName, $name = null) /** * Returns marked places. * - * @param object $subject A subject - * @param bool $placesNameOnly If true, returns only places name. If false returns the raw representation - * @param string $name A workflow name - * * @return string[]|int[] */ - public function getMarkedPlaces($subject, $placesNameOnly = true, $name = null) + public function getMarkedPlaces(object $subject, bool $placesNameOnly = true, string $name = null): array { $places = $this->workflowRegistry->get($subject, $name)->getMarking($subject)->getPlaces(); @@ -112,12 +98,11 @@ public function getMarkedPlaces($subject, $placesNameOnly = true, $name = null) /** * Returns the metadata for a specific subject. * - * @param object $subject A subject * @param string|Transition|null $metadataSubject Use null to get workflow metadata * Use a string (the place name) to get place metadata * Use a Transition instance to get transition metadata */ - public function getMetadata($subject, string $key, $metadataSubject = null, string $name = null) + public function getMetadata(object $subject, string $key, $metadataSubject = null, string $name = null) { return $this ->workflowRegistry @@ -127,15 +112,10 @@ public function getMetadata($subject, string $key, $metadataSubject = null, stri ; } - public function buildTransitionBlockerList($subject, string $transitionName, string $name = null): TransitionBlockerList + public function buildTransitionBlockerList(object $subject, string $transitionName, string $name = null): TransitionBlockerList { $workflow = $this->workflowRegistry->get($subject, $name); return $workflow->buildTransitionBlockerList($subject, $transitionName); } - - public function getName() - { - return 'workflow'; - } } diff --git a/src/Symfony/Bridge/Twig/Extension/YamlExtension.php b/src/Symfony/Bridge/Twig/Extension/YamlExtension.php index 02d19d8ae3d3b..63df1336030bf 100644 --- a/src/Symfony/Bridge/Twig/Extension/YamlExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/YamlExtension.php @@ -12,7 +12,6 @@ namespace Symfony\Bridge\Twig\Extension; use Symfony\Component\Yaml\Dumper as YamlDumper; -use Symfony\Component\Yaml\Yaml; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; @@ -20,17 +19,13 @@ * Provides integration of the Yaml component with Twig. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class YamlExtension extends AbstractExtension +final class YamlExtension extends AbstractExtension { /** * {@inheritdoc} - * - * @return TwigFilter[] */ - public function getFilters() + public function getFilters(): array { return [ new TwigFilter('yaml_encode', [$this, 'encode']), @@ -38,7 +33,7 @@ public function getFilters() ]; } - public function encode($input, $inline = 0, $dumpObjects = 0) + public function encode($input, int $inline = 0, int $dumpObjects = 0): string { static $dumper; @@ -53,7 +48,7 @@ public function encode($input, $inline = 0, $dumpObjects = 0) return $dumper->dump($input, $inline, 0, false, $dumpObjects); } - public function dump($value, $inline = 0, $dumpObjects = false) + public function dump($value, int $inline = 0, int $dumpObjects = 0): string { if (\is_resource($value)) { return '%Resource%'; @@ -65,12 +60,4 @@ public function dump($value, $inline = 0, $dumpObjects = false) return $this->encode($value, $inline, $dumpObjects); } - - /** - * {@inheritdoc} - */ - public function getName() - { - return 'yaml'; - } } diff --git a/src/Symfony/Bridge/Twig/Form/TwigRendererEngine.php b/src/Symfony/Bridge/Twig/Form/TwigRendererEngine.php index 1e97ce3371d1d..bc3b82d2f595f 100644 --- a/src/Symfony/Bridge/Twig/Form/TwigRendererEngine.php +++ b/src/Symfony/Bridge/Twig/Form/TwigRendererEngine.php @@ -40,7 +40,7 @@ public function __construct(array $defaultThemes, Environment $environment) /** * {@inheritdoc} */ - public function renderBlock(FormView $view, $resource, $blockName, array $variables = []) + public function renderBlock(FormView $view, $resource, string $blockName, array $variables = []) { $cacheKey = $view->vars[self::CACHE_KEY_VAR]; @@ -70,13 +70,9 @@ public function renderBlock(FormView $view, $resource, $blockName, array $variab * * @see getResourceForBlock() * - * @param string $cacheKey The cache key of the form view - * @param FormView $view The form view for finding the applying themes - * @param string $blockName The name of the block to load - * * @return bool True if the resource could be loaded, false otherwise */ - protected function loadResourceForBlockName($cacheKey, FormView $view, $blockName) + protected function loadResourceForBlockName(string $cacheKey, FormView $view, string $blockName) { // The caller guarantees that $this->resources[$cacheKey][$block] is // not set, but it doesn't have to check whether $this->resources[$cacheKey] @@ -143,14 +139,13 @@ protected function loadResourceForBlockName($cacheKey, FormView $view, $blockNam /** * Loads the resources for all blocks in a theme. * - * @param string $cacheKey The cache key for storing the resource - * @param mixed $theme The theme to load the block from. This parameter - * is passed by reference, because it might be necessary - * to initialize the theme first. Any changes made to - * this variable will be kept and be available upon - * further calls to this method using the same theme. + * @param mixed $theme The theme to load the block from. This parameter + * is passed by reference, because it might be necessary + * to initialize the theme first. Any changes made to + * this variable will be kept and be available upon + * further calls to this method using the same theme. */ - protected function loadResourcesFromTheme($cacheKey, &$theme) + protected function loadResourcesFromTheme(string $cacheKey, &$theme) { if (!$theme instanceof Template) { /* @var Template $theme */ diff --git a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php index 166b3c195ff17..47901d31081a1 100644 --- a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php +++ b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php @@ -55,7 +55,7 @@ public function render(Message $message): void } if (isset($messageContext['email'])) { - throw new InvalidArgumentException(sprintf('A "%s" context cannot have an "email" entry as this is a reserved variable.', \get_class($message))); + throw new InvalidArgumentException(sprintf('A "%s" context cannot have an "email" entry as this is a reserved variable.', get_debug_type($message))); } $vars = array_merge($this->context, $messageContext, [ diff --git a/src/Symfony/Bridge/Twig/Mime/NotificationEmail.php b/src/Symfony/Bridge/Twig/Mime/NotificationEmail.php index e6b28c4db43d2..a91ce2c8b8858 100644 --- a/src/Symfony/Bridge/Twig/Mime/NotificationEmail.php +++ b/src/Symfony/Bridge/Twig/Mime/NotificationEmail.php @@ -37,6 +37,7 @@ class NotificationEmail extends TemplatedEmail 'action_url' => null, 'markdown' => false, 'raw' => false, + 'footer_text' => 'Notification e-mail sent by Symfony', ]; public function __construct(Headers $headers = null, AbstractPart $body = null) @@ -57,6 +58,18 @@ public function __construct(Headers $headers = null, AbstractPart $body = null) parent::__construct($headers, $body); } + /** + * Creates a NotificationEmail instance that is appropriate to send to normal (non-admin) users. + */ + public static function asPublicEmail(Headers $headers = null, AbstractPart $body = null): self + { + $email = new static($headers, $body); + $email->context['importance'] = null; + $email->context['footer_text'] = null; + + return $email; + } + /** * @return $this */ @@ -166,7 +179,9 @@ public function getPreparedHeaders(): Headers $importance = $this->context['importance'] ?? self::IMPORTANCE_LOW; $this->priority($this->determinePriority($importance)); - $headers->setHeaderBody('Text', 'Subject', sprintf('[%s] %s', strtoupper($importance), $this->getSubject())); + if ($this->context['importance']) { + $headers->setHeaderBody('Text', 'Subject', sprintf('[%s] %s', strtoupper($importance), $this->getSubject())); + } return $headers; } diff --git a/src/Symfony/Bridge/Twig/Node/DumpNode.php b/src/Symfony/Bridge/Twig/Node/DumpNode.php index d82d9ade1feaf..16718e8a75986 100644 --- a/src/Symfony/Bridge/Twig/Node/DumpNode.php +++ b/src/Symfony/Bridge/Twig/Node/DumpNode.php @@ -16,14 +16,12 @@ /** * @author Julien Galenski - * - * @final since Symfony 4.4 */ -class DumpNode extends Node +final class DumpNode extends Node { private $varPrefix; - public function __construct($varPrefix, Node $values = null, int $lineno, string $tag = null) + public function __construct($varPrefix, ?Node $values, int $lineno, string $tag = null) { $nodes = []; if (null !== $values) { @@ -34,10 +32,7 @@ public function __construct($varPrefix, Node $values = null, int $lineno, string $this->varPrefix = $varPrefix; } - /** - * @return void - */ - public function compile(Compiler $compiler) + public function compile(Compiler $compiler): void { $compiler ->write("if (\$this->env->isDebug()) {\n") diff --git a/src/Symfony/Bridge/Twig/Node/FormThemeNode.php b/src/Symfony/Bridge/Twig/Node/FormThemeNode.php index b17243060f302..e37311267bb17 100644 --- a/src/Symfony/Bridge/Twig/Node/FormThemeNode.php +++ b/src/Symfony/Bridge/Twig/Node/FormThemeNode.php @@ -17,20 +17,15 @@ /** * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class FormThemeNode extends Node +final class FormThemeNode extends Node { public function __construct(Node $form, Node $resources, int $lineno, string $tag = null, bool $only = false) { parent::__construct(['form' => $form, 'resources' => $resources], ['only' => $only], $lineno, $tag); } - /** - * @return void - */ - public function compile(Compiler $compiler) + public function compile(Compiler $compiler): void { $compiler ->addDebugInfo($this) diff --git a/src/Symfony/Bridge/Twig/Node/RenderBlockNode.php b/src/Symfony/Bridge/Twig/Node/RenderBlockNode.php index 29402a8024fae..4d4cf61365772 100644 --- a/src/Symfony/Bridge/Twig/Node/RenderBlockNode.php +++ b/src/Symfony/Bridge/Twig/Node/RenderBlockNode.php @@ -21,15 +21,10 @@ * is "foo", the block "foo" will be rendered. * * @author Bernhard Schussek - * - * @final since Symfony 4.4 */ -class RenderBlockNode extends FunctionExpression +final class RenderBlockNode extends FunctionExpression { - /** - * @return void - */ - public function compile(Compiler $compiler) + public function compile(Compiler $compiler): void { $compiler->addDebugInfo($this); $arguments = iterator_to_array($this->getNode('arguments')); diff --git a/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php b/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php index bf22c329d6a13..9967639d16636 100644 --- a/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php +++ b/src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php @@ -18,15 +18,10 @@ /** * @author Bernhard Schussek - * - * @final since Symfony 4.4 */ -class SearchAndRenderBlockNode extends FunctionExpression +final class SearchAndRenderBlockNode extends FunctionExpression { - /** - * @return void - */ - public function compile(Compiler $compiler) + public function compile(Compiler $compiler): void { $compiler->addDebugInfo($this); $compiler->raw('$this->env->getRuntime(\'Symfony\Component\Form\FormRenderer\')->searchAndRenderBlock('); diff --git a/src/Symfony/Bridge/Twig/Node/StopwatchNode.php b/src/Symfony/Bridge/Twig/Node/StopwatchNode.php index b4dd8a9b37b4f..cfa4d8a197f9b 100644 --- a/src/Symfony/Bridge/Twig/Node/StopwatchNode.php +++ b/src/Symfony/Bridge/Twig/Node/StopwatchNode.php @@ -19,20 +19,15 @@ * Represents a stopwatch node. * * @author Wouter J - * - * @final since Symfony 4.4 */ -class StopwatchNode extends Node +final class StopwatchNode extends Node { public function __construct(Node $name, Node $body, AssignNameExpression $var, int $lineno = 0, string $tag = null) { parent::__construct(['body' => $body, 'name' => $name, 'var' => $var], [], $lineno, $tag); } - /** - * @return void - */ - public function compile(Compiler $compiler) + public function compile(Compiler $compiler): void { $compiler ->addDebugInfo($this) diff --git a/src/Symfony/Bridge/Twig/Node/TransDefaultDomainNode.php b/src/Symfony/Bridge/Twig/Node/TransDefaultDomainNode.php index 49ceac1404c5e..df29f0a19931f 100644 --- a/src/Symfony/Bridge/Twig/Node/TransDefaultDomainNode.php +++ b/src/Symfony/Bridge/Twig/Node/TransDefaultDomainNode.php @@ -17,20 +17,15 @@ /** * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class TransDefaultDomainNode extends Node +final class TransDefaultDomainNode extends Node { public function __construct(AbstractExpression $expr, int $lineno = 0, string $tag = null) { parent::__construct(['expr' => $expr], [], $lineno, $tag); } - /** - * @return void - */ - public function compile(Compiler $compiler) + public function compile(Compiler $compiler): void { // noop as this node is just a marker for TranslationDefaultDomainNodeVisitor } diff --git a/src/Symfony/Bridge/Twig/Node/TransNode.php b/src/Symfony/Bridge/Twig/Node/TransNode.php index bc87d75bd7db2..8a126ba569172 100644 --- a/src/Symfony/Bridge/Twig/Node/TransNode.php +++ b/src/Symfony/Bridge/Twig/Node/TransNode.php @@ -19,15 +19,10 @@ use Twig\Node\Node; use Twig\Node\TextNode; -// BC/FC with namespaced Twig -class_exists(ArrayExpression::class); - /** * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class TransNode extends Node +final class TransNode extends Node { public function __construct(Node $body, Node $domain = null, AbstractExpression $count = null, AbstractExpression $vars = null, AbstractExpression $locale = null, int $lineno = 0, string $tag = null) { @@ -48,10 +43,7 @@ public function __construct(Node $body, Node $domain = null, AbstractExpression parent::__construct($nodes, [], $lineno, $tag); } - /** - * @return void - */ - public function compile(Compiler $compiler) + public function compile(Compiler $compiler): void { $compiler->addDebugInfo($this); @@ -108,7 +100,7 @@ public function compile(Compiler $compiler) $compiler->raw(");\n"); } - protected function compileString(Node $body, ArrayExpression $vars, $ignoreStrictCheck = false) + private function compileString(Node $body, ArrayExpression $vars, bool $ignoreStrictCheck = false): array { if ($body instanceof ConstantExpression) { $msg = $body->getAttribute('value'); diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php b/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php index 642623f2a693c..765b4b69bd88c 100644 --- a/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php +++ b/src/Symfony/Bridge/Twig/NodeVisitor/Scope.php @@ -50,14 +50,11 @@ public function leave() /** * Stores data into current scope. * - * @param string $key - * @param mixed $value - * * @return $this * * @throws \LogicException */ - public function set($key, $value) + public function set(string $key, $value) { if ($this->left) { throw new \LogicException('Left scope is not mutable.'); @@ -71,11 +68,9 @@ public function set($key, $value) /** * Tests if a data is visible from current scope. * - * @param string $key - * * @return bool */ - public function has($key) + public function has(string $key) { if (\array_key_exists($key, $this->data)) { return true; @@ -91,12 +86,9 @@ public function has($key) /** * Returns data visible from current scope. * - * @param string $key - * @param mixed $default - * * @return mixed */ - public function get($key, $default = null) + public function get(string $key, $default = null) { if (\array_key_exists($key, $this->data)) { return $this->data[$key]; diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php index 72badea2d2bd0..213365ed9f1ef 100644 --- a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php +++ b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php @@ -27,10 +27,8 @@ /** * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class TranslationDefaultDomainNodeVisitor extends AbstractNodeVisitor +final class TranslationDefaultDomainNodeVisitor extends AbstractNodeVisitor { private $scope; @@ -41,10 +39,8 @@ public function __construct() /** * {@inheritdoc} - * - * @return Node */ - protected function doEnterNode(Node $node, Environment $env) + protected function doEnterNode(Node $node, Environment $env): Node { if ($node instanceof BlockNode || $node instanceof ModuleNode) { $this->scope = $this->scope->enter(); @@ -68,21 +64,18 @@ protected function doEnterNode(Node $node, Environment $env) return $node; } - if ($node instanceof FilterExpression && \in_array($node->getNode('filter')->getAttribute('value'), ['trans', 'transchoice'])) { + if ($node instanceof FilterExpression && 'trans' === $node->getNode('filter')->getAttribute('value')) { $arguments = $node->getNode('arguments'); - $ind = 'trans' === $node->getNode('filter')->getAttribute('value') ? 1 : 2; if ($this->isNamedArguments($arguments)) { - if (!$arguments->hasNode('domain') && !$arguments->hasNode($ind)) { + if (!$arguments->hasNode('domain') && !$arguments->hasNode(1)) { $arguments->setNode('domain', $this->scope->get('domain')); } - } else { - if (!$arguments->hasNode($ind)) { - if (!$arguments->hasNode($ind - 1)) { - $arguments->setNode($ind - 1, new ArrayExpression([], $node->getTemplateLine())); - } - - $arguments->setNode($ind, $this->scope->get('domain')); + } elseif (!$arguments->hasNode(1)) { + if (!$arguments->hasNode(0)) { + $arguments->setNode(0, new ArrayExpression([], $node->getTemplateLine())); } + + $arguments->setNode(1, $this->scope->get('domain')); } } elseif ($node instanceof TransNode) { if (!$node->hasNode('domain')) { @@ -95,10 +88,8 @@ protected function doEnterNode(Node $node, Environment $env) /** * {@inheritdoc} - * - * @return Node|null */ - protected function doLeaveNode(Node $node, Environment $env) + protected function doLeaveNode(Node $node, Environment $env): ?Node { if ($node instanceof TransDefaultDomainNode) { return null; @@ -113,10 +104,8 @@ protected function doLeaveNode(Node $node, Environment $env) /** * {@inheritdoc} - * - * @return int */ - public function getPriority() + public function getPriority(): int { return -10; } diff --git a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php index b9b5959bbd766..23c244e4248f7 100644 --- a/src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php +++ b/src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php @@ -15,6 +15,7 @@ use Twig\Environment; use Twig\Node\Expression\ConstantExpression; use Twig\Node\Expression\FilterExpression; +use Twig\Node\Expression\FunctionExpression; use Twig\Node\Node; use Twig\NodeVisitor\AbstractNodeVisitor; @@ -22,45 +23,35 @@ * TranslationNodeVisitor extracts translation messages. * * @author Fabien Potencier - * - * @final since Symfony 4.4 */ -class TranslationNodeVisitor extends AbstractNodeVisitor +final class TranslationNodeVisitor extends AbstractNodeVisitor { public const UNDEFINED_DOMAIN = '_undefined'; private $enabled = false; private $messages = []; - /** - * @return void - */ - public function enable() + public function enable(): void { $this->enabled = true; $this->messages = []; } - /** - * @return void - */ - public function disable() + public function disable(): void { $this->enabled = false; $this->messages = []; } - public function getMessages() + public function getMessages(): array { return $this->messages; } /** * {@inheritdoc} - * - * @return Node */ - protected function doEnterNode(Node $node, Environment $env) + protected function doEnterNode(Node $node, Environment $env): Node { if (!$this->enabled) { return $node; @@ -78,14 +69,18 @@ protected function doEnterNode(Node $node, Environment $env) ]; } elseif ( $node instanceof FilterExpression && - 'transchoice' === $node->getNode('filter')->getAttribute('value') && - $node->getNode('node') instanceof ConstantExpression + 'trans' === $node->getNode('filter')->getAttribute('value') && + $node->getNode('node') instanceof FunctionExpression && + 't' === $node->getNode('node')->getAttribute('name') ) { - // extract constant nodes with a trans filter - $this->messages[] = [ - $node->getNode('node')->getAttribute('value'), - $this->getReadDomainFromArguments($node->getNode('arguments'), 2), - ]; + $nodeArguments = $node->getNode('node')->getNode('arguments'); + + if ($nodeArguments->getIterator()->current() instanceof ConstantExpression) { + $this->messages[] = [ + $this->getReadMessageFromArguments($nodeArguments, 0), + $this->getReadDomainFromArguments($nodeArguments, 2), + ]; + } } elseif ($node instanceof TransNode) { // extract trans nodes $this->messages[] = [ @@ -99,24 +94,42 @@ protected function doEnterNode(Node $node, Environment $env) /** * {@inheritdoc} - * - * @return Node|null */ - protected function doLeaveNode(Node $node, Environment $env) + protected function doLeaveNode(Node $node, Environment $env): ?Node { return $node; } /** * {@inheritdoc} - * - * @return int */ - public function getPriority() + public function getPriority(): int { return 0; } + private function getReadMessageFromArguments(Node $arguments, int $index): ?string + { + if ($arguments->hasNode('message')) { + $argument = $arguments->getNode('message'); + } elseif ($arguments->hasNode($index)) { + $argument = $arguments->getNode($index); + } else { + return null; + } + + return $this->getReadMessageFromNode($argument); + } + + private function getReadMessageFromNode(Node $node): ?string + { + if ($node instanceof ConstantExpression) { + return $node->getAttribute('value'); + } + + return null; + } + private function getReadDomainFromArguments(Node $arguments, int $index): ?string { if ($arguments->hasNode('domain')) { diff --git a/src/Symfony/Bridge/Twig/Resources/views/Email/zurb_2/notification/body.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Email/zurb_2/notification/body.html.twig index 2f3a346df5903..0a52d36b374ed 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Email/zurb_2/notification/body.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Email/zurb_2/notification/body.html.twig @@ -16,7 +16,7 @@ {% block lead %} - {{ importance|upper }} + {% if importance is not null %}{{ importance|upper }}{% endif %}

{{ email.subject }}

@@ -49,13 +49,15 @@ {% block footer %} + {% if footer_text is defined and footer_text is not null %} {% block footer_content %} -

Notification e-mail sent by Symfony

+

{{ footer_text }}

{% endblock %}
+ {% endif %} {% endblock %}
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig index 44492cebe74d7..9c8a0cc14f38d 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_3_layout.html.twig @@ -99,7 +99,7 @@ {%- endif -%} {%- endif -%} - {{- widget|raw }} {{ label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans(label_translation_parameters, translation_domain)) -}} + {{- widget|raw }} {{ label is not same as(false) ? (translation_domain is same as(false) ? (label_html is same as(false) ? label : label|raw) : (label_html is same as(false) ? label|trans(label_translation_parameters, translation_domain) : label|trans(label_translation_parameters, translation_domain)|raw)) -}} {%- endif -%} {%- endblock checkbox_radio_label %} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index 7db2a0dadd3e3..c990d81370f3c 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -123,7 +123,9 @@ {%- set type = type|default('file') -%} {{- block('form_widget_simple') -}} {%- set label_attr = label_attr|merge({ class: (label_attr.class|default('') ~ ' custom-file-label')|trim }) -%} -