diff --git a/.appveyor.yml b/.appveyor.yml
index 4cdaf958bfd33..3cbe5480282b1 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -12,6 +12,7 @@ init:
- SET SYMFONY_DEPRECATIONS_HELPER=strict
- SET ANSICON=121x90 (121x90)
- SET SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE=1
+ - SET SYMFONY_DEPRECATIONS_HELPER=max[indirect]=170
- REG ADD "HKEY_CURRENT_USER\Software\Microsoft\Command Processor" /v DelayedExpansion /t REG_DWORD /d 1 /f
install:
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
deleted file mode 100644
index 16e2603b76a1d..0000000000000
--- a/.github/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Code of Conduct
-
-This project follows a [Code of Conduct][code_of_conduct] in order to ensure an open and welcoming environment.
-Please read the full text for understanding the accepted and unaccepted behavior.
-Please read also the [reporting guidelines][guidelines], in case you encountered or witnessed any misbehavior.
-
-[code_of_conduct]: https://symfony.com/doc/current/contributing/code_of_conduct/index.html
-[guidelines]: https://symfony.com/doc/current/contributing/code_of_conduct/reporting_guidelines.html
diff --git a/.github/ISSUE_TEMPLATE/1_Bug_report.md b/.github/ISSUE_TEMPLATE/1_Bug_report.md
deleted file mode 100644
index 0e34075718894..0000000000000
--- a/.github/ISSUE_TEMPLATE/1_Bug_report.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-name: 🐛 Bug Report
-about: Report errors and problems
-labels: Bug
-
----
-
-**Symfony version(s) affected**: x.y.z
-
-**Description**
-
-
-**How to reproduce**
-
-
-**Possible Solution**
-
-
-**Additional context**
-
diff --git a/.github/ISSUE_TEMPLATE/2_Feature_request.md b/.github/ISSUE_TEMPLATE/2_Feature_request.md
deleted file mode 100644
index 335321e413607..0000000000000
--- a/.github/ISSUE_TEMPLATE/2_Feature_request.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-name: 🚀 Feature Request
-about: RFC and ideas for new features and improvements
-
----
-
-**Description**
-
-
-**Example**
-
diff --git a/.github/ISSUE_TEMPLATE/3_Support_question.md b/.github/ISSUE_TEMPLATE/3_Support_question.md
deleted file mode 100644
index 9480710c15655..0000000000000
--- a/.github/ISSUE_TEMPLATE/3_Support_question.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-name: ⛔ Support Question
-about: See https://symfony.com/support for questions about using Symfony and its components
-
----
-
-We use GitHub issues only to discuss about Symfony bugs and new features. For
-this kind of questions about using Symfony or third-party bundles, please use
-any of the support alternatives shown in https://symfony.com/support
-
-Thanks!
diff --git a/.github/ISSUE_TEMPLATE/4_Documentation_issue.md b/.github/ISSUE_TEMPLATE/4_Documentation_issue.md
deleted file mode 100644
index 0855c3c5f1e12..0000000000000
--- a/.github/ISSUE_TEMPLATE/4_Documentation_issue.md
+++ /dev/null
@@ -1,10 +0,0 @@
----
-name: ⛔ Documentation Issue
-about: See https://github.com/symfony/symfony-docs/issues for documentation issues
-
----
-
-Symfony Documentation has its own dedicated repository. Please open your
-documentation-related issue at https://github.com/symfony/symfony-docs/issues
-
-Thanks!
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 2b27d887c2f74..d4182db630352 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,6 @@
| Q | A
| ------------- | ---
-| Branch? | 5.x for features / 4.4, 5.1 or 5.2 for bug fixes
+| Branch? | 5.x for features / 4.4 or 5.2 for bug fixes
| Bug fix? | yes/no
| New feature? | yes/no
| Deprecations? | yes/no
@@ -17,4 +17,5 @@ Additionally (see https://symfony.com/releases):
- Bug fixes must be submitted against the lowest maintained branch where they apply
(lowest branches are regularly merged to upper ones so they get the fixes too.)
- Features and deprecations must be submitted against branch 5.x.
+ - Changelog entry should follow https://symfony.com/doc/current/contributing/code/conventions.html#writing-a-changelog-entry
-->
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
deleted file mode 100644
index 60990950bf039..0000000000000
--- a/.github/SECURITY.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Security Policy
-===============
-
-If you found any issues that might have security implications,
-please send a report to security[at]symfony.com
-DO NOT PUBLISH SECURITY REPORTS PUBLICLY.
-
-The full [Security Policy][1] is described in the official documentation.
-
- [1]: https://symfony.com/security
diff --git a/.github/psalm/.gitignore b/.github/psalm/.gitignore
new file mode 100644
index 0000000000000..d6b7ef32c8478
--- /dev/null
+++ b/.github/psalm/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/.github/psalm/psalm.baseline.xml b/.github/psalm/psalm.baseline.xml
new file mode 100644
index 0000000000000..f74693accd46f
--- /dev/null
+++ b/.github/psalm/psalm.baseline.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/.github/workflows/intl-data-tests.yml b/.github/workflows/intl-data-tests.yml
index 17e26dad0d1ec..0ca0322281448 100644
--- a/.github/workflows/intl-data-tests.yml
+++ b/.github/workflows/intl-data-tests.yml
@@ -1,47 +1,50 @@
name: Intl data tests
on:
- push:
- paths:
- - 'src/Symfony/Component/Intl/Resources/data/**'
- pull_request:
- paths:
- - 'src/Symfony/Component/Intl/Resources/data/**'
+ push:
+ paths:
+ - 'src/Symfony/Component/Intl/Resources/data/**'
+ pull_request:
+ paths:
+ - 'src/Symfony/Component/Intl/Resources/data/**'
-jobs:
+defaults:
+ run:
+ shell: bash
- tests:
- name: Tests (intl-data)
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout
- uses: actions/checkout@v2
-
- - name: Define the ICU version
- run: |
- SYMFONY_ICU_VERSION=$(php -r 'require "src/Symfony/Component/Intl/Intl.php"; echo Symfony\Component\Intl\Intl::getIcuStubVersion();')
- echo "SYMFONY_ICU_VERSION=$SYMFONY_ICU_VERSION" >> $GITHUB_ENV
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- coverage: "none"
- extensions: "zip,intl-${{env.SYMFONY_ICU_VERSION}}"
- ini-values: "memory_limit=-1"
- php-version: "7.4"
-
- - name: Install dependencies
- run: |
- echo "::group::composer update"
- composer update --no-progress --no-suggest --ansi
- echo "::endgroup::"
- echo "::group::install phpunit"
- ./phpunit install
- echo "::endgroup::"
-
- - name: Report the ICU version
- run: icu-config --version && php -i | grep 'ICU version'
-
- - name: Run intl-data tests
- run: ./phpunit --group intl-data -v
+jobs:
+ tests:
+ name: Tests (intl-data)
+ runs-on: Ubuntu-20.04
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Define the ICU version
+ run: |
+ SYMFONY_ICU_VERSION=$(php -r 'require "src/Symfony/Component/Intl/Intl.php"; echo Symfony\Component\Intl\Intl::getIcuStubVersion();')
+ echo "SYMFONY_ICU_VERSION=$SYMFONY_ICU_VERSION" >> $GITHUB_ENV
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: "none"
+ extensions: "zip,intl-${{env.SYMFONY_ICU_VERSION}}"
+ ini-values: "memory_limit=-1"
+ php-version: "7.4"
+
+ - name: Install dependencies
+ run: |
+ echo "::group::composer update"
+ composer update --no-progress --no-suggest --ansi
+ echo "::endgroup::"
+ echo "::group::install phpunit"
+ ./phpunit install
+ echo "::endgroup::"
+
+ - name: Report the ICU version
+ run: icu-config --version && php -i | grep 'ICU version'
+
+ - name: Run intl-data tests
+ run: ./phpunit --group intl-data -v
diff --git a/.github/workflows/phpunit-bridge.yml b/.github/workflows/phpunit-bridge.yml
index bdda65de1b6f5..b503ce48d8a17 100644
--- a/.github/workflows/phpunit-bridge.yml
+++ b/.github/workflows/phpunit-bridge.yml
@@ -1,28 +1,31 @@
name: PhpUnitBridge
on:
- push:
- paths:
- - 'src/Symfony/Bridge/PhpUnit/**'
- pull_request:
- paths:
- - 'src/Symfony/Bridge/PhpUnit/**'
+ push:
+ paths:
+ - 'src/Symfony/Bridge/PhpUnit/**'
+ pull_request:
+ paths:
+ - 'src/Symfony/Bridge/PhpUnit/**'
-jobs:
+defaults:
+ run:
+ shell: bash
- lint:
- name: Lint
- runs-on: ubuntu-latest
+jobs:
+ lint:
+ name: Lint
+ runs-on: Ubuntu-20.04
- steps:
- - name: Checkout
- uses: actions/checkout@v2
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- coverage: "none"
- php-version: "5.5"
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: "none"
+ php-version: "5.5"
- - name: Lint
- run: find ./src/Symfony/Bridge/PhpUnit -name '*.php' | grep -v -e /Tests/ -e ForV6 -e ForV7 -e ForV8 -e ForV9 -e ConstraintLogicTrait | parallel -j 4 php -l {}
+ - name: Lint
+ run: find ./src/Symfony/Bridge/PhpUnit -name '*.php' | grep -v -e /Tests/ -e ForV6 -e ForV7 -e ForV8 -e ForV9 -e ConstraintLogicTrait | parallel -j 4 php -l {}
diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml
new file mode 100644
index 0000000000000..4c15203380059
--- /dev/null
+++ b/.github/workflows/psalm.yml
@@ -0,0 +1,58 @@
+name: Static analysis
+
+on:
+ pull_request: ~
+
+defaults:
+ run:
+ shell: bash
+
+jobs:
+ psalm:
+ name: Psalm
+ runs-on: Ubuntu-20.04
+
+ steps:
+ - name: Set up PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.0'
+ extensions: "json,memcached,mongodb,redis,xsl,ldap,dom"
+ ini-values: "memory_limit=-1"
+ coverage: none
+
+ - name: Checkout target branch
+ uses: actions/checkout@v2
+ with:
+ ref: ${{ github.base_ref }}
+
+ - name: Checkout PR
+ uses: actions/checkout@v2
+
+ - name: Configure composer
+ run: |
+ COMPOSER_HOME="$(composer config home)"
+ ([ -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: Install Psalm
+ run: |
+ echo "::group::modify composer.json"
+ composer remove --no-update --no-interaction symfony/phpunit-bridge
+ composer require --no-update psalm/phar phpunit/phpunit php-http/discovery psr/event-dispatcher
+ echo "::endgroup::"
+ echo "::group::composer update"
+ composer update --no-progress --ansi
+ git checkout composer.json
+ echo "::endgroup::"
+ ./vendor/bin/psalm.phar --version
+
+ - name: Generate Psalm baseline
+ run: |
+ git checkout -m ${{ github.base_ref }}
+ ./vendor/bin/psalm.phar --set-baseline=.github/psalm/psalm.baseline.xml --no-progress
+ git checkout -m FETCH_HEAD
+
+ - name: Psalm
+ run: |
+ ./vendor/bin/psalm.phar --output-format=github --no-progress
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 96f4b8be0996b..d8e6586e5b4b7 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -1,190 +1,193 @@
name: Tests
on:
- push:
- pull_request:
+ push:
+ pull_request:
-jobs:
+defaults:
+ run:
+ shell: bash
- integration:
- name: Integration
- runs-on: ubuntu-latest
-
- strategy:
- matrix:
- php: ['7.2', '7.4']
-
- services:
- postgres:
- image: postgres:9.6-alpine
- ports:
- - 5432:5432
- env:
- POSTGRES_PASSWORD: 'password'
- ldap:
- image: bitnami/openldap
- ports:
- - 3389:3389
- env:
- LDAP_ADMIN_USERNAME: admin
- LDAP_ADMIN_PASSWORD: symfony
- LDAP_ROOT: dc=symfony,dc=com
- LDAP_PORT_NUMBER: 3389
- LDAP_USERS: a
- LDAP_PASSWORDS: a
- redis:
- image: redis:6.0.0
- ports:
- - 6379:6379
- redis-cluster:
- image: grokzen/redis-cluster:5.0.4
- ports:
- - 7000:7000
- - 7001:7001
- - 7002:7002
- - 7003:7003
- - 7004:7004
- - 7005:7005
- - 7006:7006
- env:
- STANDALONE: 1
- redis-sentinel:
- image: bitnami/redis-sentinel:6.0
- ports:
- - 26379:26379
- env:
- REDIS_MASTER_HOST: redis
- REDIS_MASTER_SET: redis_sentinel
- REDIS_SENTINEL_QUORUM: 1
- memcached:
- image: memcached:1.6.5
- ports:
- - 11211:11211
- rabbitmq:
- 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: localhost
- 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: "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
- with:
- entrypoint: /bin/bash
- args: -c "(/opt/bitnami/openldap/bin/ldapwhoami -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony||sleep 5) && /opt/bitnami/openldap/bin/ldapadd -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif && /opt/bitnami/openldap/bin/ldapdelete -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony cn=a,ou=users,dc=symfony,dc=com"
-
- - name: Configure composer
- run: |
- COMPOSER_HOME="$(composer config home)"
- composer self-update
- ([ -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"
- ./phpunit install
- echo "::endgroup::"
-
- - name: Run tests
- run: ./phpunit --group integration -v
- env:
- REDIS_HOST: localhost
- REDIS_CLUSTER_HOSTS: 'localhost:7000 localhost:7001 localhost:7002 localhost:7003 localhost:7004 localhost:7005'
- REDIS_SENTINEL_HOSTS: 'localhost:26379'
- 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: localhost:9092
- POSTGRES_HOST: localhost
-
- - name: Run HTTP push tests
- if: matrix.php == '7.4'
- run: |
- [ -d .phpunit ] && mv .phpunit .phpunit.bak
- wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/vulcain_0.1.3_Linux_x86_64.tar.gz -O - | tar xz && mv vulcain /usr/local/bin
- docker run --rm -e COMPOSER_ROOT_VERSION -v $(pwd):/app -v $(which composer):/usr/local/bin/composer -v /usr/local/bin/vulcain:/usr/local/bin/vulcain -w /app php:7.4-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push
- sudo rm -rf .phpunit
- [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit
+jobs:
+ integration:
+ name: Integration
+ runs-on: Ubuntu-20.04
+
+ strategy:
+ matrix:
+ php: ['7.2', '7.4']
+
+ services:
+ postgres:
+ image: postgres:9.6-alpine
+ ports:
+ - 5432:5432
+ env:
+ POSTGRES_PASSWORD: 'password'
+ ldap:
+ image: bitnami/openldap
+ ports:
+ - 3389:3389
+ env:
+ LDAP_ADMIN_USERNAME: admin
+ LDAP_ADMIN_PASSWORD: symfony
+ LDAP_ROOT: dc=symfony,dc=com
+ LDAP_PORT_NUMBER: 3389
+ LDAP_USERS: a
+ LDAP_PASSWORDS: a
+ redis:
+ image: redis:6.0.0
+ ports:
+ - 6379:6379
+ redis-cluster:
+ image: grokzen/redis-cluster:5.0.4
+ ports:
+ - 7000:7000
+ - 7001:7001
+ - 7002:7002
+ - 7003:7003
+ - 7004:7004
+ - 7005:7005
+ - 7006:7006
+ env:
+ STANDALONE: 1
+ redis-sentinel:
+ image: bitnami/redis-sentinel:6.0
+ ports:
+ - 26379:26379
+ env:
+ REDIS_MASTER_HOST: redis
+ REDIS_MASTER_SET: redis_sentinel
+ REDIS_SENTINEL_QUORUM: 1
+ memcached:
+ image: memcached:1.6.5
+ ports:
+ - 11211:11211
+ rabbitmq:
+ 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: "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
+ with:
+ entrypoint: /bin/bash
+ args: -c "(/opt/bitnami/openldap/bin/ldapwhoami -h localhost:3389 -D cn=admin,dc=symfony,dc=com -w symfony||sleep 5) && /opt/bitnami/openldap/bin/ldapadd -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony -f src/Symfony/Component/Ldap/Tests/Fixtures/data/fixtures.ldif && /opt/bitnami/openldap/bin/ldapdelete -h ldap:3389 -D cn=admin,dc=symfony,dc=com -w symfony cn=a,ou=users,dc=symfony,dc=com"
+
+ - name: Configure composer
+ run: |
+ COMPOSER_HOME="$(composer config home)"
+ composer self-update
+ ([ -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"
+ ./phpunit install
+ echo "::endgroup::"
+
+ - name: Run tests
+ run: ./phpunit --group integration -v
+ env:
+ REDIS_HOST: localhost
+ REDIS_CLUSTER_HOSTS: 'localhost:7000 localhost:7001 localhost:7002 localhost:7003 localhost:7004 localhost:7005'
+ REDIS_SENTINEL_HOSTS: 'localhost:26379'
+ 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'
+ run: |
+ [ -d .phpunit ] && mv .phpunit .phpunit.bak
+ wget -q https://github.com/symfony/binary-utils/releases/download/v0.1/vulcain_0.1.3_Linux_x86_64.tar.gz -O - | tar xz && mv vulcain /usr/local/bin
+ docker run --rm -e COMPOSER_ROOT_VERSION -v $(pwd):/app -v $(which composer):/usr/local/bin/composer -v /usr/local/bin/vulcain:/usr/local/bin/vulcain -w /app php:7.4-alpine ./phpunit src/Symfony/Component/HttpClient/Tests/CurlHttpClientTest.php --filter testHttp2Push
+ sudo rm -rf .phpunit
+ [ -d .phpunit.bak ] && mv .phpunit.bak .phpunit
diff --git a/.travis.yml b/.travis.yml
index 80c86ecdf7444..009143743f598 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -54,6 +54,7 @@ before_install:
export PHPUNIT_X="$PHPUNIT --exclude-group tty,benchmark,intl-data"
export COMPOSER_UP='composer update --no-progress --ansi'
export COMPONENTS=$(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n' | sort)
+ export SYMFONY_DEPRECATIONS_HELPER=max[indirect]=170
nanoseconds () {
local cmd="date"
@@ -254,7 +255,7 @@ install:
fi
phpenv global $PHP
rm vendor/composer/package-versions-deprecated -Rf
- ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb ^1.9.0)
+ ([[ $deps ]] && cd src/Symfony/Component/HttpFoundation; cp composer.json composer.bak; composer require --dev --no-update mongodb/mongodb)
tfold 'composer update' $COMPOSER_UP
tfold 'phpunit install' ./phpunit install
if [[ $deps = high ]]; then
diff --git a/CHANGELOG-5.2.md b/CHANGELOG-5.2.md
index 7fe615b1fcca4..b77697fd01f15 100644
--- a/CHANGELOG-5.2.md
+++ b/CHANGELOG-5.2.md
@@ -7,6 +7,56 @@ 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.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)
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 5b8efba4073b3..b64aa797a5b14 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -1,8 +1,11 @@
CONTRIBUTORS
============
-Symfony is the result of the work of many people who made the code better
-(see https://symfony.com/contributors for more information):
+Symfony is the result of the work of many people who made the code better.
+
+The Symfony Connect username in parenthesis allows to get more information
+about contributors (like https://connect.symfony.com/profile/fabpot). See
+https://symfony.com/contributors for more information.
- Fabien Potencier (fabpot)
- Nicolas Grekas (nicolas-grekas)
diff --git a/composer.json b/composer.json
index e92efba50fae6..667c2dee04081 100644
--- a/composer.json
+++ b/composer.json
@@ -15,6 +15,22 @@
"homepage": "https://symfony.com/contributors"
}
],
+ "provide": {
+ "php-http/async-client-implementation": "*",
+ "php-http/client-implementation": "*",
+ "psr/cache-implementation": "1.0|2.0",
+ "psr/container-implementation": "1.0",
+ "psr/event-dispatcher-implementation": "1.0",
+ "psr/http-client-implementation": "1.0",
+ "psr/link-implementation": "1.0",
+ "psr/log-implementation": "1.0",
+ "psr/simple-cache-implementation": "1.0",
+ "symfony/cache-implementation": "1.0|2.0",
+ "symfony/event-dispatcher-implementation": "2.0",
+ "symfony/http-client-implementation": "2.2",
+ "symfony/service-implementation": "1.0|2.0",
+ "symfony/translation-implementation": "2.3"
+ },
"require": {
"php": ">=7.2.5",
"ext-xml": "*",
@@ -22,7 +38,7 @@
"doctrine/event-manager": "~1.0",
"doctrine/persistence": "^2",
"twig/twig": "^2.13|^3.0.4",
- "psr/cache": "~1.0",
+ "psr/cache": "^1.0|^2.0",
"psr/container": "^1.0",
"psr/event-dispatcher": "^1.0",
"psr/link": "^1.0",
@@ -154,6 +170,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"
],
@@ -163,7 +182,6 @@
},
"autoload-dev": {
"files": [
- "src/Symfony/Component/String/Resources/functions.php",
"src/Symfony/Component/VarDumper/Resources/functions/dump.php"
]
},
diff --git a/phpunit b/phpunit
index 9141d249d2695..cdd9af8352881 100755
--- a/phpunit
+++ b/phpunit
@@ -8,15 +8,13 @@ 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');
}
}
-if (!getenv('SYMFONY_PATCH_TYPE_DECLARATIONS')) {
+if (!getenv('SYMFONY_PATCH_TYPE_DECLARATIONS') && \PHP_VERSION_ID >= 70300) {
putenv('SYMFONY_PATCH_TYPE_DECLARATIONS=deprecations=1');
}
if (getcwd() === realpath(__DIR__.'/src/Symfony/Bridge/PhpUnit')) {
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 0000000000000..3f12f1331c272
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php b/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php
index 8415ee14b63cb..9b3c1595a41f0 100644
--- a/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php
+++ b/src/Symfony/Bridge/Doctrine/ContainerAwareEventManager.php
@@ -164,11 +164,22 @@ private function initializeListeners(string $eventName)
private function initializeSubscribers()
{
$this->initializedSubscribers = true;
+
+ $eventListeners = $this->listeners;
+ // reset eventListener to respect priority: EventSubscribers have a higher priority
+ $this->listeners = [];
foreach ($this->subscribers as $id => $subscriber) {
if (\is_string($subscriber)) {
parent::addEventSubscriber($this->subscribers[$id] = $this->container->get($subscriber));
}
}
+ foreach ($eventListeners as $event => $listeners) {
+ if (!isset($this->listeners[$event])) {
+ $this->listeners[$event] = [];
+ }
+ $this->listeners[$event] += $listeners;
+ }
+ $this->subscribers = [];
}
/**
diff --git a/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php b/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php
index 2ad16dcd4de24..d3d25c17b275d 100644
--- a/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php
+++ b/src/Symfony/Bridge/Doctrine/Test/DoctrineTestHelper.php
@@ -12,7 +12,6 @@
namespace Symfony\Bridge\Doctrine\Test;
use Doctrine\Common\Annotations\AnnotationReader;
-use Doctrine\Common\Cache\ArrayCache;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
@@ -62,8 +61,6 @@ public static function createTestConfiguration()
$config->setProxyDir(sys_get_temp_dir());
$config->setProxyNamespace('SymfonyTests\Doctrine');
$config->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader()));
- $config->setQueryCacheImpl(new ArrayCache());
- $config->setMetadataCacheImpl(new ArrayCache());
return $config;
}
diff --git a/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php b/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php
index a26ecbb35bb24..c77c13e59fecb 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/ContainerAwareEventManagerTest.php
@@ -146,11 +146,14 @@ public function testAddEventListenerAndSubscriberAfterDispatchEvent()
public function testGetListenersForEvent()
{
+ $this->evm = new ContainerAwareEventManager($this->container, ['lazy2']);
+
$this->container->set('lazy', $listener1 = new MyListener());
+ $this->container->set('lazy2', $subscriber1 = new MySubscriber(['foo']));
$this->evm->addEventListener('foo', 'lazy');
$this->evm->addEventListener('foo', $listener2 = new MyListener());
- $this->assertSame([$listener1, $listener2], array_values($this->evm->getListeners('foo')));
+ $this->assertSame([$subscriber1, $listener1, $listener2], array_values($this->evm->getListeners('foo')));
}
public function testGetListeners()
diff --git a/src/Symfony/Bridge/PhpUnit/.gitignore b/src/Symfony/Bridge/PhpUnit/.gitignore
index 9d8c4aadaf9f5..c49a5d8df5c65 100644
--- a/src/Symfony/Bridge/PhpUnit/.gitignore
+++ b/src/Symfony/Bridge/PhpUnit/.gitignore
@@ -1,4 +1,3 @@
vendor/
composer.lock
phpunit.xml
-Tests/DeprecationErrorHandler/fake_vendor/symfony/error-handler/DebugClassLoader.php
diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
index ee0fe1e4b844a..feabafb760bde 100644
--- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
+++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler.php
@@ -125,43 +125,47 @@ public function handleError($type, $msg, $file, $line, $context = [])
return \call_user_func(self::getPhpUnitErrorHandler(), $type, $msg, $file, $line, $context);
}
- $deprecation = new Deprecation($msg, debug_backtrace(), $file);
+ $trace = debug_backtrace();
+
+ if (isset($trace[1]['function'], $trace[1]['args'][0]) && ('trigger_error' === $trace[1]['function'] || 'user_error' === $trace[1]['function'])) {
+ $msg = $trace[1]['args'][0];
+ }
+
+ $deprecation = new Deprecation($msg, $trace, $file);
if ($deprecation->isMuted()) {
return null;
}
if ($this->getConfiguration()->isBaselineDeprecation($deprecation)) {
return null;
}
- $group = 'other';
- if ($deprecation->originatesFromAnObject()) {
- $class = $deprecation->originatingClass();
- $method = $deprecation->originatingMethod();
- $msg = $deprecation->getMessage();
+ $msg = $deprecation->getMessage();
- if (error_reporting() & $type) {
- $group = 'unsilenced';
- } elseif ($deprecation->isLegacy()) {
- $group = 'legacy';
- } else {
- $group = [
- Deprecation::TYPE_SELF => 'self',
- Deprecation::TYPE_DIRECT => 'direct',
- Deprecation::TYPE_INDIRECT => 'indirect',
- Deprecation::TYPE_UNDETERMINED => 'other',
- ][$deprecation->getType()];
- }
+ if (error_reporting() & $type) {
+ $group = 'unsilenced';
+ } elseif ($deprecation->isLegacy()) {
+ $group = 'legacy';
+ } else {
+ $group = [
+ Deprecation::TYPE_SELF => 'self',
+ Deprecation::TYPE_DIRECT => 'direct',
+ Deprecation::TYPE_INDIRECT => 'indirect',
+ Deprecation::TYPE_UNDETERMINED => 'other',
+ ][$deprecation->getType()];
+ }
- if ($this->getConfiguration()->shouldDisplayStackTrace($msg)) {
- echo "\n".ucfirst($group).' '.$deprecation->toString();
+ if ($this->getConfiguration()->shouldDisplayStackTrace($msg)) {
+ echo "\n".ucfirst($group).' '.$deprecation->toString();
- exit(1);
- }
- if ('legacy' !== $group) {
- $this->deprecationGroups[$group]->addNoticeFromObject($msg, $class, $method);
- } else {
- $this->deprecationGroups[$group]->addNotice();
- }
+ exit(1);
+ }
+
+ 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);
}
diff --git a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
index 3a5c6c1d08d41..3e3ebef48c7c3 100644
--- a/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
+++ b/src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php
@@ -60,25 +60,33 @@ public function __construct($message, array $trace, $file)
}
$this->trace = $trace;
-
- if ('trigger_error' === (isset($trace[1]['function']) ? $trace[1]['function'] : null)
- && (DebugClassLoader::class === ($class = (isset($trace[2]['class']) ? $trace[2]['class'] : null)) || LegacyDebugClassLoader::class === $class)
- && 'checkClass' === (isset($trace[2]['function']) ? $trace[2]['function'] : null)
- && null !== ($extraFile = (isset($trace[2]['args'][1]) ? $trace[2]['args'][1] : null))
- && '' !== $extraFile
- && false !== $extraFile = realpath($extraFile)
- ) {
- $this->getOriginalFilesStack();
- array_splice($this->originalFilesStack, 2, 1, $extraFile);
- }
-
$this->message = $message;
- $i = \count($this->trace);
- while (1 < $i && $this->lineShouldBeSkipped($this->trace[--$i])) {
+
+ $i = \count($trace);
+ while (1 < $i && $this->lineShouldBeSkipped($trace[--$i])) {
// No-op
}
- $line = $this->trace[$i];
+
+ $line = $trace[$i];
$this->triggeringFile = $file;
+
+ for ($j = 1; $j < $i; ++$j) {
+ if (!isset($trace[$j]['function'], $trace[1 + $j]['class'], $trace[1 + $j]['args'][0])) {
+ continue;
+ }
+
+ if ('trigger_error' === $trace[$j]['function'] && !isset($trace[$j]['class'])) {
+ if (\in_array($trace[1 + $j]['class'], [DebugClassLoader::class, LegacyDebugClassLoader::class], true)) {
+ $class = $trace[1 + $j]['args'][0];
+ $this->triggeringFile = isset($trace[1 + $j]['args'][1]) ? realpath($trace[1 + $j]['args'][1]) : (new \ReflectionClass($class))->getFileName();
+ $this->getOriginalFilesStack();
+ array_splice($this->originalFilesStack, 0, $j, [$this->triggeringFile]);
+ }
+
+ break;
+ }
+ }
+
if (isset($line['object']) || isset($line['class'])) {
set_error_handler(function () {});
$parsedMsg = unserialize($this->message);
@@ -101,12 +109,19 @@ public function __construct($message, array $trace, $file)
return;
}
- if (isset($line['class']) && 0 === strpos($line['class'], SymfonyTestsListenerFor::class)) {
+ 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'];
+
return;
}
- $this->originClass = isset($line['object']) ? \get_class($line['object']) : $line['class'];
- $this->originMethod = $line['function'];
+ if ('trigger_error' !== $trace[$i - 2]['function'] || isset($trace[$i - 2]['class'])) {
+ $this->originClass = \get_class($line['args'][0]);
+ $this->originMethod = $line['args'][0]->getName();
+
+ return;
+ }
}
}
@@ -140,7 +155,9 @@ public function originatingClass()
throw new \LogicException('Check with originatesFromAnObject() before calling this method.');
}
- return $this->originClass;
+ $class = $this->originClass;
+
+ return false !== strpos($class, "@anonymous\0") ? (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous' : $class;
}
/**
@@ -168,8 +185,7 @@ public function getMessage()
*/
public function isLegacy()
{
- $class = $this->originatingClass();
- if ((new \ReflectionClass($class))->isInternal()) {
+ if (!$this->originClass || (new \ReflectionClass($this->originClass))->isInternal()) {
return false;
}
@@ -178,8 +194,8 @@ public function isLegacy()
return 0 === strpos($method, 'testLegacy')
|| 0 === strpos($method, 'provideLegacy')
|| 0 === strpos($method, 'getLegacy')
- || strpos($class, '\Legacy')
- || \in_array('legacy', Test::getGroups($class, $method), true);
+ || strpos($this->originClass, '\Legacy')
+ || \in_array('legacy', Test::getGroups($this->originClass, $method), true);
}
/**
@@ -205,11 +221,10 @@ public function isMuted()
*/
public function getType()
{
- $triggeringFilePathType = $this->getPathType($this->triggeringFile);
- if (self::PATH_TYPE_SELF === $triggeringFilePathType) {
+ if (self::PATH_TYPE_SELF === $pathType = $this->getPathType($this->triggeringFile)) {
return self::TYPE_SELF;
}
- if (self::PATH_TYPE_UNDETERMINED === $triggeringFilePathType) {
+ if (self::PATH_TYPE_UNDETERMINED === $pathType) {
return self::TYPE_UNDETERMINED;
}
$erroringFile = $erroringPackage = null;
@@ -218,10 +233,10 @@ public function getType()
if ('-' === $file || 'Standard input code' === $file || !realpath($file)) {
continue;
}
- if (self::PATH_TYPE_SELF === $this->getPathType($file)) {
+ if (self::PATH_TYPE_SELF === $pathType = $this->getPathType($file)) {
return self::TYPE_DIRECT;
}
- if (self::PATH_TYPE_UNDETERMINED === $this->getPathType($file)) {
+ if (self::PATH_TYPE_UNDETERMINED === $pathType) {
return self::TYPE_UNDETERMINED;
}
if (null !== $erroringFile && null !== $erroringPackage) {
@@ -243,7 +258,7 @@ private function getOriginalFilesStack()
if (null === $this->originalFilesStack) {
$this->originalFilesStack = [];
foreach ($this->trace as $frame) {
- if (!isset($frame['file']) || \in_array($frame['function'], ['require', 'require_once', 'include', 'include_once'], true)) {
+ if (!isset($frame['file'], $frame['function']) || (!isset($frame['class']) && \in_array($frame['function'], ['require', 'require_once', 'include', 'include_once'], true))) {
continue;
}
@@ -269,13 +284,10 @@ private function getPackage($path)
$relativePath = substr($path, \strlen($vendorRoot) + 1);
$vendor = strstr($relativePath, \DIRECTORY_SEPARATOR, true);
if (false === $vendor) {
- throw new \RuntimeException(sprintf('Could not find directory separator "%s" in path "%s".', \DIRECTORY_SEPARATOR, $relativePath));
+ return 'symfony';
}
- return rtrim($vendor.'/'.strstr(substr(
- $relativePath,
- \strlen($vendor) + 1
- ), \DIRECTORY_SEPARATOR, true), '/');
+ return rtrim($vendor.'/'.strstr(substr($relativePath, \strlen($vendor) + 1), \DIRECTORY_SEPARATOR, true), '/');
}
}
@@ -289,6 +301,13 @@ private static function getVendors()
{
if (null === self::$vendors) {
self::$vendors = $paths = [];
+ self::$vendors[] = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Legacy';
+ if (class_exists(DebugClassLoader::class, false)) {
+ self::$vendors[] = \dirname((new \ReflectionClass(DebugClassLoader::class))->getFileName());
+ }
+ if (class_exists(LegacyDebugClassLoader::class, false)) {
+ self::$vendors[] = \dirname((new \ReflectionClass(LegacyDebugClassLoader::class))->getFileName());
+ }
foreach (get_declared_classes() as $class) {
if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
@@ -364,10 +383,9 @@ public function toString()
$reflection->setAccessible(true);
$reflection->setValue($exception, $this->trace);
- return 'deprecation triggered by '.$this->originatingClass().'::'.$this->originatingMethod().':'.
- "\n".$this->message.
- "\nStack trace:".
- "\n".str_replace(' '.getcwd().\DIRECTORY_SEPARATOR, ' ', $exception->getTraceAsString()).
- "\n";
+ return ($this->originatesFromAnObject() ? 'deprecation triggered by '.$this->originatingClass().'::'.$this->originatingMethod().":\n" : '')
+ .$this->message."\n"
+ ."Stack trace:\n"
+ .str_replace(' '.getcwd().\DIRECTORY_SEPARATOR, ' ', $exception->getTraceAsString())."\n";
}
}
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php
index f36c689099ec8..9cb0a0e32ce3a 100644
--- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/DeprecationTest.php
@@ -174,6 +174,8 @@ public function testGetTypeDetectsSelf(string $expectedType, string $message, st
{
$trace = [
['class' => 'MyClass1', 'function' => 'myMethod'],
+ ['function' => 'trigger_error'],
+ ['class' => SymfonyTestsListenerTrait::class, 'function' => 'endTest'],
['class' => $traceClass, 'function' => 'myMethod'],
];
$deprecation = new Deprecation($message, $trace, $file);
@@ -183,6 +185,11 @@ public function testGetTypeDetectsSelf(string $expectedType, string $message, st
public function providerGetTypeUsesRightTrace()
{
$vendorDir = self::getVendorDir();
+ $fakeTrace = [
+ ['function' => 'trigger_error'],
+ ['class' => SymfonyTestsListenerTrait::class, 'function' => 'endTest'],
+ ['class' => SymfonyTestsListenerForV5::class, 'function' => 'endTest'],
+ ];
return [
'no_file_in_stack' => [Deprecation::TYPE_DIRECT, '', [['function' => 'myfunc1'], ['function' => 'myfunc2']]],
@@ -205,7 +212,7 @@ public function providerGetTypeUsesRightTrace()
$vendorDir.'/myfakevendor/myfakepackage1/MyFakeFile2.php',
],
]),
- [['function' => 'myfunc1'], ['class' => SymfonyTestsListenerForV5::class, 'method' => 'mymethod']],
+ $fakeTrace,
],
'serialized_stack_files_from_various_packages' => [
Deprecation::TYPE_INDIRECT,
@@ -218,7 +225,7 @@ public function providerGetTypeUsesRightTrace()
$vendorDir.'/myfakevendor/myfakepackage2/MyFakeFile.php',
],
]),
- [['function' => 'myfunc1'], ['class' => SymfonyTestsListenerForV5::class, 'method' => 'mymethod']],
+ $fakeTrace,
],
];
}
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt
index 781027e84fe66..04e64d33e46b6 100644
--- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/debug_class_loader_autoload.phpt
@@ -30,16 +30,6 @@ EOPHP
);
require __DIR__.'/fake_vendor/autoload.php';
-// We need the real DebugClassLoader FQCN but in a vendor path.
-if (!file_exists($errorHandlerRootDir = __DIR__.'/../../../../Component/ErrorHandler')) {
- if (!file_exists($errorHandlerRootDir = __DIR__.'/../../vendor/symfony/error-handler')) {
- die('Could not find the ErrorHandler component root directory.');
- }
-}
-
-file_put_contents($fakeDebugClassLoadPath = __DIR__.'/fake_vendor/symfony/error-handler/DebugClassLoader.php', file_get_contents($errorHandlerRootDir.'/DebugClassLoader.php'));
-require $fakeDebugClassLoadPath;
-
\Symfony\Component\ErrorHandler\DebugClassLoader::enable();
new \App\Services\BarService();
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt
index f1fb64ed137ba..83b135b34bab7 100644
--- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/partially_quiet.phpt
@@ -24,7 +24,7 @@ require __DIR__.'/fake_vendor/acme/outdated-lib/outdated_file.php';
--EXPECTF--
Unsilenced deprecation notices (3)
-Remaining direct deprecation notices (1)
+Remaining direct deprecation notices (2)
Remaining indirect deprecation notices (1)
@@ -33,5 +33,3 @@ Remaining indirect deprecation notices (1)
Legacy deprecation notices (2)
-Other deprecation notices (1)
-
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt
index 174e2ba89b54e..c9b323f6d5ad1 100644
--- a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt
+++ b/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/weak_vendors_on_vendor.phpt
@@ -29,13 +29,11 @@ Unsilenced deprecation notices (3)
1x: unsilenced bar deprecation
1x in FooTestCase::testNonLegacyBar
-Remaining direct deprecation notices (1)
+Remaining direct deprecation notices (2)
+
+ 1x: root deprecation
1x: silenced bar deprecation
1x in FooTestCase::testNonLegacyBar
Legacy deprecation notices (2)
-
-Other deprecation notices (1)
-
- 1x: root deprecation
diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php
index 6b4407cd6059d..077050688b3c9 100644
--- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php
+++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit.php
@@ -10,7 +10,7 @@
*/
// Please update when phpunit needs to be reinstalled with fresh deps:
-// Cache-Id: 2020-01-31 10:00 UTC
+// Cache-Id: 2021-02-04 11:00 UTC
error_reporting(-1);
diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json
index 27e6daba7e505..1a1f364eb9a85 100644
--- a/src/Symfony/Bridge/Twig/composer.json
+++ b/src/Symfony/Bridge/Twig/composer.json
@@ -30,6 +30,7 @@
"symfony/form": "^5.1.9",
"symfony/http-foundation": "^4.4|^5.0",
"symfony/http-kernel": "^4.4|^5.0",
+ "symfony/intl": "^4.4|^5.0",
"symfony/mime": "^5.2",
"symfony/polyfill-intl-icu": "~1.0",
"symfony/property-info": "^4.4|^5.1",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
index 9274d7e70baf6..392541e656848 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php
@@ -333,6 +333,11 @@ private function filterCatalogue(MessageCatalogue $catalogue, string $domain): M
foreach ($catalogue->getResources() as $resource) {
$filteredCatalogue->addResource($resource);
}
+ if ($metadata = $catalogue->getMetadata('', $intlDomain)) {
+ foreach ($metadata as $k => $v) {
+ $filteredCatalogue->setMetadata($k, $v, $intlDomain);
+ }
+ }
if ($metadata = $catalogue->getMetadata('', $domain)) {
foreach ($metadata as $k => $v) {
$filteredCatalogue->setMetadata($k, $v, $domain);
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 6ab4f84169376..a0efab6b5ba64 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -97,7 +97,7 @@ public function getConfigTreeBuilder()
->enumPrototype()
->values([
'forwarded',
- 'x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port',
+ 'x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port', 'x-forwarded-prefix',
])
->end()
->end()
@@ -1446,7 +1446,7 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode)
->info('A network interface name, IP address, a host name or a UNIX socket to bind to.')
->end()
->booleanNode('verify_peer')
- ->info('Indicates if the peer should be verified in a SSL/TLS context.')
+ ->info('Indicates if the peer should be verified in an SSL/TLS context.')
->end()
->booleanNode('verify_host')
->info('Indicates if the host should exist as a certificate common name.')
@@ -1589,7 +1589,7 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode)
->info('A network interface name, IP address, a host name or a UNIX socket to bind to.')
->end()
->booleanNode('verify_peer')
- ->info('Indicates if the peer should be verified in a SSL/TLS context.')
+ ->info('Indicates if the peer should be verified in an SSL/TLS context.')
->end()
->booleanNode('verify_host')
->info('Indicates if the host should exist as a certificate common name.')
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index fdcd199772eec..c6cd60cc32fb1 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -1220,24 +1220,26 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
// Register translation resources
if ($dirs) {
$files = [];
- $finder = Finder::create()
- ->followLinks()
- ->files()
- ->filter(function (\SplFileInfo $file) {
- return 2 <= substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename());
- })
- ->in($dirs)
- ->sortByName()
- ;
- foreach ($finder as $file) {
- $fileNameParts = explode('.', basename($file));
- $locale = $fileNameParts[\count($fileNameParts) - 2];
- if (!isset($files[$locale])) {
- $files[$locale] = [];
- }
+ foreach ($dirs as $dir) {
+ $finder = Finder::create()
+ ->followLinks()
+ ->files()
+ ->filter(function (\SplFileInfo $file) {
+ return 2 <= substr_count($file->getBasename(), '.') && preg_match('/\.\w+$/', $file->getBasename());
+ })
+ ->in($dir)
+ ->sortByName()
+ ;
+ foreach ($finder as $file) {
+ $fileNameParts = explode('.', basename($file));
+ $locale = $fileNameParts[\count($fileNameParts) - 2];
+ if (!isset($files[$locale])) {
+ $files[$locale] = [];
+ }
- $files[$locale][] = (string) $file;
+ $files[$locale][] = (string) $file;
+ }
}
$projectDir = $container->getParameter('kernel.project_dir');
@@ -1441,8 +1443,8 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde
}
$container
- ->getDefinition('annotations.filesystem_cache')
- ->replaceArgument(0, $cacheDir)
+ ->getDefinition('annotations.filesystem_cache_adapter')
+ ->replaceArgument(2, $cacheDir)
;
$cacheService = 'annotations.filesystem_cache';
@@ -2303,6 +2305,7 @@ private function resolveTrustedHeaders(array $headers): int
case 'x-forwarded-host': $trustedHeaders |= Request::HEADER_X_FORWARDED_HOST; break;
case 'x-forwarded-proto': $trustedHeaders |= Request::HEADER_X_FORWARDED_PROTO; break;
case 'x-forwarded-port': $trustedHeaders |= Request::HEADER_X_FORWARDED_PORT; break;
+ case 'x-forwarded-prefix': $trustedHeaders |= Request::HEADER_X_FORWARDED_PREFIX; break;
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php
index cc66f6f6056bb..187d9da6642d0 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.php
@@ -15,9 +15,9 @@
use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Annotations\CachedReader;
use Doctrine\Common\Annotations\Reader;
-use Doctrine\Common\Cache\ArrayCache;
-use Doctrine\Common\Cache\FilesystemCache;
use Symfony\Bundle\FrameworkBundle\CacheWarmer\AnnotationsCacheWarmer;
+use Symfony\Component\Cache\Adapter\ArrayAdapter;
+use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\Cache\DoctrineProvider;
@@ -35,15 +35,24 @@
->set('annotations.cached_reader', CachedReader::class)
->args([
service('annotations.reader'),
- inline_service(ArrayCache::class),
+ inline_service(DoctrineProvider::class)->args([
+ inline_service(ArrayAdapter::class)
+ ]),
abstract_arg('Debug-Flag'),
])
- ->set('annotations.filesystem_cache', FilesystemCache::class)
+ ->set('annotations.filesystem_cache_adapter', FilesystemAdapter::class)
->args([
+ '',
+ 0,
abstract_arg('Cache-Directory'),
])
+ ->set('annotations.filesystem_cache', DoctrineProvider::class)
+ ->args([
+ service('annotations.filesystem_cache_adapter'),
+ ])
+
->set('annotations.cache_warmer', AnnotationsCacheWarmer::class)
->args([
service('annotations.reader'),
@@ -61,6 +70,7 @@
service('cache.annotations'),
]),
])
+ ->tag('container.hot_path')
->alias('annotation_reader', 'annotations.reader')
->alias(Reader::class, 'annotation_reader');
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.php
index 51c6ae38f2dd1..e4c0745c6094e 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.php
@@ -97,7 +97,10 @@
->tag('form.type')
->set('form.type.choice', ChoiceType::class)
- ->args([service('form.choice_list_factory')])
+ ->args([
+ service('form.choice_list_factory'),
+ service('translator')->ignoreOnInvalid(),
+ ])
->tag('form.type')
->set('form.type.file', FileType::class)
diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php
index 36533e12f08a8..5bdf54565d647 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Routing/DelegatingLoader.php
@@ -61,7 +61,7 @@ public function load($resource, string $type = null)
// - this handles the case and prevents the second fatal error
// by triggering an exception beforehand.
- throw new LoaderLoadException($resource, null, null, null, $type);
+ throw new LoaderLoadException($resource, null, 0, null, $type);
}
$this->loading = true;
diff --git a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php
index 038d8722b7ed5..b70437374ad24 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Routing/Router.php
@@ -180,14 +180,16 @@ private function resolve($value)
$resolved = ($this->paramFetcher)($match[1]);
- if (\is_bool($resolved)) {
- $resolved = (string) (int) $resolved;
- }
-
- if (\is_string($resolved) || is_numeric($resolved)) {
+ if (is_scalar($resolved)) {
$this->collectedParameters[$match[1]] = $resolved;
- return (string) $this->resolve($resolved);
+ if (\is_string($resolved)) {
+ $resolved = $this->resolve($resolved);
+ }
+
+ if (is_scalar($resolved)) {
+ return false === $resolved ? '0' : (string) $resolved;
+ }
}
throw new RuntimeException(sprintf('The container parameter "%s", used in the route configuration value "%s", must be a string or numeric, but it is of type "%s".', $match[1], $value, get_debug_type($resolved)));
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php
index 5f74f1f889a92..2c25b8e9f27ca 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Command/CacheClearCommand/CacheClearCommandTest.php
@@ -19,6 +19,7 @@
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
use Symfony\Component\DependencyInjection\Container;
+use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
@@ -38,13 +39,14 @@ protected function setUp(): void
protected function tearDown(): void
{
- $this->fs->remove($this->kernel->getProjectDir());
+ try {
+ $this->fs->remove($this->kernel->getProjectDir());
+ } catch (IOException $e) {
+ }
}
public function testCacheIsFreshAfterCacheClearedWithWarmup()
{
- $this->fs->mkdir($this->kernel->getProjectDir());
-
$input = new ArrayInput(['cache:clear']);
$application = new Application($this->kernel);
$application->setCatchExceptions(false);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index 95171449f9b7a..960eda35d0b62 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -836,6 +836,19 @@ public function testTranslator()
$files,
'->registerTranslatorConfiguration() finds translation resources with dots in domain'
);
+ $this->assertContains(strtr(__DIR__.'/translations/security.en.yaml', '/', \DIRECTORY_SEPARATOR), $files);
+
+ $positionOverridingTranslationFile = array_search(strtr(realpath(__DIR__.'/translations/security.en.yaml'), '/', \DIRECTORY_SEPARATOR), $files);
+
+ if (false !== $positionCoreTranslationFile = array_search(strtr(realpath(__DIR__.'/../../../../Component/Security/Core/Resources/translations/security.en.xlf'), '/', \DIRECTORY_SEPARATOR), $files)) {
+ $this->assertContains(strtr(realpath(__DIR__.'/../../../../Component/Security/Core/Resources/translations/security.en.xlf'), '/', \DIRECTORY_SEPARATOR), $files);
+ } else {
+ $this->assertContains(strtr(realpath(__DIR__.'/../../vendor/symfony/security-core/Resources/translations/security.en.xlf'), '/', \DIRECTORY_SEPARATOR), $files);
+
+ $positionCoreTranslationFile = array_search(strtr(realpath(__DIR__.'/../../vendor/symfony/security-core/Resources/translations/security.en.xlf'), '/', \DIRECTORY_SEPARATOR), $files);
+ }
+
+ $this->assertGreaterThan($positionCoreTranslationFile, $positionOverridingTranslationFile);
$calls = $container->getDefinition('translator.default')->getMethodCalls();
$this->assertEquals(['fr'], $calls[1][1][0]);
@@ -915,7 +928,7 @@ public function testAnnotations()
$container->addCompilerPass(new TestAnnotationsPass());
$container->compile();
- $this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.filesystem_cache')->getArgument(0));
+ $this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.filesystem_cache_adapter')->getArgument(2));
$this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotation_reader')->getArgument(1));
}
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/symfony/error-handler/.gitkeep b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/translations/security.en.yaml
similarity index 100%
rename from src/Symfony/Bridge/PhpUnit/Tests/DeprecationErrorHandler/fake_vendor/symfony/error-handler/.gitkeep
rename to src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/translations/security.en.yaml
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/Fixtures/with_condition.yaml b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/Fixtures/with_condition.yaml
new file mode 100644
index 0000000000000..c97edc1a42542
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/Fixtures/with_condition.yaml
@@ -0,0 +1,3 @@
+foo:
+ path: /foo
+ condition: '%parameter.condition%'
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php
index 91d9c4cfd6d3a..416695ea765ea 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php
@@ -14,11 +14,16 @@
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
+use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\Config\ResourceCheckerConfigCache;
+use Symfony\Component\Config\ResourceCheckerConfigCacheFactory;
use Symfony\Component\DependencyInjection\Config\ContainerParametersResource;
+use Symfony\Component\DependencyInjection\Config\ContainerParametersResourceChecker;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
+use Symfony\Component\Routing\Loader\YamlFileLoader;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
@@ -503,6 +508,51 @@ public function getNonStringValues()
return [[null], [false], [true], [new \stdClass()], [['foo', 'bar']], [[[]]]];
}
+ /**
+ * @dataProvider getContainerParameterForRoute
+ */
+ public function testCacheValidityWithContainerParameters($parameter)
+ {
+ $cacheDir = sys_get_temp_dir().\DIRECTORY_SEPARATOR.uniqid('router_', true);
+
+ try {
+ $container = new Container();
+ $container->set('routing.loader', new YamlFileLoader(new FileLocator(__DIR__.'/Fixtures')));
+
+ $container->setParameter('parameter.condition', $parameter);
+
+ $router = new Router($container, 'with_condition.yaml', [
+ 'debug' => true,
+ 'cache_dir' => $cacheDir,
+ ]);
+
+ $resourceCheckers = [
+ new ContainerParametersResourceChecker($container),
+ ];
+
+ $router->setConfigCacheFactory(new ResourceCheckerConfigCacheFactory($resourceCheckers));
+
+ $router->getMatcher(); // trigger cache build
+
+ $cache = new ResourceCheckerConfigCache($cacheDir.\DIRECTORY_SEPARATOR.'url_matching_routes.php', $resourceCheckers);
+
+ $this->assertTrue($cache->isFresh());
+ } finally {
+ if (is_dir($cacheDir)) {
+ array_map('unlink', glob($cacheDir.\DIRECTORY_SEPARATOR.'*'));
+ rmdir($cacheDir);
+ }
+ }
+ }
+
+ public function getContainerParameterForRoute()
+ {
+ yield 'String' => ['"foo"'];
+ yield 'Integer' => [0];
+ yield 'Boolean true' => [true];
+ yield 'Boolean false' => [false];
+ }
+
private function getServiceContainer(RouteCollection $routes): Container
{
$loader = $this->createMock(LoaderInterface::class);
diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json
index 7931966131fb2..09c00ea6a16d6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/composer.json
+++ b/src/Symfony/Bundle/FrameworkBundle/composer.json
@@ -52,6 +52,7 @@
"symfony/mime": "^4.4|^5.0",
"symfony/process": "^4.4|^5.0",
"symfony/security-bundle": "^5.1",
+ "symfony/security-core": "^4.4|^5.2",
"symfony/security-csrf": "^4.4|^5.0",
"symfony/security-http": "^4.4|^5.0",
"symfony/serializer": "^5.2",
diff --git a/src/Symfony/Bundle/SecurityBundle/CacheWarmer/ExpressionCacheWarmer.php b/src/Symfony/Bundle/SecurityBundle/CacheWarmer/ExpressionCacheWarmer.php
index 7e72f08b6040f..1ca1f32ecd98e 100644
--- a/src/Symfony/Bundle/SecurityBundle/CacheWarmer/ExpressionCacheWarmer.php
+++ b/src/Symfony/Bundle/SecurityBundle/CacheWarmer/ExpressionCacheWarmer.php
@@ -40,7 +40,7 @@ public function isOptional()
public function warmUp(string $cacheDir)
{
foreach ($this->expressions as $expression) {
- $this->expressionLanguage->parse($expression, ['token', 'user', 'object', 'subject', 'roles', 'request', 'trust_resolver']);
+ $this->expressionLanguage->parse($expression, ['token', 'user', 'object', 'subject', 'role_names', 'request', 'trust_resolver']);
}
return [];
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/CacheWarmer/ExpressionCacheWarmerTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/CacheWarmer/ExpressionCacheWarmerTest.php
index d1299bffed611..53b16fcdf7774 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/CacheWarmer/ExpressionCacheWarmerTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/CacheWarmer/ExpressionCacheWarmerTest.php
@@ -26,8 +26,8 @@ public function testWarmUp()
$expressionLang->expects($this->exactly(2))
->method('parse')
->withConsecutive(
- [$expressions[0], ['token', 'user', 'object', 'subject', 'roles', 'request', 'trust_resolver']],
- [$expressions[1], ['token', 'user', 'object', 'subject', 'roles', 'request', 'trust_resolver']]
+ [$expressions[0], ['token', 'user', 'object', 'subject', 'role_names', 'request', 'trust_resolver']],
+ [$expressions[1], ['token', 'user', 'object', 'subject', 'role_names', 'request', 'trust_resolver']]
);
(new ExpressionCacheWarmer($expressions, $expressionLang))->warmUp('');
diff --git a/src/Symfony/Component/BrowserKit/AbstractBrowser.php b/src/Symfony/Component/BrowserKit/AbstractBrowser.php
index 977dd28a8807c..43e0602acacb5 100644
--- a/src/Symfony/Component/BrowserKit/AbstractBrowser.php
+++ b/src/Symfony/Component/BrowserKit/AbstractBrowser.php
@@ -311,7 +311,7 @@ public function submit(Form $form, array $values = [], array $serverParameters =
* @param string $button The text content, id, value or name of the form
This form should not contain extra fields.
- Այս ձևը չպետք է պարունակի լրացուցիչ տողեր.
+ Այս ձևը չպետք է պարունակի լրացուցիչ տողեր։The uploaded file was too large. Please try to upload a smaller file.
- Վերբեռնված ֆայլը չափազանց մեծ է: Խնդրվում է վերբեռնել ավելի փոքր չափսի ֆայլ.
+ Վերբեռնված ֆայլը չափազանց մեծ է. Խնդրվում է վերբեռնել ավելի փոքր չափսի ֆայլ։The CSRF token is invalid. Please try to resubmit the form.
- CSRF արժեքը անթույլատրելի է: Փորձեք նորից ուղարկել ձևը.
+ CSRF արժեքը անթույլատրելի է. Փորձեք նորից ուղարկել ձևը։
+
+
+ This value is not a valid HTML5 color.
+ Այս արժեքը վավեր HTML5 գույն չէ։
+
+
+ Please enter a valid birthdate.
+ Խնդրում ենք մուտքագրել վավեր ծննդյան ամսաթիվ։
+
+
+ The selected choice is invalid.
+ Ընտրված ընտրությունն անվավեր է։
+
+
+ The collection is invalid.
+ Համախումբն անվավեր է։
+
+
+ Please select a valid color.
+ Խնդրում ենք ընտրել վավեր գույն։
+
+
+ Please select a valid country.
+ Խնդրում ենք ընտրել վավեր երկիր։
+
+
+ Please select a valid currency.
+ Խնդրում ենք ընտրել վավեր արժույթ։
+
+
+ Please choose a valid date interval.
+ Խնդրում ենք ընտրել ճիշտ ամսաթվերի միջակայք։
+
+
+ Please enter a valid date and time.
+ Խնդրում ենք մուտքագրել վավեր ամսաթիվ և ժամ։
+
+
+ Please enter a valid date.
+ Խնդրում ենք մուտքագրել վավեր ամսաթիվ։
+
+
+ Please select a valid file.
+ Խնդրում ենք ընտրել վավեր ֆայլ։
+
+
+ The hidden field is invalid.
+ Թաքնված դաշտը անվավեր է։
+
+
+ Please enter an integer.
+ Խնդրում ենք մուտքագրել ամբողջ թիվ։
+
+
+ Please select a valid language.
+ Խնդրում ենք ընտրել վավեր լեզու։
+
+
+ Please select a valid locale.
+ Խնդրում ենք ընտրել վավեր տեղայնացում։
+
+
+ Please enter a valid money amount.
+ Խնդրում ենք մուտքագրել վավեր գումար։
+
+
+ Please enter a number.
+ Խնդրում ենք մուտքագրել համար։
+
+
+ The password is invalid.
+ Գաղտնաբառն անվավեր է։
+
+
+ Please enter a percentage value.
+ Խնդրում ենք մուտքագրել տոկոսային արժեք։
+
+
+ The values do not match.
+ Արժեքները չեն համընկնում։
+
+
+ Please enter a valid time.
+ Մուտքագրեք վավեր ժամանակ։
+
+
+ Please select a valid timezone.
+ Խնդրում ենք ընտրել վավեր ժամային գոտի։
+
+
+ Please enter a valid URL.
+ Խնդրում ենք մուտքագրել վավեր URL։
+
+
+ Please enter a valid search term.
+ Խնդրում ենք մուտքագրել վավեր որոնման տերմին։
+
+
+ Please provide a valid phone number.
+ Խնդրում ենք տրամադրել վավեր հեռախոսահամար։
+
+
+ The checkbox has an invalid value.
+ Նշման վանդակը անվավեր արժեք ունի։
+
+
+ Please enter a valid email address.
+ Խնդրում ենք մուտքագրել վավեր էլ-հասցե։
+
+
+ Please select a valid option.
+ Խնդրում ենք ընտրել ճիշտ տարբերակ։
+
+
+ Please select a valid range.
+ Խնդրում ենք ընտրել վավեր տիրույթ։
+
+
+ Please enter a valid week.
+ Մուտքագրեք վավեր շաբաթ։