From 2859e46f9cface51e2318232e454e15e19ca8ea1 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Mon, 10 Jul 2023 09:48:32 -0400 Subject: [PATCH 01/56] Raised minimum PHP version to 8.1 (#19879) --- base/Object.php | 30 ------------------------------ classes.php | 1 - composer.json | 2 +- db/Schema.php | 4 ++++ 4 files changed, 5 insertions(+), 32 deletions(-) delete mode 100644 base/Object.php diff --git a/base/Object.php b/base/Object.php deleted file mode 100644 index 20b68f169..000000000 --- a/base/Object.php +++ /dev/null @@ -1,30 +0,0 @@ - - * @since 2.0 - * @deprecated since 2.0.13, the class name `Object` is invalid since PHP 7.2, use [[BaseObject]] instead. - * @see https://wiki.php.net/rfc/object-typehint - * @see https://github.com/yiisoft/yii2/issues/7936#issuecomment-315384669 - */ -class Object extends BaseObject -{ -} diff --git a/classes.php b/classes.php index 46741e318..ebb135188 100644 --- a/classes.php +++ b/classes.php @@ -43,7 +43,6 @@ 'yii\base\ModelEvent' => YII2_PATH . '/base/ModelEvent.php', 'yii\base\Module' => YII2_PATH . '/base/Module.php', 'yii\base\NotSupportedException' => YII2_PATH . '/base/NotSupportedException.php', - 'yii\base\Object' => YII2_PATH . '/base/Object.php', 'yii\base\Request' => YII2_PATH . '/base/Request.php', 'yii\base\Response' => YII2_PATH . '/base/Response.php', 'yii\base\Security' => YII2_PATH . '/base/Security.php', diff --git a/composer.json b/composer.json index 5494cae7a..8d638df3c 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,7 @@ "source": "https://github.com/yiisoft/yii2" }, "require": { - "php": ">=5.4.0", + "php": ">=8.1", "ext-mbstring": "*", "ext-ctype": "*", "lib-pcre": "*", diff --git a/db/Schema.php b/db/Schema.php index 53c0af988..3a8aa7650 100644 --- a/db/Schema.php +++ b/db/Schema.php @@ -516,6 +516,10 @@ protected function getTableNameParts($name) */ public function quoteColumnName($name) { + if ($name === null) { + return ''; + } + if (strpos($name, '(') !== false || strpos($name, '[[') !== false) { return $name; } From 9c1b0c8a81e48bfb3da2dbe43d62d429bace217b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=E4=BD=B3=E4=BC=9F?= <1028244674@qq.com> Date: Thu, 13 Jul 2023 15:07:07 +0800 Subject: [PATCH 02/56] Remove methods mset, mget and madd of `yii\caching\Cache`, getHasChanged of `yii\caching\Dependency` (#19892) --- caching/Cache.php | 53 ------------------------------------------ caching/Dependency.php | 11 --------- 2 files changed, 64 deletions(-) diff --git a/caching/Cache.php b/caching/Cache.php index 5e1828ef8..7900585bf 100644 --- a/caching/Cache.php +++ b/caching/Cache.php @@ -166,23 +166,6 @@ public function exists($key) return $value !== false; } - /** - * Retrieves multiple values from cache with the specified keys. - * Some caches (such as memcache, apc) allow retrieving multiple cached values at the same time, - * which may improve the performance. In case a cache does not support this feature natively, - * this method will try to simulate it. - * - * @param string[] $keys list of string keys identifying the cached values - * @return array list of cached values corresponding to the specified keys. The array - * is returned in terms of (key, value) pairs. - * If a value is not cached or expired, the corresponding array value will be false. - * @deprecated This method is an alias for [[multiGet()]] and will be removed in 2.1.0. - */ - public function mget($keys) - { - return $this->multiGet($keys); - } - /** * Retrieves multiple values from cache with the specified keys. * Some caches (such as memcache, apc) allow retrieving multiple cached values at the same time, @@ -255,25 +238,6 @@ public function set($key, $value, $duration = null, $dependency = null) return $this->setValue($key, $value, $duration); } - /** - * Stores multiple items in cache. Each item contains a value identified by a key. - * If the cache already contains such a key, the existing value and - * expiration time will be replaced with the new ones, respectively. - * - * @param array $items the items to be cached, as key-value pairs. - * @param int|null $duration default duration in seconds before the cache will expire. If not set, - * default [[defaultDuration]] value is used. - * @param Dependency|null $dependency dependency of the cached items. If the dependency changes, - * the corresponding values in the cache will be invalidated when it is fetched via [[get()]]. - * This parameter is ignored if [[serializer]] is false. - * @return array array of failed keys - * @deprecated This method is an alias for [[multiSet()]] and will be removed in 2.1.0. - */ - public function mset($items, $duration = null, $dependency = null) - { - return $this->multiSet($items, $duration, $dependency); - } - /** * Stores multiple items in cache. Each item contains a value identified by a key. * If the cache already contains such a key, the existing value and @@ -313,23 +277,6 @@ public function multiSet($items, $duration = null, $dependency = null) return $this->setValues($data, $duration); } - /** - * Stores multiple items in cache. Each item contains a value identified by a key. - * If the cache already contains such a key, the existing value and expiration time will be preserved. - * - * @param array $items the items to be cached, as key-value pairs. - * @param int $duration default number of seconds in which the cached values will expire. 0 means never expire. - * @param Dependency|null $dependency dependency of the cached items. If the dependency changes, - * the corresponding values in the cache will be invalidated when it is fetched via [[get()]]. - * This parameter is ignored if [[serializer]] is false. - * @return array array of failed keys - * @deprecated This method is an alias for [[multiAdd()]] and will be removed in 2.1.0. - */ - public function madd($items, $duration = 0, $dependency = null) - { - return $this->multiAdd($items, $duration, $dependency); - } - /** * Stores multiple items in cache. Each item contains a value identified by a key. * If the cache already contains such a key, the existing value and expiration time will be preserved. diff --git a/caching/Dependency.php b/caching/Dependency.php index e558bfef8..c4de5078a 100644 --- a/caching/Dependency.php +++ b/caching/Dependency.php @@ -57,17 +57,6 @@ public function evaluateDependency($cache) } } - /** - * Returns a value indicating whether the dependency has changed. - * @deprecated since version 2.0.11. Will be removed in version 2.1. Use [[isChanged()]] instead. - * @param CacheInterface $cache the cache component that is currently evaluating this dependency - * @return bool whether the dependency has changed. - */ - public function getHasChanged($cache) - { - return $this->isChanged($cache); - } - /** * Checks whether the dependency is changed. * @param CacheInterface $cache the cache component that is currently evaluating this dependency From 81ea5b70fa0d3d1788d8689827f88193f90271af Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Sun, 16 Jul 2023 09:45:39 -0400 Subject: [PATCH 03/56] Remove deprecated method `className()` for branch `2.2`. (#19894) --- UPGRADE.md | 5 ++--- base/BaseObject.php | 10 ---------- base/Controller.php | 4 ++-- behaviors/SluggableBehavior.php | 2 +- caching/DbCache.php | 2 +- caching/DbDependency.php | 2 +- console/controllers/CacheController.php | 2 +- console/controllers/FixtureController.php | 2 +- console/controllers/MessageController.php | 2 +- console/controllers/MigrateController.php | 4 ++-- data/BaseDataProvider.php | 4 ++-- data/DataFilter.php | 4 ++-- data/SqlDataProvider.php | 2 +- db/ActiveRecord.php | 2 +- db/Migration.php | 6 +++--- db/Query.php | 4 ++-- db/Schema.php | 4 ++-- db/cubrid/Schema.php | 2 +- db/mssql/Schema.php | 4 ++-- db/mysql/Schema.php | 4 ++-- db/oci/Schema.php | 4 ++-- db/pgsql/Schema.php | 2 +- db/sqlite/Schema.php | 4 ++-- filters/AccessControl.php | 2 +- grid/GridView.php | 4 ++-- i18n/DbMessageSource.php | 2 +- log/DbTarget.php | 2 +- mail/BaseMailer.php | 2 +- mutex/DbMutex.php | 2 +- rbac/DbManager.php | 4 ++-- rbac/PhpManager.php | 2 +- rest/Controller.php | 8 ++++---- rest/IndexAction.php | 2 +- rest/UrlRule.php | 2 +- test/DbFixture.php | 2 +- validators/UniqueValidator.php | 6 +++++- web/AssetManager.php | 4 ++-- web/CompositeUrlRule.php | 2 +- web/DbSession.php | 2 +- web/UrlManager.php | 2 +- web/UrlRule.php | 2 +- web/View.php | 2 +- widgets/BaseListView.php | 4 ++-- 43 files changed, 66 insertions(+), 73 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 7d2ca03eb..8286cf010 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -292,7 +292,7 @@ Upgrade from Yii 2.0.34 public function rules() { return [ - ['attribute', 'each', 'rule' => ['exist', 'targetClass' => static::className(), 'targetAttribute' => 'id']], + ['attribute', 'each', 'rule' => ['exist', 'targetClass' => static::class, 'targetAttribute' => 'id']], ]; } ``` @@ -521,9 +521,8 @@ Upgrade from Yii 2.0.13 * Log targets (like `yii\log\EmailTarget`) are now throwing `yii\log\LogRuntimeException` in case log can not be properly exported. -* You can start preparing your application for Yii 2.1 by doing the following: +* You can start preparing your application for Yii 2.2 by doing the following: - - Replace `::className()` calls with `::class` (if you’re running PHP 5.5+). - Replace usages of `yii\base\InvalidParamException` with `yii\base\InvalidArgumentException`. - Replace calls to `Yii::trace()` with `Yii::debug()`. - Remove calls to `yii\BaseYii::powered()`. diff --git a/base/BaseObject.php b/base/BaseObject.php index 174fcd1e9..2f9448efc 100644 --- a/base/BaseObject.php +++ b/base/BaseObject.php @@ -76,16 +76,6 @@ */ class BaseObject implements Configurable { - /** - * Returns the fully qualified name of this class. - * @return string the fully qualified name of this class. - * @deprecated since 2.0.14. On PHP >=5.5, use `::class` instead. - */ - public static function className() - { - return get_called_class(); - } - /** * Constructor. * diff --git a/base/Controller.php b/base/Controller.php index 2205712fb..c1e1983c7 100644 --- a/base/Controller.php +++ b/base/Controller.php @@ -102,8 +102,8 @@ public function __construct($id, $module, $config = []) public function init() { parent::init(); - $this->request = Instance::ensure($this->request, Request::className()); - $this->response = Instance::ensure($this->response, Response::className()); + $this->request = Instance::ensure($this->request, Request::class); + $this->response = Instance::ensure($this->response, Response::class); } /** diff --git a/behaviors/SluggableBehavior.php b/behaviors/SluggableBehavior.php index c18bd4fa2..369be6c37 100644 --- a/behaviors/SluggableBehavior.php +++ b/behaviors/SluggableBehavior.php @@ -243,7 +243,7 @@ protected function validateSlug($slug) /* @var $model BaseActiveRecord */ $validator = Yii::createObject(array_merge( [ - 'class' => UniqueValidator::className(), + 'class' => UniqueValidator::class, ], $this->uniqueValidator )); diff --git a/caching/DbCache.php b/caching/DbCache.php index 5bf3b02de..5003adad2 100644 --- a/caching/DbCache.php +++ b/caching/DbCache.php @@ -95,7 +95,7 @@ class DbCache extends Cache public function init() { parent::init(); - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); } /** diff --git a/caching/DbDependency.php b/caching/DbDependency.php index 43a51d926..525c3e02b 100644 --- a/caching/DbDependency.php +++ b/caching/DbDependency.php @@ -50,7 +50,7 @@ class DbDependency extends Dependency protected function generateDependencyData($cache) { /* @var $db Connection */ - $db = Instance::ensure($this->db, Connection::className()); + $db = Instance::ensure($this->db, Connection::class); if ($this->sql === null) { throw new InvalidConfigException('DbDependency::sql must be set.'); } diff --git a/console/controllers/CacheController.php b/console/controllers/CacheController.php index d5d0a756e..4a2fabff7 100644 --- a/console/controllers/CacheController.php +++ b/console/controllers/CacheController.php @@ -300,6 +300,6 @@ private function isCacheClass($className) */ private function canBeFlushed($className) { - return !is_a($className, ApcCache::className(), true) || PHP_SAPI !== 'cli'; + return !is_a($className, ApcCache::class, true) || PHP_SAPI !== 'cli'; } } diff --git a/console/controllers/FixtureController.php b/console/controllers/FixtureController.php index caba5d271..a210034b7 100644 --- a/console/controllers/FixtureController.php +++ b/console/controllers/FixtureController.php @@ -258,7 +258,7 @@ private function notifyLoaded($fixtures) $fixtureClassNames = []; foreach ($fixtures as $fixture) { - $fixtureClassNames[] = $fixture::className(); + $fixtureClassNames[] = $fixture::class; } $this->outputList($fixtureClassNames); diff --git a/console/controllers/MessageController.php b/console/controllers/MessageController.php index e1a735769..4650cec79 100644 --- a/console/controllers/MessageController.php +++ b/console/controllers/MessageController.php @@ -318,7 +318,7 @@ public function actionExtract($configFile = null) } } elseif ($this->config['format'] === 'db') { /** @var Connection $db */ - $db = Instance::ensure($this->config['db'], Connection::className()); + $db = Instance::ensure($this->config['db'], Connection::class); $sourceMessageTable = isset($this->config['sourceMessageTable']) ? $this->config['sourceMessageTable'] : '{{%source_message}}'; $messageTable = isset($this->config['messageTable']) ? $this->config['messageTable'] : '{{%message}}'; $this->saveMessagesToDb( diff --git a/console/controllers/MigrateController.php b/console/controllers/MigrateController.php index 17b6a7638..b2e1db3ec 100644 --- a/console/controllers/MigrateController.php +++ b/console/controllers/MigrateController.php @@ -180,7 +180,7 @@ public function optionAliases() public function beforeAction($action) { if (parent::beforeAction($action)) { - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); return true; } @@ -471,7 +471,7 @@ protected function generateMigrationSourceCode($params) if ($relatedColumn === null) { $relatedColumn = 'id'; try { - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); $relatedTableSchema = $this->db->getTableSchema($relatedTable); if ($relatedTableSchema !== null) { $primaryKeyCount = count($relatedTableSchema->primaryKey); diff --git a/data/BaseDataProvider.php b/data/BaseDataProvider.php index 82af0aa7c..5d1509662 100644 --- a/data/BaseDataProvider.php +++ b/data/BaseDataProvider.php @@ -211,7 +211,7 @@ public function getPagination() public function setPagination($value) { if (is_array($value)) { - $config = ['class' => Pagination::className()]; + $config = ['class' => Pagination::class]; if ($this->id !== null) { $config['pageParam'] = $this->id . '-page'; $config['pageSizeParam'] = $this->id . '-per-page'; @@ -252,7 +252,7 @@ public function getSort() public function setSort($value) { if (is_array($value)) { - $config = ['class' => Sort::className()]; + $config = ['class' => Sort::class]; if ($this->id !== null) { $config['sortParam'] = $this->id . '-sort'; } diff --git a/data/DataFilter.php b/data/DataFilter.php index 057509203..587b7b10a 100644 --- a/data/DataFilter.php +++ b/data/DataFilter.php @@ -288,7 +288,7 @@ public function getSearchModel() if (!is_object($this->_searchModel) || $this->_searchModel instanceof \Closure) { $model = Yii::createObject($this->_searchModel); if (!$model instanceof Model) { - throw new InvalidConfigException('`' . get_class($this) . '::$searchModel` should be an instance of `' . Model::className() . '` or its DI compatible configuration.'); + throw new InvalidConfigException('`' . get_class($this) . '::$searchModel` should be an instance of `' . Model::class . '` or its DI compatible configuration.'); } $this->_searchModel = $model; } @@ -302,7 +302,7 @@ public function getSearchModel() public function setSearchModel($model) { if (is_object($model) && !$model instanceof Model && !$model instanceof \Closure) { - throw new InvalidConfigException('`' . get_class($this) . '::$searchModel` should be an instance of `' . Model::className() . '` or its DI compatible configuration.'); + throw new InvalidConfigException('`' . get_class($this) . '::$searchModel` should be an instance of `' . Model::class . '` or its DI compatible configuration.'); } $this->_searchModel = $model; } diff --git a/data/SqlDataProvider.php b/data/SqlDataProvider.php index 5a8f9631d..1f4e9ec36 100644 --- a/data/SqlDataProvider.php +++ b/data/SqlDataProvider.php @@ -96,7 +96,7 @@ class SqlDataProvider extends BaseDataProvider public function init() { parent::init(); - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); if ($this->sql === null) { throw new InvalidConfigException('The "sql" property must be set.'); } diff --git a/db/ActiveRecord.php b/db/ActiveRecord.php index 130285617..29d5efe0b 100644 --- a/db/ActiveRecord.php +++ b/db/ActiveRecord.php @@ -411,7 +411,7 @@ public static function deleteAll($condition = null, $params = []) */ public static function find() { - return Yii::createObject(ActiveQuery::className(), [get_called_class()]); + return Yii::createObject(ActiveQuery::class, [get_called_class()]); } /** diff --git a/db/Migration.php b/db/Migration.php index 975898cd5..58df34b55 100644 --- a/db/Migration.php +++ b/db/Migration.php @@ -87,7 +87,7 @@ class Migration extends Component implements MigrationInterface public function init() { parent::init(); - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); $this->db->getSchema()->refresh(); $this->db->enableSlaves = false; } @@ -311,7 +311,7 @@ public function delete($table, $condition = '', $params = []) * * If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly * put into the generated SQL. - * + * * Example usage: * ```php * class m200000_000000_create_table_fruits extends \yii\db\Migration @@ -319,7 +319,7 @@ public function delete($table, $condition = '', $params = []) * public function safeUp() * { * $this->createTable('{{%fruits}}', [ - * // ... + * // ... * 'column_name double precision null default null', * ``` diff --git a/db/Query.php b/db/Query.php index f0b215859..243d08c4a 100644 --- a/db/Query.php +++ b/db/Query.php @@ -198,7 +198,7 @@ public function prepare($builder) public function batch($batchSize = 100, $db = null) { return Yii::createObject([ - 'class' => BatchQueryResult::className(), + 'class' => BatchQueryResult::class, 'query' => $this, 'batchSize' => $batchSize, 'db' => $db, @@ -226,7 +226,7 @@ public function batch($batchSize = 100, $db = null) public function each($batchSize = 100, $db = null) { return Yii::createObject([ - 'class' => BatchQueryResult::className(), + 'class' => BatchQueryResult::class, 'query' => $this, 'batchSize' => $batchSize, 'db' => $db, diff --git a/db/Schema.php b/db/Schema.php index 3a8aa7650..43e15d99b 100644 --- a/db/Schema.php +++ b/db/Schema.php @@ -313,7 +313,7 @@ public function refreshTableSchema($name) */ public function createQueryBuilder() { - return Yii::createObject(QueryBuilder::className(), [$this->db]); + return Yii::createObject(QueryBuilder::class, [$this->db]); } /** @@ -328,7 +328,7 @@ public function createQueryBuilder() */ public function createColumnSchemaBuilder($type, $length = null) { - return Yii::createObject(ColumnSchemaBuilder::className(), [$type, $length]); + return Yii::createObject(ColumnSchemaBuilder::class, [$type, $length]); } /** diff --git a/db/cubrid/Schema.php b/db/cubrid/Schema.php index 65b6c11b9..74adba234 100644 --- a/db/cubrid/Schema.php +++ b/db/cubrid/Schema.php @@ -249,7 +249,7 @@ public function releaseSavepoint($name) */ public function createQueryBuilder() { - return Yii::createObject(QueryBuilder::className(), [$this->db]); + return Yii::createObject(QueryBuilder::class, [$this->db]); } /** diff --git a/db/mssql/Schema.php b/db/mssql/Schema.php index 005b1555f..07dbaac98 100644 --- a/db/mssql/Schema.php +++ b/db/mssql/Schema.php @@ -332,7 +332,7 @@ public function rollBackSavepoint($name) */ public function createQueryBuilder() { - return Yii::createObject(QueryBuilder::className(), [$this->db]); + return Yii::createObject(QueryBuilder::class, [$this->db]); } /** @@ -811,6 +811,6 @@ public function insert($table, $columns) */ public function createColumnSchemaBuilder($type, $length = null) { - return Yii::createObject(ColumnSchemaBuilder::className(), [$type, $length, $this->db]); + return Yii::createObject(ColumnSchemaBuilder::class, [$type, $length, $this->db]); } } diff --git a/db/mysql/Schema.php b/db/mysql/Schema.php index fa2270eb7..38dec4ca0 100644 --- a/db/mysql/Schema.php +++ b/db/mysql/Schema.php @@ -222,7 +222,7 @@ protected function loadTableDefaultValues($tableName) */ public function createQueryBuilder() { - return Yii::createObject(QueryBuilder::className(), [$this->db]); + return Yii::createObject(QueryBuilder::class, [$this->db]); } /** @@ -472,7 +472,7 @@ public function findUniqueIndexes($table) */ public function createColumnSchemaBuilder($type, $length = null) { - return Yii::createObject(ColumnSchemaBuilder::className(), [$type, $length, $this->db]); + return Yii::createObject(ColumnSchemaBuilder::class, [$type, $length, $this->db]); } /** diff --git a/db/oci/Schema.php b/db/oci/Schema.php index e0e4c05e2..05b3cb5ea 100644 --- a/db/oci/Schema.php +++ b/db/oci/Schema.php @@ -262,7 +262,7 @@ public function quoteSimpleTableName($name) */ public function createQueryBuilder() { - return Yii::createObject(QueryBuilder::className(), [$this->db]); + return Yii::createObject(QueryBuilder::class, [$this->db]); } /** @@ -270,7 +270,7 @@ public function createQueryBuilder() */ public function createColumnSchemaBuilder($type, $length = null) { - return Yii::createObject(ColumnSchemaBuilder::className(), [$type, $length]); + return Yii::createObject(ColumnSchemaBuilder::class, [$type, $length]); } /** diff --git a/db/pgsql/Schema.php b/db/pgsql/Schema.php index 154e01a38..c379176de 100644 --- a/db/pgsql/Schema.php +++ b/db/pgsql/Schema.php @@ -289,7 +289,7 @@ protected function loadTableDefaultValues($tableName) */ public function createQueryBuilder() { - return Yii::createObject(QueryBuilder::className(), [$this->db]); + return Yii::createObject(QueryBuilder::class, [$this->db]); } /** diff --git a/db/sqlite/Schema.php b/db/sqlite/Schema.php index 32b209b22..2ff7ba835 100644 --- a/db/sqlite/Schema.php +++ b/db/sqlite/Schema.php @@ -207,7 +207,7 @@ protected function loadTableDefaultValues($tableName) */ public function createQueryBuilder() { - return Yii::createObject(QueryBuilder::className(), [$this->db]); + return Yii::createObject(QueryBuilder::class, [$this->db]); } /** @@ -216,7 +216,7 @@ public function createQueryBuilder() */ public function createColumnSchemaBuilder($type, $length = null) { - return Yii::createObject(ColumnSchemaBuilder::className(), [$type, $length]); + return Yii::createObject(ColumnSchemaBuilder::class, [$type, $length]); } /** diff --git a/filters/AccessControl.php b/filters/AccessControl.php index 7ec2c5e55..a648feb77 100644 --- a/filters/AccessControl.php +++ b/filters/AccessControl.php @@ -99,7 +99,7 @@ public function init() { parent::init(); if ($this->user !== false) { - $this->user = Instance::ensure($this->user, User::className()); + $this->user = Instance::ensure($this->user, User::class); } foreach ($this->rules as $i => $rule) { if (is_array($rule)) { diff --git a/grid/GridView.php b/grid/GridView.php index 7ee0e06bb..8b5afefe7 100644 --- a/grid/GridView.php +++ b/grid/GridView.php @@ -547,7 +547,7 @@ protected function initColumns() $column = $this->createDataColumn($column); } else { $column = Yii::createObject(array_merge([ - 'class' => $this->dataColumnClass ?: DataColumn::className(), + 'class' => $this->dataColumnClass ?: DataColumn::class, 'grid' => $this, ], $column)); } @@ -572,7 +572,7 @@ protected function createDataColumn($text) } return Yii::createObject([ - 'class' => $this->dataColumnClass ?: DataColumn::className(), + 'class' => $this->dataColumnClass ?: DataColumn::class, 'grid' => $this, 'attribute' => $matches[1], 'format' => isset($matches[3]) ? $matches[3] : 'text', diff --git a/i18n/DbMessageSource.php b/i18n/DbMessageSource.php index 0686291d2..eccc7fbd1 100644 --- a/i18n/DbMessageSource.php +++ b/i18n/DbMessageSource.php @@ -96,7 +96,7 @@ class DbMessageSource extends MessageSource public function init() { parent::init(); - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); if ($this->enableCaching) { $this->cache = Instance::ensure($this->cache, 'yii\caching\CacheInterface'); } diff --git a/log/DbTarget.php b/log/DbTarget.php index c2c3d6a62..1ecf07f2b 100644 --- a/log/DbTarget.php +++ b/log/DbTarget.php @@ -53,7 +53,7 @@ class DbTarget extends Target public function init() { parent::init(); - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); } /** diff --git a/mail/BaseMailer.php b/mail/BaseMailer.php index c5f76fb75..e334d74aa 100644 --- a/mail/BaseMailer.php +++ b/mail/BaseMailer.php @@ -142,7 +142,7 @@ public function getView() protected function createView(array $config) { if (!array_key_exists('class', $config)) { - $config['class'] = View::className(); + $config['class'] = View::class; } return Yii::createObject($config); diff --git a/mutex/DbMutex.php b/mutex/DbMutex.php index 593cff4e0..a19a1adf8 100644 --- a/mutex/DbMutex.php +++ b/mutex/DbMutex.php @@ -37,6 +37,6 @@ abstract class DbMutex extends Mutex public function init() { parent::init(); - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); } } diff --git a/rbac/DbManager.php b/rbac/DbManager.php index 2685ad5a1..240914838 100644 --- a/rbac/DbManager.php +++ b/rbac/DbManager.php @@ -119,7 +119,7 @@ class DbManager extends BaseManager public function init() { parent::init(); - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); if ($this->cache !== null) { $this->cache = Instance::ensure($this->cache, 'yii\caching\CacheInterface'); } @@ -449,7 +449,7 @@ protected function getItems($type) */ protected function populateItem($row) { - $class = $row['type'] == Item::TYPE_PERMISSION ? Permission::className() : Role::className(); + $class = $row['type'] == Item::TYPE_PERMISSION ? Permission::class : Role::class; if (!isset($row['data']) || ($data = @unserialize(is_resource($row['data']) ? stream_get_contents($row['data']) : $row['data'])) === false) { $data = null; diff --git a/rbac/PhpManager.php b/rbac/PhpManager.php index 291d72976..9411a7f93 100644 --- a/rbac/PhpManager.php +++ b/rbac/PhpManager.php @@ -724,7 +724,7 @@ protected function load() $rules = $this->loadFromFile($this->ruleFile); foreach ($items as $name => $item) { - $class = $item['type'] == Item::TYPE_PERMISSION ? Permission::className() : Role::className(); + $class = $item['type'] == Item::TYPE_PERMISSION ? Permission::class : Role::class; $this->items[$name] = new $class([ 'name' => $name, diff --git a/rest/Controller.php b/rest/Controller.php index 9512ee75e..3705417ac 100644 --- a/rest/Controller.php +++ b/rest/Controller.php @@ -49,21 +49,21 @@ public function behaviors() { return [ 'contentNegotiator' => [ - 'class' => ContentNegotiator::className(), + 'class' => ContentNegotiator::class, 'formats' => [ 'application/json' => Response::FORMAT_JSON, 'application/xml' => Response::FORMAT_XML, ], ], 'verbFilter' => [ - 'class' => VerbFilter::className(), + 'class' => VerbFilter::class, 'actions' => $this->verbs(), ], 'authenticator' => [ - 'class' => CompositeAuth::className(), + 'class' => CompositeAuth::class, ], 'rateLimiter' => [ - 'class' => RateLimiter::className(), + 'class' => RateLimiter::class, ], ]; } diff --git a/rest/IndexAction.php b/rest/IndexAction.php index 81b19cab7..ab3e53293 100644 --- a/rest/IndexAction.php +++ b/rest/IndexAction.php @@ -183,7 +183,7 @@ protected function prepareDataProvider() } return Yii::createObject([ - 'class' => ActiveDataProvider::className(), + 'class' => ActiveDataProvider::class, 'query' => $query, 'pagination' => $pagination, 'sort' => $sort, diff --git a/rest/UrlRule.php b/rest/UrlRule.php index 48b1bbe79..8f32e32c4 100644 --- a/rest/UrlRule.php +++ b/rest/UrlRule.php @@ -233,7 +233,7 @@ public function parseRequest($manager, $request) Yii::debug([ 'rule' => method_exists($rule, '__toString') ? $rule->__toString() : get_class($rule), 'match' => $result !== false, - 'parent' => self::className(), + 'parent' => self::class, ], __METHOD__); } if ($result !== false) { diff --git a/test/DbFixture.php b/test/DbFixture.php index d5a6322f9..0a9b090e9 100644 --- a/test/DbFixture.php +++ b/test/DbFixture.php @@ -38,6 +38,6 @@ abstract class DbFixture extends Fixture public function init() { parent::init(); - $this->db = Instance::ensure($this->db, BaseObject::className()); + $this->db = Instance::ensure($this->db, BaseObject::class); } } diff --git a/validators/UniqueValidator.php b/validators/UniqueValidator.php index 74edcfd66..dadc8b4ed 100644 --- a/validators/UniqueValidator.php +++ b/validators/UniqueValidator.php @@ -189,7 +189,11 @@ private function modelExists($targetClass, $conditions, $model) /** @var ActiveRecordInterface|\yii\base\BaseObject $targetClass $query */ $query = $this->prepareQuery($targetClass, $conditions); - if (!$model instanceof ActiveRecordInterface || $model->getIsNewRecord() || $model::className() !== $targetClass::className()) { + if ( + !$model instanceof ActiveRecordInterface || + $model->getIsNewRecord() || + !$model instanceof $targetClass + ) { // if current $model isn't in the database yet, then it's OK just to call exists() // also there's no need to run check based on primary keys, when $targetClass is not the same as $model's class $exists = $query->exists(); diff --git a/web/AssetManager.php b/web/AssetManager.php index 0ad3a21cc..40d8ca2b1 100644 --- a/web/AssetManager.php +++ b/web/AssetManager.php @@ -394,10 +394,10 @@ protected function resolveAsset($bundle, $asset) public function getConverter() { if ($this->_converter === null) { - $this->_converter = Yii::createObject(AssetConverter::className()); + $this->_converter = Yii::createObject(AssetConverter::class); } elseif (is_array($this->_converter) || is_string($this->_converter)) { if (is_array($this->_converter) && !isset($this->_converter['class'])) { - $this->_converter['class'] = AssetConverter::className(); + $this->_converter['class'] = AssetConverter::class; } $this->_converter = Yii::createObject($this->_converter); } diff --git a/web/CompositeUrlRule.php b/web/CompositeUrlRule.php index 30d08e189..f43cbcbbc 100644 --- a/web/CompositeUrlRule.php +++ b/web/CompositeUrlRule.php @@ -60,7 +60,7 @@ public function parseRequest($manager, $request) Yii::debug([ 'rule' => method_exists($rule, '__toString') ? $rule->__toString() : get_class($rule), 'match' => $result !== false, - 'parent' => self::className(), + 'parent' => self::class, ], __METHOD__); } if ($result !== false) { diff --git a/web/DbSession.php b/web/DbSession.php index 4d4e5030d..a742885ec 100644 --- a/web/DbSession.php +++ b/web/DbSession.php @@ -90,7 +90,7 @@ class DbSession extends MultiFieldSession public function init() { parent::init(); - $this->db = Instance::ensure($this->db, Connection::className()); + $this->db = Instance::ensure($this->db, Connection::class); } /** diff --git a/web/UrlManager.php b/web/UrlManager.php index 292c4bc3e..fddb8b342 100644 --- a/web/UrlManager.php +++ b/web/UrlManager.php @@ -178,7 +178,7 @@ public function init() if ($this->normalizer !== false) { $this->normalizer = Yii::createObject($this->normalizer); if (!$this->normalizer instanceof UrlNormalizer) { - throw new InvalidConfigException('`' . get_class($this) . '::normalizer` should be an instance of `' . UrlNormalizer::className() . '` or its DI compatible configuration.'); + throw new InvalidConfigException('`' . get_class($this) . '::normalizer` should be an instance of `' . UrlNormalizer::class . '` or its DI compatible configuration.'); } } diff --git a/web/UrlRule.php b/web/UrlRule.php index fbbf6ffe1..170a2f24c 100644 --- a/web/UrlRule.php +++ b/web/UrlRule.php @@ -195,7 +195,7 @@ public function init() throw new InvalidConfigException('UrlRule::route must be set.'); } if (is_array($this->normalizer)) { - $normalizerConfig = array_merge(['class' => UrlNormalizer::className()], $this->normalizer); + $normalizerConfig = array_merge(['class' => UrlNormalizer::class], $this->normalizer); $this->normalizer = Yii::createObject($normalizerConfig); } if ($this->normalizer !== null && $this->normalizer !== false && !$this->normalizer instanceof UrlNormalizer) { diff --git a/web/View.php b/web/View.php index f2c19fc72..d9addacca 100644 --- a/web/View.php +++ b/web/View.php @@ -521,7 +521,7 @@ private function registerFile($type, $url, $options = [], $key = null) } } else { $this->getAssetManager()->bundles[$key] = Yii::createObject([ - 'class' => AssetBundle::className(), + 'class' => AssetBundle::class, 'baseUrl' => '', 'basePath' => '@webroot', (string)$type => [ArrayHelper::merge([!Url::isRelative($url) ? $url : ltrim($url, '/')], $originalOptions)], diff --git a/widgets/BaseListView.php b/widgets/BaseListView.php index cee83fcaf..4aa9b7826 100644 --- a/widgets/BaseListView.php +++ b/widgets/BaseListView.php @@ -253,7 +253,7 @@ public function renderPager() } /* @var $class LinkPager */ $pager = $this->pager; - $class = ArrayHelper::remove($pager, 'class', LinkPager::className()); + $class = ArrayHelper::remove($pager, 'class', LinkPager::class); $pager['pagination'] = $pagination; $pager['view'] = $this->getView(); @@ -272,7 +272,7 @@ public function renderSorter() } /* @var $class LinkSorter */ $sorter = $this->sorter; - $class = ArrayHelper::remove($sorter, 'class', LinkSorter::className()); + $class = ArrayHelper::remove($sorter, 'class', LinkSorter::class); $sorter['sort'] = $sort; $sorter['view'] = $this->getView(); From a944ef096e8a258a3918cd2f3752c8a79b93c1a8 Mon Sep 17 00:00:00 2001 From: "Stefano D. Mtangoo" Date: Tue, 18 Jul 2023 17:00:54 +0300 Subject: [PATCH 04/56] Fix #19902: Remove support for CUBRID --- CHANGELOG.md | 8 + behaviors/AttributeTypecastBehavior.php | 9 +- classes.php | 5 +- db/BaseActiveRecord.php | 13 +- db/ColumnSchemaBuilder.php | 5 +- db/Command.php | 15 +- db/Connection.php | 7 +- db/cubrid/ColumnSchemaBuilder.php | 72 --- db/cubrid/QueryBuilder.php | 294 ------------ db/cubrid/Schema.php | 419 ------------------ db/cubrid/conditions/LikeConditionBuilder.php | 29 -- 11 files changed, 45 insertions(+), 831 deletions(-) delete mode 100644 db/cubrid/ColumnSchemaBuilder.php delete mode 100644 db/cubrid/QueryBuilder.php delete mode 100644 db/cubrid/Schema.php delete mode 100644 db/cubrid/conditions/LikeConditionBuilder.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 9214c9204..8bd17d17e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,21 @@ Yii Framework 2 Change Log ========================== +2.2 under development +------------------------ + +- Chg #19902: Remove support for CUBRID (mtangoo) + + 2.0.49 under development ------------------------ +- Bug #19857: Fix AttributeTypecastBehavior::resetOldAttributes() causes "class has no attribute named" InvalidArgumentException (uaoleg) - Bug #18859: Fix `yii\web\Controller::bindInjectedParams()` to not throw error when argument of `ReflectionUnionType` type is passed (bizley) - Enh #19841: Allow jQuery 3.7 to be installed (wouter90) - Enh #19853: Added support for default value for `\yii\helpers\Console::select()` (rhertogh) - Bug #19868: Added whitespace sanitation for tests, due to updates in ICU 72 (schmunk42) +- Enh #19884: Added support Enums in Query Builder (sk1t0n) 2.0.48.1 May 24, 2023 diff --git a/behaviors/AttributeTypecastBehavior.php b/behaviors/AttributeTypecastBehavior.php index fc3ce9559..a418b15de 100644 --- a/behaviors/AttributeTypecastBehavior.php +++ b/behaviors/AttributeTypecastBehavior.php @@ -366,7 +366,10 @@ public function afterFind($event) $this->resetOldAttributes(); } - private function resetOldAttributes() + /** + * Resets the old values of the named attributes. + */ + protected function resetOldAttributes() { if ($this->attributeTypes === null) { return; @@ -375,7 +378,9 @@ private function resetOldAttributes() $attributes = array_keys($this->attributeTypes); foreach ($attributes as $attribute) { - $this->owner->setOldAttribute($attribute, $this->owner->{$attribute}); + if ($this->owner->canSetOldAttribute($attribute)) { + $this->owner->setOldAttribute($attribute, $this->owner->{$attribute}); + } } } } diff --git a/classes.php b/classes.php index ebb135188..3d4759ed4 100644 --- a/classes.php +++ b/classes.php @@ -1,4 +1,5 @@ YII2_PATH . '/db/conditions/OrCondition.php', 'yii\db\conditions\SimpleCondition' => YII2_PATH . '/db/conditions/SimpleCondition.php', 'yii\db\conditions\SimpleConditionBuilder' => YII2_PATH . '/db/conditions/SimpleConditionBuilder.php', - 'yii\db\cubrid\ColumnSchemaBuilder' => YII2_PATH . '/db/cubrid/ColumnSchemaBuilder.php', - 'yii\db\cubrid\QueryBuilder' => YII2_PATH . '/db/cubrid/QueryBuilder.php', - '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', diff --git a/db/BaseActiveRecord.php b/db/BaseActiveRecord.php index 06e6d7460..88fb2f11d 100644 --- a/db/BaseActiveRecord.php +++ b/db/BaseActiveRecord.php @@ -576,13 +576,24 @@ public function getOldAttribute($name) */ public function setOldAttribute($name, $value) { - if (isset($this->_oldAttributes[$name]) || $this->hasAttribute($name)) { + if ($this->canSetOldAttribute($name)) { $this->_oldAttributes[$name] = $value; } else { throw new InvalidArgumentException(get_class($this) . ' has no attribute named "' . $name . '".'); } } + /** + * Returns if the old named attribute can be set. + * @param string $name the attribute name + * @return bool whether the old attribute can be set + * @see setOldAttribute() + */ + public function canSetOldAttribute($name) + { + return (isset($this->_oldAttributes[$name]) || $this->hasAttribute($name)); + } + /** * Marks an attribute dirty. * This method may be called to force updating a record when calling [[update()]], diff --git a/db/ColumnSchemaBuilder.php b/db/ColumnSchemaBuilder.php index 756b4b8aa..8bfe2d3e3 100644 --- a/db/ColumnSchemaBuilder.php +++ b/db/ColumnSchemaBuilder.php @@ -1,4 +1,5 @@ pendingParams[$name] = [$value->getValue(), $value->getType()]; $this->params[$name] = $value->getValue(); } else { + if (version_compare(PHP_VERSION, '8.1.0') >= 0) { + if ($value instanceof \BackedEnum) { + $value = $value->value; + } elseif ($value instanceof \UnitEnum) { + $value = $value->name; + } + } $type = $schema->getPdoType($value); $this->pendingParams[$name] = [$value, $type]; $this->params[$name] = $value; @@ -631,15 +638,15 @@ public function delete($table, $condition = '', $params = []) * * The columns in the new table should be specified as name-definition pairs (e.g. 'name' => 'string'), * where name stands for a column name which will be properly quoted by the method, and definition - * stands for the column type which must contain an abstract DB type. - * + * stands for the column type which must contain an abstract DB type. + * * The method [[QueryBuilder::getColumnType()]] will be called * to convert the abstract column types to physical ones. For example, `string` will be converted * as `varchar(255)`, and `string not null` becomes `varchar(255) not null`. * * If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly * inserted into the generated SQL. - * + * * Example usage: * ```php * Yii::$app->db->createCommand()->createTable('post', [ @@ -647,7 +654,7 @@ public function delete($table, $condition = '', $params = []) * 'title' => 'string', * 'text' => 'text', * 'column_name double precision null default null', - * ]); + * ]); * ``` * * @param string $table the name of the table to be created. The name will be properly quoted by the method. diff --git a/db/Connection.php b/db/Connection.php index 4df8f3af6..050b5fe9f 100644 --- a/db/Connection.php +++ b/db/Connection.php @@ -1,4 +1,5 @@ 'yii\db\oci\Schema', // Oracle driver 'mssql' => 'yii\db\mssql\Schema', // older MSSQL driver on MS Windows hosts 'dblib' => 'yii\db\mssql\Schema', // dblib drivers on GNU/Linux (and maybe other OSes) hosts - 'cubrid' => 'yii\db\cubrid\Schema', // CUBRID ]; /** * @var string|null Custom PDO wrapper class. If not set, it will use [[PDO]] or [[\yii\db\mssql\PDO]] when MSSQL is used. @@ -319,7 +319,6 @@ class Connection extends Component 'oci' => 'yii\db\oci\Command', // Oracle driver 'mssql' => 'yii\db\Command', // older MSSQL driver on MS Windows hosts 'dblib' => 'yii\db\Command', // dblib drivers on GNU/Linux (and maybe other OSes) hosts - 'cubrid' => 'yii\db\Command', // CUBRID ]; /** * @var bool whether to enable [savepoint](https://en.wikipedia.org/wiki/Savepoint). @@ -745,7 +744,7 @@ protected function initConnection() if (!$this->isSybase && in_array($this->getDriverName(), ['mssql', 'dblib'], true)) { $this->pdo->exec('SET ANSI_NULL_DFLT_ON ON'); } - if ($this->charset !== null && in_array($this->getDriverName(), ['pgsql', 'mysql', 'mysqli', 'cubrid'], true)) { + if ($this->charset !== null && in_array($this->getDriverName(), ['pgsql', 'mysql', 'mysqli'], true)) { $this->pdo->exec('SET NAMES ' . $this->pdo->quote($this->charset)); } $this->trigger(self::EVENT_AFTER_OPEN); diff --git a/db/cubrid/ColumnSchemaBuilder.php b/db/cubrid/ColumnSchemaBuilder.php deleted file mode 100644 index e3f402b03..000000000 --- a/db/cubrid/ColumnSchemaBuilder.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @since 2.0.8 - */ -class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder -{ - /** - * {@inheritdoc} - */ - protected function buildUnsignedString() - { - return $this->isUnsigned ? ' UNSIGNED' : ''; - } - - /** - * {@inheritdoc} - */ - protected function buildAfterString() - { - return $this->after !== null ? - ' AFTER ' . $this->db->quoteColumnName($this->after) : - ''; - } - - /** - * {@inheritdoc} - */ - protected function buildFirstString() - { - return $this->isFirst ? ' FIRST' : ''; - } - - /** - * {@inheritdoc} - */ - protected function buildCommentString() - { - return $this->comment !== null ? ' COMMENT ' . $this->db->quoteValue($this->comment) : ''; - } - - /** - * {@inheritdoc} - */ - public function __toString() - { - switch ($this->getTypeCategory()) { - case self::CATEGORY_PK: - $format = '{type}{check}{comment}{append}{pos}'; - break; - case self::CATEGORY_NUMERIC: - $format = '{type}{length}{unsigned}{notnull}{unique}{default}{check}{comment}{append}{pos}'; - break; - default: - $format = '{type}{length}{notnull}{unique}{default}{check}{comment}{append}{pos}'; - } - - return $this->buildCompleteString($format); - } -} diff --git a/db/cubrid/QueryBuilder.php b/db/cubrid/QueryBuilder.php deleted file mode 100644 index 72ac4df6e..000000000 --- a/db/cubrid/QueryBuilder.php +++ /dev/null @@ -1,294 +0,0 @@ - - * @since 2.0 - */ -class QueryBuilder extends \yii\db\QueryBuilder -{ - /** - * @var array mapping from abstract column types (keys) to physical column types (values). - */ - public $typeMap = [ - Schema::TYPE_PK => 'int NOT NULL AUTO_INCREMENT PRIMARY KEY', - Schema::TYPE_UPK => 'int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY', - Schema::TYPE_BIGPK => 'bigint NOT NULL AUTO_INCREMENT PRIMARY KEY', - Schema::TYPE_UBIGPK => 'bigint UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY', - Schema::TYPE_CHAR => 'char(1)', - Schema::TYPE_STRING => 'varchar(255)', - Schema::TYPE_TEXT => 'varchar', - Schema::TYPE_TINYINT => 'smallint', - Schema::TYPE_SMALLINT => 'smallint', - Schema::TYPE_INTEGER => 'int', - Schema::TYPE_BIGINT => 'bigint', - Schema::TYPE_FLOAT => 'float(7)', - Schema::TYPE_DOUBLE => 'double(15)', - Schema::TYPE_DECIMAL => 'decimal(10,0)', - Schema::TYPE_DATETIME => 'datetime', - Schema::TYPE_TIMESTAMP => 'timestamp', - Schema::TYPE_TIME => 'time', - Schema::TYPE_DATE => 'date', - Schema::TYPE_BINARY => 'blob', - Schema::TYPE_BOOLEAN => 'smallint', - Schema::TYPE_MONEY => 'decimal(19,4)', - ]; - - - /** - * {@inheritdoc} - */ - protected function defaultExpressionBuilders() - { - return array_merge(parent::defaultExpressionBuilders(), [ - 'yii\db\conditions\LikeCondition' => 'yii\db\cubrid\conditions\LikeConditionBuilder', - ]); - } - - /** - * {@inheritdoc} - * @see https://www.cubrid.org/manual/en/9.3.0/sql/query/merge.html - */ - public function upsert($table, $insertColumns, $updateColumns, &$params) - { - /** @var Constraint[] $constraints */ - list($uniqueNames, $insertNames, $updateNames) = $this->prepareUpsertColumns($table, $insertColumns, $updateColumns, $constraints); - if (empty($uniqueNames)) { - return $this->insert($table, $insertColumns, $params); - } - if ($updateNames === []) { - // there are no columns to update - $updateColumns = false; - } - - $onCondition = ['or']; - $quotedTableName = $this->db->quoteTableName($table); - foreach ($constraints as $constraint) { - $constraintCondition = ['and']; - foreach ($constraint->columnNames as $name) { - $quotedName = $this->db->quoteColumnName($name); - $constraintCondition[] = "$quotedTableName.$quotedName=\"EXCLUDED\".$quotedName"; - } - $onCondition[] = $constraintCondition; - } - $on = $this->buildCondition($onCondition, $params); - list(, $placeholders, $values, $params) = $this->prepareInsertValues($table, $insertColumns, $params); - $mergeSql = 'MERGE INTO ' . $this->db->quoteTableName($table) . ' ' - . 'USING (' . (!empty($placeholders) ? 'VALUES (' . implode(', ', $placeholders) . ')' : ltrim($values, ' ')) . ') AS "EXCLUDED" (' . implode(', ', $insertNames) . ') ' - . "ON ($on)"; - $insertValues = []; - foreach ($insertNames as $name) { - $quotedName = $this->db->quoteColumnName($name); - if (strrpos($quotedName, '.') === false) { - $quotedName = '"EXCLUDED".' . $quotedName; - } - $insertValues[] = $quotedName; - } - $insertSql = 'INSERT (' . implode(', ', $insertNames) . ')' - . ' VALUES (' . implode(', ', $insertValues) . ')'; - if ($updateColumns === false) { - return "$mergeSql WHEN NOT MATCHED THEN $insertSql"; - } - - if ($updateColumns === true) { - $updateColumns = []; - foreach ($updateNames as $name) { - $quotedName = $this->db->quoteColumnName($name); - if (strrpos($quotedName, '.') === false) { - $quotedName = '"EXCLUDED".' . $quotedName; - } - $updateColumns[$name] = new Expression($quotedName); - } - } - list($updates, $params) = $this->prepareUpdateSets($table, $updateColumns, $params); - $updateSql = 'UPDATE SET ' . implode(', ', $updates); - return "$mergeSql WHEN MATCHED THEN $updateSql WHEN NOT MATCHED THEN $insertSql"; - } - - /** - * Creates a SQL statement for resetting the sequence value of a table's primary key. - * The sequence will be reset such that the primary key of the next new row inserted - * will have the specified value or 1. - * @param string $tableName the name of the table whose primary key sequence will be reset - * @param mixed $value the value for the primary key of the next new row inserted. If this is not set, - * the next new row's primary key will have a value 1. - * @return string the SQL statement for resetting sequence - * @throws InvalidArgumentException if the table does not exist or there is no sequence associated with the table. - */ - public function resetSequence($tableName, $value = null) - { - $table = $this->db->getTableSchema($tableName); - if ($table !== null && $table->sequenceName !== null) { - $tableName = $this->db->quoteTableName($tableName); - if ($value === null) { - $key = reset($table->primaryKey); - $value = (int) $this->db->createCommand("SELECT MAX(`$key`) FROM " . $this->db->schema->quoteTableName($tableName))->queryScalar() + 1; - } else { - $value = (int) $value; - } - - return 'ALTER TABLE ' . $this->db->schema->quoteTableName($tableName) . " AUTO_INCREMENT=$value;"; - } elseif ($table === null) { - throw new InvalidArgumentException("Table not found: $tableName"); - } - - throw new InvalidArgumentException("There is not sequence associated with table '$tableName'."); - } - - /** - * {@inheritdoc} - */ - public function buildLimit($limit, $offset) - { - $sql = ''; - // limit is not optional in CUBRID - // https://www.cubrid.org/manual/en/9.3.0/sql/query/select.html#limit-clause - // "You can specify a very big integer for row_count to display to the last row, starting from a specific row." - if ($this->hasLimit($limit)) { - $sql = 'LIMIT ' . $limit; - if ($this->hasOffset($offset)) { - $sql .= ' OFFSET ' . $offset; - } - } elseif ($this->hasOffset($offset)) { - $sql = "LIMIT 9223372036854775807 OFFSET $offset"; // 2^63-1 - } - - return $sql; - } - - /** - * {@inheritdoc} - * @since 2.0.8 - */ - public function selectExists($rawSql) - { - return 'SELECT CASE WHEN EXISTS(' . $rawSql . ') THEN 1 ELSE 0 END'; - } - - /** - * {@inheritdoc} - * @see https://www.cubrid.org/manual/en/9.3.0/sql/schema/table.html#drop-index-clause - */ - public function dropIndex($name, $table) - { - /** @var Schema $schema */ - $schema = $this->db->getSchema(); - foreach ($schema->getTableUniques($table) as $unique) { - if ($unique->name === $name) { - return $this->dropUnique($name, $table); - } - } - - return 'DROP INDEX ' . $this->db->quoteTableName($name) . ' ON ' . $this->db->quoteTableName($table); - } - - /** - * {@inheritdoc} - * @throws NotSupportedException this is not supported by CUBRID. - */ - public function addCheck($name, $table, $expression) - { - throw new NotSupportedException(__METHOD__ . ' is not supported by CUBRID.'); - } - - /** - * {@inheritdoc} - * @throws NotSupportedException this is not supported by CUBRID. - */ - public function dropCheck($name, $table) - { - throw new NotSupportedException(__METHOD__ . ' is not supported by CUBRID.'); - } - - /** - * {@inheritdoc} - * @since 2.0.8 - */ - public function addCommentOnColumn($table, $column, $comment) - { - $definition = $this->getColumnDefinition($table, $column); - $definition = trim(preg_replace("/COMMENT '(.*?)'/i", '', $definition)); - - return 'ALTER TABLE ' . $this->db->quoteTableName($table) - . ' CHANGE ' . $this->db->quoteColumnName($column) - . ' ' . $this->db->quoteColumnName($column) - . (empty($definition) ? '' : ' ' . $definition) - . ' COMMENT ' . $this->db->quoteValue($comment); - } - - /** - * {@inheritdoc} - * @since 2.0.8 - */ - public function addCommentOnTable($table, $comment) - { - return 'ALTER TABLE ' . $this->db->quoteTableName($table) . ' COMMENT ' . $this->db->quoteValue($comment); - } - - /** - * {@inheritdoc} - * @since 2.0.8 - */ - public function dropCommentFromColumn($table, $column) - { - return $this->addCommentOnColumn($table, $column, ''); - } - - /** - * {@inheritdoc} - * @since 2.0.8 - */ - public function dropCommentFromTable($table) - { - return $this->addCommentOnTable($table, ''); - } - - - /** - * Gets column definition. - * - * @param string $table table name - * @param string $column column name - * @return string|null the column definition - * @throws Exception in case when table does not contain column - * @since 2.0.8 - */ - private function getColumnDefinition($table, $column) - { - $row = $this->db->createCommand('SHOW CREATE TABLE ' . $this->db->quoteTableName($table))->queryOne(); - if ($row === false) { - throw new Exception("Unable to find column '$column' in table '$table'."); - } - if (isset($row['Create Table'])) { - $sql = $row['Create Table']; - } else { - $row = array_values($row); - $sql = $row[1]; - } - $sql = preg_replace('/^[^(]+\((.*)\).*$/', '\1', $sql); - $sql = str_replace(', [', ",\n[", $sql); - if (preg_match_all('/^\s*\[(.*?)\]\s+(.*?),?$/m', $sql, $matches)) { - foreach ($matches[1] as $i => $c) { - if ($c === $column) { - return $matches[2][$i]; - } - } - } - - return null; - } -} diff --git a/db/cubrid/Schema.php b/db/cubrid/Schema.php deleted file mode 100644 index 74adba234..000000000 --- a/db/cubrid/Schema.php +++ /dev/null @@ -1,419 +0,0 @@ - - * @since 2.0 - */ -class Schema extends \yii\db\Schema implements ConstraintFinderInterface -{ - use ConstraintFinderTrait; - - /** - * @var array mapping from physical column types (keys) to abstract column types (values) - * Please refer to [CUBRID manual](https://www.cubrid.org/manual/en/9.3.0/sql/datatype.html) for - * details on data types. - */ - public $typeMap = [ - // Numeric data types - 'short' => self::TYPE_SMALLINT, - 'smallint' => self::TYPE_SMALLINT, - 'int' => self::TYPE_INTEGER, - 'integer' => self::TYPE_INTEGER, - 'bigint' => self::TYPE_BIGINT, - 'numeric' => self::TYPE_DECIMAL, - 'decimal' => self::TYPE_DECIMAL, - 'float' => self::TYPE_FLOAT, - 'real' => self::TYPE_FLOAT, - 'double' => self::TYPE_DOUBLE, - 'double precision' => self::TYPE_DOUBLE, - 'monetary' => self::TYPE_MONEY, - // Date/Time data types - 'date' => self::TYPE_DATE, - 'time' => self::TYPE_TIME, - 'timestamp' => self::TYPE_TIMESTAMP, - 'datetime' => self::TYPE_DATETIME, - // String data types - 'char' => self::TYPE_CHAR, - 'varchar' => self::TYPE_STRING, - 'char varying' => self::TYPE_STRING, - 'nchar' => self::TYPE_CHAR, - 'nchar varying' => self::TYPE_STRING, - 'string' => self::TYPE_STRING, - // BLOB/CLOB data types - 'blob' => self::TYPE_BINARY, - 'clob' => self::TYPE_BINARY, - // Bit string data types - 'bit' => self::TYPE_INTEGER, - 'bit varying' => self::TYPE_INTEGER, - // Collection data types (considered strings for now) - 'set' => self::TYPE_STRING, - 'multiset' => self::TYPE_STRING, - 'list' => self::TYPE_STRING, - 'sequence' => self::TYPE_STRING, - 'enum' => self::TYPE_STRING, - ]; - /** - * @var array map of DB errors and corresponding exceptions - * If left part is found in DB error message exception class from the right part is used. - */ - public $exceptionMap = [ - 'Operation would have caused one or more unique constraint violations' => 'yii\db\IntegrityException', - ]; - - /** - * {@inheritdoc} - */ - protected $tableQuoteCharacter = '"'; - - - /** - * {@inheritdoc} - */ - protected function findTableNames($schema = '') - { - $pdo = $this->db->getSlavePdo(true); - $tables = $pdo->cubrid_schema(\PDO::CUBRID_SCH_TABLE); - $tableNames = []; - foreach ($tables as $table) { - // do not list system tables - if ($table['TYPE'] != 0) { - $tableNames[] = $table['NAME']; - } - } - - return $tableNames; - } - - /** - * {@inheritdoc} - */ - protected function loadTableSchema($name) - { - $pdo = $this->db->getSlavePdo(true); - - $tableInfo = $pdo->cubrid_schema(\PDO::CUBRID_SCH_TABLE, $name); - - if (!isset($tableInfo[0]['NAME'])) { - return null; - } - - $table = new TableSchema(); - $table->fullName = $table->name = $tableInfo[0]['NAME']; - - $sql = 'SHOW FULL COLUMNS FROM ' . $this->quoteSimpleTableName($table->name); - $columns = $this->db->createCommand($sql)->queryAll(); - - foreach ($columns as $info) { - $column = $this->loadColumnSchema($info); - $table->columns[$column->name] = $column; - } - - $primaryKeys = $pdo->cubrid_schema(\PDO::CUBRID_SCH_PRIMARY_KEY, $table->name); - foreach ($primaryKeys as $key) { - $column = $table->columns[$key['ATTR_NAME']]; - $column->isPrimaryKey = true; - $table->primaryKey[] = $column->name; - if ($column->autoIncrement) { - $table->sequenceName = ''; - } - } - - $foreignKeys = $pdo->cubrid_schema(\PDO::CUBRID_SCH_IMPORTED_KEYS, $table->name); - foreach ($foreignKeys as $key) { - if (isset($table->foreignKeys[$key['FK_NAME']])) { - $table->foreignKeys[$key['FK_NAME']][$key['FKCOLUMN_NAME']] = $key['PKCOLUMN_NAME']; - } else { - $table->foreignKeys[$key['FK_NAME']] = [ - $key['PKTABLE_NAME'], - $key['FKCOLUMN_NAME'] => $key['PKCOLUMN_NAME'], - ]; - } - } - - return $table; - } - - /** - * {@inheritdoc} - */ - protected function loadTablePrimaryKey($tableName) - { - $primaryKey = $this->db->getSlavePdo(true)->cubrid_schema(\PDO::CUBRID_SCH_PRIMARY_KEY, $tableName); - if (empty($primaryKey)) { - return null; - } - - ArrayHelper::multisort($primaryKey, 'KEY_SEQ', SORT_ASC, SORT_NUMERIC); - return new Constraint([ - 'name' => $primaryKey[0]['KEY_NAME'], - 'columnNames' => ArrayHelper::getColumn($primaryKey, 'ATTR_NAME'), - ]); - } - - /** - * {@inheritdoc} - */ - protected function loadTableForeignKeys($tableName) - { - static $actionTypes = [ - 0 => 'CASCADE', - 1 => 'RESTRICT', - 2 => 'NO ACTION', - 3 => 'SET NULL', - ]; - - $foreignKeys = $this->db->getSlavePdo(true)->cubrid_schema(\PDO::CUBRID_SCH_IMPORTED_KEYS, $tableName); - $foreignKeys = ArrayHelper::index($foreignKeys, null, 'FK_NAME'); - ArrayHelper::multisort($foreignKeys, 'KEY_SEQ', SORT_ASC, SORT_NUMERIC); - $result = []; - foreach ($foreignKeys as $name => $foreignKey) { - $result[] = new ForeignKeyConstraint([ - 'name' => $name, - 'columnNames' => ArrayHelper::getColumn($foreignKey, 'FKCOLUMN_NAME'), - 'foreignTableName' => $foreignKey[0]['PKTABLE_NAME'], - 'foreignColumnNames' => ArrayHelper::getColumn($foreignKey, 'PKCOLUMN_NAME'), - 'onDelete' => isset($actionTypes[$foreignKey[0]['DELETE_RULE']]) ? $actionTypes[$foreignKey[0]['DELETE_RULE']] : null, - 'onUpdate' => isset($actionTypes[$foreignKey[0]['UPDATE_RULE']]) ? $actionTypes[$foreignKey[0]['UPDATE_RULE']] : null, - ]); - } - - return $result; - } - - /** - * {@inheritdoc} - */ - protected function loadTableIndexes($tableName) - { - return $this->loadTableConstraints($tableName, 'indexes'); - } - - /** - * {@inheritdoc} - */ - protected function loadTableUniques($tableName) - { - return $this->loadTableConstraints($tableName, 'uniques'); - } - - /** - * {@inheritdoc} - * @throws NotSupportedException if this method is called. - */ - protected function loadTableChecks($tableName) - { - throw new NotSupportedException('CUBRID does not support check constraints.'); - } - - /** - * {@inheritdoc} - * @throws NotSupportedException if this method is called. - */ - protected function loadTableDefaultValues($tableName) - { - throw new NotSupportedException('CUBRID does not support default value constraints.'); - } - - /** - * {@inheritdoc} - */ - public function releaseSavepoint($name) - { - // does nothing as cubrid does not support this - } - - /** - * Creates a query builder for the CUBRID database. - * @return QueryBuilder query builder instance - */ - public function createQueryBuilder() - { - return Yii::createObject(QueryBuilder::class, [$this->db]); - } - - /** - * Loads the column information into a [[ColumnSchema]] object. - * @param array $info column information - * @return \yii\db\ColumnSchema the column schema object - */ - protected function loadColumnSchema($info) - { - $column = $this->createColumnSchema(); - - $column->name = $info['Field']; - $column->allowNull = $info['Null'] === 'YES'; - $column->isPrimaryKey = false; // primary key will be set by loadTableSchema() later - $column->autoIncrement = stripos($info['Extra'], 'auto_increment') !== false; - - $column->dbType = $info['Type']; - $column->unsigned = strpos($column->dbType, 'unsigned') !== false; - - $column->type = self::TYPE_STRING; - if (preg_match('/^([\w ]+)(?:\(([^\)]+)\))?$/', $column->dbType, $matches)) { - $type = strtolower($matches[1]); - $column->dbType = $type . (isset($matches[2]) ? "({$matches[2]})" : ''); - if (isset($this->typeMap[$type])) { - $column->type = $this->typeMap[$type]; - } - if (!empty($matches[2])) { - if ($type === 'enum') { - $values = preg_split('/\s*,\s*/', $matches[2]); - foreach ($values as $i => $value) { - $values[$i] = trim($value, "'"); - } - $column->enumValues = $values; - } else { - $values = explode(',', $matches[2]); - $column->size = $column->precision = (int) $values[0]; - if (isset($values[1])) { - $column->scale = (int) $values[1]; - } - if ($column->size === 1 && $type === 'bit') { - $column->type = 'boolean'; - } elseif ($type === 'bit') { - if ($column->size > 32) { - $column->type = 'bigint'; - } elseif ($column->size === 32) { - $column->type = 'integer'; - } - } - } - } - } - - $column->phpType = $this->getColumnPhpType($column); - - if ($column->isPrimaryKey) { - return $column; - } - - if ($column->type === 'timestamp' && $info['Default'] === 'SYS_TIMESTAMP' || - $column->type === 'datetime' && $info['Default'] === 'SYS_DATETIME' || - $column->type === 'date' && $info['Default'] === 'SYS_DATE' || - $column->type === 'time' && $info['Default'] === 'SYS_TIME' - ) { - $column->defaultValue = new Expression($info['Default']); - } elseif (isset($type) && $type === 'bit') { - $column->defaultValue = hexdec(trim($info['Default'], 'X\'')); - } else { - $column->defaultValue = $column->phpTypecast($info['Default']); - } - - return $column; - } - - /** - * Determines the PDO type for the given PHP data value. - * @param mixed $data the data whose PDO type is to be determined - * @return int the PDO type - * @see https://www.php.net/manual/en/pdo.constants.php - */ - public function getPdoType($data) - { - static $typeMap = [ - // php type => PDO type - 'boolean' => \PDO::PARAM_INT, // PARAM_BOOL is not supported by CUBRID PDO - 'integer' => \PDO::PARAM_INT, - 'string' => \PDO::PARAM_STR, - 'resource' => \PDO::PARAM_LOB, - 'NULL' => \PDO::PARAM_NULL, - ]; - $type = gettype($data); - - return isset($typeMap[$type]) ? $typeMap[$type] : \PDO::PARAM_STR; - } - - /** - * {@inheritdoc} - * @see https://www.cubrid.org/manual/en/9.3.0/sql/transaction.html#database-concurrency - */ - public function setTransactionIsolationLevel($level) - { - // translate SQL92 levels to CUBRID levels: - switch ($level) { - case Transaction::SERIALIZABLE: - $level = '6'; // SERIALIZABLE - break; - case Transaction::REPEATABLE_READ: - $level = '5'; // REPEATABLE READ CLASS with REPEATABLE READ INSTANCES - break; - case Transaction::READ_COMMITTED: - $level = '4'; // REPEATABLE READ CLASS with READ COMMITTED INSTANCES - break; - case Transaction::READ_UNCOMMITTED: - $level = '3'; // REPEATABLE READ CLASS with READ UNCOMMITTED INSTANCES - break; - } - parent::setTransactionIsolationLevel($level); - } - - /** - * {@inheritdoc} - */ - public function createColumnSchemaBuilder($type, $length = null) - { - return new ColumnSchemaBuilder($type, $length, $this->db); - } - - /** - * Loads multiple types of constraints and returns the specified ones. - * @param string $tableName table name. - * @param string $returnType return type: - * - indexes - * - uniques - * @return mixed constraints. - */ - private function loadTableConstraints($tableName, $returnType) - { - $constraints = $this->db->getSlavePdo(true)->cubrid_schema(\PDO::CUBRID_SCH_CONSTRAINT, $tableName); - $constraints = ArrayHelper::index($constraints, null, ['TYPE', 'NAME']); - ArrayHelper::multisort($constraints, 'KEY_ORDER', SORT_ASC, SORT_NUMERIC); - $result = [ - 'indexes' => [], - 'uniques' => [], - ]; - foreach ($constraints as $type => $names) { - foreach ($names as $name => $constraint) { - $isUnique = in_array((int) $type, [0, 2], true); - $result['indexes'][] = new IndexConstraint([ - 'isPrimary' => (bool) $constraint[0]['PRIMARY_KEY'], - 'isUnique' => $isUnique, - 'name' => $name, - 'columnNames' => ArrayHelper::getColumn($constraint, 'ATTR_NAME'), - ]); - if ($isUnique) { - $result['uniques'][] = new Constraint([ - 'name' => $name, - 'columnNames' => ArrayHelper::getColumn($constraint, 'ATTR_NAME'), - ]); - } - } - } - foreach ($result as $type => $data) { - $this->setTableMetadata($tableName, $type, $data); - } - - return $result[$returnType]; - } -} diff --git a/db/cubrid/conditions/LikeConditionBuilder.php b/db/cubrid/conditions/LikeConditionBuilder.php deleted file mode 100644 index 80cd27173..000000000 --- a/db/cubrid/conditions/LikeConditionBuilder.php +++ /dev/null @@ -1,29 +0,0 @@ - '!%', - '_' => '!_', - '!' => '!!', - ]; -} From ca8759834bbdadfdf72c7a23ed75a30d8bfaa1f6 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Tue, 18 Jul 2023 10:54:55 -0400 Subject: [PATCH 05/56] Remove deprecated `InvalidParamException::class` in branch `2.2`. (#19896) --- base/InvalidArgumentException.php | 2 +- base/InvalidParamException.php | 26 ----------------------- classes.php | 1 - console/controllers/FixtureController.php | 4 ++-- db/BaseActiveRecord.php | 5 ++--- db/conditions/ConditionInterface.php | 4 ++-- rbac/CheckAccessInterface.php | 2 +- rbac/ManagerInterface.php | 2 +- web/ErrorHandler.php | 2 +- 9 files changed, 10 insertions(+), 38 deletions(-) delete mode 100644 base/InvalidParamException.php diff --git a/base/InvalidArgumentException.php b/base/InvalidArgumentException.php index 20a7c6c75..428d73b58 100644 --- a/base/InvalidArgumentException.php +++ b/base/InvalidArgumentException.php @@ -13,7 +13,7 @@ * @author Qiang Xue * @since 2.0.14 */ -class InvalidArgumentException extends InvalidParamException +class InvalidArgumentException extends \BadMethodCallException { /** * @return string the user-friendly name of this exception diff --git a/base/InvalidParamException.php b/base/InvalidParamException.php deleted file mode 100644 index 0024602ec..000000000 --- a/base/InvalidParamException.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @since 2.0 - * @deprecated since 2.0.14. Use [[InvalidArgumentException]] instead. - */ -class InvalidParamException extends \BadMethodCallException -{ - /** - * @return string the user-friendly name of this exception - */ - public function getName() - { - return 'Invalid Parameter'; - } -} diff --git a/classes.php b/classes.php index 3d4759ed4..4f52f31ba 100644 --- a/classes.php +++ b/classes.php @@ -37,7 +37,6 @@ 'yii\base\InvalidArgumentException' => YII2_PATH . '/base/InvalidArgumentException.php', 'yii\base\InvalidCallException' => YII2_PATH . '/base/InvalidCallException.php', 'yii\base\InvalidConfigException' => YII2_PATH . '/base/InvalidConfigException.php', - 'yii\base\InvalidParamException' => YII2_PATH . '/base/InvalidParamException.php', 'yii\base\InvalidRouteException' => YII2_PATH . '/base/InvalidRouteException.php', 'yii\base\InvalidValueException' => YII2_PATH . '/base/InvalidValueException.php', 'yii\base\Model' => YII2_PATH . '/base/Model.php', diff --git a/console/controllers/FixtureController.php b/console/controllers/FixtureController.php index a210034b7..9187ea517 100644 --- a/console/controllers/FixtureController.php +++ b/console/controllers/FixtureController.php @@ -8,8 +8,8 @@ namespace yii\console\controllers; use Yii; +use yii\base\InvalidArgumentException; use yii\base\InvalidConfigException; -use yii\base\InvalidParamException; use yii\console\Controller; use yii\console\Exception; use yii\console\ExitCode; @@ -536,7 +536,7 @@ private function getFixturePath() { try { return Yii::getAlias('@' . str_replace('\\', '/', $this->namespace)); - } catch (InvalidParamException $e) { + } catch (InvalidArgumentException $e) { throw new InvalidConfigException('Invalid fixture namespace: "' . $this->namespace . '". Please, check your FixtureController::namespace parameter'); } } diff --git a/db/BaseActiveRecord.php b/db/BaseActiveRecord.php index 88fb2f11d..42271a144 100644 --- a/db/BaseActiveRecord.php +++ b/db/BaseActiveRecord.php @@ -11,7 +11,6 @@ use yii\base\InvalidArgumentException; use yii\base\InvalidCallException; use yii\base\InvalidConfigException; -use yii\base\InvalidParamException; use yii\base\Model; use yii\base\ModelEvent; use yii\base\NotSupportedException; @@ -1632,7 +1631,7 @@ public function getAttributeLabel($attribute) } else { try { $relation = $relatedModel->getRelation($relationName); - } catch (InvalidParamException $e) { + } catch (InvalidArgumentException $e) { return $this->generateAttributeLabel($attribute); } /* @var $modelClass ActiveRecordInterface */ @@ -1674,7 +1673,7 @@ public function getAttributeHint($attribute) } else { try { $relation = $relatedModel->getRelation($relationName); - } catch (InvalidParamException $e) { + } catch (InvalidArgumentException $e) { return ''; } /* @var $modelClass ActiveRecordInterface */ diff --git a/db/conditions/ConditionInterface.php b/db/conditions/ConditionInterface.php index fc8146940..96d63548c 100644 --- a/db/conditions/ConditionInterface.php +++ b/db/conditions/ConditionInterface.php @@ -7,7 +7,7 @@ namespace yii\db\conditions; -use yii\base\InvalidParamException; +use InvalidArgumentException; use yii\db\ExpressionInterface; /** @@ -27,7 +27,7 @@ interface ConditionInterface extends ExpressionInterface * @param array $operands array of corresponding operands * * @return $this - * @throws InvalidParamException if input parameters are not suitable for this condition + * @throws InvalidArgumentException if input parameters are not suitable for this condition */ public static function fromArrayDefinition($operator, $operands); } diff --git a/rbac/CheckAccessInterface.php b/rbac/CheckAccessInterface.php index 38d86ee7a..7f4dce00b 100644 --- a/rbac/CheckAccessInterface.php +++ b/rbac/CheckAccessInterface.php @@ -23,7 +23,7 @@ interface CheckAccessInterface * @param array $params name-value pairs that will be passed to the rules associated * with the roles and permissions assigned to the user. * @return bool whether the user has the specified permission. - * @throws \yii\base\InvalidParamException if $permissionName does not refer to an existing permission + * @throws \yii\base\InvalidArgumentException if $permissionName does not refer to an existing permission */ public function checkAccess($userId, $permissionName, $params = []); } diff --git a/rbac/ManagerInterface.php b/rbac/ManagerInterface.php index e4d2c7029..fec06fdc0 100644 --- a/rbac/ManagerInterface.php +++ b/rbac/ManagerInterface.php @@ -83,7 +83,7 @@ public function getRolesByUser($userId); * @param string $roleName name of the role to file child roles for * @return Role[] Child roles. The array is indexed by the role names. * First element is an instance of the parent Role itself. - * @throws \yii\base\InvalidParamException if Role was not found that are getting by $roleName + * @throws \yii\base\InvalidArgumentException if Role was not found that are getting by $roleName * @since 2.0.10 */ public function getChildRoles($roleName); diff --git a/web/ErrorHandler.php b/web/ErrorHandler.php index 3806c576c..cf97936e0 100644 --- a/web/ErrorHandler.php +++ b/web/ErrorHandler.php @@ -487,7 +487,7 @@ public function argumentsToString($args) */ public function getExceptionName($exception) { - if ($exception instanceof \yii\base\Exception || $exception instanceof \yii\base\InvalidCallException || $exception instanceof \yii\base\InvalidParamException || $exception instanceof \yii\base\UnknownMethodException) { + if ($exception instanceof \yii\base\Exception || $exception instanceof \yii\base\InvalidCallException || $exception instanceof \yii\base\InvalidArgumentException || $exception instanceof \yii\base\UnknownMethodException) { return $exception->getName(); } From 76a90214d585bd7aa61616447a0daf3ece0a53f6 Mon Sep 17 00:00:00 2001 From: "Stefano D. Mtangoo" Date: Mon, 24 Jul 2023 09:08:59 +0300 Subject: [PATCH 06/56] Remove XCache and ZendDataCache support (#19904) Co-authored-by: Stefano Mtangoo --- CHANGELOG.md | 1 + UPGRADE.md | 1 - caching/XCache.php | 111 -------------------------------------- caching/ZendDataCache.php | 89 ------------------------------ classes.php | 2 - 5 files changed, 1 insertion(+), 203 deletions(-) delete mode 100644 caching/XCache.php delete mode 100644 caching/ZendDataCache.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bd17d17e..06d86c145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Yii Framework 2 Change Log ------------------------ - Chg #19902: Remove support for CUBRID (mtangoo) +- Chg #19891: Remove XCache and ZendDataCache support (mtangoo) 2.0.49 under development diff --git a/UPGRADE.md b/UPGRADE.md index 8286cf010..539873408 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -526,7 +526,6 @@ Upgrade from Yii 2.0.13 - Replace usages of `yii\base\InvalidParamException` with `yii\base\InvalidArgumentException`. - Replace calls to `Yii::trace()` with `Yii::debug()`. - Remove calls to `yii\BaseYii::powered()`. - - If you are using XCache or Zend data cache, those are going away in 2.1 so you might want to start looking for an alternative. * In case you aren't using CSRF cookies (REST APIs etc.) you should turn them off explicitly by setting `\yii\web\Request::$enableCsrfCookie` to `false` in your config file. diff --git a/caching/XCache.php b/caching/XCache.php deleted file mode 100644 index 06c305de2..000000000 --- a/caching/XCache.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @since 2.0 - * @deprecated since 2.0.14. This class will be removed in 2.1.0. - */ -class XCache extends Cache -{ - /** - * Checks whether a specified key exists in the cache. - * This can be faster than getting the value from the cache if the data is big. - * Note that this method does not check whether the dependency associated - * with the cached data, if there is any, has changed. So a call to [[get]] - * may return false while exists returns true. - * @param mixed $key a key identifying the cached value. This can be a simple string or - * a complex data structure consisting of factors representing the key. - * @return bool true if a value exists in cache, false if the value is not in the cache or expired. - */ - public function exists($key) - { - $key = $this->buildKey($key); - - return xcache_isset($key); - } - - /** - * Retrieves a value from cache with a specified key. - * This is the implementation of the method declared in the parent class. - * @param string $key a unique key identifying the cached value - * @return mixed|false the value stored in cache, false if the value is not in the cache or expired. - */ - protected function getValue($key) - { - return xcache_isset($key) ? xcache_get($key) : false; - } - - /** - * Stores a value identified by a key in cache. - * This is the implementation of the method declared in the parent class. - * - * @param string $key the key identifying the value to be cached - * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]], - * it could be something else. - * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire. - * @return bool true if the value is successfully stored into cache, false otherwise - */ - protected function setValue($key, $value, $duration) - { - return xcache_set($key, $value, $duration); - } - - /** - * Stores a value identified by a key into cache if the cache does not contain this key. - * This is the implementation of the method declared in the parent class. - * - * @param string $key the key identifying the value to be cached - * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]], - * it could be something else. - * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire. - * @return bool true if the value is successfully stored into cache, false otherwise - */ - protected function addValue($key, $value, $duration) - { - return !xcache_isset($key) ? $this->setValue($key, $value, $duration) : false; - } - - /** - * Deletes a value with the specified key from cache - * This is the implementation of the method declared in the parent class. - * @param string $key the key of the value to be deleted - * @return bool if no error happens during deletion - */ - protected function deleteValue($key) - { - return xcache_unset($key); - } - - /** - * Deletes all values from cache. - * This is the implementation of the method declared in the parent class. - * @return bool whether the flush operation was successful. - */ - protected function flushValues() - { - for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) { - if (xcache_clear_cache(XC_TYPE_VAR, $i) === false) { - return false; - } - } - - return true; - } -} diff --git a/caching/ZendDataCache.php b/caching/ZendDataCache.php deleted file mode 100644 index 0f49501db..000000000 --- a/caching/ZendDataCache.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @since 2.0 - * @deprecated since 2.0.14. This class will be removed in 2.1.0. - */ -class ZendDataCache extends Cache -{ - /** - * Retrieves a value from cache with a specified key. - * This is the implementation of the method declared in the parent class. - * @param string $key a unique key identifying the cached value - * @return mixed|false the value stored in cache, false if the value is not in the cache or expired. - */ - protected function getValue($key) - { - $result = zend_shm_cache_fetch($key); - - return $result === null ? false : $result; - } - - /** - * Stores a value identified by a key in cache. - * This is the implementation of the method declared in the parent class. - * - * @param string $key the key identifying the value to be cached - * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]], - * it could be something else. - * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire. - * @return bool true if the value is successfully stored into cache, false otherwise - */ - protected function setValue($key, $value, $duration) - { - return zend_shm_cache_store($key, $value, $duration); - } - - /** - * Stores a value identified by a key into cache if the cache does not contain this key. - * This is the implementation of the method declared in the parent class. - * - * @param string $key the key identifying the value to be cached - * @param mixed $value the value to be cached. Most often it's a string. If you have disabled [[serializer]], - * it could be something else. - * @param int $duration the number of seconds in which the cached value will expire. 0 means never expire. - * @return bool true if the value is successfully stored into cache, false otherwise - */ - protected function addValue($key, $value, $duration) - { - return zend_shm_cache_fetch($key) === null ? $this->setValue($key, $value, $duration) : false; - } - - /** - * Deletes a value with the specified key from cache - * This is the implementation of the method declared in the parent class. - * @param string $key the key of the value to be deleted - * @return bool if no error happens during deletion - */ - protected function deleteValue($key) - { - return zend_shm_cache_delete($key); - } - - /** - * Deletes all values from cache. - * This is the implementation of the method declared in the parent class. - * @return bool whether the flush operation was successful. - */ - protected function flushValues() - { - return zend_shm_cache_clear(); - } -} diff --git a/classes.php b/classes.php index 4f52f31ba..c148e32ef 100644 --- a/classes.php +++ b/classes.php @@ -85,8 +85,6 @@ 'yii\caching\MemCacheServer' => YII2_PATH . '/caching/MemCacheServer.php', 'yii\caching\TagDependency' => YII2_PATH . '/caching/TagDependency.php', 'yii\caching\WinCache' => YII2_PATH . '/caching/WinCache.php', - 'yii\caching\XCache' => YII2_PATH . '/caching/XCache.php', - 'yii\caching\ZendDataCache' => YII2_PATH . '/caching/ZendDataCache.php', 'yii\captcha\Captcha' => YII2_PATH . '/captcha/Captcha.php', 'yii\captcha\CaptchaAction' => YII2_PATH . '/captcha/CaptchaAction.php', 'yii\captcha\CaptchaAsset' => YII2_PATH . '/captcha/CaptchaAsset.php', From 25e58ebeb7581371977fa3a6dcdd3f9f63c705b3 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Mon, 18 Sep 2023 09:59:16 -0300 Subject: [PATCH 07/56] Update framework/CHANGELOG.md Co-authored-by: Robert Korulczyk --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 544684837..91ff0a353 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,6 @@ Yii Framework 2 Change Log - Chg #19891: Remove XCache and ZendDataCache support (mtangoo) -2.0.49 under development 2.0.50 under development ------------------------ From bf0a0f9262d5f450a42257c8b0e98e588fafa057 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Mon, 18 Sep 2023 10:02:20 -0300 Subject: [PATCH 08/56] Apply suggestion review. --- BaseYii.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BaseYii.php b/BaseYii.php index 496f6aa12..29490b908 100644 --- a/BaseYii.php +++ b/BaseYii.php @@ -93,7 +93,7 @@ class BaseYii */ public static function getVersion() { - return '2.0.50-dev'; + return '2.2-dev'; } /** From 6109652817d80b8459c434cebcafb75803d75b9f Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Thu, 21 Sep 2023 10:26:00 -0300 Subject: [PATCH 09/56] Remove deprecated methods to `BaseYii::class`. --- BaseYii.php | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/BaseYii.php b/BaseYii.php index 29490b908..c34360beb 100644 --- a/BaseYii.php +++ b/BaseYii.php @@ -408,18 +408,6 @@ public static function debug($message, $category = 'application') } } - /** - * Alias of [[debug()]]. - * @param string|array $message the message to be logged. This can be a simple string or a more - * complex data structure, such as an array. - * @param string $category the category of the message. - * @deprecated since 2.0.14. Use [[debug()]] instead. - */ - public static function trace($message, $category = 'application') - { - static::debug($message, $category); - } - /** * Logs an error message. * An error message is typically logged when an unrecoverable error occurs @@ -494,19 +482,6 @@ public static function endProfile($token, $category = 'application') static::getLogger()->log($token, Logger::LEVEL_PROFILE_END, $category); } - /** - * Returns an HTML hyperlink that can be displayed on your Web page showing "Powered by Yii Framework" information. - * @return string an HTML hyperlink that can be displayed on your Web page showing "Powered by Yii Framework" information - * @deprecated since 2.0.14, this method will be removed in 2.1.0. - */ - public static function powered() - { - return \Yii::t('yii', 'Powered by {yii}', [ - 'yii' => '' . \Yii::t('yii', - 'Yii Framework') . '', - ]); - } - /** * Translates a message to the specified language. * From b57f3812c1579253703a5abf4e3a1826510d731d Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Thu, 21 Sep 2023 10:38:15 -0300 Subject: [PATCH 10/56] Remove deprecated methods to `Security::class`. --- base/Security.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/base/Security.php b/base/Security.php index e8281b2a6..b63ce5880 100644 --- a/base/Security.php +++ b/base/Security.php @@ -73,16 +73,6 @@ class Security extends Component * Set as high as possible to hinder dictionary password attacks. */ public $derivationIterations = 100000; - /** - * @var string strategy, which should be used to generate password hash. - * Available strategies: - * - 'password_hash' - use of PHP `password_hash()` function with PASSWORD_DEFAULT algorithm. - * This option is recommended, but it requires PHP version >= 5.5.0 - * - 'crypt' - use PHP `crypt()` function. - * @deprecated since version 2.0.7, [[generatePasswordHash()]] ignores [[passwordHashStrategy]] and - * uses `password_hash()` when available or `crypt()` when not. - */ - public $passwordHashStrategy; /** * @var int Default cost used for password hashing. * Allowed value is between 4 and 31. From 5e8d30079bb350da5b8fceb3e87ab04056ab0084 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Thu, 21 Sep 2023 11:00:42 -0300 Subject: [PATCH 11/56] Remove deprecated constant `Controller::class`. --- console/Controller.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/console/Controller.php b/console/Controller.php index 579b59778..5d1b66081 100644 --- a/console/Controller.php +++ b/console/Controller.php @@ -38,15 +38,6 @@ */ class Controller extends \yii\base\Controller { - /** - * @deprecated since 2.0.13. Use [[ExitCode::OK]] instead. - */ - const EXIT_CODE_NORMAL = 0; - /** - * @deprecated since 2.0.13. Use [[ExitCode::UNSPECIFIED_ERROR]] instead. - */ - const EXIT_CODE_ERROR = 1; - /** * @var bool whether to run the command interactively. */ From 8b2f26b718f13e9072fead706b53f8c912db87c6 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Fri, 22 Sep 2023 06:40:49 -0300 Subject: [PATCH 12/56] Remove deprecated methods to `Connection::class`. --- db/Connection.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/db/Connection.php b/db/Connection.php index 050b5fe9f..38f1b1e64 100644 --- a/db/Connection.php +++ b/db/Connection.php @@ -289,15 +289,6 @@ class Connection extends Component * @see pdo */ public $pdoClass; - /** - * @var string the class used to create new database [[Command]] objects. If you want to extend the [[Command]] class, - * you may configure this property to use your extended version of the class. - * Since version 2.0.14 [[$commandMap]] is used if this property is set to its default value. - * @see createCommand - * @since 2.0.7 - * @deprecated since 2.0.14. Use [[$commandMap]] for precise configuration. - */ - public $commandClass = 'yii\db\Command'; /** * @var array mapping between PDO driver names and [[Command]] classes. * The keys of the array are PDO driver names while the values are either the corresponding @@ -760,9 +751,7 @@ public function createCommand($sql = null, $params = []) { $driver = $this->getDriverName(); $config = ['class' => 'yii\db\Command']; - if ($this->commandClass !== $config['class']) { - $config['class'] = $this->commandClass; - } elseif (isset($this->commandMap[$driver])) { + if (isset($this->commandMap[$driver])) { $config = !is_array($this->commandMap[$driver]) ? ['class' => $this->commandMap[$driver]] : $this->commandMap[$driver]; } $config['db'] = $this; From 74d18b74ca73f9d302e5f5c810881eecf0054fc0 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Fri, 22 Sep 2023 06:55:44 -0300 Subject: [PATCH 13/56] Remove deprecated methods to `Query::class`. --- db/Query.php | 53 ---------------------------------------------------- 1 file changed, 53 deletions(-) diff --git a/db/Query.php b/db/Query.php index 243d08c4a..9374f9d84 100644 --- a/db/Query.php +++ b/db/Query.php @@ -715,59 +715,6 @@ protected function normalizeSelect($columns) return $select; } - /** - * Returns unique column names excluding duplicates. - * Columns to be removed: - * - if column definition already present in SELECT part with same alias - * - if column definition without alias already present in SELECT part without alias too - * @param array $columns the columns to be merged to the select. - * @since 2.0.14 - * @deprecated in 2.0.21 - */ - protected function getUniqueColumns($columns) - { - $unaliasedColumns = $this->getUnaliasedColumnsFromSelect(); - - $result = []; - foreach ($columns as $columnAlias => $columnDefinition) { - if (!$columnDefinition instanceof Query) { - if (is_string($columnAlias)) { - $existsInSelect = isset($this->select[$columnAlias]) && $this->select[$columnAlias] === $columnDefinition; - if ($existsInSelect) { - continue; - } - } elseif (is_int($columnAlias)) { - $existsInSelect = in_array($columnDefinition, $unaliasedColumns, true); - $existsInResultSet = in_array($columnDefinition, $result, true); - if ($existsInSelect || $existsInResultSet) { - continue; - } - } - } - - $result[$columnAlias] = $columnDefinition; - } - return $result; - } - - /** - * @return array List of columns without aliases from SELECT statement. - * @since 2.0.14 - * @deprecated in 2.0.21 - */ - protected function getUnaliasedColumnsFromSelect() - { - $result = []; - if (is_array($this->select)) { - foreach ($this->select as $name => $value) { - if (is_int($name)) { - $result[] = $value; - } - } - } - return array_unique($result); - } - /** * Sets the value indicating whether to SELECT DISTINCT or not. * @param bool $value whether to SELECT DISTINCT or not. From c7da77ba810df1e4a5c0fd0f38a968caabfb25de Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Fri, 22 Sep 2023 09:45:35 -0300 Subject: [PATCH 14/56] Remove deprecated methods to `QueryBuilder::class`. --- db/QueryBuilder.php | 139 -------------------------------------- db/mssql/QueryBuilder.php | 11 --- 2 files changed, 150 deletions(-) diff --git a/db/QueryBuilder.php b/db/QueryBuilder.php index 114116e67..daa40beaf 100644 --- a/db/QueryBuilder.php +++ b/db/QueryBuilder.php @@ -53,12 +53,6 @@ class QueryBuilder extends \yii\base\BaseObject */ public $typeMap = []; - /** - * @var array map of query condition to builder methods. - * These methods are used by [[buildCondition]] to build SQL conditions from array syntax. - * @deprecated since 2.0.14. Is not used, will be dropped in 2.1.0. - */ - protected $conditionBuilders = []; /** * @var array map of condition aliases to condition classes. For example: * @@ -1611,139 +1605,6 @@ public function createConditionFromArray($condition) return new HashCondition($condition); } - /** - * Creates a condition based on column-value pairs. - * @param array $condition the condition specification. - * @param array $params the binding parameters to be populated - * @return string the generated SQL expression - * @deprecated since 2.0.14. Use `buildCondition()` instead. - */ - public function buildHashCondition($condition, &$params) - { - return $this->buildCondition(new HashCondition($condition), $params); - } - - /** - * Connects two or more SQL expressions with the `AND` or `OR` operator. - * @param string $operator the operator to use for connecting the given operands - * @param array $operands the SQL expressions to connect. - * @param array $params the binding parameters to be populated - * @return string the generated SQL expression - * @deprecated since 2.0.14. Use `buildCondition()` instead. - */ - public function buildAndCondition($operator, $operands, &$params) - { - array_unshift($operands, $operator); - return $this->buildCondition($operands, $params); - } - - /** - * Inverts an SQL expressions with `NOT` operator. - * @param string $operator the operator to use for connecting the given operands - * @param array $operands the SQL expressions to connect. - * @param array $params the binding parameters to be populated - * @return string the generated SQL expression - * @throws InvalidArgumentException if wrong number of operands have been given. - * @deprecated since 2.0.14. Use `buildCondition()` instead. - */ - public function buildNotCondition($operator, $operands, &$params) - { - array_unshift($operands, $operator); - return $this->buildCondition($operands, $params); - } - - /** - * Creates an SQL expressions with the `BETWEEN` operator. - * @param string $operator the operator to use (e.g. `BETWEEN` or `NOT BETWEEN`) - * @param array $operands the first operand is the column name. The second and third operands - * describe the interval that column value should be in. - * @param array $params the binding parameters to be populated - * @return string the generated SQL expression - * @throws InvalidArgumentException if wrong number of operands have been given. - * @deprecated since 2.0.14. Use `buildCondition()` instead. - */ - public function buildBetweenCondition($operator, $operands, &$params) - { - array_unshift($operands, $operator); - return $this->buildCondition($operands, $params); - } - - /** - * Creates an SQL expressions with the `IN` operator. - * @param string $operator the operator to use (e.g. `IN` or `NOT IN`) - * @param array $operands the first operand is the column name. If it is an array - * a composite IN condition will be generated. - * The second operand is an array of values that column value should be among. - * If it is an empty array the generated expression will be a `false` value if - * operator is `IN` and empty if operator is `NOT IN`. - * @param array $params the binding parameters to be populated - * @return string the generated SQL expression - * @throws Exception if wrong number of operands have been given. - * @deprecated since 2.0.14. Use `buildCondition()` instead. - */ - public function buildInCondition($operator, $operands, &$params) - { - array_unshift($operands, $operator); - return $this->buildCondition($operands, $params); - } - - /** - * Creates an SQL expressions with the `LIKE` operator. - * @param string $operator the operator to use (e.g. `LIKE`, `NOT LIKE`, `OR LIKE` or `OR NOT LIKE`) - * @param array $operands an array of two or three operands - * - * - The first operand is the column name. - * - The second operand is a single value or an array of values that column value - * should be compared with. If it is an empty array the generated expression will - * be a `false` value if operator is `LIKE` or `OR LIKE`, and empty if operator - * is `NOT LIKE` or `OR NOT LIKE`. - * - An optional third operand can also be provided to specify how to escape special characters - * in the value(s). The operand should be an array of mappings from the special characters to their - * escaped counterparts. If this operand is not provided, a default escape mapping will be used. - * You may use `false` or an empty array to indicate the values are already escaped and no escape - * should be applied. Note that when using an escape mapping (or the third operand is not provided), - * the values will be automatically enclosed within a pair of percentage characters. - * @param array $params the binding parameters to be populated - * @return string the generated SQL expression - * @throws InvalidArgumentException if wrong number of operands have been given. - * @deprecated since 2.0.14. Use `buildCondition()` instead. - */ - public function buildLikeCondition($operator, $operands, &$params) - { - array_unshift($operands, $operator); - return $this->buildCondition($operands, $params); - } - - /** - * Creates an SQL expressions with the `EXISTS` operator. - * @param string $operator the operator to use (e.g. `EXISTS` or `NOT EXISTS`) - * @param array $operands contains only one element which is a [[Query]] object representing the sub-query. - * @param array $params the binding parameters to be populated - * @return string the generated SQL expression - * @throws InvalidArgumentException if the operand is not a [[Query]] object. - * @deprecated since 2.0.14. Use `buildCondition()` instead. - */ - public function buildExistsCondition($operator, $operands, &$params) - { - array_unshift($operands, $operator); - return $this->buildCondition($operands, $params); - } - - /** - * Creates an SQL expressions like `"column" operator value`. - * @param string $operator the operator to use. Anything could be used e.g. `>`, `<=`, etc. - * @param array $operands contains two column names. - * @param array $params the binding parameters to be populated - * @return string the generated SQL expression - * @throws InvalidArgumentException if wrong number of operands have been given. - * @deprecated since 2.0.14. Use `buildCondition()` instead. - */ - public function buildSimpleCondition($operator, $operands, &$params) - { - array_unshift($operands, $operator); - return $this->buildCondition($operands, $params); - } - /** * Creates a SELECT EXISTS() SQL statement. * @param string $rawSql the subquery in a raw form to select from. diff --git a/db/mssql/QueryBuilder.php b/db/mssql/QueryBuilder.php index 1225c466c..ee85e6ed3 100644 --- a/db/mssql/QueryBuilder.php +++ b/db/mssql/QueryBuilder.php @@ -428,17 +428,6 @@ protected function getAllColumnNames($modelClass = null) return array_keys($schema->columns); } - /** - * @return bool whether the version of the MSSQL being used is older than 2012. - * @throws \yii\base\InvalidConfigException - * @throws \yii\db\Exception - * @deprecated 2.0.14 Use [[Schema::getServerVersion]] with [[\version_compare()]]. - */ - protected function isOldMssql() - { - return version_compare($this->db->getSchema()->getServerVersion(), '11', '<'); - } - /** * {@inheritdoc} * @since 2.0.8 From ee2ab7d5b67d56b8cbd5d09d6950494be00076c3 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Fri, 22 Sep 2023 10:05:46 -0300 Subject: [PATCH 15/56] Remove deprecated methods to `ColumnSchema::class`. --- db/mysql/ColumnSchema.php | 15 ++------------ db/pgsql/ColumnSchema.php | 42 ++++----------------------------------- 2 files changed, 6 insertions(+), 51 deletions(-) diff --git a/db/mysql/ColumnSchema.php b/db/mysql/ColumnSchema.php index ca9c48703..074335688 100644 --- a/db/mysql/ColumnSchema.php +++ b/db/mysql/ColumnSchema.php @@ -18,17 +18,6 @@ */ class ColumnSchema extends \yii\db\ColumnSchema { - /** - * @var bool whether the column schema should OMIT using JSON support feature. - * You can use this property to make upgrade to Yii 2.0.14 easier. - * Default to `false`, meaning JSON support is enabled. - * - * @since 2.0.14.1 - * @deprecated Since 2.0.14.1 and will be removed in 2.1. - */ - public $disableJsonSupport = false; - - /** * {@inheritdoc} */ @@ -42,7 +31,7 @@ public function dbTypecast($value) return $value; } - if (!$this->disableJsonSupport && $this->dbType === Schema::TYPE_JSON) { + if ($this->dbType === Schema::TYPE_JSON) { return new JsonExpression($value, $this->type); } @@ -58,7 +47,7 @@ public function phpTypecast($value) return null; } - if (!$this->disableJsonSupport && $this->type === Schema::TYPE_JSON) { + if ($this->type === Schema::TYPE_JSON) { return json_decode($value, true); } diff --git a/db/pgsql/ColumnSchema.php b/db/pgsql/ColumnSchema.php index 33d97bbdf..271c5f30c 100644 --- a/db/pgsql/ColumnSchema.php +++ b/db/pgsql/ColumnSchema.php @@ -22,33 +22,6 @@ class ColumnSchema extends \yii\db\ColumnSchema * @var int the dimension of array. Defaults to 0, means this column is not an array. */ public $dimension = 0; - /** - * @var bool whether the column schema should OMIT using JSON support feature. - * You can use this property to make upgrade to Yii 2.0.14 easier. - * Default to `false`, meaning JSON support is enabled. - * - * @since 2.0.14.1 - * @deprecated Since 2.0.14.1 and will be removed in 2.1. - */ - public $disableJsonSupport = false; - /** - * @var bool whether the column schema should OMIT using PgSQL Arrays support feature. - * You can use this property to make upgrade to Yii 2.0.14 easier. - * Default to `false`, meaning Arrays support is enabled. - * - * @since 2.0.14.1 - * @deprecated Since 2.0.14.1 and will be removed in 2.1. - */ - public $disableArraySupport = false; - /** - * @var bool whether the Array column value should be unserialized to an [[ArrayExpression]] object. - * You can use this property to make upgrade to Yii 2.0.14 easier. - * Default to `true`, meaning arrays are unserialized to [[ArrayExpression]] objects. - * - * @since 2.0.14.1 - * @deprecated Since 2.0.14.1 and will be removed in 2.1. - */ - public $deserializeArrayColumnToArrayExpression = true; /** * @var string name of associated sequence if column is auto-incremental * @since 2.0.29 @@ -70,11 +43,9 @@ public function dbTypecast($value) } if ($this->dimension > 0) { - return $this->disableArraySupport - ? (string) $value - : new ArrayExpression($value, $this->dbType, $this->dimension); + return new ArrayExpression($value, $this->dbType, $this->dimension); } - if (!$this->disableJsonSupport && in_array($this->dbType, [Schema::TYPE_JSON, Schema::TYPE_JSONB], true)) { + if (in_array($this->dbType, [Schema::TYPE_JSON, Schema::TYPE_JSONB], true)) { return new JsonExpression($value, $this->dbType); } @@ -87,9 +58,6 @@ public function dbTypecast($value) public function phpTypecast($value) { if ($this->dimension > 0) { - if ($this->disableArraySupport) { - return $value; - } if (!is_array($value)) { $value = $this->getArrayParser()->parse($value); } @@ -101,9 +69,7 @@ public function phpTypecast($value) return null; } - return $this->deserializeArrayColumnToArrayExpression - ? new ArrayExpression($value, $this->dbType, $this->dimension) - : $value; + return $value; } return $this->phpTypecastValue($value); @@ -133,7 +99,7 @@ protected function phpTypecastValue($value) } return (bool) $value; case Schema::TYPE_JSON: - return $this->disableJsonSupport ? $value : json_decode($value, true); + return json_decode($value, true); } return parent::phpTypecast($value); From aaf051f167fa5068f8a8ad0355f8c38120a48cee Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Fri, 22 Sep 2023 11:13:24 -0300 Subject: [PATCH 16/56] Remove deprecated methods to `DbMessageSource::class`. --- i18n/DbMessageSource.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/i18n/DbMessageSource.php b/i18n/DbMessageSource.php index eccc7fbd1..68f183f04 100644 --- a/i18n/DbMessageSource.php +++ b/i18n/DbMessageSource.php @@ -39,12 +39,6 @@ */ class DbMessageSource extends MessageSource { - /** - * Prefix which would be used when generating cache key. - * @deprecated This constant has never been used and will be removed in 2.1.0. - */ - const CACHE_KEY_PREFIX = 'DbMessageSource'; - /** * @var Connection|array|string the DB connection object or the application component ID of the DB connection. * From 837e04aab86aa57d8193fd1e6f62e3af7043371f Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Fri, 22 Sep 2023 18:19:59 -0300 Subject: [PATCH 17/56] Remove deprecated property to `FileTarget::class`. --- log/FileTarget.php | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/log/FileTarget.php b/log/FileTarget.php index d816f73a8..29e76d470 100644 --- a/log/FileTarget.php +++ b/log/FileTarget.php @@ -20,9 +20,6 @@ * files are moved backwards by one place, i.e., '.2' to '.3', '.1' to '.2', and so on. * The property [[maxLogFiles]] specifies how many history files to keep. * - * Since 2.0.46 rotation of the files is done only by copy and the - * `rotateByCopy` property is deprecated. - * * @author Qiang Xue * @since 2.0 */ @@ -61,22 +58,6 @@ class FileTarget extends Target * but read-only for other users. */ public $dirMode = 0775; - /** - * @var bool Whether to rotate log files by copy and truncate in contrast to rotation by - * renaming files. Defaults to `true` to be more compatible with log tailers and windows - * systems which do not play well with rename on open files. Rotation by renaming however is - * a bit faster. - * - * The problem with windows systems where the [rename()](https://www.php.net/manual/en/function.rename.php) - * function does not work with files that are opened by some process is described in a - * [comment by Martin Pelletier](https://www.php.net/manual/en/function.rename.php#102274) in - * the PHP documentation. By setting rotateByCopy to `true` you can work - * around this. - * @deprecated since 2.0.46 and setting it to false has no effect anymore - * since rotating is now always done by copy. - */ - public $rotateByCopy = true; - /** * Initializes the route. From a1009a6fea88d503102cd688e54b193b1bdd6d35 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Fri, 22 Sep 2023 18:42:02 -0300 Subject: [PATCH 18/56] Remove deprecated constants `CSRF_MASK_LENGTH`. --- web/Request.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/web/Request.php b/web/Request.php index d87489ce3..a4e86e4e4 100644 --- a/web/Request.php +++ b/web/Request.php @@ -94,11 +94,6 @@ class Request extends \yii\base\Request * The name of the HTTP header for sending CSRF token. */ const CSRF_HEADER = 'X-CSRF-Token'; - /** - * The length of the CSRF token mask. - * @deprecated since 2.0.12. The mask length is now equal to the token length. - */ - const CSRF_MASK_LENGTH = 8; /** * @var bool whether to enable CSRF (Cross-Site Request Forgery) validation. Defaults to true. From 994447d0f66c17ada5a448a6ec88298187e06f4a Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Fri, 22 Sep 2023 18:48:30 -0300 Subject: [PATCH 19/56] Remove deprecated methods to `User::class`. --- web/User.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/web/User.php b/web/User.php index 086b3c5dc..5f80fc8bc 100644 --- a/web/User.php +++ b/web/User.php @@ -788,20 +788,6 @@ public function checkRedirectAcceptable() return false; } - /** - * Returns auth manager associated with the user component. - * - * By default this is the `authManager` application component. - * You may override this method to return a different auth manager instance if needed. - * @return \yii\rbac\ManagerInterface - * @since 2.0.6 - * @deprecated since version 2.0.9, to be removed in 2.1. Use [[getAccessChecker()]] instead. - */ - protected function getAuthManager() - { - return Yii::$app->getAuthManager(); - } - /** * Returns the access checker used for checking access. * @return CheckAccessInterface @@ -809,6 +795,6 @@ protected function getAuthManager() */ protected function getAccessChecker() { - return $this->accessChecker !== null ? $this->accessChecker : $this->getAuthManager(); + return $this->accessChecker !== null ? $this->accessChecker : Yii::$app->getAuthManager(); } } From 1905446093c2f5b9d7781752cbe853aae9c901ec Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Fri, 22 Sep 2023 18:59:21 -0300 Subject: [PATCH 20/56] Add method `className()`, don't break BC third party extensions. --- base/BaseObject.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/base/BaseObject.php b/base/BaseObject.php index 2f9448efc..84e887304 100644 --- a/base/BaseObject.php +++ b/base/BaseObject.php @@ -282,4 +282,14 @@ public function hasMethod($name) { return method_exists($this, $name); } + + /** + * Returns the fully qualified name of this class. + * + * @return string the fully qualified name of this class. + */ + public static function className(): string + { + return static::class; + } } From 50f12e2a6c09f9b3dfede1d84ba05477885e8f27 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Thu, 19 Oct 2023 12:17:15 -0300 Subject: [PATCH 21/56] Sync to master. (#20012) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added pcntl to requirements check * Fix #13920: Fixed erroneous validation for specific cases * Fix #13920: Added my name to CHANGELOG.md * trim(): Passing null to parameter #1 ($string) of type string is deprecated * Added section about Unsafe Reflection in Security best practices doc (#19948) Co-authored-by: Bizley * Update CHANGELOG.md * Fixed tests. * Fix #13920: Add unit test * Update `bower-asset/inputmask`, `bower-asset/punycode`. * added CHANGELOG line * Fix order. * fix: #19978 - Mistake in Korean translation * fix: keep doublequote * Do not duplicate log messages in memory * Update framework/log/FileTarget.php Co-authored-by: Bizley * Update concept-di-container.md Сслка "Конфигурация приложения" была не верной, она вела на страницу "Service-locator'a" * Update CHANGELOG.md * release version 2.0.49.1 * prepare for next release * Revert changes in `mimeTypes.php` from 4a1f2c6b9bc90427e91da73f5e8c8fa33d3c53c1 restores https://github.com/yiisoft/yii2/pull/19936 * update actions/checkout to v4 * Fix mime type generator * Added note * Update structure-controllers.md (#20003) добавил пропущенное слово "как" * Update CHANGELOG.md 2.0.49.2 changelog * release version 2.0.49.2 * prepare for next release * New methods: BaseActiveRecord::loadRelations() and BaseActiveRecord::loadRelationsFor(). * Fixed a bug where the yii serve command would break if a custom router was supplied and it had a space in the path * Fix `MaskedInputAsset::class`. * Fix #19927: Fixed `console\controllers\MessageController` when saving translations to database: fixed FK error when adding new string and language at the same time, checking/regenerating all missing messages and dropping messages for unused languages * Added 'zh' into 'framework/messages/config.php' (#19995) --------- Co-authored-by: Tobias Munk Co-authored-by: Tim Fischer Co-authored-by: Tim Fischer <35448254+tim-fischer-maschinensucher@users.noreply.github.com> Co-authored-by: Alexander Makarov Co-authored-by: Oleg Poludnenko Co-authored-by: Bizley Co-authored-by: Sonia Zorba Co-authored-by: Tobias Munk Co-authored-by: Akbar Herlambang Co-authored-by: lubosdz Co-authored-by: Yuriy Bachevskiy Co-authored-by: Robert Korulczyk Co-authored-by: salehhashemi1992 <81674631+salehhashemi1992@users.noreply.github.com> Co-authored-by: PowerGamer1 Co-authored-by: Brad Bell Co-authored-by: Alexandru Trandafir Catalin Co-authored-by: Nabi KaramAliZadeh --- CHANGELOG.md | 16 +++ assets/yii.activeForm.js | 8 ++ composer.json | 4 +- console/controllers/MessageController.php | 161 +++++++++++++--------- console/controllers/ServeController.php | 2 +- db/BaseActiveRecord.php | 53 +++++++ db/Query.php | 4 +- helpers/mimeAliases.php | 3 + helpers/mimeExtensions.php | 3 + helpers/mimeTypes.php | 3 + log/FileTarget.php | 3 +- messages/config.php | 3 +- messages/ko/yii.php | 4 +- requirements/requirements.php | 7 + widgets/MaskedInputAsset.php | 2 +- 15 files changed, 199 insertions(+), 77 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91ff0a353..8306ab213 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,25 @@ Yii Framework 2 Change Log 2.0.50 under development ------------------------ +- Bug #13920: Fixed erroneous validation for specific cases (tim-fischer-maschinensucher) +- Bug #19927: Fixed `console\controllers\MessageController` when saving translations to database: fixed FK error when adding new string and language at the same time, checking/regenerating all missing messages and dropping messages for unused languages (atrandafir) +- Enh #12743: Added new methods `BaseActiveRecord::loadRelations()` and `BaseActiveRecord::loadRelationsFor()` to eager load related models for existing primary model instances (PowerGamer1) + + +2.0.49.2 October 12, 2023 +------------------------- + - Bug #19925: Improved PHP version check when handling MIME types (schmunk42) + + +2.0.49.1 October 05, 2023 +------------------------- + - Bug #19940: File Log writer without newline (terabytesoftw) +- Bug #19950: Fix `Query::groupBy(null)` causes error for PHP 8.1: `trim(): Passing null to parameter #1 ($string) of type string is deprecated` (uaoleg) - Bug #19951: Removed unneeded MIME file tests (schmunk42) +- Bug #19984: Do not duplicate log messages in memory (lubosdz) +- Enh #19780: added pcntl to requirements check (schmunk42) 2.0.49 August 29, 2023 diff --git a/assets/yii.activeForm.js b/assets/yii.activeForm.js index b12f812c3..5b9ce4aae 100644 --- a/assets/yii.activeForm.js +++ b/assets/yii.activeForm.js @@ -395,9 +395,11 @@ data: $form.serialize() + extData, dataType: data.settings.ajaxDataType, complete: function (jqXHR, textStatus) { + currentAjaxRequest = null; $form.trigger(events.ajaxComplete, [jqXHR, textStatus]); }, beforeSend: function (jqXHR, settings) { + currentAjaxRequest = jqXHR; $form.trigger(events.ajaxBeforeSend, [jqXHR, settings]); }, success: function (msgs) { @@ -563,6 +565,9 @@ return; } + if (currentAjaxRequest !== null) { + currentAjaxRequest.abort(); + } if (data.settings.timer !== undefined) { clearTimeout(data.settings.timer); } @@ -929,4 +934,7 @@ $form.find(attribute.input).attr('aria-invalid', hasError ? 'true' : 'false'); } } + + var currentAjaxRequest = null; + })(window.jQuery); diff --git a/composer.json b/composer.json index 8d638df3c..0b27d62ff 100644 --- a/composer.json +++ b/composer.json @@ -71,8 +71,8 @@ "ezyang/htmlpurifier": "^4.6", "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": "~3.2.2 | ~3.3.5", - "bower-asset/punycode": "1.3.*", + "bower-asset/inputmask": "^5.0.8 ", + "bower-asset/punycode": "^2.2", "bower-asset/yii2-pjax": "~2.0.1", "paragonie/random_compat": ">=1" }, diff --git a/console/controllers/MessageController.php b/console/controllers/MessageController.php index 4650cec79..fb4e012f5 100644 --- a/console/controllers/MessageController.php +++ b/console/controllers/MessageController.php @@ -353,17 +353,7 @@ protected function saveMessagesToDb($messages, $db, $sourceMessageTable, $messag foreach ($rows as $row) { $currentMessages[$row['category']][$row['id']] = $row['message']; } - - $currentLanguages = []; - $rows = (new Query())->select(['language'])->from($messageTable)->groupBy('language')->all($db); - foreach ($rows as $row) { - $currentLanguages[] = $row['language']; - } - $missingLanguages = []; - if (!empty($currentLanguages)) { - $missingLanguages = array_diff($languages, $currentLanguages); - } - + $new = []; $obsolete = []; @@ -372,89 +362,130 @@ protected function saveMessagesToDb($messages, $db, $sourceMessageTable, $messag if (isset($currentMessages[$category])) { $new[$category] = array_diff($msgs, $currentMessages[$category]); + // obsolete messages per category $obsolete += array_diff($currentMessages[$category], $msgs); } else { $new[$category] = $msgs; } } - + + // obsolete categories foreach (array_diff(array_keys($currentMessages), array_keys($messages)) as $category) { $obsolete += $currentMessages[$category]; } if (!$removeUnused) { foreach ($obsolete as $pk => $msg) { + // skip already marked unused if (strncmp($msg, '@@', 2) === 0 && substr($msg, -2) === '@@') { unset($obsolete[$pk]); } } - } - - $obsolete = array_keys($obsolete); + } + $this->stdout('Inserting new messages...'); - $savedFlag = false; + $insertCount = 0; foreach ($new as $category => $msgs) { foreach ($msgs as $msg) { - $savedFlag = true; - $lastPk = $db->schema->insert($sourceMessageTable, ['category' => $category, 'message' => $msg]); - foreach ($languages as $language) { - $db->createCommand() - ->insert($messageTable, ['id' => $lastPk['id'], 'language' => $language]) - ->execute(); - } - } - } - - if (!empty($missingLanguages)) { - $updatedMessages = []; - $rows = (new Query())->select(['id', 'category', 'message'])->from($sourceMessageTable)->all($db); - foreach ($rows as $row) { - $updatedMessages[$row['category']][$row['id']] = $row['message']; - } - foreach ($updatedMessages as $category => $msgs) { - foreach ($msgs as $id => $msg) { - $savedFlag = true; - foreach ($missingLanguages as $language) { - $db->createCommand() - ->insert($messageTable, ['id' => $id, 'language' => $language]) - ->execute(); - } - } + $insertCount++; + $db->schema->insert($sourceMessageTable, ['category' => $category, 'message' => $msg]); } } - - $this->stdout($savedFlag ? "saved.\n" : "Nothing to save.\n"); + + $this->stdout($insertCount ? "{$insertCount} saved.\n" : "Nothing to save.\n"); + $this->stdout($removeUnused ? 'Deleting obsoleted messages...' : 'Updating obsoleted messages...'); if (empty($obsolete)) { $this->stdout("Nothing obsoleted...skipped.\n"); - return; } - if ($removeUnused) { - $db->createCommand() - ->delete($sourceMessageTable, ['in', 'id', $obsolete]) - ->execute(); - $this->stdout("deleted.\n"); - } elseif ($markUnused) { - $rows = (new Query()) - ->select(['id', 'message']) - ->from($sourceMessageTable) - ->where(['in', 'id', $obsolete]) - ->all($db); - - foreach ($rows as $row) { - $db->createCommand()->update( - $sourceMessageTable, - ['message' => '@@' . $row['message'] . '@@'], - ['id' => $row['id']] - )->execute(); + if ($obsolete) { + if ($removeUnused) { + $affected = $db->createCommand() + ->delete($sourceMessageTable, ['in', 'id', array_keys($obsolete)]) + ->execute(); + $this->stdout("{$affected} deleted.\n"); + } elseif ($markUnused) { + $marked=0; + $rows = (new Query()) + ->select(['id', 'message']) + ->from($sourceMessageTable) + ->where(['in', 'id', array_keys($obsolete)]) + ->all($db); + + foreach ($rows as $row) { + $marked++; + $db->createCommand()->update( + $sourceMessageTable, + ['message' => '@@' . $row['message'] . '@@'], + ['id' => $row['id']] + )->execute(); + } + $this->stdout("{$marked} updated.\n"); + } else { + $this->stdout("kept untouched.\n"); } - $this->stdout("updated.\n"); - } else { - $this->stdout("kept untouched.\n"); } + + // get fresh message id list + $freshMessagesIds = []; + $rows = (new Query())->select(['id'])->from($sourceMessageTable)->all($db); + foreach ($rows as $row) { + $freshMessagesIds[] = $row['id']; + } + + $this->stdout("Generating missing rows..."); + $generatedMissingRows = []; + + foreach ($languages as $language) { + $count = 0; + + // get list of ids of translations for this language + $msgRowsIds = []; + $msgRows = (new Query())->select(['id'])->from($messageTable)->where([ + 'language'=>$language, + ])->all($db); + foreach ($msgRows as $row) { + $msgRowsIds[] = $row['id']; + } + + // insert missing + foreach ($freshMessagesIds as $id) { + if (!in_array($id, $msgRowsIds)) { + $db->createCommand() + ->insert($messageTable, ['id' => $id, 'language' => $language]) + ->execute(); + $count++; + } + } + if ($count) { + $generatedMissingRows[] = "{$count} for {$language}"; + } + } + + $this->stdout($generatedMissingRows ? implode(", ", $generatedMissingRows).".\n" : "Nothing to do.\n"); + + $this->stdout("Dropping unused languages..."); + $droppedLanguages=[]; + + $currentLanguages = []; + $rows = (new Query())->select(['language'])->from($messageTable)->groupBy('language')->all($db); + foreach ($rows as $row) { + $currentLanguages[] = $row['language']; + } + + foreach ($currentLanguages as $currentLanguage) { + if (!in_array($currentLanguage, $languages)) { + $deleted=$db->createCommand()->delete($messageTable, "language=:language", [ + 'language'=>$currentLanguage, + ])->execute(); + $droppedLanguages[] = "removed {$deleted} rows for $currentLanguage"; + } + } + + $this->stdout($droppedLanguages ? implode(", ", $droppedLanguages).".\n" : "Nothing to do.\n"); } /** diff --git a/console/controllers/ServeController.php b/console/controllers/ServeController.php index 68a7e50c2..d02c98204 100644 --- a/console/controllers/ServeController.php +++ b/console/controllers/ServeController.php @@ -80,7 +80,7 @@ public function actionIndex($address = 'localhost') } $this->stdout("Quit the server with CTRL-C or COMMAND-C.\n"); - passthru('"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\" $router"); + passthru('"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\" \"$router\""); } /** diff --git a/db/BaseActiveRecord.php b/db/BaseActiveRecord.php index e1bb4cc2d..7baa338ce 100644 --- a/db/BaseActiveRecord.php +++ b/db/BaseActiveRecord.php @@ -1786,4 +1786,57 @@ private function isValueDifferent($newValue, $oldValue) return $newValue !== $oldValue; } + + /** + * Eager loads related models for the already loaded primary models. + * + * Helps to reduce the number of queries performed against database if some related models are only used + * when a specific condition is met. For example: + * + * ```php + * $customers = Customer::find()->where(['country_id' => 123])->all(); + * if (Yii:app()->getUser()->getIdentity()->canAccessOrders()) { + * Customer::loadRelationsFor($customers, 'orders.items'); + * } + * ``` + * + * @param array|ActiveRecordInterface[] $models array of primary models. Each model should have the same type and can be: + * - an active record instance; + * - active record instance represented by array (i.e. active record was loaded using [[ActiveQuery::asArray()]]). + * @param string|array $relationNames the names of the relations of primary models to be loaded from database. See [[ActiveQueryInterface::with()]] on how to specify this argument. + * @param bool $asArray whether to load each related model as an array or an object (if the relation itself does not specify that). + * @since 2.0.49 + */ + public static function loadRelationsFor(&$models, $relationNames, $asArray = false) + { + // ActiveQueryTrait::findWith() called below assumes $models array is non-empty. + if (empty($models)) { + return; + } + + static::find()->asArray($asArray)->findWith((array)$relationNames, $models); + } + + /** + * Eager loads related models for the already loaded primary model. + * + * Helps to reduce the number of queries performed against database if some related models are only used + * when a specific condition is met. For example: + * + * ```php + * $customer = Customer::find()->where(['id' => 123])->one(); + * if (Yii:app()->getUser()->getIdentity()->canAccessOrders()) { + * $customer->loadRelations('orders.items'); + * } + * ``` + * + * @param string|array $relationNames the names of the relations of this model to be loaded from database. See [[ActiveQueryInterface::with()]] on how to specify this argument. + * @param bool $asArray whether to load each relation as an array or an object (if the relation itself does not specify that). + * @since 2.0.49 + */ + public function loadRelations($relationNames, $asArray = false) + { + $models = [$this]; + static::loadRelationsFor($models, $relationNames, $asArray); + } } diff --git a/db/Query.php b/db/Query.php index 9374f9d84..f44a1c447 100644 --- a/db/Query.php +++ b/db/Query.php @@ -996,7 +996,7 @@ public function rightJoin($table, $on = '', $params = []) /** * Sets the GROUP BY part of the query. - * @param string|array|ExpressionInterface $columns the columns to be grouped by. + * @param string|array|ExpressionInterface|null $columns the columns to be grouped by. * Columns can be specified in either a string (e.g. "id, name") or an array (e.g. ['id', 'name']). * The method will automatically quote the column names unless a column contains some parenthesis * (which means the column contains a DB expression). @@ -1014,7 +1014,7 @@ public function groupBy($columns) { if ($columns instanceof ExpressionInterface) { $columns = [$columns]; - } elseif (!is_array($columns)) { + } elseif (!is_array($columns) && !is_null($columns)) { $columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY); } $this->groupBy = $columns; diff --git a/helpers/mimeAliases.php b/helpers/mimeAliases.php index 4cd89888a..a9e677adc 100644 --- a/helpers/mimeAliases.php +++ b/helpers/mimeAliases.php @@ -3,6 +3,9 @@ * MIME aliases. * * This file contains aliases for MIME types. + * + * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php + * otherwise they will be lost on next build. */ return [ 'text/rtf' => 'application/rtf', diff --git a/helpers/mimeExtensions.php b/helpers/mimeExtensions.php index 946d61cd0..e4936030f 100644 --- a/helpers/mimeExtensions.php +++ b/helpers/mimeExtensions.php @@ -8,6 +8,9 @@ * Its content is generated from the apache http mime.types file. * https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup * This file has been placed in the public domain for unlimited redistribution. + * + * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php + * otherwise they will be lost on next build. */ return [ 'application/andrew-inset' => 'ez', diff --git a/helpers/mimeTypes.php b/helpers/mimeTypes.php index e91f80f95..f895e8d07 100644 --- a/helpers/mimeTypes.php +++ b/helpers/mimeTypes.php @@ -7,6 +7,9 @@ * Its content is generated from the apache http mime.types file. * https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup * This file has been placed in the public domain for unlimited redistribution. + * + * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php + * otherwise they will be lost on next build. */ $mimeTypes = [ 123 => 'application/vnd.lotus-1-2-3', diff --git a/log/FileTarget.php b/log/FileTarget.php index 29e76d470..3e13278a3 100644 --- a/log/FileTarget.php +++ b/log/FileTarget.php @@ -88,9 +88,8 @@ public function init() public function export() { $text = implode("\n", array_map([$this, 'formatMessage'], $this->messages)) . "\n"; - $trimmedText = trim($text); - if (empty($trimmedText)) { + if (trim($text) === '') { return; // No messages to export, so we exit the function early } diff --git a/messages/config.php b/messages/config.php index 93845f2e0..6028328f3 100644 --- a/messages/config.php +++ b/messages/config.php @@ -15,8 +15,7 @@ 'languages' => [ 'af', 'ar', 'az', 'be', 'bg', 'bs', 'ca', 'cs', 'da', 'de', 'el', 'es', 'et', 'fa', 'fi', 'fr', 'he', 'hi', 'pt-BR', 'ro', 'hr', 'hu', 'hy', 'id', 'it', 'ja', 'ka', 'kk', 'ko', 'kz', 'lt', 'lv', 'ms', 'nb-NO', 'nl', - 'pl', 'pt', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'uz-Cy', 'vi', 'zh-CN', - 'zh-TW' + 'pl', 'pt', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'uz-Cy', 'vi', 'zh', 'zh-TW' ], // string, the name of the function for translating messages. // Defaults to 'Yii::t'. This is used as a mark to find the messages to be diff --git a/messages/ko/yii.php b/messages/ko/yii.php index 4fe82311f..b0ad872fe 100644 --- a/messages/ko/yii.php +++ b/messages/ko/yii.php @@ -75,8 +75,8 @@ '{attribute} must be greater than or equal to "{compareValue}".' => '{attribute}는 "{compareValue}" 보다 크거나 같아야 합니다.', '{attribute} must be less than "{compareValue}".' => '{attribute}는 "{compareValue}" 보다 작아야 합니다.', '{attribute} must be less than or equal to "{compareValue}".' => '{attribute}는 "{compareValue}" 보다 작거나 같아야 합니다.', - '{attribute} must be no greater than {max}.' => '{attribute}는 "{compareValue}" 보다 클 수 없습니다.', - '{attribute} must be no less than {min}.' => '{attribute}는 "{compareValue}" 보다 작을 수 없습니다.', + '{attribute} must be no greater than {max}.' => '{attribute}는 "{max}" 보다 클 수 없습니다.', + '{attribute} must be no less than {min}.' => '{attribute}는 "{min}" 보다 작을 수 없습니다.', '{attribute} must be repeated exactly.' => '{attribute}는 정확하게 반복합니다.', '{attribute} must not be equal to "{compareValue}".' => '{attribute}는 "{compareValue}"와 같을 수 없습니다.', '{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => '{attribute}는 최소 {min}자 이어야합니다.', diff --git a/requirements/requirements.php b/requirements/requirements.php index 555930615..d065f6363 100644 --- a/requirements/requirements.php +++ b/requirements/requirements.php @@ -111,5 +111,12 @@ 'memo' => 'When IpValidator::expandIPv6 property is set to true, PHP must support IPv6 protocol stack. Currently PHP constant AF_INET6 is not defined and IPv6 is probably unsupported.' + ), + array( + 'name' => 'pcntl', + 'mandatory' => false, + 'condition' => extension_loaded('pcntl'), + 'by' => 'Process Control', + 'memo' => 'Recommended for yii2-queue CLI operations' ) ); diff --git a/widgets/MaskedInputAsset.php b/widgets/MaskedInputAsset.php index 57748be86..473f4315f 100644 --- a/widgets/MaskedInputAsset.php +++ b/widgets/MaskedInputAsset.php @@ -21,7 +21,7 @@ class MaskedInputAsset extends AssetBundle { public $sourcePath = '@bower/inputmask/dist'; public $js = [ - 'jquery.inputmask.bundle.js', + 'jquery.inputmask.js', ]; public $depends = [ 'yii\web\YiiAsset', From 9a4561aceb7710beb0bb817a862624a385d3d276 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Thu, 19 Oct 2023 14:21:07 -0300 Subject: [PATCH 22/56] Remove unsed package, fix error typo. (#20017) --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 0b27d62ff..4934013b6 100644 --- a/composer.json +++ b/composer.json @@ -73,8 +73,7 @@ "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 ", "bower-asset/punycode": "^2.2", - "bower-asset/yii2-pjax": "~2.0.1", - "paragonie/random_compat": ">=1" + "bower-asset/yii2-pjax": "~2.0.1" }, "autoload": { "psr-4": {"yii\\": ""} From a2b9f2ad2f750aa44f8339a6c9f9322dc5dfb527 Mon Sep 17 00:00:00 2001 From: Bizley Date: Sun, 22 Oct 2023 11:39:45 +0200 Subject: [PATCH 23/56] Revert to 169c5fb --- CHANGELOG.md | 16 --- assets/yii.activeForm.js | 8 -- composer.json | 7 +- console/controllers/MessageController.php | 161 +++++++++------------- console/controllers/ServeController.php | 2 +- db/BaseActiveRecord.php | 53 ------- db/Query.php | 4 +- helpers/mimeAliases.php | 3 - helpers/mimeExtensions.php | 3 - helpers/mimeTypes.php | 3 - log/FileTarget.php | 3 +- messages/config.php | 3 +- messages/ko/yii.php | 4 +- requirements/requirements.php | 7 - widgets/MaskedInputAsset.php | 2 +- 15 files changed, 79 insertions(+), 200 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8306ab213..91ff0a353 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,25 +11,9 @@ Yii Framework 2 Change Log 2.0.50 under development ------------------------ -- Bug #13920: Fixed erroneous validation for specific cases (tim-fischer-maschinensucher) -- Bug #19927: Fixed `console\controllers\MessageController` when saving translations to database: fixed FK error when adding new string and language at the same time, checking/regenerating all missing messages and dropping messages for unused languages (atrandafir) -- Enh #12743: Added new methods `BaseActiveRecord::loadRelations()` and `BaseActiveRecord::loadRelationsFor()` to eager load related models for existing primary model instances (PowerGamer1) - - -2.0.49.2 October 12, 2023 -------------------------- - - Bug #19925: Improved PHP version check when handling MIME types (schmunk42) - - -2.0.49.1 October 05, 2023 -------------------------- - - Bug #19940: File Log writer without newline (terabytesoftw) -- Bug #19950: Fix `Query::groupBy(null)` causes error for PHP 8.1: `trim(): Passing null to parameter #1 ($string) of type string is deprecated` (uaoleg) - Bug #19951: Removed unneeded MIME file tests (schmunk42) -- Bug #19984: Do not duplicate log messages in memory (lubosdz) -- Enh #19780: added pcntl to requirements check (schmunk42) 2.0.49 August 29, 2023 diff --git a/assets/yii.activeForm.js b/assets/yii.activeForm.js index 5b9ce4aae..b12f812c3 100644 --- a/assets/yii.activeForm.js +++ b/assets/yii.activeForm.js @@ -395,11 +395,9 @@ data: $form.serialize() + extData, dataType: data.settings.ajaxDataType, complete: function (jqXHR, textStatus) { - currentAjaxRequest = null; $form.trigger(events.ajaxComplete, [jqXHR, textStatus]); }, beforeSend: function (jqXHR, settings) { - currentAjaxRequest = jqXHR; $form.trigger(events.ajaxBeforeSend, [jqXHR, settings]); }, success: function (msgs) { @@ -565,9 +563,6 @@ return; } - if (currentAjaxRequest !== null) { - currentAjaxRequest.abort(); - } if (data.settings.timer !== undefined) { clearTimeout(data.settings.timer); } @@ -934,7 +929,4 @@ $form.find(attribute.input).attr('aria-invalid', hasError ? 'true' : 'false'); } } - - var currentAjaxRequest = null; - })(window.jQuery); diff --git a/composer.json b/composer.json index 4934013b6..8d638df3c 100644 --- a/composer.json +++ b/composer.json @@ -71,9 +71,10 @@ "ezyang/htmlpurifier": "^4.6", "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 ", - "bower-asset/punycode": "^2.2", - "bower-asset/yii2-pjax": "~2.0.1" + "bower-asset/inputmask": "~3.2.2 | ~3.3.5", + "bower-asset/punycode": "1.3.*", + "bower-asset/yii2-pjax": "~2.0.1", + "paragonie/random_compat": ">=1" }, "autoload": { "psr-4": {"yii\\": ""} diff --git a/console/controllers/MessageController.php b/console/controllers/MessageController.php index fb4e012f5..4650cec79 100644 --- a/console/controllers/MessageController.php +++ b/console/controllers/MessageController.php @@ -353,7 +353,17 @@ protected function saveMessagesToDb($messages, $db, $sourceMessageTable, $messag foreach ($rows as $row) { $currentMessages[$row['category']][$row['id']] = $row['message']; } - + + $currentLanguages = []; + $rows = (new Query())->select(['language'])->from($messageTable)->groupBy('language')->all($db); + foreach ($rows as $row) { + $currentLanguages[] = $row['language']; + } + $missingLanguages = []; + if (!empty($currentLanguages)) { + $missingLanguages = array_diff($languages, $currentLanguages); + } + $new = []; $obsolete = []; @@ -362,130 +372,89 @@ protected function saveMessagesToDb($messages, $db, $sourceMessageTable, $messag if (isset($currentMessages[$category])) { $new[$category] = array_diff($msgs, $currentMessages[$category]); - // obsolete messages per category $obsolete += array_diff($currentMessages[$category], $msgs); } else { $new[$category] = $msgs; } } - - // obsolete categories + foreach (array_diff(array_keys($currentMessages), array_keys($messages)) as $category) { $obsolete += $currentMessages[$category]; } if (!$removeUnused) { foreach ($obsolete as $pk => $msg) { - // skip already marked unused if (strncmp($msg, '@@', 2) === 0 && substr($msg, -2) === '@@') { unset($obsolete[$pk]); } } - } - + } + + $obsolete = array_keys($obsolete); $this->stdout('Inserting new messages...'); - $insertCount = 0; + $savedFlag = false; foreach ($new as $category => $msgs) { foreach ($msgs as $msg) { - $insertCount++; - $db->schema->insert($sourceMessageTable, ['category' => $category, 'message' => $msg]); + $savedFlag = true; + $lastPk = $db->schema->insert($sourceMessageTable, ['category' => $category, 'message' => $msg]); + foreach ($languages as $language) { + $db->createCommand() + ->insert($messageTable, ['id' => $lastPk['id'], 'language' => $language]) + ->execute(); + } + } + } + + if (!empty($missingLanguages)) { + $updatedMessages = []; + $rows = (new Query())->select(['id', 'category', 'message'])->from($sourceMessageTable)->all($db); + foreach ($rows as $row) { + $updatedMessages[$row['category']][$row['id']] = $row['message']; + } + foreach ($updatedMessages as $category => $msgs) { + foreach ($msgs as $id => $msg) { + $savedFlag = true; + foreach ($missingLanguages as $language) { + $db->createCommand() + ->insert($messageTable, ['id' => $id, 'language' => $language]) + ->execute(); + } + } } } - - $this->stdout($insertCount ? "{$insertCount} saved.\n" : "Nothing to save.\n"); - + + $this->stdout($savedFlag ? "saved.\n" : "Nothing to save.\n"); $this->stdout($removeUnused ? 'Deleting obsoleted messages...' : 'Updating obsoleted messages...'); if (empty($obsolete)) { $this->stdout("Nothing obsoleted...skipped.\n"); + return; } - if ($obsolete) { - if ($removeUnused) { - $affected = $db->createCommand() - ->delete($sourceMessageTable, ['in', 'id', array_keys($obsolete)]) - ->execute(); - $this->stdout("{$affected} deleted.\n"); - } elseif ($markUnused) { - $marked=0; - $rows = (new Query()) - ->select(['id', 'message']) - ->from($sourceMessageTable) - ->where(['in', 'id', array_keys($obsolete)]) - ->all($db); - - foreach ($rows as $row) { - $marked++; - $db->createCommand()->update( - $sourceMessageTable, - ['message' => '@@' . $row['message'] . '@@'], - ['id' => $row['id']] - )->execute(); - } - $this->stdout("{$marked} updated.\n"); - } else { - $this->stdout("kept untouched.\n"); - } - } - - // get fresh message id list - $freshMessagesIds = []; - $rows = (new Query())->select(['id'])->from($sourceMessageTable)->all($db); - foreach ($rows as $row) { - $freshMessagesIds[] = $row['id']; - } - - $this->stdout("Generating missing rows..."); - $generatedMissingRows = []; - - foreach ($languages as $language) { - $count = 0; - - // get list of ids of translations for this language - $msgRowsIds = []; - $msgRows = (new Query())->select(['id'])->from($messageTable)->where([ - 'language'=>$language, - ])->all($db); - foreach ($msgRows as $row) { - $msgRowsIds[] = $row['id']; - } - - // insert missing - foreach ($freshMessagesIds as $id) { - if (!in_array($id, $msgRowsIds)) { - $db->createCommand() - ->insert($messageTable, ['id' => $id, 'language' => $language]) - ->execute(); - $count++; + if ($removeUnused) { + $db->createCommand() + ->delete($sourceMessageTable, ['in', 'id', $obsolete]) + ->execute(); + $this->stdout("deleted.\n"); + } elseif ($markUnused) { + $rows = (new Query()) + ->select(['id', 'message']) + ->from($sourceMessageTable) + ->where(['in', 'id', $obsolete]) + ->all($db); + + foreach ($rows as $row) { + $db->createCommand()->update( + $sourceMessageTable, + ['message' => '@@' . $row['message'] . '@@'], + ['id' => $row['id']] + )->execute(); } - } - if ($count) { - $generatedMissingRows[] = "{$count} for {$language}"; - } - } - - $this->stdout($generatedMissingRows ? implode(", ", $generatedMissingRows).".\n" : "Nothing to do.\n"); - - $this->stdout("Dropping unused languages..."); - $droppedLanguages=[]; - - $currentLanguages = []; - $rows = (new Query())->select(['language'])->from($messageTable)->groupBy('language')->all($db); - foreach ($rows as $row) { - $currentLanguages[] = $row['language']; + $this->stdout("updated.\n"); + } else { + $this->stdout("kept untouched.\n"); } - - foreach ($currentLanguages as $currentLanguage) { - if (!in_array($currentLanguage, $languages)) { - $deleted=$db->createCommand()->delete($messageTable, "language=:language", [ - 'language'=>$currentLanguage, - ])->execute(); - $droppedLanguages[] = "removed {$deleted} rows for $currentLanguage"; - } - } - - $this->stdout($droppedLanguages ? implode(", ", $droppedLanguages).".\n" : "Nothing to do.\n"); } /** diff --git a/console/controllers/ServeController.php b/console/controllers/ServeController.php index d02c98204..68a7e50c2 100644 --- a/console/controllers/ServeController.php +++ b/console/controllers/ServeController.php @@ -80,7 +80,7 @@ public function actionIndex($address = 'localhost') } $this->stdout("Quit the server with CTRL-C or COMMAND-C.\n"); - passthru('"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\" \"$router\""); + passthru('"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\" $router"); } /** diff --git a/db/BaseActiveRecord.php b/db/BaseActiveRecord.php index 7baa338ce..e1bb4cc2d 100644 --- a/db/BaseActiveRecord.php +++ b/db/BaseActiveRecord.php @@ -1786,57 +1786,4 @@ private function isValueDifferent($newValue, $oldValue) return $newValue !== $oldValue; } - - /** - * Eager loads related models for the already loaded primary models. - * - * Helps to reduce the number of queries performed against database if some related models are only used - * when a specific condition is met. For example: - * - * ```php - * $customers = Customer::find()->where(['country_id' => 123])->all(); - * if (Yii:app()->getUser()->getIdentity()->canAccessOrders()) { - * Customer::loadRelationsFor($customers, 'orders.items'); - * } - * ``` - * - * @param array|ActiveRecordInterface[] $models array of primary models. Each model should have the same type and can be: - * - an active record instance; - * - active record instance represented by array (i.e. active record was loaded using [[ActiveQuery::asArray()]]). - * @param string|array $relationNames the names of the relations of primary models to be loaded from database. See [[ActiveQueryInterface::with()]] on how to specify this argument. - * @param bool $asArray whether to load each related model as an array or an object (if the relation itself does not specify that). - * @since 2.0.49 - */ - public static function loadRelationsFor(&$models, $relationNames, $asArray = false) - { - // ActiveQueryTrait::findWith() called below assumes $models array is non-empty. - if (empty($models)) { - return; - } - - static::find()->asArray($asArray)->findWith((array)$relationNames, $models); - } - - /** - * Eager loads related models for the already loaded primary model. - * - * Helps to reduce the number of queries performed against database if some related models are only used - * when a specific condition is met. For example: - * - * ```php - * $customer = Customer::find()->where(['id' => 123])->one(); - * if (Yii:app()->getUser()->getIdentity()->canAccessOrders()) { - * $customer->loadRelations('orders.items'); - * } - * ``` - * - * @param string|array $relationNames the names of the relations of this model to be loaded from database. See [[ActiveQueryInterface::with()]] on how to specify this argument. - * @param bool $asArray whether to load each relation as an array or an object (if the relation itself does not specify that). - * @since 2.0.49 - */ - public function loadRelations($relationNames, $asArray = false) - { - $models = [$this]; - static::loadRelationsFor($models, $relationNames, $asArray); - } } diff --git a/db/Query.php b/db/Query.php index f44a1c447..9374f9d84 100644 --- a/db/Query.php +++ b/db/Query.php @@ -996,7 +996,7 @@ public function rightJoin($table, $on = '', $params = []) /** * Sets the GROUP BY part of the query. - * @param string|array|ExpressionInterface|null $columns the columns to be grouped by. + * @param string|array|ExpressionInterface $columns the columns to be grouped by. * Columns can be specified in either a string (e.g. "id, name") or an array (e.g. ['id', 'name']). * The method will automatically quote the column names unless a column contains some parenthesis * (which means the column contains a DB expression). @@ -1014,7 +1014,7 @@ public function groupBy($columns) { if ($columns instanceof ExpressionInterface) { $columns = [$columns]; - } elseif (!is_array($columns) && !is_null($columns)) { + } elseif (!is_array($columns)) { $columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY); } $this->groupBy = $columns; diff --git a/helpers/mimeAliases.php b/helpers/mimeAliases.php index a9e677adc..4cd89888a 100644 --- a/helpers/mimeAliases.php +++ b/helpers/mimeAliases.php @@ -3,9 +3,6 @@ * MIME aliases. * * This file contains aliases for MIME types. - * - * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php - * otherwise they will be lost on next build. */ return [ 'text/rtf' => 'application/rtf', diff --git a/helpers/mimeExtensions.php b/helpers/mimeExtensions.php index e4936030f..946d61cd0 100644 --- a/helpers/mimeExtensions.php +++ b/helpers/mimeExtensions.php @@ -8,9 +8,6 @@ * Its content is generated from the apache http mime.types file. * https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup * This file has been placed in the public domain for unlimited redistribution. - * - * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php - * otherwise they will be lost on next build. */ return [ 'application/andrew-inset' => 'ez', diff --git a/helpers/mimeTypes.php b/helpers/mimeTypes.php index f895e8d07..e91f80f95 100644 --- a/helpers/mimeTypes.php +++ b/helpers/mimeTypes.php @@ -7,9 +7,6 @@ * Its content is generated from the apache http mime.types file. * https://svn.apache.org/viewvc/httpd/httpd/trunk/docs/conf/mime.types?view=markup * This file has been placed in the public domain for unlimited redistribution. - * - * All extra changes made to this file must be comitted to /build/controllers/MimeTypeController.php - * otherwise they will be lost on next build. */ $mimeTypes = [ 123 => 'application/vnd.lotus-1-2-3', diff --git a/log/FileTarget.php b/log/FileTarget.php index 3e13278a3..29e76d470 100644 --- a/log/FileTarget.php +++ b/log/FileTarget.php @@ -88,8 +88,9 @@ public function init() public function export() { $text = implode("\n", array_map([$this, 'formatMessage'], $this->messages)) . "\n"; + $trimmedText = trim($text); - if (trim($text) === '') { + if (empty($trimmedText)) { return; // No messages to export, so we exit the function early } diff --git a/messages/config.php b/messages/config.php index 6028328f3..93845f2e0 100644 --- a/messages/config.php +++ b/messages/config.php @@ -15,7 +15,8 @@ 'languages' => [ 'af', 'ar', 'az', 'be', 'bg', 'bs', 'ca', 'cs', 'da', 'de', 'el', 'es', 'et', 'fa', 'fi', 'fr', 'he', 'hi', 'pt-BR', 'ro', 'hr', 'hu', 'hy', 'id', 'it', 'ja', 'ka', 'kk', 'ko', 'kz', 'lt', 'lv', 'ms', 'nb-NO', 'nl', - 'pl', 'pt', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'uz-Cy', 'vi', 'zh', 'zh-TW' + 'pl', 'pt', 'ru', 'sk', 'sl', 'sr', 'sr-Latn', 'sv', 'tg', 'th', 'tr', 'uk', 'uz', 'uz-Cy', 'vi', 'zh-CN', + 'zh-TW' ], // string, the name of the function for translating messages. // Defaults to 'Yii::t'. This is used as a mark to find the messages to be diff --git a/messages/ko/yii.php b/messages/ko/yii.php index b0ad872fe..4fe82311f 100644 --- a/messages/ko/yii.php +++ b/messages/ko/yii.php @@ -75,8 +75,8 @@ '{attribute} must be greater than or equal to "{compareValue}".' => '{attribute}는 "{compareValue}" 보다 크거나 같아야 합니다.', '{attribute} must be less than "{compareValue}".' => '{attribute}는 "{compareValue}" 보다 작아야 합니다.', '{attribute} must be less than or equal to "{compareValue}".' => '{attribute}는 "{compareValue}" 보다 작거나 같아야 합니다.', - '{attribute} must be no greater than {max}.' => '{attribute}는 "{max}" 보다 클 수 없습니다.', - '{attribute} must be no less than {min}.' => '{attribute}는 "{min}" 보다 작을 수 없습니다.', + '{attribute} must be no greater than {max}.' => '{attribute}는 "{compareValue}" 보다 클 수 없습니다.', + '{attribute} must be no less than {min}.' => '{attribute}는 "{compareValue}" 보다 작을 수 없습니다.', '{attribute} must be repeated exactly.' => '{attribute}는 정확하게 반복합니다.', '{attribute} must not be equal to "{compareValue}".' => '{attribute}는 "{compareValue}"와 같을 수 없습니다.', '{attribute} should contain at least {min, number} {min, plural, one{character} other{characters}}.' => '{attribute}는 최소 {min}자 이어야합니다.', diff --git a/requirements/requirements.php b/requirements/requirements.php index d065f6363..555930615 100644 --- a/requirements/requirements.php +++ b/requirements/requirements.php @@ -111,12 +111,5 @@ 'memo' => 'When IpValidator::expandIPv6 property is set to true, PHP must support IPv6 protocol stack. Currently PHP constant AF_INET6 is not defined and IPv6 is probably unsupported.' - ), - array( - 'name' => 'pcntl', - 'mandatory' => false, - 'condition' => extension_loaded('pcntl'), - 'by' => 'Process Control', - 'memo' => 'Recommended for yii2-queue CLI operations' ) ); diff --git a/widgets/MaskedInputAsset.php b/widgets/MaskedInputAsset.php index 473f4315f..57748be86 100644 --- a/widgets/MaskedInputAsset.php +++ b/widgets/MaskedInputAsset.php @@ -21,7 +21,7 @@ class MaskedInputAsset extends AssetBundle { public $sourcePath = '@bower/inputmask/dist'; public $js = [ - 'jquery.inputmask.js', + 'jquery.inputmask.bundle.js', ]; public $depends = [ 'yii\web\YiiAsset', From 01316620e9b5e14025c456e83d20b45e95801bb9 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Sun, 22 Oct 2023 07:40:27 -0300 Subject: [PATCH 24/56] Remove unsed package "paragonie/random_compat". --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 0b27d62ff..4934013b6 100644 --- a/composer.json +++ b/composer.json @@ -73,8 +73,7 @@ "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 ", "bower-asset/punycode": "^2.2", - "bower-asset/yii2-pjax": "~2.0.1", - "paragonie/random_compat": ">=1" + "bower-asset/yii2-pjax": "~2.0.1" }, "autoload": { "psr-4": {"yii\\": ""} From dfd27a39cb2ba5f19e6f1e8bdae231c39decda09 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Wed, 25 Oct 2023 07:33:47 -0300 Subject: [PATCH 25/56] Fix type boolean in `MSSQL`. (#20040) --- CHANGELOG.md | 1 + db/mssql/Schema.php | 18 ++++++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dc6fbdba..a975e77a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Yii Framework 2 Change Log 2.2 under development ------------------------ +- Bug #20040: Fix type `boolean` in `MSSQL` (terabytesoftw) - Chg #19902: Remove support for CUBRID (mtangoo) - Chg #19891: Remove XCache and ZendDataCache support (mtangoo) diff --git a/db/mssql/Schema.php b/db/mssql/Schema.php index 07dbaac98..a3fe3e329 100644 --- a/db/mssql/Schema.php +++ b/db/mssql/Schema.php @@ -386,28 +386,26 @@ protected function loadColumnSchema($info) $column->isComputed = (bool)$info['is_computed']; $column->unsigned = stripos($column->dbType, 'unsigned') !== false; $column->comment = $info['comment'] === null ? '' : $info['comment']; - $column->type = self::TYPE_STRING; + if (preg_match('/^(\w+)(?:\(([^\)]+)\))?/', $column->dbType, $matches)) { $type = $matches[1]; + if (isset($this->typeMap[$type])) { $column->type = $this->typeMap[$type]; } + + if ($type === 'bit') { + $column->type = 'boolean'; + } + if (!empty($matches[2])) { $values = explode(',', $matches[2]); $column->size = $column->precision = (int) $values[0]; + if (isset($values[1])) { $column->scale = (int) $values[1]; } - if ($column->size === 1 && ($type === 'tinyint' || $type === 'bit')) { - $column->type = 'boolean'; - } elseif ($type === 'bit') { - if ($column->size > 32) { - $column->type = 'bigint'; - } elseif ($column->size === 32) { - $column->type = 'integer'; - } - } } } From 2be8715ef1d876e2d5828e02fae0ed22d86d0ee3 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Tue, 31 Oct 2023 14:41:22 -0300 Subject: [PATCH 26/56] Update `CHANGELOG.md`. --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b99a3202f..1e2ae1d83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,6 @@ Yii Framework 2 Change Log 2.2 under development ------------------------ -- Bug #20040: Fix type `boolean` in `MSSQL` (terabytesoftw) - Chg #19902: Remove support for CUBRID (mtangoo) - Chg #19891: Remove XCache and ZendDataCache support (mtangoo) From c69df63191274d121143aacc0306d59337a67c05 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula Date: Sun, 27 Apr 2025 06:25:17 -0400 Subject: [PATCH 27/56] Fix error typo. --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d84ef95..24ad9ecce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,6 @@ Yii Framework 2 Change Log - Chg #19891: Remove XCache and ZendDataCache support (mtangoo) -2.0.50 under development 2.0.53 under development ------------------------ From 9340705677f474fa405e36f8251e9e1d4c83268b Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Tue, 29 Apr 2025 05:32:03 -0400 Subject: [PATCH 28/56] Sync master branch to 2.2. (#20365) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Максим Спирков <63721828+max-s-lab@users.noreply.github.com> fixed Psalm/PHPStan annotations for ActiveRecord and ActiveQuery (#20363) --- db/ActiveQuery.php | 41 +++++++++++++++-------------------------- db/ActiveRecord.php | 6 ++++++ di/Container.php | 11 +++++------ di/Instance.php | 6 ++++++ 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/db/ActiveQuery.php b/db/ActiveQuery.php index 67d48b98b..7bfa3b820 100644 --- a/db/ActiveQuery.php +++ b/db/ActiveQuery.php @@ -71,6 +71,21 @@ * @since 2.0 * * @template T of (ActiveRecord|array) + * + * @phpstan-method T|null one($db = null) + * @psalm-method T|null one($db = null) + * + * @phpstan-method T[] all($db = null) + * @psalm-method T[] all($db = null) + * + * @phpstan-method ($value is true ? (T is array ? self : self) : self) asArray($value = true) + * @psalm-method ($value is true ? (T is array ? self : self) : self) asArray($value = true) + * + * @phpstan-method BatchQueryResult batch($batchSize = 100, $db = null) + * @psalm-method BatchQueryResult batch($batchSize = 100, $db = null) + * + * @phpstan-method BatchQueryResult each($batchSize = 100, $db = null) + * @psalm-method BatchQueryResult each($batchSize = 100, $db = null) */ class ActiveQuery extends Query implements ActiveQueryInterface { @@ -316,32 +331,6 @@ public function one($db = null) return null; } - /** - * {@inheritdoc} - * - * @return BatchQueryResult - * @psalm-return T[][]|BatchQueryResult - * @phpstan-return T[][]|BatchQueryResult - * @codeCoverageIgnore - */ - public function batch($batchSize = 100, $db = null) - { - return parent::batch($batchSize, $db); - } - - /** - * {@inheritdoc} - * - * @return BatchQueryResult - * @psalm-return T[]|BatchQueryResult - * @phpstan-return T[]|BatchQueryResult - * @codeCoverageIgnore - */ - public function each($batchSize = 100, $db = null) - { - return parent::each($batchSize, $db); - } - /** * Creates a DB command that can be used to execute this query. * @param Connection|null $db the DB connection used to create the DB command. diff --git a/db/ActiveRecord.php b/db/ActiveRecord.php index 29d5efe0b..c34b51168 100644 --- a/db/ActiveRecord.php +++ b/db/ActiveRecord.php @@ -156,6 +156,9 @@ public static function getDb() * @param string $sql the SQL statement to be executed * @param array $params parameters to be bound to the SQL statement during execution. * @return ActiveQuery the newly created [[ActiveQuery]] instance + * + * @phpstan-return ActiveQuery + * @psalm-return ActiveQuery */ public static function findBySql($sql, $params = []) { @@ -408,6 +411,9 @@ public static function deleteAll($condition = null, $params = []) /** * {@inheritdoc} * @return ActiveQuery the newly created [[ActiveQuery]] instance. + * + * @phpstan-return ActiveQuery + * @psalm-return ActiveQuery */ public static function find() { diff --git a/di/Container.php b/di/Container.php index 817f0b0a2..1d34887f4 100644 --- a/di/Container.php +++ b/di/Container.php @@ -158,12 +158,11 @@ class Container extends Component * @throws InvalidConfigException if the class cannot be recognized or correspond to an invalid definition * @throws NotInstantiableException If resolved to an abstract class or an interface (since 2.0.9) * - * - * @template T of class-string - * @psalm-param class-string|array{class: class-string} $class - * @phpstan-param class-string|array{class: class-string} $class - * @psalm-return T - * @phpstan-return T + * @template T of object + * @psalm-param string|class-string|Instance $class + * @phpstan-param string|class-string|Instance $class + * @psalm-return ($class is class-string ? T : object) + * @phpstan-return ($class is class-string ? T : object) */ public function get($class, $params = [], $config = []) { diff --git a/di/Instance.php b/di/Instance.php index edecbe9be..020e81718 100644 --- a/di/Instance.php +++ b/di/Instance.php @@ -114,6 +114,12 @@ public static function of($id, $optional = false) * @param ServiceLocator|Container|null $container the container. This will be passed to [[get()]]. * @return object the object referenced by the Instance, or `$reference` itself if it is an object. * @throws InvalidConfigException if the reference is invalid + * + * @template T of object + * @psalm-param class-string|null $type + * @phpstan-param class-string|null $type + * @psalm-return ($type is null ? object : T) + * @phpstan-return ($type is null ? object : T) */ public static function ensure($reference, $type = null, $container = null) { From fd41f65fb0bfdc872c179702a040b04c43ffd609 Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Sun, 4 May 2025 07:37:37 -0400 Subject: [PATCH 29/56] Refactor asset management: Migrate from `Bower` to `NPM` for package dependencies and update related documentation. (#20368) --- CHANGELOG.md | 1 + base/Application.php | 3 +-- composer.json | 6 +----- validators/PunycodeAsset.php | 2 +- web/JqueryAsset.php | 2 +- widgets/MaskedInputAsset.php | 2 +- widgets/PjaxAsset.php | 2 +- 7 files changed, 7 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24ad9ecce..bae37c111 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Yii Framework 2 Change Log - Chg #19902: Remove support for CUBRID (mtangoo) - Chg #19891: Remove XCache and ZendDataCache support (mtangoo) +- Enh #20368: Refactor asset management: Migrate from `Bower` to `NPM` for package dependencies and update related documentation (terabytesoftw) 2.0.53 under development diff --git a/base/Application.php b/base/Application.php index e2944b82a..fddd279b7 100644 --- a/base/Application.php +++ b/base/Application.php @@ -459,8 +459,7 @@ public function setVendorPath($path) { $this->_vendorPath = Yii::getAlias($path); Yii::setAlias('@vendor', $this->_vendorPath); - Yii::setAlias('@bower', $this->_vendorPath . DIRECTORY_SEPARATOR . 'bower'); - Yii::setAlias('@npm', $this->_vendorPath . DIRECTORY_SEPARATOR . 'npm'); + Yii::setAlias('@npm', $this->getBasePath() . DIRECTORY_SEPARATOR . 'node_modules'); } /** diff --git a/composer.json b/composer.json index ad247b928..e7612a41b 100644 --- a/composer.json +++ b/composer.json @@ -69,11 +69,7 @@ "lib-pcre": "*", "yiisoft/yii2-composer": "~2.0.4", "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 ", - "bower-asset/punycode": "^1.4", - "bower-asset/yii2-pjax": "~2.0.1" + "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0" }, "autoload": { "psr-4": {"yii\\": ""} diff --git a/validators/PunycodeAsset.php b/validators/PunycodeAsset.php index 8d928838c..0e5917a5b 100644 --- a/validators/PunycodeAsset.php +++ b/validators/PunycodeAsset.php @@ -17,7 +17,7 @@ */ class PunycodeAsset extends AssetBundle { - public $sourcePath = '@bower/punycode'; + public $sourcePath = '@npm/punycode'; public $js = [ 'punycode.js', ]; diff --git a/web/JqueryAsset.php b/web/JqueryAsset.php index df365d768..e7a534671 100644 --- a/web/JqueryAsset.php +++ b/web/JqueryAsset.php @@ -15,7 +15,7 @@ */ class JqueryAsset extends AssetBundle { - public $sourcePath = '@bower/jquery/dist'; + public $sourcePath = '@npm/jquery/dist'; public $js = [ 'jquery.js', ]; diff --git a/widgets/MaskedInputAsset.php b/widgets/MaskedInputAsset.php index 473f4315f..2a0a6a197 100644 --- a/widgets/MaskedInputAsset.php +++ b/widgets/MaskedInputAsset.php @@ -19,7 +19,7 @@ */ class MaskedInputAsset extends AssetBundle { - public $sourcePath = '@bower/inputmask/dist'; + public $sourcePath = '@npm/inputmask/dist'; public $js = [ 'jquery.inputmask.js', ]; diff --git a/widgets/PjaxAsset.php b/widgets/PjaxAsset.php index 47795f683..c084763f9 100644 --- a/widgets/PjaxAsset.php +++ b/widgets/PjaxAsset.php @@ -17,7 +17,7 @@ */ class PjaxAsset extends AssetBundle { - public $sourcePath = '@bower/yii2-pjax'; + public $sourcePath = '@npm/yii2-pjax'; public $js = [ 'jquery.pjax.js', ]; From d7ac8ecda96921128610285fe3d0ba465e26d93d Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Sat, 10 May 2025 10:17:53 -0400 Subject: [PATCH 30/56] Add `package.json` for `2.2`. (#20383) --- package.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 000000000..09a66d2bc --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "yii2", + "description": "a modern PHP framework designed for professional Web development", + "dependencies": { + "inputmask": "^5.0.8", + "jquery-pjax": "^2.0.1", + "jquery": "~3.6.4", + "punycode": "^1.4.0", + "yii2-pjax": "^2.0.8" + }, + "keywords": [ + "php", + "framework" + ], + "license": "BSD-3-Clause", + "bugs": { + "url": "https://github.com/yiisoft/yii2/issues" + }, + "homepage": "https://github.com/yiisoft/yii2" +} From 1eaabe0c5f2b323950d52b11021394e9d002eaac Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Sat, 10 May 2025 14:57:51 -0400 Subject: [PATCH 31/56] Add "foxy" flag to extra section in `composer.json`. (#20384) --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e7612a41b..461206ffd 100644 --- a/composer.json +++ b/composer.json @@ -80,6 +80,7 @@ "extra": { "branch-alias": { "dev-master": "2.0.x-dev" - } + }, + "foxy": true } } From 251f399f9dc76917f36498df1402f8dd5b9cb1fd Mon Sep 17 00:00:00 2001 From: Wilmer Arambula <42547589+terabytesoftw@users.noreply.github.com> Date: Mon, 9 Jun 2025 12:03:50 -0400 Subject: [PATCH 32/56] Sync to master branch. (#20401) --- BaseYii.php | 5 ++- CHANGELOG.md | 8 ++++- base/Controller.php | 2 +- base/DynamicModel.php | 2 +- base/Model.php | 6 ++-- base/Module.php | 4 +-- base/View.php | 4 +-- base/Widget.php | 6 ++-- behaviors/OptimisticLockBehavior.php | 4 +-- behaviors/SluggableBehavior.php | 4 +-- behaviors/TimestampBehavior.php | 2 +- caching/DbDependency.php | 4 +-- captcha/CaptchaValidator.php | 2 +- console/UnknownCommandException.php | 4 +-- console/controllers/HelpController.php | 4 +-- console/controllers/ServeController.php | 2 +- data/ActiveDataProvider.php | 4 +-- db/ActiveQuery.php | 16 ++++----- db/ActiveQueryTrait.php | 6 ++-- db/ActiveRecord.php | 2 +- db/ActiveRelationTrait.php | 14 ++++---- db/BaseActiveRecord.php | 44 ++++++++++++------------ db/Command.php | 2 +- db/Connection.php | 4 +-- db/Schema.php | 4 +-- db/mssql/QueryBuilder.php | 4 +-- db/mysql/QueryBuilder.php | 8 +++++ db/sqlite/Schema.php | 2 +- di/Container.php | 2 +- filters/AccessControl.php | 2 +- grid/DataColumn.php | 6 ++-- grid/GridView.php | 10 +++--- helpers/BaseArrayHelper.php | 12 ++++++- helpers/BaseMarkdown.php | 2 +- log/Target.php | 4 +-- rbac/PhpManager.php | 12 +++---- requirements/requirements.php | 8 ++--- requirements/views/console/index.php | 8 ++--- requirements/views/web/index.php | 8 +++-- rest/Action.php | 2 +- rest/CreateAction.php | 2 +- rest/IndexAction.php | 2 +- rest/UpdateAction.php | 2 +- rest/UrlRule.php | 4 +-- test/ActiveFixture.php | 2 +- test/BaseActiveFixture.php | 2 +- test/FixtureTrait.php | 2 -- validators/ExistValidator.php | 2 +- validators/UniqueValidator.php | 2 +- views/_addComments.php | 5 +-- views/_createTable.php | 7 ++-- views/_dropTable.php | 5 +-- views/_foreignTables.php | 3 +- views/addColumnMigration.php | 10 +++--- views/createJunctionMigration.php | 12 +++---- views/createTableMigration.php | 14 ++++---- views/dropColumnMigration.php | 10 +++--- views/dropTableMigration.php | 10 +++--- views/errorHandler/callStackItem.php | 22 ++++++------ views/errorHandler/error.php | 6 ++-- views/errorHandler/exception.php | 8 +++-- views/errorHandler/previousException.php | 6 ++-- views/migration.php | 6 ++-- web/AssetManager.php | 2 +- web/CompositeUrlRule.php | 4 +-- web/UrlManager.php | 6 ++-- web/User.php | 36 +++++++++++++++++-- widgets/ActiveField.php | 4 +-- widgets/ActiveForm.php | 7 ++-- widgets/BaseListView.php | 8 ++--- 70 files changed, 265 insertions(+), 195 deletions(-) diff --git a/BaseYii.php b/BaseYii.php index 091b920f1..253205bba 100644 --- a/BaseYii.php +++ b/BaseYii.php @@ -93,7 +93,7 @@ class BaseYii */ public static function getVersion() { - return '2.2-dev'; + return '22.0.x-dev'; } /** @@ -127,6 +127,9 @@ public static function getVersion() * @return string|false the path corresponding to the alias, false if the root alias is not previously registered. * @throws InvalidArgumentException if the alias is invalid while $throwException is true. * @see setAlias() + * + * @phpstan-return ($throwException is true ? string : string|false) + * @psalm-return ($throwException is true ? string : string|false) */ public static function getAlias($alias, $throwException = true) { diff --git a/CHANGELOG.md b/CHANGELOG.md index 47cca0834..60c9d7d25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ Yii Framework 2 Change Log ========================== -2.2 under development +22.0 under development ------------------------ - Chg #19902: Remove support for CUBRID (mtangoo) @@ -12,6 +12,8 @@ Yii Framework 2 Change Log 2.0.53 under development ------------------------ +- Enh #20385: Fixed the memory leak issue when using `Query::exists()` with MySQL (snewer) +- Bug #20387: Fixed the command generated to use router.php file in php built-in server (eseperio) - Enh #20309: Add custom attributes support to style tags (nzwz) - Bug #20329: pgsql: Column Schema doesn't recognize PG type cast (arkhamvm) - Bug #8298: Loading fixtures does not update table sequence for Postgresql database (mtangoo) @@ -24,6 +26,10 @@ Yii Framework 2 Change Log - Enh #20372: Add PHPStan/Psalm annotations for `AssetBundle`, `AssetManager` and `View` (max-s-lab) - Bug #20373: Fixed the type of the first parameter `yii\base\Controller::bindInjectedParams()` (max-s-lab) - Enh #20374: Add PHPStan/Psalm annotations for `BaseYii`, `BaseObject`, `Component`, `Model`, `Module` and `yii\base\Controller` (max-s-lab) +- Enh #20394: Add PHPStan/Psalm annotations for `Yii::getAlias` (max-s-lab) +- Enh #20400: Add PHPStan/Psalm annotations for `yii\web\User` (samuelrajan747) +- Enh #20395: Add PHPStan/Psalm annotations for `ActiveForm::validate` (samuelrajan747) +- Enh #20397: Add PHPStan/Psalm annotations for `ArrayHelper::merge` (samuelrajan747) 2.0.52 February 13, 2025 diff --git a/base/Controller.php b/base/Controller.php index a8f8ae625..7542daf7e 100644 --- a/base/Controller.php +++ b/base/Controller.php @@ -187,7 +187,7 @@ public function runAction($id, $params = []) // call afterAction on modules foreach ($modules as $module) { - /* @var $module Module */ + /** @var Module $module */ $result = $module->afterAction($action, $result); } } diff --git a/base/DynamicModel.php b/base/DynamicModel.php index 9ce466b8f..eb4ee9649 100644 --- a/base/DynamicModel.php +++ b/base/DynamicModel.php @@ -217,7 +217,7 @@ public function addRule($attributes, $validator, $options = []) */ public static function validateData(array $data, $rules = []) { - /* @var $model DynamicModel */ + /** @var self $model */ $model = new static($data); if (!empty($rules)) { $validators = $model->getValidators(); diff --git a/base/Model.php b/base/Model.php index 30b98f8ec..afa74646e 100644 --- a/base/Model.php +++ b/base/Model.php @@ -932,7 +932,7 @@ public function load($data, $formName = null) public static function loadMultiple($models, $data, $formName = null) { if ($formName === null) { - /* @var $first Model|false */ + /** @var self|false $first */ $first = reset($models); if ($first === false) { return false; @@ -942,7 +942,7 @@ public static function loadMultiple($models, $data, $formName = null) $success = false; foreach ($models as $i => $model) { - /* @var $model Model */ + /** @var self $model */ if ($formName == '') { if (!empty($data[$i]) && $model->load($data[$i], '')) { $success = true; @@ -969,7 +969,7 @@ public static function loadMultiple($models, $data, $formName = null) public static function validateMultiple($models, $attributeNames = null) { $valid = true; - /* @var $model Model */ + /** @var self $model */ foreach ($models as $model) { $valid = $model->validate($attributeNames) && $valid; } diff --git a/base/Module.php b/base/Module.php index a95cfcf4e..d730d9151 100644 --- a/base/Module.php +++ b/base/Module.php @@ -444,7 +444,7 @@ public function getModule($id, $load = true) return $this->_modules[$id]; } elseif ($load) { Yii::debug("Loading module: $id", __METHOD__); - /* @var $module Module */ + /** @var self $module */ $module = Yii::createObject($this->_modules[$id], [$id, $this]); $module::setInstance($module); return $this->_modules[$id] = $module; @@ -548,7 +548,7 @@ public function runAction($route, $params = []) { $parts = $this->createController($route); if (is_array($parts)) { - /* @var $controller Controller */ + /** @var Controller $controller */ list($controller, $actionID) = $parts; $oldController = Yii::$app->controller; Yii::$app->controller = $controller; diff --git a/base/View.php b/base/View.php index 574954fc6..81d1acfa8 100644 --- a/base/View.php +++ b/base/View.php @@ -251,7 +251,7 @@ public function renderFile($viewFile, $params = [], $context = null) if (is_array($this->renderers[$ext]) || is_string($this->renderers[$ext])) { $this->renderers[$ext] = Yii::createObject($this->renderers[$ext]); } - /* @var $renderer ViewRenderer */ + /** @var ViewRenderer $renderer */ $renderer = $this->renderers[$ext]; $output = $renderer->render($this, $viewFile, $params); } else { @@ -550,7 +550,7 @@ public function beginCache($id, $properties = []) { $properties['id'] = $id; $properties['view'] = $this; - /* @var $cache FragmentCache */ + /** @var FragmentCache $cache */ $cache = FragmentCache::begin($properties); if ($cache->getCachedContent() !== false) { $this->endCache(); diff --git a/base/Widget.php b/base/Widget.php index 5e1615819..1baaa42b6 100644 --- a/base/Widget.php +++ b/base/Widget.php @@ -90,7 +90,7 @@ public function init() public static function begin($config = []) { $config['class'] = get_called_class(); - /* @var $widget Widget */ + /** @var self $widget */ $widget = Yii::createObject($config); self::$stack[] = $widget; self::$_resolvedClasses[get_called_class()] = get_class($widget); @@ -113,7 +113,7 @@ public static function end() $calledClass = self::$_resolvedClasses[get_called_class()] ?? get_called_class(); if (get_class($widget) === $calledClass) { - /* @var $widget Widget */ + /** @var self $widget */ if ($widget->beforeRun()) { $result = $widget->run(); $result = $widget->afterRun($result); @@ -141,8 +141,8 @@ public static function widget($config = []) ob_start(); ob_implicit_flush(false); try { - /* @var $widget Widget */ $config['class'] = get_called_class(); + /** @var self $widget */ $widget = Yii::createObject($config); $out = ''; if ($widget->beforeRun()) { diff --git a/behaviors/OptimisticLockBehavior.php b/behaviors/OptimisticLockBehavior.php index 92243f5c7..18d80bd48 100644 --- a/behaviors/OptimisticLockBehavior.php +++ b/behaviors/OptimisticLockBehavior.php @@ -118,7 +118,7 @@ protected function getLockAttribute() return $this->_lockAttribute; } - /* @var $owner BaseActiveRecord */ + /** @var BaseActiveRecord $owner */ $owner = $this->owner; $lock = $owner->optimisticLock(); if ($lock === null || $owner->hasAttribute($lock) === false) { @@ -159,7 +159,7 @@ protected function getValue($event) */ public function upgrade() { - /* @var $owner BaseActiveRecord */ + /** @var BaseActiveRecord $owner */ $owner = $this->owner; if ($owner->getIsNewRecord()) { throw new InvalidCallException('Upgrading the model version is not possible on a new record.'); diff --git a/behaviors/SluggableBehavior.php b/behaviors/SluggableBehavior.php index 369be6c37..4b9ec90a7 100644 --- a/behaviors/SluggableBehavior.php +++ b/behaviors/SluggableBehavior.php @@ -239,8 +239,7 @@ protected function makeUnique($slug) */ protected function validateSlug($slug) { - /* @var $validator UniqueValidator */ - /* @var $model BaseActiveRecord */ + /** @var UniqueValidator $validator */ $validator = Yii::createObject(array_merge( [ 'class' => UniqueValidator::class, @@ -248,6 +247,7 @@ protected function validateSlug($slug) $this->uniqueValidator )); + /** @var BaseActiveRecord $model */ $model = clone $this->owner; $model->clearErrors(); $model->{$this->slugAttribute} = $slug; diff --git a/behaviors/TimestampBehavior.php b/behaviors/TimestampBehavior.php index bb0d6ca27..ef927b1d6 100644 --- a/behaviors/TimestampBehavior.php +++ b/behaviors/TimestampBehavior.php @@ -131,7 +131,7 @@ protected function getValue($event) */ public function touch($attribute) { - /* @var $owner BaseActiveRecord */ + /** @var BaseActiveRecord $owner */ $owner = $this->owner; if ($owner->getIsNewRecord()) { throw new InvalidCallException('Updating the timestamp is not possible on a new record.'); diff --git a/caching/DbDependency.php b/caching/DbDependency.php index 525c3e02b..cd11983a4 100644 --- a/caching/DbDependency.php +++ b/caching/DbDependency.php @@ -49,8 +49,8 @@ class DbDependency extends Dependency */ protected function generateDependencyData($cache) { - /* @var $db Connection */ - $db = Instance::ensure($this->db, Connection::class); + /** @var Connection $db */ + $db = Instance::ensure($this->db, Connection::className()); if ($this->sql === null) { throw new InvalidConfigException('DbDependency::sql must be set.'); } diff --git a/captcha/CaptchaValidator.php b/captcha/CaptchaValidator.php index c84f199c5..641abbd04 100644 --- a/captcha/CaptchaValidator.php +++ b/captcha/CaptchaValidator.php @@ -72,7 +72,7 @@ public function createCaptchaAction() { $ca = Yii::$app->createController($this->captchaAction); if ($ca !== false) { - /* @var $controller \yii\base\Controller */ + /** @var \yii\base\Controller $controller */ list($controller, $actionID) = $ca; $action = $controller->createAction($actionID); if ($action !== null) { diff --git a/console/UnknownCommandException.php b/console/UnknownCommandException.php index 917887c86..a0e09674b 100644 --- a/console/UnknownCommandException.php +++ b/console/UnknownCommandException.php @@ -70,13 +70,13 @@ public function getSuggestedAlternatives() if ($help === false || $this->command === '') { return []; } - /** @var $helpController HelpController */ + /** @var HelpController $helpController */ list($helpController, $actionID) = $help; $availableActions = []; foreach ($helpController->getCommands() as $command) { $result = $this->application->createController($command); - /** @var $controller Controller */ + /** @var Controller $controller */ list($controller, $actionID) = $result; if ($controller->createAction($controller->defaultAction) !== null) { // add the command itself (default action) diff --git a/console/controllers/HelpController.php b/console/controllers/HelpController.php index c620f26cd..8c0a951e0 100644 --- a/console/controllers/HelpController.php +++ b/console/controllers/HelpController.php @@ -77,7 +77,7 @@ public function actionList() { foreach ($this->getCommandDescriptions() as $command => $description) { $result = Yii::$app->createController($command); - /** @var $controller Controller */ + /** @var Controller $controller */ list($controller, $actionID) = $result; $actions = $this->getActions($controller); $prefix = $controller->getUniqueId(); @@ -300,7 +300,7 @@ protected function getDefaultHelp() $maxLength = 0; foreach ($commands as $command => $description) { $result = Yii::$app->createController($command); - /** @var $controller Controller */ + /** @var Controller $controller */ list($controller, $actionID) = $result; $actions = $this->getActions($controller); $prefix = $controller->getUniqueId(); diff --git a/console/controllers/ServeController.php b/console/controllers/ServeController.php index b806f67d5..af812984b 100644 --- a/console/controllers/ServeController.php +++ b/console/controllers/ServeController.php @@ -83,7 +83,7 @@ public function actionIndex($address = 'localhost') $command = '"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\""; if ($this->router !== null && $router !== '') { - $command .= " -r \"{$router}\""; + $command .= " \"{$router}\""; } $this->runCommand($command); diff --git a/data/ActiveDataProvider.php b/data/ActiveDataProvider.php index 3a129aa72..47555c326 100644 --- a/data/ActiveDataProvider.php +++ b/data/ActiveDataProvider.php @@ -132,7 +132,7 @@ protected function prepareKeys($models) return $keys; } elseif ($this->query instanceof ActiveQueryInterface) { - /* @var $class \yii\db\ActiveRecordInterface */ + /** @var \yii\db\ActiveRecordInterface $class */ $class = $this->query->modelClass; $pks = $class::primaryKey(); if (count($pks) === 1) { @@ -175,7 +175,7 @@ public function setSort($value) { parent::setSort($value); if ($this->query instanceof ActiveQueryInterface && ($sort = $this->getSort()) !== false) { - /* @var $modelClass Model */ + /** @var Model $modelClass */ $modelClass = $this->query->modelClass; $model = $modelClass::instance(); if (empty($sort->attributes)) { diff --git a/db/ActiveQuery.php b/db/ActiveQuery.php index 7bfa3b820..a01d76688 100644 --- a/db/ActiveQuery.php +++ b/db/ActiveQuery.php @@ -188,7 +188,7 @@ public function prepare($builder) $this->filterByModels($viaModels); } elseif (is_array($this->via)) { // via relation - /* @var $viaQuery ActiveQuery */ + /** @var self $viaQuery */ list($viaName, $viaQuery, $viaCallableUsed) = $this->via; if ($viaQuery->multiple) { if ($viaCallableUsed) { @@ -266,7 +266,7 @@ public function populate($rows) private function removeDuplicatedModels($models) { $hash = []; - /* @var $class ActiveRecord */ + /** @var ActiveRecord $class */ $class = $this->modelClass; $pks = $class::primaryKey(); @@ -339,7 +339,7 @@ public function one($db = null) */ public function createCommand($db = null) { - /* @var $modelClass ActiveRecord */ + /** @var ActiveRecord $modelClass */ $modelClass = $this->modelClass; if ($db === null) { $db = $modelClass::getDb(); @@ -363,7 +363,7 @@ public function createCommand($db = null) */ protected function queryScalar($selectExpression, $db) { - /* @var $modelClass ActiveRecord */ + /** @var ActiveRecord $modelClass */ $modelClass = $this->modelClass; if ($db === null) { $db = $modelClass::getDb(); @@ -452,7 +452,7 @@ public function joinWith($with, $eagerLoading = true, $joinType = 'LEFT JOIN') list(, $relation, $alias) = $matches; $name = $relation; $callback = function ($query) use ($callback, $alias) { - /* @var $query ActiveQuery */ + /** @var self $query */ $query->alias($alias); if ($callback !== null) { call_user_func($callback, $query); @@ -475,7 +475,7 @@ private function buildJoinWith() $join = $this->join; $this->join = []; - /* @var $modelClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $modelClass */ $modelClass = $this->modelClass; $model = $modelClass::instance(); foreach ($this->joinWith as $config) { @@ -570,7 +570,7 @@ private function joinWithRelations($model, $with, $joinType) } else { $relation = $relations[$fullName]; } - /* @var $relationModelClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $relationModelClass */ $relationModelClass = $relation->modelClass; $primaryModel = $relationModelClass::instance(); $parent = $relation; @@ -870,7 +870,7 @@ public function getTablesUsedInFrom() */ protected function getPrimaryTableName() { - /* @var $modelClass ActiveRecord */ + /** @var ActiveRecord $modelClass */ $modelClass = $this->modelClass; return $modelClass::tableName(); } diff --git a/db/ActiveQueryTrait.php b/db/ActiveQueryTrait.php index d49fa0fba..d8cb893ee 100644 --- a/db/ActiveQueryTrait.php +++ b/db/ActiveQueryTrait.php @@ -115,7 +115,7 @@ protected function createModels($rows) return $rows; } else { $models = []; - /* @var $class ActiveRecord */ + /** @var ActiveRecord $class */ $class = $this->modelClass; foreach ($rows as $row) { $model = $class::instantiate($row); @@ -141,12 +141,12 @@ public function findWith($with, &$models) $primaryModel = reset($models); if (!$primaryModel instanceof ActiveRecordInterface) { - /* @var $modelClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $modelClass */ $modelClass = $this->modelClass; $primaryModel = $modelClass::instance(); } $relations = $this->normalizeRelations($primaryModel, $with); - /* @var $relation ActiveQuery */ + /** @var ActiveQuery $relation */ foreach ($relations as $name => $relation) { if ($relation->asArray === null) { // inherit asArray from primary query diff --git a/db/ActiveRecord.php b/db/ActiveRecord.php index c34b51168..796a97710 100644 --- a/db/ActiveRecord.php +++ b/db/ActiveRecord.php @@ -295,7 +295,7 @@ public function refresh() } $query->where($pk); - /* @var $record BaseActiveRecord */ + /** @var BaseActiveRecord $record */ $record = $query->noCache()->one(); return $this->refreshInternal($record); } diff --git a/db/ActiveRelationTrait.php b/db/ActiveRelationTrait.php index 73b935fdb..0a4f903ce 100644 --- a/db/ActiveRelationTrait.php +++ b/db/ActiveRelationTrait.php @@ -206,7 +206,7 @@ private function addInverseRelations(&$result) $relatedModel->populateRelation($this->inverseOf, $inverseRelation->multiple ? [$this->primaryModel] : $this->primaryModel); } else { if (!isset($inverseRelation)) { - /* @var $modelClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $modelClass */ $modelClass = $this->modelClass; $inverseRelation = $modelClass::instance()->getRelation($this->inverseOf); } @@ -230,13 +230,13 @@ public function populateRelation($name, &$primaryModels) if ($this->via instanceof self) { // via junction table - /* @var $viaQuery ActiveRelationTrait */ + /** @var self $viaQuery */ $viaQuery = $this->via; $viaModels = $viaQuery->findJunctionRows($primaryModels); $this->filterByModels($viaModels); } elseif (is_array($this->via)) { // via relation - /* @var $viaQuery ActiveRelationTrait|ActiveQueryTrait */ + /** @var self|ActiveQueryTrait $viaQuery */ list($viaName, $viaQuery) = $this->via; if ($viaQuery->asArray === null) { // inherit asArray from primary query @@ -339,11 +339,11 @@ private function populateInverseRelation(&$primaryModels, $models, $primaryName, return; } $model = reset($models); - /* @var $relation ActiveQueryInterface|ActiveQuery */ + /** @var ActiveQueryInterface|ActiveQuery $relation */ if ($model instanceof ActiveRecordInterface) { $relation = $model->getRelation($name); } else { - /* @var $modelClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $modelClass */ $modelClass = $this->modelClass; $relation = $modelClass::instance()->getRelation($name); } @@ -496,7 +496,7 @@ private function prefixKeyColumns($attributes) { if ($this instanceof ActiveQuery && (!empty($this->join) || !empty($this->joinWith))) { if (empty($this->from)) { - /* @var $modelClass ActiveRecord */ + /** @var ActiveRecord $modelClass */ $modelClass = $this->modelClass; $alias = $modelClass::tableName(); } else { @@ -625,7 +625,7 @@ private function findJunctionRows($primaryModels) return []; } $this->filterByModels($primaryModels); - /* @var $primaryModel ActiveRecord */ + /** @var ActiveRecord $primaryModel */ $primaryModel = reset($primaryModels); if (!$primaryModel instanceof ActiveRecordInterface) { // when primaryModels are array of arrays (asArray case) diff --git a/db/BaseActiveRecord.php b/db/BaseActiveRecord.php index 3772f047b..8b35e79b2 100644 --- a/db/BaseActiveRecord.php +++ b/db/BaseActiveRecord.php @@ -441,8 +441,8 @@ public function hasMany($class, $link) */ protected function createRelationQuery($class, $link, $multiple) { - /* @var $class ActiveRecordInterface */ - /* @var $query ActiveQuery */ + /** @var ActiveRecordInterface $class */ + /** @var ActiveQuery $query */ $query = $class::find(); $query->primaryModel = $this; $query->link = $link; @@ -1060,7 +1060,7 @@ public function afterDelete() */ public function refresh() { - /* @var $record BaseActiveRecord */ + /** @var self $record */ $record = static::findOne($this->getPrimaryKey(true)); return $this->refreshInternal($record); } @@ -1299,7 +1299,7 @@ public function getRelation($name, $throwException = true) */ public function link($name, $model, $extraColumns = []) { - /* @var $relation ActiveQueryInterface|ActiveQuery */ + /** @var ActiveQueryInterface|ActiveQuery $relation */ $relation = $this->getRelation($name); if ($relation->via !== null) { @@ -1307,7 +1307,7 @@ public function link($name, $model, $extraColumns = []) throw new InvalidCallException('Unable to link models: the models being linked cannot be newly created.'); } if (is_array($relation->via)) { - /* @var $viaRelation ActiveQuery */ + /** @var ActiveQuery $viaRelation */ list($viaName, $viaRelation) = $relation->via; $viaClass = $viaRelation->modelClass; // unset $viaName so that it can be reloaded to reflect the change @@ -1327,15 +1327,15 @@ public function link($name, $model, $extraColumns = []) $columns[$k] = $v; } if (is_array($relation->via)) { - /* @var $viaClass ActiveRecordInterface */ - /* @var $record ActiveRecordInterface */ + /** @var ActiveRecordInterface $viaClass */ + /** @var ActiveRecordInterface $record */ $record = Yii::createObject($viaClass); foreach ($columns as $column => $value) { $record->$column = $value; } $record->insert(false); } else { - /* @var $viaTable string */ + /** @var string $viaTable */ static::getDb()->createCommand()->insert($viaTable, $columns)->execute(); } } else { @@ -1395,12 +1395,12 @@ public function link($name, $model, $extraColumns = []) */ public function unlink($name, $model, $delete = false) { - /* @var $relation ActiveQueryInterface|ActiveQuery */ + /** @var ActiveQueryInterface|ActiveQuery $relation */ $relation = $this->getRelation($name); if ($relation->via !== null) { if (is_array($relation->via)) { - /* @var $viaRelation ActiveQuery */ + /** @var ActiveQuery $viaRelation */ list($viaName, $viaRelation) = $relation->via; $viaClass = $viaRelation->modelClass; unset($this->_related[$viaName]); @@ -1423,15 +1423,15 @@ public function unlink($name, $model, $delete = false) $columns = ['and', $columns, $viaRelation->on]; } if (is_array($relation->via)) { - /* @var $viaClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $viaClass */ if ($delete) { $viaClass::deleteAll($columns); } else { $viaClass::updateAll($nulls, $columns); } } else { - /* @var $viaTable string */ - /* @var $command Command */ + /** @var string $viaTable */ + /** @var Command $command */ $command = static::getDb()->createCommand(); if ($delete) { $command->delete($viaTable, $columns)->execute(); @@ -1472,7 +1472,7 @@ public function unlink($name, $model, $delete = false) if (!$relation->multiple) { unset($this->_related[$name]); } elseif (isset($this->_related[$name])) { - /* @var $b ActiveRecordInterface */ + /** @var ActiveRecordInterface $b */ foreach ($this->_related[$name] as $a => $b) { if ($model->getPrimaryKey() === $b->getPrimaryKey()) { unset($this->_related[$name][$a]); @@ -1498,12 +1498,12 @@ public function unlink($name, $model, $delete = false) */ public function unlinkAll($name, $delete = false) { - /* @var $relation ActiveQueryInterface|ActiveQuery */ + /** @var ActiveQueryInterface|ActiveQuery $relation */ $relation = $this->getRelation($name); if ($relation->via !== null) { if (is_array($relation->via)) { - /* @var $viaRelation ActiveQuery */ + /** @var ActiveQuery $viaRelation */ list($viaName, $viaRelation) = $relation->via; $viaClass = $viaRelation->modelClass; unset($this->_related[$viaName]); @@ -1524,15 +1524,15 @@ public function unlinkAll($name, $delete = false) $condition = ['and', $condition, $viaRelation->on]; } if (is_array($relation->via)) { - /* @var $viaClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $viaClass */ if ($delete) { $viaClass::deleteAll($condition); } else { $viaClass::updateAll($nulls, $condition); } } else { - /* @var $viaTable string */ - /* @var $command Command */ + /** @var string $viaTable */ + /** @var Command $command */ $command = static::getDb()->createCommand(); if ($delete) { $command->delete($viaTable, $condition)->execute(); @@ -1541,7 +1541,7 @@ public function unlinkAll($name, $delete = false) } } } else { - /* @var $relatedModel ActiveRecordInterface */ + /** @var ActiveRecordInterface $relatedModel */ $relatedModel = $relation->modelClass; if (!$delete && count($relation->link) === 1 && is_array($this->{$b = reset($relation->link)})) { // relation via array valued attribute @@ -1647,7 +1647,7 @@ public function getAttributeLabel($attribute) } catch (InvalidArgumentException $e) { break; } - /* @var $modelClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $modelClass */ $modelClass = $relation->modelClass; $model = $modelClass::instance(); } @@ -1683,7 +1683,7 @@ public function getAttributeHint($attribute) } catch (InvalidArgumentException $e) { return ''; } - /* @var $modelClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $modelClass */ $modelClass = $relation->modelClass; $relatedModel = $modelClass::instance(); } diff --git a/db/Command.php b/db/Command.php index fb32071d2..359550950 100644 --- a/db/Command.php +++ b/db/Command.php @@ -1167,7 +1167,7 @@ protected function queryInternal($method, $fetchMode = null) if ($method !== '') { $info = $this->db->getQueryCacheInfo($this->queryCacheDuration, $this->queryCacheDependency); if (is_array($info)) { - /* @var $cache \yii\caching\CacheInterface */ + /** @var \yii\caching\CacheInterface $cache */ $cache = $info[0]; $cacheKey = $this->getCacheKey($method, $fetchMode, ''); $result = $cache->get($cacheKey); diff --git a/db/Connection.php b/db/Connection.php index 12c442702..e172118f7 100644 --- a/db/Connection.php +++ b/db/Connection.php @@ -1197,7 +1197,7 @@ protected function openFromPoolSequentially(array $pool, array $sharedConfig) continue; } - /* @var $db Connection */ + /** @var self $db */ $db = Yii::createObject($config); try { @@ -1219,7 +1219,7 @@ protected function openFromPoolSequentially(array $pool, array $sharedConfig) // ignore the cache and try to connect anyway // $pool now only contains servers we did not already try in the loop above foreach ($pool as $config) { - /* @var $db Connection */ + /** @var self $db */ $db = Yii::createObject($config); try { $db->open(); diff --git a/db/Schema.php b/db/Schema.php index 43e15d99b..5f54b5ab2 100644 --- a/db/Schema.php +++ b/db/Schema.php @@ -278,7 +278,7 @@ public function getPdoType($data) */ public function refresh() { - /* @var $cache CacheInterface */ + /** @var CacheInterface $cache */ $cache = is_string($this->db->schemaCache) ? Yii::$app->get($this->db->schemaCache, false) : $this->db->schemaCache; if ($this->db->enableSchemaCache && $cache instanceof CacheInterface) { TagDependency::invalidate($cache, $this->getCacheTag()); @@ -299,7 +299,7 @@ public function refreshTableSchema($name) $rawName = $this->getRawTableName($name); unset($this->_tableMetadata[$rawName]); $this->_tableNames = []; - /* @var $cache CacheInterface */ + /** @var CacheInterface $cache */ $cache = is_string($this->db->schemaCache) ? Yii::$app->get($this->db->schemaCache, false) : $this->db->schemaCache; if ($this->db->enableSchemaCache && $cache instanceof CacheInterface) { $cache->delete($this->getCacheKey($rawName)); diff --git a/db/mssql/QueryBuilder.php b/db/mssql/QueryBuilder.php index f17817f85..2c4d438c9 100644 --- a/db/mssql/QueryBuilder.php +++ b/db/mssql/QueryBuilder.php @@ -425,7 +425,7 @@ protected function getAllColumnNames($modelClass = null) if (!$modelClass) { return null; } - /* @var $modelClass \yii\db\ActiveRecord */ + /** @var \yii\db\ActiveRecord $modelClass */ $schema = $modelClass::getTableSchema(); return array_keys($schema->columns); } @@ -477,7 +477,7 @@ public function insert($table, $columns, &$params) $cols = []; $outputColumns = []; if ($version2005orLater) { - /* @var $schema TableSchema */ + /** @var TableSchema $schema */ $schema = $this->db->getTableSchema($table); foreach ($schema->columns as $column) { if ($column->isComputed) { diff --git a/db/mysql/QueryBuilder.php b/db/mysql/QueryBuilder.php index 293b1d2cb..6c9083d45 100644 --- a/db/mysql/QueryBuilder.php +++ b/db/mysql/QueryBuilder.php @@ -339,6 +339,14 @@ public function dropCommentFromTable($table) return $this->addCommentOnTable($table, ''); } + /** + * {@inheritdoc} + * @since 2.0.8 + */ + public function selectExists($rawSql) + { + return 'SELECT EXISTS(' . $rawSql . ') AS ' . $this->db->quoteColumnName('result'); + } /** * Gets column definition. diff --git a/db/sqlite/Schema.php b/db/sqlite/Schema.php index 2ff7ba835..8163c0b0b 100644 --- a/db/sqlite/Schema.php +++ b/db/sqlite/Schema.php @@ -160,7 +160,7 @@ protected function loadTableChecks($tableName) $sql = $this->db->createCommand('SELECT `sql` FROM `sqlite_master` WHERE name = :tableName', [ ':tableName' => $tableName, ])->queryScalar(); - /** @var $code SqlToken[]|SqlToken[][]|SqlToken[][][] */ + /** @var SqlToken[]|SqlToken[][]|SqlToken[][][] $code */ $code = (new SqlTokenizer($sql))->tokenize(); $pattern = (new SqlTokenizer('any CREATE any TABLE any()'))->tokenize(); if (!$code[0]->matches($pattern, 0, $firstMatchIndex, $lastMatchIndex)) { diff --git a/di/Container.php b/di/Container.php index 1d34887f4..9c88b6186 100644 --- a/di/Container.php +++ b/di/Container.php @@ -387,7 +387,7 @@ public function getDefinitions() */ protected function build($class, $params, $config) { - /* @var $reflection ReflectionClass */ + /** @var ReflectionClass $reflection */ list($reflection, $dependencies) = $this->getDependencies($class); $addDependencies = []; diff --git a/filters/AccessControl.php b/filters/AccessControl.php index a648feb77..1785f5e79 100644 --- a/filters/AccessControl.php +++ b/filters/AccessControl.php @@ -118,7 +118,7 @@ public function beforeAction($action) { $user = $this->user; $request = Yii::$app->getRequest(); - /* @var $rule AccessRule */ + /** @var AccessRule $rule */ foreach ($this->rules as $rule) { if ($allow = $rule->allows($action, $user, $request)) { return true; diff --git a/grid/DataColumn.php b/grid/DataColumn.php index 453fc099e..0995ffaf4 100644 --- a/grid/DataColumn.php +++ b/grid/DataColumn.php @@ -172,12 +172,12 @@ protected function getHeaderCellLabel() if ($this->attribute === null) { $label = ''; } elseif ($provider instanceof ActiveDataProvider && $provider->query instanceof ActiveQueryInterface) { - /* @var $modelClass Model */ + /** @var Model $modelClass */ $modelClass = $provider->query->modelClass; $model = $modelClass::instance(); $label = $model->getAttributeLabel($this->attribute); } elseif ($provider instanceof ArrayDataProvider && $provider->modelClass !== null) { - /* @var $modelClass Model */ + /** @var Model $modelClass */ $modelClass = $provider->modelClass; $model = $modelClass::instance(); $label = $model->getAttributeLabel($this->attribute); @@ -186,7 +186,7 @@ protected function getHeaderCellLabel() } else { $models = $provider->getModels(); if (($model = reset($models)) instanceof Model) { - /* @var $model Model */ + /** @var Model $model */ $label = $model->getAttributeLabel($this->attribute); } else { $label = Inflector::camel2words($this->attribute); diff --git a/grid/GridView.php b/grid/GridView.php index 8b5afefe7..452a7b0f3 100644 --- a/grid/GridView.php +++ b/grid/GridView.php @@ -400,7 +400,7 @@ public function renderCaption() public function renderColumnGroup() { foreach ($this->columns as $column) { - /* @var $column Column */ + /** @var Column $column */ if (!empty($column->options)) { $cols = []; foreach ($this->columns as $col) { @@ -422,7 +422,7 @@ public function renderTableHeader() { $cells = []; foreach ($this->columns as $column) { - /* @var $column Column */ + /** @var Column $column */ $cells[] = $column->renderHeaderCell(); } $content = Html::tag('tr', implode('', $cells), $this->headerRowOptions); @@ -443,7 +443,7 @@ public function renderTableFooter() { $cells = []; foreach ($this->columns as $column) { - /* @var $column Column */ + /** @var Column $column */ $cells[] = $column->renderFooterCell(); } $content = Html::tag('tr', implode('', $cells), $this->footerRowOptions); @@ -463,7 +463,7 @@ public function renderFilters() if ($this->filterModel !== null) { $cells = []; foreach ($this->columns as $column) { - /* @var $column Column */ + /** @var Column $column */ $cells[] = $column->renderFilterCell(); } @@ -520,7 +520,7 @@ public function renderTableBody() public function renderTableRow($model, $key, $index) { $cells = []; - /* @var $column Column */ + /** @var Column $column */ foreach ($this->columns as $column) { $cells[] = $column->renderDataCell($model, $key, $index); } diff --git a/helpers/BaseArrayHelper.php b/helpers/BaseArrayHelper.php index b9366c220..eb3cc7e5e 100644 --- a/helpers/BaseArrayHelper.php +++ b/helpers/BaseArrayHelper.php @@ -117,8 +117,18 @@ public static function toArray($object, $properties = [], $recursive = true) * @param array $b array to be merged from. You can specify additional * arrays via third argument, fourth argument etc. * @return array the merged array (the original arrays are not changed.) + * @phpstan-template TItemA + * @phpstan-template TItemB + * @psalm-template TItemA + * @psalm-template TItemB + * @phpstan-param array $a + * @phpstan-param array> ...$b + * @psalm-param array $a + * @psalm-param array> ...$b + * @phpstan-return array + * @psalm-return array */ - public static function merge($a, $b) + public static function merge($a, ...$b) { $args = func_get_args(); $res = array_shift($args); diff --git a/helpers/BaseMarkdown.php b/helpers/BaseMarkdown.php index b0c711733..df7e38c78 100644 --- a/helpers/BaseMarkdown.php +++ b/helpers/BaseMarkdown.php @@ -95,7 +95,7 @@ protected static function getParser($flavor) if ($flavor === null) { $flavor = static::$defaultFlavor; } - /* @var $parser \cebe\markdown\Markdown */ + /** @var \cebe\markdown\Markdown $parser */ if (!isset(static::$flavors[$flavor])) { throw new InvalidArgumentException("Markdown flavor '$flavor' is not defined.'"); } elseif (!is_object($config = static::$flavors[$flavor])) { diff --git a/log/Target.php b/log/Target.php index 1d9a22f23..8d5d2e365 100644 --- a/log/Target.php +++ b/log/Target.php @@ -344,7 +344,7 @@ public function getMessagePrefix($message) $request = Yii::$app->getRequest(); $ip = $request instanceof Request ? $request->getUserIP() : '-'; - /* @var $user \yii\web\User */ + /** @var \yii\web\User $user */ $user = Yii::$app->has('user', true) ? Yii::$app->get('user') : null; if ($user && ($identity = $user->getIdentity(false))) { $userID = $identity->getId(); @@ -352,7 +352,7 @@ public function getMessagePrefix($message) $userID = '-'; } - /* @var $session \yii\web\Session */ + /** @var \yii\web\Session $session */ $session = Yii::$app->has('session', true) ? Yii::$app->get('session') : null; $sessionID = $session && $session->getIsActive() ? $session->getId() : '-'; diff --git a/rbac/PhpManager.php b/rbac/PhpManager.php index 9411a7f93..03c828dab 100644 --- a/rbac/PhpManager.php +++ b/rbac/PhpManager.php @@ -134,7 +134,7 @@ protected function checkAccessRecursive($user, $itemName, $params, $assignments) return false; } - /* @var $item Item */ + /** @var Item $item */ $item = $this->items[$itemName]; Yii::debug($item instanceof Role ? "Checking role: $itemName" : "Checking permission : $itemName", __METHOD__); @@ -208,7 +208,7 @@ protected function detectLoop($parent, $child) return false; } foreach ($this->children[$child->name] as $grandchild) { - /* @var $grandchild Item */ + /** @var Item $grandchild */ if ($this->detectLoop($parent, $grandchild)) { return true; } @@ -320,7 +320,7 @@ public function getItems($type) $items = []; foreach ($this->items as $name => $item) { - /* @var $item Item */ + /** @var Item $item */ if ($item->type == $type) { $items[$name] = $item; } @@ -822,7 +822,7 @@ protected function saveItems() { $items = []; foreach ($this->items as $name => $item) { - /* @var $item Item */ + /** @var Item $item */ $items[$name] = array_filter( [ 'type' => $item->type, @@ -833,7 +833,7 @@ protected function saveItems() ); if (isset($this->children[$name])) { foreach ($this->children[$name] as $child) { - /* @var $child Item */ + /** @var Item $child */ $items[$name]['children'][] = $child->name; } } @@ -849,7 +849,7 @@ protected function saveAssignments() $assignmentData = []; foreach ($this->assignments as $userId => $assignments) { foreach ($assignments as $name => $assignment) { - /* @var $assignment Assignment */ + /** @var Assignment $assignment */ $assignmentData[$userId][] = $assignment->roleName; } } diff --git a/requirements/requirements.php b/requirements/requirements.php index 1bf372aee..2790d1fe9 100644 --- a/requirements/requirements.php +++ b/requirements/requirements.php @@ -3,11 +3,9 @@ * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license https://www.yiiframework.com/license/ - */ - -/* @var $this YiiRequirementChecker */ - -/** + * + * @var YiiRequirementChecker $this + * * These are the Yii core requirements for the [[YiiRequirementChecker]] instance. * These requirements are mandatory for any Yii application. */ diff --git a/requirements/views/console/index.php b/requirements/views/console/index.php index acf912698..eb6aae19c 100644 --- a/requirements/views/console/index.php +++ b/requirements/views/console/index.php @@ -3,12 +3,12 @@ * @link https://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license https://www.yiiframework.com/license/ + * + * @var YiiRequirementChecker $this + * @var array $summary + * @var array[] $requirements */ -/* @var $this YiiRequirementChecker */ -/* @var $summary array */ -/* @var $requirements array[] */ - echo "\nYii Application Requirement Checker\n\n"; echo "This script checks if your server configuration meets the requirements\n"; diff --git a/requirements/views/web/index.php b/requirements/views/web/index.php index 15b2233d5..4c672a76e 100644 --- a/requirements/views/web/index.php +++ b/requirements/views/web/index.php @@ -1,7 +1,9 @@ diff --git a/rest/Action.php b/rest/Action.php index 49cc4236f..3b6b2e2eb 100644 --- a/rest/Action.php +++ b/rest/Action.php @@ -84,7 +84,7 @@ public function findModel($id) return call_user_func($this->findModel, $id, $this); } - /* @var $modelClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $modelClass */ $modelClass = $this->modelClass; $keys = $modelClass::primaryKey(); if (count($keys) > 1) { diff --git a/rest/CreateAction.php b/rest/CreateAction.php index be6e3e355..0dab7044f 100644 --- a/rest/CreateAction.php +++ b/rest/CreateAction.php @@ -43,7 +43,7 @@ public function run() call_user_func($this->checkAccess, $this->id); } - /* @var $model \yii\db\ActiveRecord */ + /** @var \yii\db\ActiveRecord $model */ $model = new $this->modelClass([ 'scenario' => $this->scenario, ]); diff --git a/rest/IndexAction.php b/rest/IndexAction.php index ab3e53293..8b0891917 100644 --- a/rest/IndexAction.php +++ b/rest/IndexAction.php @@ -143,7 +143,7 @@ protected function prepareDataProvider() return call_user_func($this->prepareDataProvider, $this, $filter); } - /* @var $modelClass \yii\db\BaseActiveRecord */ + /** @var \yii\db\BaseActiveRecord $modelClass */ $modelClass = $this->modelClass; $query = $modelClass::find(); diff --git a/rest/UpdateAction.php b/rest/UpdateAction.php index c30714423..62cbf5e4b 100644 --- a/rest/UpdateAction.php +++ b/rest/UpdateAction.php @@ -36,7 +36,7 @@ class UpdateAction extends Action */ public function run($id) { - /* @var $model ActiveRecord */ + /** @var ActiveRecord $model */ $model = $this->findModel($id); if ($this->checkAccess) { diff --git a/rest/UrlRule.php b/rest/UrlRule.php index 8f32e32c4..1d595592c 100644 --- a/rest/UrlRule.php +++ b/rest/UrlRule.php @@ -227,7 +227,7 @@ public function parseRequest($manager, $request) foreach ($this->rules as $urlName => $rules) { if (strpos($pathInfo, $urlName) !== false) { foreach ($rules as $rule) { - /* @var $rule WebUrlRule */ + /** @var WebUrlRule $rule */ $result = $rule->parseRequest($manager, $request); if (YII_DEBUG) { Yii::debug([ @@ -254,7 +254,7 @@ public function createUrl($manager, $route, $params) $this->createStatus = WebUrlRule::CREATE_STATUS_SUCCESS; foreach ($this->controller as $urlName => $controller) { if (strpos($route, $controller) !== false) { - /* @var $rules UrlRuleInterface[] */ + /** @var UrlRuleInterface[] $rules */ $rules = $this->rules[$urlName]; $url = $this->iterateRules($rules, $manager, $route, $params); if ($url !== false) { diff --git a/test/ActiveFixture.php b/test/ActiveFixture.php index 61974c188..c4cb4b2c9 100644 --- a/test/ActiveFixture.php +++ b/test/ActiveFixture.php @@ -151,7 +151,7 @@ public function getTableSchema() $db = $this->db; $tableName = $this->tableName; if ($tableName === null) { - /* @var $modelClass \yii\db\ActiveRecord */ + /** @var \yii\db\ActiveRecord $modelClass */ $modelClass = $this->modelClass; $tableName = $modelClass::tableName(); } diff --git a/test/BaseActiveFixture.php b/test/BaseActiveFixture.php index f953f9180..0fb45dd48 100644 --- a/test/BaseActiveFixture.php +++ b/test/BaseActiveFixture.php @@ -58,7 +58,7 @@ public function getModel($name) throw new InvalidConfigException('The "modelClass" property must be set.'); } $row = $this->data[$name]; - /* @var $modelClass \yii\db\ActiveRecord */ + /** @var \yii\db\ActiveRecord $modelClass */ $modelClass = $this->modelClass; $keys = []; foreach ($modelClass::primaryKey() as $key) { diff --git a/test/FixtureTrait.php b/test/FixtureTrait.php index cd4bd1431..4be70470e 100644 --- a/test/FixtureTrait.php +++ b/test/FixtureTrait.php @@ -88,7 +88,6 @@ public function loadFixtures($fixtures = null) $fixtures = $this->getFixtures(); } - /* @var $fixture Fixture */ foreach ($fixtures as $fixture) { $fixture->beforeLoad(); } @@ -112,7 +111,6 @@ public function unloadFixtures($fixtures = null) $fixtures = $this->getFixtures(); } - /* @var $fixture Fixture */ foreach ($fixtures as $fixture) { $fixture->beforeUnload(); } diff --git a/validators/ExistValidator.php b/validators/ExistValidator.php index 738d938cb..c0f72f691 100644 --- a/validators/ExistValidator.php +++ b/validators/ExistValidator.php @@ -299,7 +299,7 @@ private function queryValueExists($query, $value) */ protected function createQuery($targetClass, $condition) { - /* @var $targetClass \yii\db\ActiveRecordInterface */ + /** @var \yii\db\ActiveRecordInterface $targetClass */ $query = $targetClass::find()->andWhere($condition); if ($this->filter instanceof \Closure) { call_user_func($this->filter, $query); diff --git a/validators/UniqueValidator.php b/validators/UniqueValidator.php index dadc8b4ed..e29cc7144 100644 --- a/validators/UniqueValidator.php +++ b/validators/UniqueValidator.php @@ -142,7 +142,7 @@ public function validateAttribute($model, $attribute) $conditions[] = [$key => $value]; } - /* @var $targetClass ActiveRecordInterface */ + /** @var ActiveRecordInterface $targetClass */ $targetClass = $this->getTargetClass($model); $db = $targetClass::getDb(); diff --git a/views/_addComments.php b/views/_addComments.php index fe5992139..e8956a677 100644 --- a/views/_addComments.php +++ b/views/_addComments.php @@ -1,7 +1,8 @@ $this->addCommentOnTable('', ''); diff --git a/views/_createTable.php b/views/_createTable.php index 076829914..6f241b8a0 100644 --- a/views/_createTable.php +++ b/views/_createTable.php @@ -2,10 +2,11 @@ /** * Creates a call for the method `yii\db\Migration::createTable()`. + * + * @var string $table the name table + * @var array $fields the fields + * @var array $foreignKeys the foreign keys */ -/* @var $table string the name table */ -/* @var $fields array the fields */ -/* @var $foreignKeys array the foreign keys */ ?> $this->createTable('', [ render('_dropForeignKeys', [ 'table' => $table, diff --git a/views/_foreignTables.php b/views/_foreignTables.php index 2baacda47..a884759c4 100644 --- a/views/_foreignTables.php +++ b/views/_foreignTables.php @@ -2,8 +2,9 @@ /** * Creates a call for the method `yii\db\Migration::createTable()`. + * + * @var array $foreignKeys the foreign keys */ -/* @var $foreignKeys array the foreign keys */ if (!empty($foreignKeys)):?> * Has foreign keys to the tables: diff --git a/views/addColumnMigration.php b/views/addColumnMigration.php index 9e84d2283..3973f30d3 100644 --- a/views/addColumnMigration.php +++ b/views/addColumnMigration.php @@ -4,13 +4,13 @@ * This view is used by console/controllers/MigrateController.php. * * The following variables are available in this view: + * + * @var string $className the new migration class name without namespace + * @var string $namespace the new migration class namespace + * @var string $table the name table + * @var array $fields the fields */ -/* @var $className string the new migration class name without namespace */ -/* @var $namespace string the new migration class namespace */ -/* @var $table string the name table */ -/* @var $fields array the fields */ - echo " diff --git a/views/errorHandler/error.php b/views/errorHandler/error.php index 630bbec03..3c3d46b09 100644 --- a/views/errorHandler/error.php +++ b/views/errorHandler/error.php @@ -1,6 +1,8 @@ statusCode; } else { diff --git a/views/errorHandler/exception.php b/views/errorHandler/exception.php index e22498984..995bd4d33 100644 --- a/views/errorHandler/exception.php +++ b/views/errorHandler/exception.php @@ -1,7 +1,9 @@ beginPage() ?> diff --git a/views/errorHandler/previousException.php b/views/errorHandler/previousException.php index a93f59f79..af7034359 100644 --- a/views/errorHandler/previousException.php +++ b/views/errorHandler/previousException.php @@ -1,6 +1,8 @@