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/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 --------- 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/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. diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index e0164c0136f..8d01a3f505f 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -20,10 +20,12 @@ 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 #20087: Add custom attributes to script tags (skepticspriggan) - Enh #20121: Added `yiisoft/yii2-coding-standards` to composer `require-dev` and lint code to comply with PSR12 (razvanphp) - New: Added `yii\caching\CallbackDependency` to allow using a callback to determine if a cache dependency is still valid (laxity7) - 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 ------------------------- 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 ", diff --git a/framework/db/BaseActiveRecord.php b/framework/db/BaseActiveRecord.php index 41732caab1d..8931c84f3ed 100644 --- a/framework/db/BaseActiveRecord.php +++ b/framework/db/BaseActiveRecord.php @@ -681,6 +681,7 @@ public function getDirtyAttributes($names = null) * @param array|null $attributeNames list of attribute names that need to be saved. Defaults to null, * meaning all attributes that are loaded from DB will be saved. * @return bool whether the saving succeeded (i.e. no validation errors occurred). + * @throws Exception in case update or insert failed. */ public function save($runValidation = true, $attributeNames = null) { diff --git a/framework/helpers/BaseHtml.php b/framework/helpers/BaseHtml.php index e610af6ca1f..0eab768e6e9 100644 --- a/framework/helpers/BaseHtml.php +++ b/framework/helpers/BaseHtml.php @@ -220,6 +220,11 @@ public static function style($content, $options = []) */ public static function script($content, $options = []) { + $view = Yii::$app->getView(); + if ($view instanceof \yii\web\View && !empty($view->scriptOptions)) { + $options = array_merge($view->scriptOptions, $options); + } + return static::tag('script', $content, $options); } 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/framework/web/View.php b/framework/web/View.php index 21970711a59..a23b1228ca1 100644 --- a/framework/web/View.php +++ b/framework/web/View.php @@ -131,6 +131,11 @@ class View extends \yii\base\View * @see registerJsFile() */ public $jsFiles = []; + /** + * @since 2.0.50 + * @var array the script tag options. + */ + public $scriptOptions = []; private $_assetManager; diff --git a/tests/framework/helpers/HtmlTest.php b/tests/framework/helpers/HtmlTest.php index c8d36466813..24c8186181b 100644 --- a/tests/framework/helpers/HtmlTest.php +++ b/tests/framework/helpers/HtmlTest.php @@ -90,6 +90,21 @@ public function testScript() $this->assertEquals("", Html::script($content, ['type' => 'text/js'])); } + public function testScriptCustomAttribute() + { + $nonce = Yii::$app->security->generateRandomString(); + $this->mockApplication([ + 'components' => [ + 'view' => [ + 'class' => 'yii\web\View', + 'scriptOptions' => ['nonce' => $nonce], + ], + ], + ]); + $content = 'a <>'; + $this->assertEquals("", Html::script($content)); + } + public function testCssFile() { $this->assertEquals('', Html::cssFile('http://example.com')); 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'));