diff --git a/docs/guide-uk/intro-yii.md b/docs/guide-uk/intro-yii.md index 4a8d293e70..e9c890db4d 100644 --- a/docs/guide-uk/intro-yii.md +++ b/docs/guide-uk/intro-yii.md @@ -30,12 +30,10 @@ Yii – це універсальний фреймворк і може бути Завдяки надійній архітектурі розширень Yii, досить легко використовувати або розробляти поширюванні розширення. - Висока швидкодія завжди є головною ціллю Yii. -Yii — не проект однієї людини. Він підтримується і розвивається [сильною командою][about_yii] і великою спільнотою розробників, +Yii — не проект однієї людини. Він підтримується і розвивається [сильною командою](https://www.yiiframework.com/team/) і великою спільнотою розробників, які їй допомагають. Команда розробників фреймворку Yii стежать за тенденціями веб-розробки і розвитком інших проектів. Найбільш значимі можливості та кращі практики регулярно впроваджуються у фреймворк у вигляді простих й елегантних інтерфейсів. -[about_yii]: http://www.yiiframework.com/about/ - Версії Yii ---------- diff --git a/docs/guide/security-authentication.md b/docs/guide/security-authentication.md index a6890f8926..b353d048be 100644 --- a/docs/guide/security-authentication.md +++ b/docs/guide/security-authentication.md @@ -49,7 +49,9 @@ the following methods: If a particular method is not needed, you may implement it with an empty body. For example, if your application is a pure stateless RESTful application, you would only need to implement [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] -and [[yii\web\IdentityInterface::getId()|getId()]] while leaving all other methods with an empty body. +and [[yii\web\IdentityInterface::getId()|getId()]] while leaving all other methods with an empty body. Or if your +application uses session only authentication, you would need to implement all the methods except +[[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]. In the following example, an [[yii\web\User::identityClass|identity class]] is implemented as an [Active Record](db-active-record.md) class associated with the `user` database table. @@ -98,7 +100,7 @@ class User extends ActiveRecord implements IdentityInterface } /** - * @return string current user auth key + * @return string|null current user auth key */ public function getAuthKey() { @@ -107,7 +109,7 @@ class User extends ActiveRecord implements IdentityInterface /** * @param string $authKey - * @return bool if auth key is valid for current user + * @return bool|null if auth key is valid for current user */ public function validateAuthKey($authKey) { @@ -117,7 +119,7 @@ class User extends ActiveRecord implements IdentityInterface ``` You may use the following code to generate an auth key for each -user and store it in the `user` table: +user and then store it in the `user` table: ```php class User extends ActiveRecord implements IdentityInterface diff --git a/framework/BaseYii.php b/framework/BaseYii.php index d114048a0b..cc1e6bfbed 100644 --- a/framework/BaseYii.php +++ b/framework/BaseYii.php @@ -93,7 +93,7 @@ class BaseYii */ public static function getVersion() { - return '2.0.42-dev'; + return '2.0.43-dev'; } /** diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index ef9e84a5de..7bcff0e094 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -1,31 +1,38 @@ Yii Framework 2 Change Log ========================== -2.0.42 under development +2.0.43 under development ------------------------ -- Bug #18323: Fix client validation of RadioList when there are disabled items (toir427) -- Enh #18534: Added `prepareSearchQuery` property in `yii\rest\IndexAction` (programmis) -- Enh #18566: Throw the original exception when `yii\web\Controller::bindInjectedParams()` catches HttpException (pigochu) -- Bug #18585: Fix `yii\validators\EmailValidator` to handle an edge case where `IDN` is enabled, but fails ascii conversion for valid email addresses (ihitbuttons) -- Bug #18574: Fix `yii\web\DbSession` to use the correct db if strict mode is used (Mignar) +- no changes in this release. + + +2.0.42 May 05, 2021 +------------------- + +- Bug #14343: Fix `yii\test\ActiveFixture` to use model's DB connection instead of the default one (margori, bizley) +- Bug #17174: Fix `yii\db\BaseActiveRecord::unlink()` to not ignore `on` conditions in `via` relations (bizley) +- Bug #17203: Fix `yii\db\Connection` to persist customized `queryBuilder` configuration after the `close()` → `open()` cycle (silverfire) - Bug #17479: Fix `yii\grid\ActionColumn` to render icons when no glyphicons are available (simialbi) +- Bug #17631: Fix `yii\widgets\BaseListView` to properly render custom summary (sjaakp, bizley) +- Bug #18323: Fix client validation of RadioList when there are disabled items (toir427) +- Bug #18325: Fix `yii\db\pgsql\Schema` to respect non-default PgSQL schema name for data types (theonedemon, silverfire) +- Bug #18526: Fix `yii\caching\DbCache` to work with MSSQL, add `normalizeTableRowData()` to `yii\db\mssql\QueryBuilder::upsert()` (darkdef) - Bug #18544: Fix `yii\validators\NumberValidator` to disallow values with whitespaces (bizley) - Bug #18552: Fix `yii\data\SqlDataProvider` to properly handle SQL with `ORDER BY` clause (bizley) -- Bug #17174: Fix `yii\db\BaseActiveRecord::unlink()` to not ignore `on` conditions in `via` relations (bizley) - Bug #18557: Fix `yii\data\ActiveDataProvider` to handle DB connection configuration of different type than just `yii\db\Connection` (bizley) -- Bug #18526: Fix `yii\caching\DbCache` to work with MSSQL, add `normalizeTableRowData()` to `yii\db\mssql\QueryBuilder::upsert()` (darkdef) -- Bug #14343: Fix `yii\test\ActiveFixture` to use model's DB connection instead of the default one (margori, bizley) -- Bug #17631: Fix `yii\widgets\BaseListView` to properly render custom summary (sjaakp, bizley) -- Bug #17203: Fix `yii\db\Connection` to persist customized `queryBuilder` configuration after the `close()` → `open()` cycle (silverfire) -- Bug #18325: Fix `yii\db\pgsql\Schema` to respect non-default PgSQL schema name for data types (theonedemon, silverfire) -- Bug #18593: Fix setting the `maxlength` attribute for `Html::activeInput()` and `Html::activeTextArea()` based on `length` parameter of validator (BSCheshir) -- Bug #18592: Fix `yii\db\Command::getRawSql()` to not replace query params in invalid places (sartor) +- Bug #18574: Fix `yii\web\DbSession` to use the correct db if strict mode is used (Mignar) +- Bug #18585: Fix `yii\validators\EmailValidator` to handle an edge case where `IDN` is enabled, but fails ascii conversion for valid email addresses (ihitbuttons) - Bug #18590: Fix `yii\web\UrlManager` to instantiate cache only when it's actually needed (bizley) -- Enh #18569: Add `NumberValidator::$allowArray` (raidkon) +- Bug #18592: Fix `yii\db\Command::getRawSql()` to not replace query params in invalid places (sartor) +- Bug #18593: Fix setting the `maxlength` attribute for `Html::activeInput()` and `Html::activeTextArea()` based on `length` parameter of validator (BSCheshir) +- Bug #18604: Function alterColumn for MSSQL build incorrect query with default values `NULL` and other expressions (darkdef) - Bug #18613: Do not call static methods non-statically in `BaseActiveRecord` (samdark) - Bug #18619: Do not modify `yii\web\Cookie::$path` on `yii\web\Response::sendCookies()` (mikk150) -- Bug #18604: Function alterColumn for MSSQL build incorrect query with default values `NULL` and other expressions (darkdef) +- Bug #18624: Fix `yii\di\Container` to properly resolve dependencies in case of PHP 8 union types (bizley) +- Enh #18534: Add `prepareSearchQuery` property in `yii\rest\IndexAction` (programmis) +- Enh #18566: Throw the original exception when `yii\web\Controller::bindInjectedParams()` catches HttpException (pigochu) +- Enh #18569: Add `NumberValidator::$allowArray` (raidkon) 2.0.41.1 March 04, 2021 diff --git a/framework/caching/DbCache.php b/framework/caching/DbCache.php index 1b82305971..191ba5c005 100644 --- a/framework/caching/DbCache.php +++ b/framework/caching/DbCache.php @@ -86,6 +86,7 @@ class DbCache extends Cache protected $isVarbinaryDataField; + /** * Initializes the DbCache component. * This method will initialize the [[db]] property to make sure it refers to a valid DB connection. @@ -297,9 +298,8 @@ class DbCache extends Cache } /** - * @return bool - * - * Checking Mssql: if field is varbinary - return true + * @return bool whether field is MSSQL varbinary + * @since 2.0.42 */ protected function isVarbinaryDataField() { @@ -311,8 +311,8 @@ class DbCache extends Cache } /** - * @return string - * Returning `data` field name with converting for usage in MSSQL (if needs) + * @return string `data` field name converted for usage in MSSQL (if needed) + * @since 2.0.42 */ protected function getDataFieldName() { @@ -320,10 +320,8 @@ class DbCache extends Cache } /** - * @param $value - * @return PdoValue - * - * Return PdoValue or direct $value for usage in MSSQL + * @return PdoValue PdoValue or direct $value for usage in MSSQL + * @since 2.0.42 */ protected function getDataFieldValue($value) { diff --git a/framework/classes.php b/framework/classes.php index ac9767168b..028210c63d 100644 --- a/framework/classes.php +++ b/framework/classes.php @@ -174,6 +174,7 @@ return [ 'yii\db\cubrid\Schema' => YII2_PATH . '/db/cubrid/Schema.php', 'yii\db\cubrid\conditions\LikeConditionBuilder' => YII2_PATH . '/db/cubrid/conditions/LikeConditionBuilder.php', 'yii\db\mssql\ColumnSchema' => YII2_PATH . '/db/mssql/ColumnSchema.php', + 'yii\db\mssql\ColumnSchemaBuilder' => YII2_PATH . '/db/mssql/ColumnSchemaBuilder.php', 'yii\db\mssql\DBLibPDO' => YII2_PATH . '/db/mssql/DBLibPDO.php', 'yii\db\mssql\PDO' => YII2_PATH . '/db/mssql/PDO.php', 'yii\db\mssql\QueryBuilder' => YII2_PATH . '/db/mssql/QueryBuilder.php', diff --git a/framework/db/Connection.php b/framework/db/Connection.php index c8fa4161c1..391ef7f7f7 100644 --- a/framework/db/Connection.php +++ b/framework/db/Connection.php @@ -429,10 +429,8 @@ class Connection extends Component * Is used to restore a QueryBuilder configuration after the connection close/open cycle. * * @see restoreQueryBuilderConfiguration() - * @since 2.0.42 */ private $_queryBuilderConfigurations = []; - /** * @var Transaction the currently active transaction */ @@ -892,8 +890,6 @@ class Connection extends Component /** * Restores custom QueryBuilder configuration after the connection close/open cycle - * - * @since 2.0.42 */ private function restoreQueryBuilderConfiguration() { diff --git a/framework/db/mssql/ColumnSchemaBuilder.php b/framework/db/mssql/ColumnSchemaBuilder.php index 35a8ac1ac9..f95d9dd98e 100644 --- a/framework/db/mssql/ColumnSchemaBuilder.php +++ b/framework/db/mssql/ColumnSchemaBuilder.php @@ -13,6 +13,10 @@ use yii\db\Expression; /** * ColumnSchemaBuilder is the schema builder for MSSQL databases. * + * @property-read string|null $checkValue The `CHECK` constraint for the column. This property is read-only. + * @property-read string|Expression|null $defaultValue Default value of the column. This property is + * read-only. + * * @author Valerii Gorbachev * @since 2.0.42 */ @@ -20,6 +24,7 @@ class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder { protected $format = '{type}{length}{notnull}{unique}{default}{check}{append}'; + /** * Builds the full string for the column's schema. * @return string @@ -36,7 +41,7 @@ class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder } /** - * Changes default format string to MSSQL ALTER COMMAND + * Changes default format string to MSSQL ALTER COMMAND. */ public function setAlterColumnFormat() { @@ -45,7 +50,7 @@ class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder /** * Getting the `Default` value for constraint - * @return string|Expression|null + * @return string|Expression|null default value of the column. */ public function getDefaultValue() { @@ -58,7 +63,7 @@ class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder /** * Get the `Check` value for constraint - * @return string|null + * @return string|null the `CHECK` constraint for the column. */ public function getCheckValue() { @@ -66,7 +71,7 @@ class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder } /** - * @return bool + * @return bool whether the column values should be unique. If this is `true`, a `UNIQUE` constraint will be added. */ public function isUnique() { diff --git a/framework/di/Container.php b/framework/di/Container.php index e527edb712..19678348de 100644 --- a/framework/di/Container.php +++ b/framework/di/Container.php @@ -524,7 +524,10 @@ class Container extends Component if (PHP_VERSION_ID >= 80000) { $c = $param->getType(); - $isClass = $c !== null && !$param->getType()->isBuiltin(); + $isClass = false; + if ($c instanceof ReflectionNamedType) { + $isClass = !$c->isBuiltin(); + } } else { try { $c = $param->getClass(); diff --git a/framework/validators/NumberValidator.php b/framework/validators/NumberValidator.php index ea195c0241..56c9d1403e 100644 --- a/framework/validators/NumberValidator.php +++ b/framework/validators/NumberValidator.php @@ -29,7 +29,6 @@ class NumberValidator extends Validator * @since 2.0.42 */ public $allowArray = false; - /** * @var bool whether the attribute value can only be an integer. Defaults to false. */ diff --git a/framework/web/IdentityInterface.php b/framework/web/IdentityInterface.php index f5ba6227e3..737a0242ba 100644 --- a/framework/web/IdentityInterface.php +++ b/framework/web/IdentityInterface.php @@ -43,6 +43,13 @@ namespace yii\web; * } * ``` * + * In some situations not all of these methods are required to be implemented. + * For example, if your application is a pure stateless RESTful application, + * you would only need to implement [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] + * and [[yii\web\IdentityInterface::getId()|getId()]] while leaving all other methods with an empty body. + * Or if your application uses session only authentication, you would need to implement all the methods + * except [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]. + * * @author Qiang Xue * @since 2.0 */ @@ -87,7 +94,7 @@ interface IdentityInterface * Make sure to invalidate earlier issued authKeys when you implement force user logout, password change and * other scenarios, that require forceful access revocation for old sessions. * - * @return string a key that is used to check the validity of a given identity ID. + * @return string|null a key that is used to check the validity of a given identity ID. * @see validateAuthKey() */ public function getAuthKey(); @@ -96,7 +103,7 @@ interface IdentityInterface * Validates the given auth key. * * @param string $authKey the given auth key - * @return bool whether the given auth key is valid. + * @return bool|null whether the given auth key is valid. * @see getAuthKey() */ public function validateAuthKey($authKey); diff --git a/framework/web/Request.php b/framework/web/Request.php index 9495b45bce..70fa32dffd 100644 --- a/framework/web/Request.php +++ b/framework/web/Request.php @@ -36,7 +36,7 @@ use yii\validators\IpValidator; * is not given. This property is read-only. * @property-read string|null $authUser The username sent via HTTP authentication, `null` if the username is * not given. This property is read-only. - * @property string $baseUrl The relative URL for the application (usually with a leading slash). + * @property string $baseUrl The relative URL for the application. * @property array $bodyParams The request parameters given in the request body. * @property-read string $contentType Request content-type. Null is returned if this information is not * available. This property is read-only. diff --git a/tests/framework/di/ContainerTest.php b/tests/framework/di/ContainerTest.php index a9c2fd7aec..71c8e2f269 100644 --- a/tests/framework/di/ContainerTest.php +++ b/tests/framework/di/ContainerTest.php @@ -26,6 +26,9 @@ use yiiunit\framework\di\stubs\Kappa; use yiiunit\framework\di\stubs\Qux; use yiiunit\framework\di\stubs\QuxInterface; use yiiunit\framework\di\stubs\QuxFactory; +use yiiunit\framework\di\stubs\UnionTypeNotNull; +use yiiunit\framework\di\stubs\UnionTypeNull; +use yiiunit\framework\di\stubs\UnionTypeWithClass; use yiiunit\framework\di\stubs\Zeta; use yiiunit\TestCase; @@ -621,4 +624,53 @@ class ContainerTest extends TestCase $this->assertNull($zeta->unknown); $this->assertNull($zeta->unknownNull); } + + public function testUnionTypeWithNullConstructorParameters() + { + if (PHP_VERSION_ID < 80000) { + $this->markTestSkipped('Can not be tested on PHP < 8.0'); + return; + } + + $unionType = (new Container())->get(UnionTypeNull::className()); + $this->assertInstanceOf(UnionTypeNull::className(), $unionType); + } + + public function testUnionTypeWithoutNullConstructorParameters() + { + if (PHP_VERSION_ID < 80000) { + $this->markTestSkipped('Can not be tested on PHP < 8.0'); + return; + } + + $unionType = (new Container())->get(UnionTypeNotNull::className(), ['value' => 'a']); + $this->assertInstanceOf(UnionTypeNotNull::className(), $unionType); + + $unionType = (new Container())->get(UnionTypeNotNull::className(), ['value' => 1]); + $this->assertInstanceOf(UnionTypeNotNull::className(), $unionType); + + $unionType = (new Container())->get(UnionTypeNotNull::className(), ['value' => 2.3]); + $this->assertInstanceOf(UnionTypeNotNull::className(), $unionType); + + $unionType = (new Container())->get(UnionTypeNotNull::className(), ['value' => true]); + $this->assertInstanceOf(UnionTypeNotNull::className(), $unionType); + + $this->expectException('TypeError'); + (new Container())->get(UnionTypeNotNull::className()); + } + + public function testUnionTypeWithClassConstructorParameters() + { + if (PHP_VERSION_ID < 80000) { + $this->markTestSkipped('Can not be tested on PHP < 8.0'); + return; + } + + $unionType = (new Container())->get(UnionTypeWithClass::className(), ['value' => new Beta()]); + $this->assertInstanceOf(UnionTypeWithClass::className(), $unionType); + $this->assertInstanceOf(Beta::className(), $unionType->value); + + $this->expectException('TypeError'); + (new Container())->get(UnionTypeNotNull::className()); + } } diff --git a/tests/framework/di/stubs/UnionTypeNotNull.php b/tests/framework/di/stubs/UnionTypeNotNull.php new file mode 100644 index 0000000000..3b2eff9f1c --- /dev/null +++ b/tests/framework/di/stubs/UnionTypeNotNull.php @@ -0,0 +1,12 @@ +