From a292af13bf78c56629bb38312866cb0c417588d8 Mon Sep 17 00:00:00 2001 From: Ayesh Karunaratne Date: Tue, 26 Mar 2024 15:27:58 +0700 Subject: [PATCH 1/7] [PHP 8.4] Fixes for implicit nullability deprecation (#20133) Fixes all issues that emit deprecation notices on PHP 8.4 for implicit nullable parameter type declarations. Related to #20128. See: - [RFC](https://wiki.php.net/rfc/deprecate-implicitly-nullable-types) - [PHP 8.4: Implicitly nullable parameter declarations deprecated](https://php.watch/versions/8.4/implicitly-marking-parameter-type-nullable-deprecated) Co-authored-by: Wilmer Arambula Co-authored-by: Alexander Makarov --- framework/base/Component.php | 2 +- framework/db/ActiveQuery.php | 2 +- framework/db/ActiveQueryInterface.php | 2 +- framework/db/ActiveRelationTrait.php | 2 +- framework/mail/BaseMessage.php | 2 +- framework/mail/MessageInterface.php | 2 +- tests/framework/console/FakePhp71Controller.php | 2 +- tests/framework/di/ContainerTest.php | 2 +- tests/framework/di/stubs/Alpha.php | 8 ++++---- tests/framework/web/FakePhp71Controller.php | 2 +- tests/framework/web/FakePhp7Controller.php | 4 ++-- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/framework/base/Component.php b/framework/base/Component.php index fb4805df0ce..f2eb9bf05c1 100644 --- a/framework/base/Component.php +++ b/framework/base/Component.php @@ -605,7 +605,7 @@ public function off($name, $handler = null) * @param string $name the event name * @param Event|null $event the event instance. If not set, a default [[Event]] object will be created. */ - public function trigger($name, Event $event = null) + public function trigger($name, ?Event $event = null) { $this->ensureBehaviors(); diff --git a/framework/db/ActiveQuery.php b/framework/db/ActiveQuery.php index 2153e7db155..8f5fc9903e1 100644 --- a/framework/db/ActiveQuery.php +++ b/framework/db/ActiveQuery.php @@ -785,7 +785,7 @@ public function orOnCondition($condition, $params = []) * @throws InvalidConfigException when query is not initialized properly * @see via() */ - public function viaTable($tableName, $link, callable $callable = null) + public function viaTable($tableName, $link, ?callable $callable = null) { $modelClass = $this->primaryModel ? get_class($this->primaryModel) : $this->modelClass; $relation = new self($modelClass, [ diff --git a/framework/db/ActiveQueryInterface.php b/framework/db/ActiveQueryInterface.php index ec53af2d4bc..f15e49eb008 100644 --- a/framework/db/ActiveQueryInterface.php +++ b/framework/db/ActiveQueryInterface.php @@ -97,7 +97,7 @@ public function with(); * Its signature should be `function($query)`, where `$query` is the query to be customized. * @return $this the relation object itself. */ - public function via($relationName, callable $callable = null); + public function via($relationName, ?callable $callable = null); /** * Finds the related records for the specified primary record. diff --git a/framework/db/ActiveRelationTrait.php b/framework/db/ActiveRelationTrait.php index 7e01e25fd99..467203e8a9f 100644 --- a/framework/db/ActiveRelationTrait.php +++ b/framework/db/ActiveRelationTrait.php @@ -104,7 +104,7 @@ public function __clone() * Its signature should be `function($query)`, where `$query` is the query to be customized. * @return $this the relation object itself. */ - public function via($relationName, callable $callable = null) + public function via($relationName, ?callable $callable = null) { $relation = $this->primaryModel->getRelation($relationName); $callableUsed = $callable !== null; diff --git a/framework/mail/BaseMessage.php b/framework/mail/BaseMessage.php index ca53dac10c9..30940994499 100644 --- a/framework/mail/BaseMessage.php +++ b/framework/mail/BaseMessage.php @@ -39,7 +39,7 @@ abstract class BaseMessage extends BaseObject implements MessageInterface * the "mailer" application component will be used instead. * @return bool whether this message is sent successfully. */ - public function send(MailerInterface $mailer = null) + public function send(?MailerInterface $mailer = null) { if ($mailer === null && $this->mailer === null) { $mailer = Yii::$app->getMailer(); diff --git a/framework/mail/MessageInterface.php b/framework/mail/MessageInterface.php index 091dce5faa7..e4c62a2d528 100644 --- a/framework/mail/MessageInterface.php +++ b/framework/mail/MessageInterface.php @@ -209,7 +209,7 @@ public function embedContent($content, array $options = []); * If null, the "mailer" application component will be used instead. * @return bool whether this message is sent successfully. */ - public function send(MailerInterface $mailer = null); + public function send(?MailerInterface $mailer = null); /** * Returns string representation of this message. diff --git a/tests/framework/console/FakePhp71Controller.php b/tests/framework/console/FakePhp71Controller.php index dbed836f8d1..cc23ae60299 100644 --- a/tests/framework/console/FakePhp71Controller.php +++ b/tests/framework/console/FakePhp71Controller.php @@ -14,7 +14,7 @@ class FakePhp71Controller extends Controller { - public function actionInjection($before, Request $request, $between, DummyService $dummyService, Post $post = null, $after) + public function actionInjection($before, Request $request, $between, DummyService $dummyService, ?Post $post = null, $after) { } diff --git a/tests/framework/di/ContainerTest.php b/tests/framework/di/ContainerTest.php index ba62b598b73..2555f43c2d6 100644 --- a/tests/framework/di/ContainerTest.php +++ b/tests/framework/di/ContainerTest.php @@ -252,7 +252,7 @@ public function testOptionalDependencies() { $container = new Container(); // Test optional unresolvable dependency. - $closure = function (QuxInterface $test = null) { + $closure = function (?QuxInterface $test = null) { return $test; }; $this->assertNull($container->invoke($closure)); diff --git a/tests/framework/di/stubs/Alpha.php b/tests/framework/di/stubs/Alpha.php index 151d2f109bb..a5af3ffed78 100644 --- a/tests/framework/di/stubs/Alpha.php +++ b/tests/framework/di/stubs/Alpha.php @@ -12,10 +12,10 @@ class Alpha extends BaseObject public $color = true; public function __construct( - Beta $beta = null, - QuxInterface $omega = null, - Unknown $unknown = null, - AbstractColor $color = null + ?Beta $beta = null, + ?QuxInterface $omega = null, + ?Unknown $unknown = null, + ?AbstractColor $color = null ) { $this->beta = $beta; $this->omega = $omega; diff --git a/tests/framework/web/FakePhp71Controller.php b/tests/framework/web/FakePhp71Controller.php index d8aa0e406c5..f84214c6e8d 100644 --- a/tests/framework/web/FakePhp71Controller.php +++ b/tests/framework/web/FakePhp71Controller.php @@ -21,7 +21,7 @@ class FakePhp71Controller extends Controller { public $enableCsrfValidation = false; - public function actionInjection($before, Request $request, $between, VendorImage $vendorImage, Post $post = null, $after) + public function actionInjection($before, Request $request, $between, VendorImage $vendorImage, ?Post $post = null, $after) { } diff --git a/tests/framework/web/FakePhp7Controller.php b/tests/framework/web/FakePhp7Controller.php index 4d267a85e15..381ba3e0ee3 100644 --- a/tests/framework/web/FakePhp7Controller.php +++ b/tests/framework/web/FakePhp7Controller.php @@ -17,11 +17,11 @@ class FakePhp7Controller extends Controller { public $enableCsrfValidation = false; - public function actionAksi1(int $foo, float $bar = null, bool $true, bool $false) + public function actionAksi1(int $foo, ?float $bar = null, bool $true, bool $false) { } - public function actionStringy(string $foo = null) + public function actionStringy(?string $foo = null) { } } From 923c30938df274a3b57a77fed9683dca85ad5a8a Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Tue, 26 Mar 2024 13:31:20 -0300 Subject: [PATCH 2/7] Fix optional parameter declared before required parameter implicitly (#20139) --- tests/framework/console/FakePhp71Controller.php | 11 ++++++++--- tests/framework/web/FakePhp71Controller.php | 11 ++++++++--- tests/framework/web/FakePhp7Controller.php | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/tests/framework/console/FakePhp71Controller.php b/tests/framework/console/FakePhp71Controller.php index cc23ae60299..44ba0fbd310 100644 --- a/tests/framework/console/FakePhp71Controller.php +++ b/tests/framework/console/FakePhp71Controller.php @@ -14,9 +14,14 @@ class FakePhp71Controller extends Controller { - public function actionInjection($before, Request $request, $between, DummyService $dummyService, ?Post $post = null, $after) - { - + public function actionInjection( + $before, + Request $request, + $between, + DummyService $dummyService, + ?Post $post, + $after + ) { } public function actionNullableInjection(?Request $request, ?Post $post) diff --git a/tests/framework/web/FakePhp71Controller.php b/tests/framework/web/FakePhp71Controller.php index f84214c6e8d..c48243e2fed 100644 --- a/tests/framework/web/FakePhp71Controller.php +++ b/tests/framework/web/FakePhp71Controller.php @@ -21,9 +21,14 @@ class FakePhp71Controller extends Controller { public $enableCsrfValidation = false; - public function actionInjection($before, Request $request, $between, VendorImage $vendorImage, ?Post $post = null, $after) - { - + public function actionInjection( + $before, + Request $request, + $between, + VendorImage $vendorImage, + ?Post $post, + $after + ) { } public function actionNullableInjection(?Request $request, ?Post $post) diff --git a/tests/framework/web/FakePhp7Controller.php b/tests/framework/web/FakePhp7Controller.php index 381ba3e0ee3..74008f49fad 100644 --- a/tests/framework/web/FakePhp7Controller.php +++ b/tests/framework/web/FakePhp7Controller.php @@ -17,7 +17,7 @@ class FakePhp7Controller extends Controller { public $enableCsrfValidation = false; - public function actionAksi1(int $foo, ?float $bar = null, bool $true, bool $false) + public function actionAksi1(int $foo, ?float $bar, bool $true, bool $false) { } From 953a1265d7f68b936069d824f9dd5bf6b0fb8305 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Tue, 26 Mar 2024 15:04:45 -0300 Subject: [PATCH 3/7] Update `ezyang/htmlpurifier` dependency to version `4.17`. --- .github/workflows/build.yml | 5 +++++ .github/workflows/ci-mssql.yml | 5 +++++ .github/workflows/ci-mysql.yml | 7 ++++++- .github/workflows/ci-pgsql.yml | 7 ++++++- .github/workflows/ci-sqlite.yml | 7 ++++++- composer.json | 2 +- framework/composer.json | 2 +- 7 files changed, 30 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a0e2bd033aa..9e8e898b3d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,8 +65,13 @@ jobs: uses: niden/actions-memcached@v7 - name: Install dependencies. + if: matrix.php != '8.4' run: composer update $DEFAULT_COMPOSER_FLAGS + - name: Install dependencies with PHP 8.4. + if: matrix.php == '8.4' + run: composer update $DEFAULT_COMPOSER_FLAGS --ignore-platform-reqs + - name: Run tests with PHPUnit and generate coverage. if: matrix.php == '7.4' run: vendor/bin/phpunit --verbose --exclude-group $PHPUNIT_EXCLUDE_GROUP --coverage-clover=coverage.xml --colors=always diff --git a/.github/workflows/ci-mssql.yml b/.github/workflows/ci-mssql.yml index 698cf613040..5ed0abcb763 100644 --- a/.github/workflows/ci-mssql.yml +++ b/.github/workflows/ci-mssql.yml @@ -66,8 +66,13 @@ jobs: run: composer self-update - name: Install dependencies with composer + if: matrix.php != '8.4' run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + - name: Install dependencies with PHP 8.4. + if: matrix.php == '8.4' + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ignore-platform-reqs --ansi + - name: Run MSSQL tests with PHPUnit and generate coverage. run: vendor/bin/phpunit --group mssql --coverage-clover=coverage.xml --colors=always diff --git a/.github/workflows/ci-mysql.yml b/.github/workflows/ci-mysql.yml index 7bec2352248..5753d916958 100644 --- a/.github/workflows/ci-mysql.yml +++ b/.github/workflows/ci-mysql.yml @@ -47,9 +47,14 @@ jobs: php-version: ${{ matrix.php }} tools: composer:v2, pecl - - name: Install dependencies with composer. + - name: Install dependencies with composer + if: matrix.php != '8.4' run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + - name: Install dependencies with PHP 8.4. + if: matrix.php == '8.4' + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ignore-platform-reqs --ansi + - name: Run MySQL tests with PHPUnit and generate coverage. run: vendor/bin/phpunit --group mysql --coverage-clover=coverage.xml --colors=always diff --git a/.github/workflows/ci-pgsql.yml b/.github/workflows/ci-pgsql.yml index 8dd8b3d6da5..4b926645b82 100644 --- a/.github/workflows/ci-pgsql.yml +++ b/.github/workflows/ci-pgsql.yml @@ -51,9 +51,14 @@ jobs: - name: Update composer. run: composer self-update - - name: Install dependencies with composer. + - name: Install dependencies with composer + if: matrix.php != '8.4' run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + - name: Install dependencies with PHP 8.4. + if: matrix.php == '8.4' + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ignore-platform-reqs --ansi + - name: Run Pgsql tests with PHPUnit and generate coverage. run: vendor/bin/phpunit --group pgsql --coverage-clover=coverage.xml --colors=always diff --git a/.github/workflows/ci-sqlite.yml b/.github/workflows/ci-sqlite.yml index bf53dc35975..fe7405ea4e2 100644 --- a/.github/workflows/ci-sqlite.yml +++ b/.github/workflows/ci-sqlite.yml @@ -40,9 +40,14 @@ jobs: - name: Update composer. run: composer self-update - - name: Install dependencies with composer. + - name: Install dependencies with composer + if: matrix.php != '8.4' run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + - name: Install dependencies with PHP 8.4. + if: matrix.php == '8.4' + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ignore-platform-reqs --ansi + - name: Run SQLite tests with PHPUnit and generate coverage. run: vendor/bin/phpunit --group sqlite --coverage-clover=coverage.xml --colors=always diff --git a/composer.json b/composer.json index 90dc2720717..af172dbb762 100644 --- a/composer.json +++ b/composer.json @@ -73,7 +73,7 @@ "ext-ctype": "*", "lib-pcre": "*", "yiisoft/yii2-composer": "~2.0.4", - "ezyang/htmlpurifier": "^4.6", + "ezyang/htmlpurifier": "^4.17", "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0", "bower-asset/jquery": "3.7.*@stable | 3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", "bower-asset/inputmask": "^5.0.8 ", diff --git a/framework/composer.json b/framework/composer.json index 37c438afb17..d24703fb442 100644 --- a/framework/composer.json +++ b/framework/composer.json @@ -68,7 +68,7 @@ "ext-ctype": "*", "lib-pcre": "*", "yiisoft/yii2-composer": "~2.0.4", - "ezyang/htmlpurifier": "^4.6", + "ezyang/htmlpurifier": "^4.17", "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0", "bower-asset/jquery": "3.7.*@stable | 3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", "bower-asset/inputmask": "^5.0.8 ", From 26f9e326c4ceae2d67a8977ef83444986b7aa83e Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Wed, 27 Mar 2024 06:09:44 -0300 Subject: [PATCH 4/7] Add line to `CHANGELOG.md`. --- framework/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 57567d20712..84c56493049 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -22,7 +22,7 @@ Yii Framework 2 Change Log - Enh #20034: Added `yii\helpers\BaseStringHelper::findBetween()` to retrieve a substring that lies between two strings (salehhashemi1992) - Enh #20121: Added `yiisoft/yii2-coding-standards` to composer `require-dev` and lint code to comply with PSR12 (razvanphp) - Enh #20134: Raise minimum `PHP` version to `7.3` (@terabytesoftw) - +- Bug #20141: Update `ezyang/htmlpurifier` dependency to version `4.17` (@terabytesoftw) 2.0.49.2 October 12, 2023 ------------------------- From 1cdb04236d640c80d3193f77af0c381cd90253a3 Mon Sep 17 00:00:00 2001 From: Rutger Hertogh Date: Wed, 27 Mar 2024 21:19:02 +0100 Subject: [PATCH 5/7] Added "Versions & PHP compatibility" section to readme.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index b2aa8475b7a..4bc05115c8d 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,20 @@ and a [Definitive Guide Mirror](http://stuff.cebe.cc/yii2docs/) which is updated - For Yii 1.1 users, there is [Upgrading from Yii 1.1](https://www.yiiframework.com/doc/guide/2.0/en/intro-upgrade-from-v1) to get an idea of what has changed in 2.0. +Versions & PHP compatibility +---------------------------- + +| Yii2 Version | PHP version | Development status | EOL ¹ | +|--------------|----------------|-----------------------------------|----------------------------------------------------------------| +| <= 2.0.49.* | >= 5.4, <= 8.3 | security fixes only | 23 Nov 2026 ³ | +| >= 2.0.50 | >= 7.3, <= 8.4 | bug fixes and security fixes only | bugfixes till 23 Nov 2026 ³, security fixes till 21 Nov 2027 ⁴ | +| >= 2.2.0 ² | >= 8.1 | active development | | + +¹ All mentioned dates may be subject to change and no rights can be derived from them. +² Note: Yii 2.1 was [skipped](https://github.com/yiisoft/yii2/discussions/19831#discussioncomment-5858046), [Yii 2.2](https://github.com/yiisoft/yii2/tree/2.2) has not yet been released. +³ [PHP 8.3 EOL date](https://www.php.net/supported-versions.php). +⁴ [Expected PHP 8.4 EOL date](https://wiki.php.net/todo/php84). + Community --------- From e56e77732506a98bb79febe85d2bcb83b72e0b33 Mon Sep 17 00:00:00 2001 From: skepticspriggan <91023755+skepticspriggan@users.noreply.github.com> Date: Tue, 2 Apr 2024 23:40:02 +0200 Subject: [PATCH 6/7] Fix #20083: Fix deprecated warning implicit conversion from float --- framework/CHANGELOG.md | 1 + framework/i18n/Formatter.php | 2 +- tests/framework/i18n/FormatterDateTest.php | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 84c56493049..593400797e3 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -20,6 +20,7 @@ Yii Framework 2 Change Log - Enh #20042: Add empty array check to `ActiveQueryTrait::findWith()` (renkas) - Enh #20032: Added `yii\helpers\BaseStringHelper::mask()` method for string masking with multibyte support (salehhashemi1992) - Enh #20034: Added `yii\helpers\BaseStringHelper::findBetween()` to retrieve a substring that lies between two strings (salehhashemi1992) +- Bug #20083: Fix deprecated warning implicit conversion from float (skepticspriggan) - Enh #20121: Added `yiisoft/yii2-coding-standards` to composer `require-dev` and lint code to comply with PSR12 (razvanphp) - Enh #20134: Raise minimum `PHP` version to `7.3` (@terabytesoftw) - Bug #20141: Update `ezyang/htmlpurifier` dependency to version `4.17` (@terabytesoftw) diff --git a/framework/i18n/Formatter.php b/framework/i18n/Formatter.php index b72385eaa59..c1b9d9106eb 100644 --- a/framework/i18n/Formatter.php +++ b/framework/i18n/Formatter.php @@ -1059,7 +1059,7 @@ public function asDuration($value, $implodeString = ', ', $negativeSign = '-') } elseif (is_numeric($value)) { $isNegative = $value < 0; $zeroDateTime = (new DateTime())->setTimestamp(0); - $valueDateTime = (new DateTime())->setTimestamp(abs($value)); + $valueDateTime = (new DateTime())->setTimestamp(abs((int) $value)); $interval = $valueDateTime->diff($zeroDateTime); } elseif (strncmp($value, 'P-', 2) === 0) { $interval = new DateInterval('P' . substr($value, 2)); diff --git a/tests/framework/i18n/FormatterDateTest.php b/tests/framework/i18n/FormatterDateTest.php index c62ff491b11..1af75fc49e0 100644 --- a/tests/framework/i18n/FormatterDateTest.php +++ b/tests/framework/i18n/FormatterDateTest.php @@ -536,6 +536,7 @@ public function testAsDuration() // other options $this->assertSame('minus 244 seconds', $this->formatter->asDuration($interval_244_seconds, ' and ', 'minus ')); $this->assertSame('minus 4 minutes and 4 seconds', $this->formatter->asDuration(-244, ' and ', 'minus ')); + $this->assertSame('1 second', $this->formatter->asDuration(1.5)); // Pass a inverted DateInterval string $this->assertSame('-1 year, 2 months, 10 days, 2 hours, 30 minutes', $this->formatter->asDuration('2008-05-11T15:30:00Z/2007-03-01T13:00:00Z')); From f7cba1b9de5efec695771868931ac48c0bd85a2f Mon Sep 17 00:00:00 2001 From: skepticspriggan <91023755+skepticspriggan@users.noreply.github.com> Date: Tue, 2 Apr 2024 23:40:39 +0200 Subject: [PATCH 7/7] Fix required branch not specified (#20143) --- docs/internals/git-workflow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/internals/git-workflow.md b/docs/internals/git-workflow.md index 11e8a499a6c..b3ede5011a0 100644 --- a/docs/internals/git-workflow.md +++ b/docs/internals/git-workflow.md @@ -111,7 +111,7 @@ review your suggestion, and provide appropriate feedback along the way. ### 2. Pull the latest code from the main Yii branch ``` -git pull upstream +git pull upstream master ``` You should start at this point for every new contribution to make sure you are working on the latest code.