From fb0062114e41de59a48736d27258c95c4db583af Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Thu, 4 Jun 2015 12:57:16 +0300 Subject: [PATCH 01/23] Method `yii\db\Schema::refreshTableSchema()` added --- framework/db/Schema.php | 17 +++++++++++++++++ tests/framework/db/SchemaTest.php | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/framework/db/Schema.php b/framework/db/Schema.php index c45a13b9c9..857c28a017 100644 --- a/framework/db/Schema.php +++ b/framework/db/Schema.php @@ -280,6 +280,23 @@ abstract class Schema extends Object $this->_tables = []; } + /** + * Refreshes the particular table schema. + * This method cleans up cached table schema so that it can be re-created later + * to reflect the database schema change. + * @param string $name table name. + */ + public function refreshTableSchema($name) + { + unset($this->_tables[$name]); + $this->_tableNames = []; + /* @var $cache Cache */ + $cache = is_string($this->db->schemaCache) ? Yii::$app->get($this->db->schemaCache, false) : $this->db->schemaCache; + if ($this->db->enableSchemaCache && $cache instanceof Cache) { + $cache->delete($this->getCacheKey($name)); + } + } + /** * Creates a query builder for the database. * This method may be overridden by child classes to create a DBMS-specific query builder. diff --git a/tests/framework/db/SchemaTest.php b/tests/framework/db/SchemaTest.php index 1277faade9..7d1df9f6c7 100644 --- a/tests/framework/db/SchemaTest.php +++ b/tests/framework/db/SchemaTest.php @@ -67,6 +67,23 @@ class SchemaTest extends DatabaseTestCase $this->assertEquals($noCacheTable, $cachedTable); } + /** + * @depends testSchemaCache + */ + public function testRefreshTableSchema() + { + /* @var $schema Schema */ + $schema = $this->getConnection()->schema; + + $schema->db->enableSchemaCache = true; + $schema->db->schemaCache = new FileCache(); + $noCacheTable = $schema->getTableSchema('type', true); + + $schema->refreshTableSchema('type'); + $refreshedTable = $schema->getTableSchema('type', false); + $this->assertFalse($noCacheTable === $refreshedTable); + } + public function testCompositeFk() { /* @var $schema Schema */ From 72f9e63e10844a9d343d3c8acd86f33efe94e1e6 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Thu, 4 Jun 2015 13:53:11 +0300 Subject: [PATCH 02/23] Table schema auto refreshing on DDL added to `yii\db\Command` --- framework/db/Command.php | 33 ++++++++++++++++++++++++++++++ tests/framework/db/CommandTest.php | 21 +++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/framework/db/Command.php b/framework/db/Command.php index 9197e7922d..c9c118d13b 100644 --- a/framework/db/Command.php +++ b/framework/db/Command.php @@ -93,6 +93,10 @@ class Command extends Component * @var string the SQL statement that this command represents */ private $_sql; + /** + * @var string name of the table, which schema, should be refreshed after command execution. + */ + private $_refreshTableName; /** @@ -537,6 +541,7 @@ class Command extends Component public function renameTable($table, $newName) { $sql = $this->db->getQueryBuilder()->renameTable($table, $newName); + $this->requireTableSchemaRefreshment($table); return $this->setSql($sql); } @@ -549,6 +554,7 @@ class Command extends Component public function dropTable($table) { $sql = $this->db->getQueryBuilder()->dropTable($table); + $this->requireTableSchemaRefreshment($table); return $this->setSql($sql); } @@ -577,6 +583,7 @@ class Command extends Component public function addColumn($table, $column, $type) { $sql = $this->db->getQueryBuilder()->addColumn($table, $column, $type); + $this->requireTableSchemaRefreshment($table); return $this->setSql($sql); } @@ -590,6 +597,7 @@ class Command extends Component public function dropColumn($table, $column) { $sql = $this->db->getQueryBuilder()->dropColumn($table, $column); + $this->requireTableSchemaRefreshment($table); return $this->setSql($sql); } @@ -604,6 +612,7 @@ class Command extends Component public function renameColumn($table, $oldName, $newName) { $sql = $this->db->getQueryBuilder()->renameColumn($table, $oldName, $newName); + $this->requireTableSchemaRefreshment($table); return $this->setSql($sql); } @@ -620,6 +629,7 @@ class Command extends Component public function alterColumn($table, $column, $type) { $sql = $this->db->getQueryBuilder()->alterColumn($table, $column, $type); + $this->requireTableSchemaRefreshment($table); return $this->setSql($sql); } @@ -635,6 +645,7 @@ class Command extends Component public function addPrimaryKey($name, $table, $columns) { $sql = $this->db->getQueryBuilder()->addPrimaryKey($name, $table, $columns); + $this->requireTableSchemaRefreshment($table); return $this->setSql($sql); } @@ -648,6 +659,7 @@ class Command extends Component public function dropPrimaryKey($name, $table) { $sql = $this->db->getQueryBuilder()->dropPrimaryKey($name, $table); + $this->requireTableSchemaRefreshment($table); return $this->setSql($sql); } @@ -776,6 +788,8 @@ class Command extends Component Yii::endProfile($token, __METHOD__); + $this->refreshTableSchema(); + return $n; } catch (\Exception $e) { Yii::endProfile($token, __METHOD__); @@ -850,4 +864,23 @@ class Command extends Component return $result; } + + /** + * Marks specified table schema to be refreshed after command execution. + * @param string $name name of the table, which schema should be refreshed. + */ + protected function requireTableSchemaRefreshment($name) + { + $this->_refreshTableName = $name; + } + + /** + * Refreshes table schema, which was marked by [[requireTableSchemaRefreshment()]] + */ + protected function refreshTableSchema() + { + if ($this->_refreshTableName !== null) { + $this->db->getSchema()->refreshTableSchema($this->_refreshTableName); + } + } } diff --git a/tests/framework/db/CommandTest.php b/tests/framework/db/CommandTest.php index 13f2e78009..bcd3270381 100644 --- a/tests/framework/db/CommandTest.php +++ b/tests/framework/db/CommandTest.php @@ -310,8 +310,6 @@ SQL; ], $record); } - - /* public function testUpdate() { @@ -509,4 +507,23 @@ SQL; $command = $db->createCommand($sql, $params); $this->assertEquals($expectedRawSql, $command->getRawSql()); } + + public function testAutoRefreshTableSchema() + { + $db = $this->getConnection(false); + $tableName = 'test'; + + $db->createCommand()->createTable($tableName, [ + 'id' => 'pk', + 'name' => 'string', + ])->execute(); + $initialSchema = $db->getSchema()->getTableSchema($tableName); + + $db->createCommand()->addColumn($tableName, 'value', 'integer')->execute(); + $newSchema = $db->getSchema()->getTableSchema($tableName); + $this->assertNotEquals($initialSchema, $newSchema); + + $db->createCommand()->dropTable($tableName)->execute(); + $this->assertNull($db->getSchema()->getTableSchema($tableName)); + } } From 6ea19e8f4533fe72d3abc44414ca147423f72793 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Thu, 4 Jun 2015 13:56:23 +0300 Subject: [PATCH 03/23] Schema refreshing added to `yii\db\Migration::execute()` --- framework/db/Migration.php | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/db/Migration.php b/framework/db/Migration.php index 7ec8abc5bb..7462a08e8d 100644 --- a/framework/db/Migration.php +++ b/framework/db/Migration.php @@ -162,6 +162,7 @@ class Migration extends Component implements MigrationInterface $time = microtime(true); $this->db->createCommand($sql)->bindValues($params)->execute(); echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; + $this->db->getSchema()->refresh(); // ensure possible schema changes applied } /** From 0bfa2e2673bb5250693785668e0ac0454f4ed01c Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Sat, 6 Jun 2015 12:58:36 +0300 Subject: [PATCH 04/23] Reset of `refreshTableName` on `yii\db\Command` reuse ensured --- framework/db/Command.php | 69 +++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/framework/db/Command.php b/framework/db/Command.php index c9c118d13b..d55f9da0f2 100644 --- a/framework/db/Command.php +++ b/framework/db/Command.php @@ -146,6 +146,7 @@ class Command extends Component $this->_sql = $this->db->quoteSql($sql); $this->_pendingParams = []; $this->params = []; + $this->_refreshTableName = null; } return $this; @@ -416,7 +417,7 @@ class Command extends Component * * @param string $table the table that new rows will be inserted into. * @param array $columns the column data (name => value) to be inserted into the table. - * @return Command the command object itself + * @return $this the command object itself */ public function insert($table, $columns) { @@ -447,7 +448,7 @@ class Command extends Component * @param string $table the table that new rows will be inserted into. * @param array $columns the column names * @param array $rows the rows to be batch inserted into the table - * @return Command the command object itself + * @return $this the command object itself */ public function batchInsert($table, $columns, $rows) { @@ -473,7 +474,7 @@ class Command extends Component * @param string|array $condition the condition that will be put in the WHERE part. Please * refer to [[Query::where()]] on how to specify condition. * @param array $params the parameters to be bound to the command - * @return Command the command object itself + * @return $this the command object itself */ public function update($table, $columns, $condition = '', $params = []) { @@ -498,7 +499,7 @@ class Command extends Component * @param string|array $condition the condition that will be put in the WHERE part. Please * refer to [[Query::where()]] on how to specify condition. * @param array $params the parameters to be bound to the command - * @return Command the command object itself + * @return $this the command object itself */ public function delete($table, $condition = '', $params = []) { @@ -523,7 +524,7 @@ class Command extends Component * @param string $table the name of the table to be created. The name will be properly quoted by the method. * @param array $columns the columns (name => definition) in the new table. * @param string $options additional SQL fragment that will be appended to the generated SQL. - * @return Command the command object itself + * @return $this the command object itself */ public function createTable($table, $columns, $options = null) { @@ -536,33 +537,31 @@ class Command extends Component * Creates a SQL command for renaming a DB table. * @param string $table the table to be renamed. The name will be properly quoted by the method. * @param string $newName the new table name. The name will be properly quoted by the method. - * @return Command the command object itself + * @return $this the command object itself */ public function renameTable($table, $newName) { $sql = $this->db->getQueryBuilder()->renameTable($table, $newName); - $this->requireTableSchemaRefreshment($table); - return $this->setSql($sql); + return $this->setSql($sql)->requireTableSchemaRefresh($table); } /** * Creates a SQL command for dropping a DB table. * @param string $table the table to be dropped. The name will be properly quoted by the method. - * @return Command the command object itself + * @return $this the command object itself */ public function dropTable($table) { $sql = $this->db->getQueryBuilder()->dropTable($table); - $this->requireTableSchemaRefreshment($table); - return $this->setSql($sql); + return $this->setSql($sql)->requireTableSchemaRefresh($table); } /** * Creates a SQL command for truncating a DB table. * @param string $table the table to be truncated. The name will be properly quoted by the method. - * @return Command the command object itself + * @return $this the command object itself */ public function truncateTable($table) { @@ -578,28 +577,26 @@ class Command extends Component * @param string $type the column type. [[\yii\db\QueryBuilder::getColumnType()]] will be called * to convert the give column type to the physical one. For example, `string` will be converted * as `varchar(255)`, and `string not null` becomes `varchar(255) not null`. - * @return Command the command object itself + * @return $this the command object itself */ public function addColumn($table, $column, $type) { $sql = $this->db->getQueryBuilder()->addColumn($table, $column, $type); - $this->requireTableSchemaRefreshment($table); - return $this->setSql($sql); + return $this->setSql($sql)->requireTableSchemaRefresh($table); } /** * Creates a SQL command for dropping a DB column. * @param string $table the table whose column is to be dropped. The name will be properly quoted by the method. * @param string $column the name of the column to be dropped. The name will be properly quoted by the method. - * @return Command the command object itself + * @return $this the command object itself */ public function dropColumn($table, $column) { $sql = $this->db->getQueryBuilder()->dropColumn($table, $column); - $this->requireTableSchemaRefreshment($table); - return $this->setSql($sql); + return $this->setSql($sql)->requireTableSchemaRefresh($table); } /** @@ -607,14 +604,13 @@ class Command extends Component * @param string $table the table whose column is to be renamed. The name will be properly quoted by the method. * @param string $oldName the old name of the column. The name will be properly quoted by the method. * @param string $newName the new name of the column. The name will be properly quoted by the method. - * @return Command the command object itself + * @return $this the command object itself */ public function renameColumn($table, $oldName, $newName) { $sql = $this->db->getQueryBuilder()->renameColumn($table, $oldName, $newName); - $this->requireTableSchemaRefreshment($table); - return $this->setSql($sql); + return $this->setSql($sql)->requireTableSchemaRefresh($table); } /** @@ -624,14 +620,13 @@ class Command extends Component * @param string $type the column type. [[\yii\db\QueryBuilder::getColumnType()]] will be called * to convert the give column type to the physical one. For example, `string` will be converted * as `varchar(255)`, and `string not null` becomes `varchar(255) not null`. - * @return Command the command object itself + * @return $this the command object itself */ public function alterColumn($table, $column, $type) { $sql = $this->db->getQueryBuilder()->alterColumn($table, $column, $type); - $this->requireTableSchemaRefreshment($table); - return $this->setSql($sql); + return $this->setSql($sql)->requireTableSchemaRefresh($table); } /** @@ -640,28 +635,26 @@ class Command extends Component * @param string $name the name of the primary key constraint. * @param string $table the table that the primary key constraint will be added to. * @param string|array $columns comma separated string or array of columns that the primary key will consist of. - * @return Command the command object itself. + * @return $this the command object itself. */ public function addPrimaryKey($name, $table, $columns) { $sql = $this->db->getQueryBuilder()->addPrimaryKey($name, $table, $columns); - $this->requireTableSchemaRefreshment($table); - return $this->setSql($sql); + return $this->setSql($sql)->requireTableSchemaRefresh($table); } /** * Creates a SQL command for removing a primary key constraint to an existing table. * @param string $name the name of the primary key constraint to be removed. * @param string $table the table that the primary key constraint will be removed from. - * @return Command the command object itself + * @return $this the command object itself */ public function dropPrimaryKey($name, $table) { $sql = $this->db->getQueryBuilder()->dropPrimaryKey($name, $table); - $this->requireTableSchemaRefreshment($table); - return $this->setSql($sql); + return $this->setSql($sql)->requireTableSchemaRefresh($table); } /** @@ -674,7 +667,7 @@ class Command extends Component * @param string|array $refColumns the name of the column that the foreign key references to. If there are multiple columns, separate them with commas. * @param string $delete the ON DELETE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL * @param string $update the ON UPDATE option. Most DBMS support these options: RESTRICT, CASCADE, NO ACTION, SET DEFAULT, SET NULL - * @return Command the command object itself + * @return $this the command object itself */ public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null) { @@ -687,7 +680,7 @@ class Command extends Component * Creates a SQL command for dropping a foreign key constraint. * @param string $name the name of the foreign key constraint to be dropped. The name will be properly quoted by the method. * @param string $table the table whose foreign is to be dropped. The name will be properly quoted by the method. - * @return Command the command object itself + * @return $this the command object itself */ public function dropForeignKey($name, $table) { @@ -703,7 +696,7 @@ class Command extends Component * @param string|array $columns the column(s) that should be included in the index. If there are multiple columns, please separate them * by commas. The column names will be properly quoted by the method. * @param boolean $unique whether to add UNIQUE constraint on the created index. - * @return Command the command object itself + * @return $this the command object itself */ public function createIndex($name, $table, $columns, $unique = false) { @@ -716,7 +709,7 @@ class Command extends Component * Creates a SQL command for dropping an index. * @param string $name the name of the index to be dropped. The name will be properly quoted by the method. * @param string $table the table whose index is to be dropped. The name will be properly quoted by the method. - * @return Command the command object itself + * @return $this the command object itself */ public function dropIndex($name, $table) { @@ -732,7 +725,7 @@ class Command extends Component * @param string $table 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 Command the command object itself + * @return $this the command object itself * @throws NotSupportedException if this is not supported by the underlying DBMS */ public function resetSequence($table, $value = null) @@ -748,7 +741,7 @@ class Command extends Component * @param string $schema the schema name of the tables. Defaults to empty string, meaning the current * or default schema. * @param string $table the table name. - * @return Command the command object itself + * @return $this the command object itself * @throws NotSupportedException if this is not supported by the underlying DBMS */ public function checkIntegrity($check = true, $schema = '', $table = '') @@ -868,10 +861,12 @@ class Command extends Component /** * Marks specified table schema to be refreshed after command execution. * @param string $name name of the table, which schema should be refreshed. + * @return $this this command instance */ - protected function requireTableSchemaRefreshment($name) + protected function requireTableSchemaRefresh($name) { $this->_refreshTableName = $name; + return $this; } /** From 8e4518c81f5f0d0d7f16ebbc2d86e712ae830319 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Sat, 6 Jun 2015 13:05:43 +0300 Subject: [PATCH 05/23] Doc comments updated --- framework/CHANGELOG.md | 1 + framework/db/Command.php | 2 ++ framework/db/Schema.php | 1 + 3 files changed, 4 insertions(+) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 3f49f76323..967368133a 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -18,6 +18,7 @@ Yii Framework 2 Change Log - Bug #8593: Fixed `yii\db\ActiveQuery` produces incorrect SQL for aggregations, when `sql` field is set (klimov-paul) - Bug #8595: Fixed `yii\rbac\DbManager::checkAccessFromCache()` to check against auth items loaded in cache recursively (achretien, qiangxue) - Bug #8606: Fixed `yii\web\Response::xSendFile()` does not reset format (vyants) +- Bug #8627: Fixed `yii\db\Migration` produces incorrect results due to table schema caching (klimov-paul) - Bug: Fixed string comparison in `BaseActiveRecord::unlink()` which may result in wrong comparison result for hash valued primary keys starting with `0e` (cebe) - Bug: Pass correct action name to `yii\console\Controller::options()` when default action was requested (cebe) - Bug: Automatic garbage collection in `yii\caching\FileCache` was not triggered (kidol) diff --git a/framework/db/Command.php b/framework/db/Command.php index d55f9da0f2..4e3f6c271f 100644 --- a/framework/db/Command.php +++ b/framework/db/Command.php @@ -862,6 +862,7 @@ class Command extends Component * Marks specified table schema to be refreshed after command execution. * @param string $name name of the table, which schema should be refreshed. * @return $this this command instance + * @since 2.0.5 */ protected function requireTableSchemaRefresh($name) { @@ -871,6 +872,7 @@ class Command extends Component /** * Refreshes table schema, which was marked by [[requireTableSchemaRefreshment()]] + * @since 2.0.5 */ protected function refreshTableSchema() { diff --git a/framework/db/Schema.php b/framework/db/Schema.php index 857c28a017..4e87ee5ab4 100644 --- a/framework/db/Schema.php +++ b/framework/db/Schema.php @@ -285,6 +285,7 @@ abstract class Schema extends Object * This method cleans up cached table schema so that it can be re-created later * to reflect the database schema change. * @param string $name table name. + * @since 2.0.5 */ public function refreshTableSchema($name) { From e683e3e79d979f1fce20d55223c3d14ae26a9c0f Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Mon, 8 Jun 2015 11:32:09 +0300 Subject: [PATCH 06/23] Schema refresh moved to `Migration::init()`. --- framework/db/Migration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/db/Migration.php b/framework/db/Migration.php index 7462a08e8d..b43f5c5635 100644 --- a/framework/db/Migration.php +++ b/framework/db/Migration.php @@ -66,6 +66,7 @@ class Migration extends Component implements MigrationInterface { parent::init(); $this->db = Instance::ensure($this->db, Connection::className()); + $this->db->getSchema()->refresh(); } /** @@ -162,7 +163,6 @@ class Migration extends Component implements MigrationInterface $time = microtime(true); $this->db->createCommand($sql)->bindValues($params)->execute(); echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; - $this->db->getSchema()->refresh(); // ensure possible schema changes applied } /** From 244f2ea856fed24f69a65d383cd910f48c751b6c Mon Sep 17 00:00:00 2001 From: Davidson Alencar Date: Mon, 8 Jun 2015 09:16:26 -0300 Subject: [PATCH 07/23] docs/guide-pt-BR/output-data-providers.md - translate [ci skip] --- docs/guide-pt-BR/output-data-providers.md | 299 ++++++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 docs/guide-pt-BR/output-data-providers.md diff --git a/docs/guide-pt-BR/output-data-providers.md b/docs/guide-pt-BR/output-data-providers.md new file mode 100644 index 0000000000..be4fc2cad9 --- /dev/null +++ b/docs/guide-pt-BR/output-data-providers.md @@ -0,0 +1,299 @@ +Data Providers (Provedores de Dados) +============== + +Nas seções [Paginação](output-pagination.md) e [ordenação](output-sorting.md), descrevemos como os usuários finais podem escolher uma determinada página de dados para exibir e ordená-los por algumas colunas. Uma vez que esta tarefa de paginação e ordenação de dados é muito comum, Yii fornece um conjunto de classes *data provider* para encapsular estes recursos. + +Um data provider é uma classe que implementa +[[yii\data\DataProviderInterface]]. Ele suporta principalmente a recuperação de dados paginados e ordenados. Geralmente é usado para trabalhar com [widgets de dados](output-data-widgets.md) de modo que os usuários finais possam interativamente paginar e ordenar dados. + +O Yii fornece as seguintes classes de data provider: + +* [[yii\data\ActiveDataProvider]]: Utilize [[yii\db\Query]] ou [[yii\db\ActiveQuery]] para consultar dados de um database e retorná-los na forma de array ou uma instância de [Active Record](db-active-record.md). +* [[yii\data\SqlDataProvider]]: executa uma instrução SQL e retorna os dados do banco de dados como array. +* [[yii\data\ArrayDataProvider]]: é preciso um grande array e retorna uma parte deste baseado na paginação e ordenação especificada. + +O uso de todos estes data providers compartilham o seguinte padrão comum: + +```php +// cria o data provider configurando suas propriedades de paginação e ordenação +$provider = new XyzDataProvider([ + 'pagination' => [...], + 'sort' => [...], +]); + +// recupera dados paginados e ordenados +$models = $provider->getModels(); + +// obtem o número de itens de dados na página atual +$count = $provider->getCount(); + +// obtem o número total de itens de dados de todas as páginas +$totalCount = $provider->getTotalCount(); +``` + +Você define o comportamento da paginação e ordenação do data provider configurando suas propriedades [[yii\data\BaseDataProvider::pagination|pagination]] e [[yii\data\BaseDataProvider::sort|sort]] que correspondem às configurações [[yii\data\Pagination]] and [[yii\data\Sort]] respectivamente. Você também pode configurá-los como false para desativar os recursos de paginação e/ou ordenação. + +[widgets de dados](output-data-widgets.md), assim como [[yii\grid\GridView]], tem uma propriedade chamada `dataProvider` que pode receber uma instância de data provider e exibir os dados que ele fornece. Por exemplo, + +```php +echo yii\grid\GridView::widget([ + 'dataProvider' => $dataProvider, +]); +``` + +Estes data providers variam principalmente conforme a fonte de dados é especificada. Nas subseções seguintes, vamos explicar o uso detalhado de cada um dos data providers. + +## Active Data Provider (Provedor de Dados) + +Para usar [[yii\data\ActiveDataProvider]], você deve configurar sua propriedade [[yii\data\ActiveDataProvider::query|query]]. +Ele pode receber qualquer um dos objetos [[yii\db\Query]] ou [[yii\db\ActiveQuery]]. Se for o primeiro, os dados serão retornados em array; se for o último, os dados podem ser retornados em array ou uma instância de [Active Record](db-active-record.md). +Por Exemplo, + +```php +use yii\data\ActiveDataProvider; + +$query = Post::find()->where(['status' => 1]); + +$provider = new ActiveDataProvider([ + 'query' => $query, + 'pagination' => [ + 'pageSize' => 10, + ], + 'sort' => [ + 'defaultOrder' => [ + 'created_at' => SORT_DESC, + 'title' => SORT_ASC, + ] + ], +]); + +// retorna um array de objetos Post +$posts = $provider->getModels(); +``` + +Se `$query` no exemplo acima fosse criada usando o código a seguir, então o data provider retornaria um array. + +```php +use yii\db\Query; + +$query = (new Query())->from('post')->where(['status' => 1]); +``` + +> Observação: Se uma query já especificou a cláusula `orderBy, as novas instruções de ordenação dadas por usuários finais + (através da configuração `sort`) será acrescentada a cláusula `orderBy` existente. Existindo qualquer uma das cláusulas `limit` e `offset` será substituído pelo request de paginação dos usuários finais (através da configuração `pagination`). + +Por padrão, [[yii\data\ActiveDataProvider]] utiliza o componente `db` da aplicação como a conexão de banco de dados. Você pode usar uma conexão de banco de dados diferente, configurando a propriedade [[yii\data\ActiveDataProvider::db]]. + +## SQL Data Provider + +[[yii\data\SqlDataProvider]] trabalha com uma instrução SQL, que é usado para obter os dados necessários. Com base nas especificações de [[yii\data\SqlDataProvider::sort|sort]] e +[[yii\data\SqlDataProvider::pagination|pagination]], o provider ajustará as cláusulas `ORDER BY` e `LIMIT` da instrução SQL em conformidade para buscar somente a página de dados solicitada na ordem desejada. + +Para usar [[yii\data\SqlDataProvider]], você deve especificar a propriedade [[yii\data\SqlDataProvider::sql|sql]] bem como a propriedade [[yii\data\SqlDataProvider::totalCount|totalCount]. Por exemplo, + +```php +use yii\data\SqlDataProvider; + +$count = Yii::$app->db->createCommand(' + SELECT COUNT(*) FROM post WHERE status=:status +', [':status' => 1])->queryScalar(); + +$provider = new SqlDataProvider([ + 'sql' => 'SELECT * FROM post WHERE status=:status', + 'params' => [':status' => 1], + 'totalCount' => $count, + 'pagination' => [ + 'pageSize' => 10, + ], + 'sort' => [ + 'attributes' => [ + 'title', + 'view_count', + 'created_at', + ], + ], +]); + +// retorna um array de linha de dados +$models = $provider->getModels(); +``` + +> Observação: A propriedade [[yii\data\SqlDataProvider::totalCount|totalCount]] é requerida somente se você precisar paginar os dados. Isto porque a instrução SQL definida por [[yii\data\SqlDataProvider::sql|sql]] será modificada pelo provider para retornar somente a página atual de dados solicitada. O provider ainda precisa saber o número total de dados a fim de calcular correctamente o número de páginas disponíveis. + +## Array Data Provider + +[[yii\data\ArrayDataProvider]] é melhor usado quando se trabalha com um grande array. O provider permite-lhe retornar uma página dos dados do array ordenados por uma ou várias colunas. Para usar [[yii\data\ArrayDataProvider]], você precisa especificar a propriedade [[yii\data\ArrayDataProvider::allModels|allModels]] como um grande array. Elementos deste array podem ser outros arrays associados +(por exemplo, resultados de uma query do [DAO](db-dao.md)) ou objetos (por exemplo uma isntância do [Active Record](db-active-record.md)). +Por exemplo, + +```php +use yii\data\ArrayDataProvider; + +$data = [ + ['id' => 1, 'name' => 'name 1', ...], + ['id' => 2, 'name' => 'name 2', ...], + ... + ['id' => 100, 'name' => 'name 100', ...], +]; + +$provider = new ArrayDataProvider([ + 'allModels' => $data, + 'pagination' => [ + 'pageSize' => 10, + ], + 'sort' => [ + 'attributes' => ['id', 'name'], + ], +]); + +// obter as linhas na página corrente +$rows = $provider->getModels(); +``` + +> Observação: Comparado [Active Data Provider](#active-data-provider) com [SQL Data Provider](#sql-data-provider), + array data provider é menos eficiante porque requer o carregamento de *todo* o dado na memória. + +## Trabalhando com chave de dados + +Ao usar os itens de dados retornados por um data provider, muitas vezes você precisa identificar cada item de dados com uma chave única. +Por exemplo, se os itens de dados representam as informações do cliente, você pode querer usar o ID do cliente como a chave +para cada dado do cliente. Data providers podem retornar uma lista das tais chaves correspondentes aos itens de dados retornados por [[yii\data\DataProviderInterface::getModels()]]. Por exemplo, + +```php +use yii\data\ActiveDataProvider; + +$query = Post::find()->where(['status' => 1]); + +$provider = new ActiveDataProvider([ + 'query' => Post::find(), +]); + +// retorna uma array de objetos Post +$posts = $provider->getModels(); + +// retorna os valores de chave primária correspondente a $posts +$ids = $provider->getKeys(); +``` + +No exemplo abaixo, como você fornecer para [[yii\data\ActiveDataProvider]] um objeto [[yii\db\ActiveQuery]], +ele é inteligente o suficiente para retornar os valores de chave primária como chaves no resultado. Você também pode especificar explicitamente como os valores de chave devem ser calculados configurando +[[yii\data\ActiveDataProvider::key]] com um nome de coluna ou com uma função calback que retorna os valores das chaves. Por exemplo, + +```php +// use "slug" column as key values +$provider = new ActiveDataProvider([ + 'query' => Post::find(), + 'key' => 'slug', +]); + +// usa o resultados do md5(id) como valor da chave +$provider = new ActiveDataProvider([ + 'query' => Post::find(), + 'key' => function ($model) { + return md5($model->id); + } +]); +``` + +## Criado Data Provider customizado + +Para criar sau prórpia classe de data provider customizada, você deve implementar [[yii\data\DataProviderInterface]]. +Um caminho fácil é extender de [[yii\data\BaseDataProvider]] o que permite a você se concentrar na lógica principal do data provider. Em particular, você precisa principalmente implementar os seguintes métodos: + +- [[yii\data\BaseDataProvider::prepareModels()|prepareModels()]]: prepara o data models que será disponibilizado na página atual e as retorna como um array. +- [[yii\data\BaseDataProvider::prepareKeys()|prepareKeys()]]:recebe um array de data models disponíveis e retorna chaves que lhes estão associados. +- [[yii\data\BaseDataProvider::prepareTotalCount()|prepareTotalCount]]: retorna um valor que indica o número total de data models no data provider. + +Abaixo está um exemplo de um data provider que lê dados em CSV eficientemente: + +```php +fileObject = new SplFileObject($this->filename); + } + /** + * @inheritdoc + */ + protected function prepareModels() + { + $models = []; + $pagination = $this->getPagination(); + if ($pagination === false) { + // no caso não há paginação, lê todas as linhas + while (!$this->fileObject->eof()) { + $models[] = $this->fileObject->fgetcsv(); + $this->fileObject->next(); + } + } else { + // no caso existe paginação, lê somente uma página + $pagination->totalCount = $this->getTotalCount(); + $this->fileObject->seek($pagination->getOffset()); + $limit = $pagination->getLimit(); + for ($count = 0; $count < $limit; ++$count) { + $models[] = $this->fileObject->fgetcsv(); + $this->fileObject->next(); + } + } + return $models; + } + /** + * @inheritdoc + */ + protected function prepareKeys($models) + { + if ($this->key !== null) { + $keys = []; + foreach ($models as $model) { + if (is_string($this->key)) { + $keys[] = $model[$this->key]; + } else { + $keys[] = call_user_func($this->key, $model); + } + } + return $keys; + } else { + return array_keys($models); + } + } + /** + * @inheritdoc + */ + protected function prepareTotalCount() + { + $count = 0; + while (!$this->fileObject->eof()) { + $this->fileObject->next(); + ++$count; + } + return $count; + } +} +``` + + From ef54f30a3351597d9cc106e5bf55ec86c723ceb2 Mon Sep 17 00:00:00 2001 From: Davidson Alencar Date: Mon, 8 Jun 2015 09:37:07 -0300 Subject: [PATCH 08/23] docs/guide-pt-BR/output-theming.md - translate [ci skip] --- docs/guide-pt-BR/output-theming.md | 95 ++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 docs/guide-pt-BR/output-theming.md diff --git a/docs/guide-pt-BR/output-theming.md b/docs/guide-pt-BR/output-theming.md new file mode 100644 index 0000000000..8fcba68c44 --- /dev/null +++ b/docs/guide-pt-BR/output-theming.md @@ -0,0 +1,95 @@ +Temas +===== + +Tema é uma forma de substituir um conjunto de [views](structure-views.md) por outras, sem a necessidade de tocar no código de renderização de view original. Você pode usar tema para alterar sistematicamente a aparência de uma aplicação. + +Para usar tema, você deve configurar a propriedade [[yii\base\View::theme|theme]] da `view (visão)` da aplicação. +A propriedade configura um objeto [[yii\base\Theme]] que rege a forma como os arquivos de views são substituídos. Você deve principalmente especificar as seguintes propriedades de [[yii\base\Theme]]: + +- [[yii\base\Theme::basePath]]: determina o diretório de base que contém os recursos temáticos (CSS, JS, images, etc.) +- [[yii\base\Theme::baseUrl]]: determina a URL base dos recursos temáticos. +- [[yii\base\Theme::pathMap]]: determina as regras de substituição dos arquivos de view. Mais detalhes serão dados nas subseções seguintes. + +Por exemplo, se você chama `$this->render('about')` no `SiteController`, você estará renderizando a view +`@app/views/site/about.php`. Todavia, se você habilitar tema na seguinte configuração da aplicação, a view `@app/themes/basic/site/about.php` será renderizada, no lugar da primeira. + +```php +return [ + 'components' => [ + 'view' => [ + 'theme' => [ + 'basePath' => '@app/themes/basic' + 'baseUrl' => '@web/themes/basic', + 'pathMap' => [ + '@app/views' => '@app/themes/basic', + ], + ], + ], + ], +]; +``` + +> Observação: aliases de caminhos são suportados por temas. Ao fazer substituição de view, aliases de caminho serão transformados nos caminhos ou URLs reais. + +Você pode acessar o objeto [[yii\base\Theme]] através da propriedade [[yii\base\View::theme]]. Por exemplo, na view, você pode escrever o seguinte código, pois `$this` refere-se ao objeto view: + +```php +$theme = $this->theme; + +// retorno: $theme->baseUrl . '/img/logo.gif' +$url = $theme->getUrl('img/logo.gif'); + +// retorno: $theme->basePath . '/img/logo.gif' +$file = $theme->getPath('img/logo.gif'); +``` + +A propriedade [[yii\base\Theme::pathMap]] rege como a view deve ser substituída. É preciso um array de pares de valores-chave, onde as chaves são os caminhos originais da view que serão substituídos e os valores são os caminhos dos temas correspondentes. A substituição é baseada na correspondência parcial: Se um caminho de view inicia com alguma chave no array [[yii\base\Theme::pathMap|pathMap]], a parte correspondente será substituída pelo valor do array. +Usando o exemplo de configuração acima, +`@app/views/site/about.php` corresponde parcialmente a chave +`@app/views`, ele será substituído por `@app/themes/basic/site/about.php`. + + +## Tema de Módulos + +A fim de configurar temas por módulos, [[yii\base\Theme::pathMap]] pode ser configurado da seguinte forma: + +```php +'pathMap' => [ + '@app/views' => '@app/themes/basic', + '@app/modules' => '@app/themes/basic/modules', // <-- !!! +], +``` + +Isto lhe permitirá tematizar `@app/modules/blog/views/comment/index.php` com `@app/themes/basic/modules/blog/views/comment/index.php`. + + +## Tema de Widgets + +A fim de configurar temas por widgets, você pode configurar [[yii\base\Theme::pathMap]] da seguinte forma: + +```php +'pathMap' => [ + '@app/views' => '@app/themes/basic', + '@app/widgets' => '@app/themes/basic/widgets', // <-- !!! +], +``` + +Isto lhe permitirá tematizar `@app/widgets/currency/views/index.php` com `@app/themes/basic/widgets/currency/index.php`. + + +## Herança de Tema + +Algumas vezes você pode querer definir um tema que contém um visual básico da aplicação, e em seguida, com base em algum feriado, você pode querer variar o visual levemente. Você pode atingir este objetivo usando herança de tema que é feito através do mapeamento de um único caminho de view para múltiplos alvos. Por exemplo, + +```php +'pathMap' => [ + '@app/views' => [ + '@app/themes/christmas', + '@app/themes/basic', + ], +] +``` + +Neste caso, a view `@app/views/site/index.php` seria tematizada tanto como `@app/themes/christmas/site/index.php` ou +`@app/themes/basic/site/index.php`, dependendo de qual arquivo de tema existir. Se os dois arquivos existirem, o primeiro terá precedência. Na prática, você iria manter mais arquivos de temas em `@app/themes/basic` e personalizar alguns deles em `@app/themes/christmas`. + From b0478d95562f55b6bff783208b6a403e8a38baf0 Mon Sep 17 00:00:00 2001 From: Davidson Alencar Date: Mon, 8 Jun 2015 09:39:15 -0300 Subject: [PATCH 09/23] docs/guide-pt-BR/security-authentication.md - translate [ci skip] --- docs/guide-pt-BR/security-authentication.md | 185 ++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 docs/guide-pt-BR/security-authentication.md diff --git a/docs/guide-pt-BR/security-authentication.md b/docs/guide-pt-BR/security-authentication.md new file mode 100644 index 0000000000..3036acc637 --- /dev/null +++ b/docs/guide-pt-BR/security-authentication.md @@ -0,0 +1,185 @@ +Autenticação +============== + +Autenticação é o processo de verificação da identidade do usuário. geralmente é usado um identificador (ex. um nome de usuário ou endereço de e-mail) e um token secreto (ex. uma senha ou um token de acesso) para determinar se o usuário é quem ele diz ser. Autenticação é a base do recurso de login. + +Yii fornece um framework de autenticação com vários componentes que dão suporte a login. Para usar este framework, você precisa primeiramente fazer o seguinte: + +* Configurar o componente [[yii\web\User|user]] da aplicação; +* Criar uma classe que implementa a interface [[yii\web\IdentityInterface]]. + + +## Configurando [[yii\web\User]] + +O componente [[yii\web\User|user]] da aplicação gerencia o status de autenticação dos usuários. Ele requer que você especifique uma [[yii\web\User::identityClass|identity class]] que contém a atual lógia de autenticação. +Na cofiguração abaixo, o [[yii\web\User::identityClass|identity class]] do +[[yii\web\User|user]] é configurada para ser `app\models\User` cuja implementação é explicada na próxima subseção: + +```php +return [ + 'components' => [ + 'user' => [ + 'identityClass' => 'app\models\User', + ], + ], +]; +``` + + +## Implementação [[yii\web\IdentityInterface]] + +O [[yii\web\User::identityClass|identity class]] deve implementar a interface [[yii\web\IdentityInterface]] que contém os seguintes métodos: + +* [[yii\web\IdentityInterface::findIdentity()|findIdentity()]]: ele procura por uma instância da classe de identidade usando o ID de usuário especificado. Este método é usado quando você precisa manter o status de login via sessão. +* [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]]: ele procura por uma instância da classe de identidade usando o token de acesso informado. Este método é usado quando você precisa autenticar um usuário por um único token secreto (ex. Em uma aplicação stateless RESTful). +* [[yii\web\IdentityInterface::getId()|getId()]]: Retorna o ID do usuário representado por essa instância da classe de identidade. +* [[yii\web\IdentityInterface::getAuthKey()|getAuthKey()]]: retorna uma chave para verificar login via cookie. A chave é mantida no cookie de login e será comparada com o informação do lado servidor para atestar a validade do cookie. +* [[yii\web\IdentityInterface::validateAuthKey()|validateAuthKey()]]: Implementa a lógica de verificação da chave de login via cookie. + +Se um método em particular não for necessário, você pode implementá-lo com um corpo vazio. Por exemplo, se a sua aplicação é somente stateless RESTful, você só precisa implementar [[yii\web\IdentityInterface::findIdentityByAccessToken()|findIdentityByAccessToken()]] +e [[yii\web\IdentityInterface::getId()|getId()]] deixando todos os outros métodos com um corpo vazio. + +No exemplo a seguir, um [[yii\web\User::identityClass|identity class]] é implementado como uma classe [Active Record](db-active-record.md) associada com a tabela `user` do banco de dados. + +```php + $token]); + } + + /** + * @return int|string current user ID + */ + public function getId() + { + return $this->id; + } + + /** + * @return string current user auth key + */ + public function getAuthKey() + { + return $this->auth_key; + } + + /** + * @param string $authKey + * @return boolean if auth key is valid for current user + */ + public function validateAuthKey($authKey) + { + return $this->getAuthKey() === $authKey; + } +} +``` + +Como explicado anteriormente, você só precisa implementar `getAuthKey()` e `validateAuthKey()` se a sua aplicação usa recurso de login via cookie. Neste caso, você pode utilizar o seguinte código para gerar uma chave de autenticação para cada usuário +e gravá-la na tabela `user`: + +```php +class User extends ActiveRecord implements IdentityInterface +{ + ...... + + public function beforeSave($insert) + { + if (parent::beforeSave($insert)) { + if ($this->isNewRecord) { + $this->auth_key = \Yii::$app->security->generateRandomString(); + } + return true; + } + return false; + } +} +``` + +> Observação: Não confunda a classe de identidade `User` com [[yii\web\User]]. O primeiro é a classe que implementa a lógica de autenticação. Muitas vezes, é implementado como uma classe [Active Record](db-active-record.md) associado com algum tipo de armazenamento persistente para armazenar as informações de credenciais do usuário. O último é um componente da apicação responsável pela gestão do estado de autenticação do usuário. + + +## Usando [[yii\web\User]] + +Você usa o [[yii\web\User]] principalmente como um componente `user` da aplicação. + +É possível detectar a identidade do usuário corrente utilizando a expressão `Yii::$app->user->identity`. retorna uma instância de [[yii\web\User::identityClass|identity class]] representando o atual usuário logado, ou null se o usuário corrente não estiver autenticado (acessando como convidado). O código a seguir mostra como recuperar outras informações relacionadas à autenticação de [[yii\web\User]]: + +```php +// identidade do usuário corrente. Null se o usuário não estiver autenticado. +$identity = Yii::$app->user->identity; + +// o ID do usuário corrente. Null se o usuário não estiver autenticado. +$id = Yii::$app->user->id; + +// se o usuário atual é um convidado (não autenticado) +$isGuest = Yii::$app->user->isGuest; +``` + +Para logar um usuário, você pode usar o seguinte código: + +```php +// encontrar uma identidade de usuário com o nome de usuário especificado. +// note que você pode quere checar a senha se necessário +$identity = User::findOne(['username' => $username]); + +// Logar o usuário +Yii::$app->user->login($identity); +``` + +O método [[yii\web\User::login()]] define a identidade do usuário atual para o [[yii\web\User]]. Se a sessão está [[yii\web\User::enableSession|enabled]], ele vai manter a identidade na sessão para que o status de autenticação do usuário seja mantido durante toda a sessão. Se for login via cookie(ex. login "remember me") for [[yii\web\User::enableAutoLogin|enabled]], ele também guardará a identidade em um cookie para que o estado de autenticação do usuário possa ser recuperado a partir do cookie enquanto o cookie permanece válido. + +A fim de permitir login via cookie, você pode configurar [[yii\web\User::enableAutoLogin]] como true na configuração da aplicação. Você também precisará fornecer um parâmetro de tempo de duração quando chamar o método [[yii\web\User::login()]]. + +Para realizar o logout de um usuário, simplesmente chame + +```php +Yii::$app->user->logout(); +``` + +Note que o logout de um usuário só tem sentido quando a sessão está habilitada. O método irá limpar o status de autenticação de usuário de memória e sessão. E por padrão, ele também destruirá *todos* os dados da sessão do usuário. Se você quiser guardar os dados da sessão, você deve chamar `Yii::$app->user->logout(false)`. + + +## Eventos de Autenticação + +A classe [[yii\web\User]] dispara alguns eventos durante os processos de login e logout. + +* [[yii\web\User::EVENT_BEFORE_LOGIN|EVENT_BEFORE_LOGIN]]: disparado no início de [[yii\web\User::login()]]. + Se o manipulador de evento define a propriedade [[yii\web\UserEvent::isValid|isValid]] do objeto de evento para false, o processo de login será cancelado. +* [[yii\web\User::EVENT_AFTER_LOGIN|EVENT_AFTER_LOGIN]]: dispara após de um login com sucesso. +* [[yii\web\User::EVENT_BEFORE_LOGOUT|EVENT_BEFORE_LOGOUT]]: dispara no início de [[yii\web\User::logout()]]. Se o manipulador de evento define a propriedade [[yii\web\UserEvent::isValid|isValid]] do objeto de evento para false, o processo de logout será cancelado. +* [[yii\web\User::EVENT_AFTER_LOGOUT|EVENT_AFTER_LOGOUT]]: dispara após um logout com sucesso. + +Você pode responder a estes eventos implementando funcionalidades, tais como auditoria de login, estatísticas de usuários on-line. Por exemplo, no manipulador +[[yii\web\User::EVENT_AFTER_LOGIN|EVENT_AFTER_LOGIN]], você pode registrar o tempo de login e endereço IP na tabela `user`. + + + From fcb45848dde193a4c8e487414ef1de155e042293 Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Mon, 8 Jun 2015 16:04:15 +0300 Subject: [PATCH 10/23] The formatting value must be array --- framework/console/Markdown.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/console/Markdown.php b/framework/console/Markdown.php index a1a5c5a24f..eb3410a1bd 100644 --- a/framework/console/Markdown.php +++ b/framework/console/Markdown.php @@ -78,7 +78,7 @@ class Markdown extends \cebe\markdown\Parser */ protected function renderEmph($element) { - return Console::ansiFormat($this->renderAbsy($element[1]), Console::ITALIC); + return Console::ansiFormat($this->renderAbsy($element[1]), [Console::ITALIC]); } /** @@ -88,7 +88,7 @@ class Markdown extends \cebe\markdown\Parser */ protected function renderStrong($element) { - return Console::ansiFormat($this->renderAbsy($element[1]), Console::BOLD); + return Console::ansiFormat($this->renderAbsy($element[1]), [Console::BOLD]); } /** From 2288f339e616714020ca0ca3539c2f1eb6218fb0 Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Mon, 8 Jun 2015 16:07:27 +0300 Subject: [PATCH 11/23] Parameter type is not compatible with declaration --- framework/db/mssql/QueryBuilder.php | 3 ++- framework/db/sqlite/QueryBuilder.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/framework/db/mssql/QueryBuilder.php b/framework/db/mssql/QueryBuilder.php index 534d7649de..dd8f40fc27 100644 --- a/framework/db/mssql/QueryBuilder.php +++ b/framework/db/mssql/QueryBuilder.php @@ -8,6 +8,7 @@ namespace yii\db\mssql; use yii\base\InvalidParamException; +use yii\db\Query; /** * QueryBuilder is the query builder for MS SQL Server databases (version 2008 and above). @@ -222,7 +223,7 @@ class QueryBuilder extends \yii\db\QueryBuilder * * @param string $operator * @param array $columns - * @param array $values + * @param Query $values * @param array $params * @return string SQL */ diff --git a/framework/db/sqlite/QueryBuilder.php b/framework/db/sqlite/QueryBuilder.php index 0581371a63..ac8edca012 100644 --- a/framework/db/sqlite/QueryBuilder.php +++ b/framework/db/sqlite/QueryBuilder.php @@ -11,6 +11,7 @@ use yii\db\Connection; use yii\db\Exception; use yii\base\InvalidParamException; use yii\base\NotSupportedException; +use yii\db\Query; /** * QueryBuilder is the query builder for SQLite databases. @@ -299,7 +300,7 @@ class QueryBuilder extends \yii\db\QueryBuilder * * @param string $operator * @param array $columns - * @param array $values + * @param Query $values * @param array $params * @return string SQL */ From 2134c72bb023a366bcd3a48168f480541278bd31 Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Mon, 8 Jun 2015 16:10:41 +0300 Subject: [PATCH 12/23] Undefined class Expression --- framework/db/oci/Schema.php | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/db/oci/Schema.php b/framework/db/oci/Schema.php index 96f83260b2..fd4cbafb3f 100644 --- a/framework/db/oci/Schema.php +++ b/framework/db/oci/Schema.php @@ -9,6 +9,7 @@ namespace yii\db\oci; use yii\base\InvalidCallException; use yii\db\Connection; +use yii\db\Expression; use yii\db\TableSchema; use yii\db\ColumnSchema; From 651ed4ee2c863fef59a30478845dd3a5933130cb Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Mon, 8 Jun 2015 16:11:16 +0300 Subject: [PATCH 13/23] Undefined class NotSupportedException --- framework/db/mssql/QueryBuilder.php | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/db/mssql/QueryBuilder.php b/framework/db/mssql/QueryBuilder.php index dd8f40fc27..f3df81879f 100644 --- a/framework/db/mssql/QueryBuilder.php +++ b/framework/db/mssql/QueryBuilder.php @@ -8,6 +8,7 @@ namespace yii\db\mssql; use yii\base\InvalidParamException; +use yii\base\NotSupportedException; use yii\db\Query; /** From 7b5744a5c3b7d15003d5873db5d389989142d541 Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Mon, 8 Jun 2015 16:17:40 +0300 Subject: [PATCH 14/23] Add to list declared variables --- framework/views/errorHandler/callStackItem.php | 1 + 1 file changed, 1 insertion(+) diff --git a/framework/views/errorHandler/callStackItem.php b/framework/views/errorHandler/callStackItem.php index 0f30012a1e..51ed203bd5 100644 --- a/framework/views/errorHandler/callStackItem.php +++ b/framework/views/errorHandler/callStackItem.php @@ -7,6 +7,7 @@ /* @var $lines string[] */ /* @var $begin integer */ /* @var $end integer */ +/* @var $args array */ /* @var $handler \yii\web\ErrorHandler */ ?>
  • Date: Tue, 2 Jun 2015 00:06:04 +0200 Subject: [PATCH 15/23] added test for createTable and alterTable test for issue #8627 close #8628 --- tests/framework/db/CommandTest.php | 45 ++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/tests/framework/db/CommandTest.php b/tests/framework/db/CommandTest.php index bcd3270381..f271f42439 100644 --- a/tests/framework/db/CommandTest.php +++ b/tests/framework/db/CommandTest.php @@ -6,6 +6,7 @@ use yii\caching\FileCache; use yii\db\Connection; use yii\db\DataReader; use yii\db\Expression; +use yii\db\Schema; /** * @group db @@ -310,6 +311,42 @@ SQL; ], $record); } + public function testCreateTable() + { + $db = $this->getConnection(); + $db->createCommand("DROP TABLE IF EXISTS testCreateTable;")->execute(); + + $db->createCommand()->createTable('testCreateTable', ['id' => Schema::TYPE_PK, 'bar' => Schema::TYPE_INTEGER])->execute(); + $db->createCommand()->insert('testCreateTable', ['bar' => 1])->execute(); + $records = $db->createCommand('SELECT [[id]], [[bar]] FROM {{testCreateTable}};')->queryAll(); + $this->assertEquals([ + ['id' => 1, 'bar' => 1], + ], $records); + } + + public function testAlterTable() + { + if ($this->driverName === 'sqlite'){ + $this->markTestSkipped('Sqlite does not support alterTable'); + } + + $db = $this->getConnection(); + $db->createCommand("DROP TABLE IF EXISTS testAlterTable;")->execute(); + + $db->createCommand()->createTable('testAlterTable', ['id' => Schema::TYPE_PK, 'bar' => Schema::TYPE_INTEGER])->execute(); + $db->createCommand()->insert('testAlterTable', ['bar' => 1])->execute(); + + $db->createCommand()->alterColumn('testAlterTable', 'bar', Schema::TYPE_STRING)->execute(); + + $db->createCommand()->insert('testAlterTable', ['bar' => 'hello'])->execute(); + $records = $db->createCommand('SELECT [[id]], [[bar]] FROM {{testAlterTable}};')->queryAll(); + $this->assertEquals([ + ['id' => 1, 'bar' => 1], + ['id' => 2, 'bar' => 'hello'], + ], $records); + } + + /* public function testUpdate() { @@ -319,10 +356,6 @@ SQL; { } - public function testCreateTable() - { - } - public function testRenameTable() { } @@ -347,10 +380,6 @@ SQL; { } - public function testAlterColumn() - { - } - public function testAddForeignKey() { } From 0c5e4b7105200af2b4110e9ecf77e10b10f52dc5 Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Mon, 8 Jun 2015 23:19:29 +0300 Subject: [PATCH 16/23] PSR-2 foreach statement --- framework/base/Model.php | 2 +- framework/data/ActiveDataProvider.php | 2 +- framework/helpers/BaseConsole.php | 4 ++-- framework/log/Target.php | 2 +- framework/web/Session.php | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/framework/base/Model.php b/framework/base/Model.php index bfeb649123..fc54442258 100644 --- a/framework/base/Model.php +++ b/framework/base/Model.php @@ -618,7 +618,7 @@ class Model extends Component implements IteratorAggregate, ArrayAccess, Arrayab { foreach ($items as $attribute => $errors) { if (is_array($errors)) { - foreach($errors as $error) { + foreach ($errors as $error) { $this->addError($attribute, $error); } } else { diff --git a/framework/data/ActiveDataProvider.php b/framework/data/ActiveDataProvider.php index 4b0a0a54b2..47a39ff972 100644 --- a/framework/data/ActiveDataProvider.php +++ b/framework/data/ActiveDataProvider.php @@ -183,7 +183,7 @@ class ActiveDataProvider extends BaseDataProvider ]; } } else { - foreach($sort->attributes as $attribute => $config) { + foreach ($sort->attributes as $attribute => $config) { if (!isset($config['label'])) { $sort->attributes[$attribute]['label'] = $model->getAttributeLabel($attribute); } diff --git a/framework/helpers/BaseConsole.php b/framework/helpers/BaseConsole.php index b1541b321e..bb6af9d5e9 100644 --- a/framework/helpers/BaseConsole.php +++ b/framework/helpers/BaseConsole.php @@ -433,7 +433,7 @@ class BaseConsole } $styleString = ''; - foreach($currentStyle as $name => $value) { + foreach ($currentStyle as $name => $value) { if (is_array($value)) { $value = implode(' ', $value); } @@ -665,7 +665,7 @@ class BaseConsole $pad = str_repeat(' ', $indent); $lines = explode("\n", wordwrap($text, $size[0] - $indent, "\n", true)); $first = true; - foreach($lines as $i => $line) { + foreach ($lines as $i => $line) { if ($first) { $first = false; continue; diff --git a/framework/log/Target.php b/framework/log/Target.php index 792f3daf85..076edb9084 100644 --- a/framework/log/Target.php +++ b/framework/log/Target.php @@ -248,7 +248,7 @@ abstract class Target extends Component } $traces = []; if (isset($message[4])) { - foreach($message[4] as $trace) { + foreach ($message[4] as $trace) { $traces[] = "in {$trace['file']}:{$trace['line']}"; } } diff --git a/framework/web/Session.php b/framework/web/Session.php index f175119d80..9f8d5f6abe 100644 --- a/framework/web/Session.php +++ b/framework/web/Session.php @@ -671,7 +671,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co * * ```php * session->getAllFlashes() as $key => $message) { + * foreach (Yii::$app->session->getAllFlashes() as $key => $message) { * echo '
    ' . $message . '
    '; * } ?> * ``` From fa428a130c95efdd9211de5bd2120be1ecb28dcb Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Mon, 8 Jun 2015 23:22:41 +0300 Subject: [PATCH 17/23] PSR-2 while statement --- framework/helpers/BaseConsole.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/helpers/BaseConsole.php b/framework/helpers/BaseConsole.php index bb6af9d5e9..2d35a314c5 100644 --- a/framework/helpers/BaseConsole.php +++ b/framework/helpers/BaseConsole.php @@ -401,7 +401,7 @@ class BaseConsole } $return = ''; - while($reset && $tags > 0) { + while ($reset && $tags > 0) { $return .= ''; $tags--; } @@ -444,7 +444,7 @@ class BaseConsole }, $string ); - while($tags > 0) { + while ($tags > 0) { $result .= ''; $tags--; } From 789cdfea86dee3998953b80f7a87eccd9fd7881d Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Mon, 8 Jun 2015 23:28:44 +0300 Subject: [PATCH 18/23] PSR-2 switch statement --- framework/db/sqlite/Schema.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/framework/db/sqlite/Schema.php b/framework/db/sqlite/Schema.php index bd3fbdcd93..2e28896281 100644 --- a/framework/db/sqlite/Schema.php +++ b/framework/db/sqlite/Schema.php @@ -270,14 +270,13 @@ class Schema extends \yii\db\Schema */ public function setTransactionIsolationLevel($level) { - switch($level) - { + switch ($level) { case Transaction::SERIALIZABLE: $this->db->createCommand("PRAGMA read_uncommitted = False;")->execute(); - break; + break; case Transaction::READ_UNCOMMITTED: $this->db->createCommand("PRAGMA read_uncommitted = True;")->execute(); - break; + break; default: throw new NotSupportedException(get_class($this) . ' only supports transaction isolation levels READ UNCOMMITTED and SERIALIZABLE.'); } From 38ca276e1f10b04c4db40114c6204025ded42036 Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Mon, 8 Jun 2015 23:32:08 +0300 Subject: [PATCH 19/23] PSR-2 try-catch statement --- framework/base/Widget.php | 2 +- framework/helpers/BaseFileHelper.php | 2 +- framework/i18n/Formatter.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/base/Widget.php b/framework/base/Widget.php index 742fb2193a..3e3f40a925 100644 --- a/framework/base/Widget.php +++ b/framework/base/Widget.php @@ -96,7 +96,7 @@ class Widget extends Component implements ViewContextInterface $config['class'] = get_called_class(); $widget = Yii::createObject($config); $out = $widget->run(); - } catch(\Exception $e) { + } catch (\Exception $e) { // close the output buffer opened above if it has not been closed already if(ob_get_level() > 0) { ob_end_clean(); diff --git a/framework/helpers/BaseFileHelper.php b/framework/helpers/BaseFileHelper.php index 5643da90e1..0081e1d607 100644 --- a/framework/helpers/BaseFileHelper.php +++ b/framework/helpers/BaseFileHelper.php @@ -461,7 +461,7 @@ class BaseFileHelper try { $result = mkdir($path, $mode); chmod($path, $mode); - } catch(\Exception $e) { + } catch (\Exception $e) { throw new \yii\base\Exception("Failed to create directory '$path': " . $e->getMessage(), $e->getCode(), $e); } diff --git a/framework/i18n/Formatter.php b/framework/i18n/Formatter.php index 47ae15828f..fb0da65969 100644 --- a/framework/i18n/Formatter.php +++ b/framework/i18n/Formatter.php @@ -658,7 +658,7 @@ class Formatter extends Component } else { return new DateTime($value, new DateTimeZone($this->defaultTimeZone)); } - } catch(\Exception $e) { + } catch (\Exception $e) { throw new InvalidParamException("'$value' is not a valid date time value: " . $e->getMessage() . "\n" . print_r(DateTime::getLastErrors(), true), $e->getCode(), $e); } From ae42a054bb950caf8a7972f386b6c8b903cff98e Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Tue, 9 Jun 2015 00:05:06 +0300 Subject: [PATCH 20/23] PSR-2 spaces, commas, etc --- .../console/controllers/MessageController.php | 2 +- framework/db/ColumnSchema.php | 4 ++-- framework/db/Query.php | 2 +- framework/db/QueryBuilder.php | 2 +- framework/db/TableSchema.php | 2 +- framework/db/oci/Schema.php | 12 +++++----- framework/db/pgsql/Schema.php | 2 +- framework/helpers/BaseConsole.php | 4 ++-- framework/helpers/BaseFileHelper.php | 4 ++-- framework/helpers/BaseHtml.php | 8 +++---- framework/helpers/BaseHtmlPurifier.php | 2 +- framework/log/EmailTarget.php | 2 +- framework/mutex/FileMutex.php | 2 +- framework/mutex/MysqlMutex.php | 4 ++-- framework/validators/DateValidator.php | 4 ++-- framework/validators/EmailValidator.php | 2 +- framework/validators/FileValidator.php | 22 +++++++++---------- framework/validators/NumberValidator.php | 4 ++-- framework/validators/UrlValidator.php | 2 +- framework/web/Controller.php | 2 +- framework/web/Request.php | 4 ++-- framework/web/User.php | 2 +- 22 files changed, 47 insertions(+), 47 deletions(-) diff --git a/framework/console/controllers/MessageController.php b/framework/console/controllers/MessageController.php index 4636a8a746..b96864dd7e 100644 --- a/framework/console/controllers/MessageController.php +++ b/framework/console/controllers/MessageController.php @@ -254,7 +254,7 @@ class MessageController extends Controller $subject = file_get_contents($fileName); $messages = []; - foreach ((array)$translator as $currentTranslator) { + foreach ((array) $translator as $currentTranslator) { $translatorTokens = token_get_all('union[] = [ 'query' => $sql, 'all' => $all ]; + $this->union[] = ['query' => $sql, 'all' => $all]; return $this; } diff --git a/framework/db/QueryBuilder.php b/framework/db/QueryBuilder.php index d5da6326fe..e455ee289d 100644 --- a/framework/db/QueryBuilder.php +++ b/framework/db/QueryBuilder.php @@ -1202,7 +1202,7 @@ class QueryBuilder extends \yii\base\Object throw new InvalidParamException("Operator '$operator' requires two operands."); } - $escape = isset($operands[2]) ? $operands[2] : ['%'=>'\%', '_'=>'\_', '\\'=>'\\\\']; + $escape = isset($operands[2]) ? $operands[2] : ['%' => '\%', '_' => '\_', '\\' => '\\\\']; unset($operands[2]); if (!preg_match('/^(AND |OR |)(((NOT |))I?LIKE)/', $operator, $matches)) { diff --git a/framework/db/TableSchema.php b/framework/db/TableSchema.php index d83bc6b0c4..7aa02181af 100644 --- a/framework/db/TableSchema.php +++ b/framework/db/TableSchema.php @@ -87,7 +87,7 @@ class TableSchema extends Object */ public function fixPrimaryKey($keys) { - $keys = (array)$keys; + $keys = (array) $keys; $this->primaryKey = $keys; foreach ($this->columns as $column) { $column->isPrimaryKey = false; diff --git a/framework/db/oci/Schema.php b/framework/db/oci/Schema.php index fd4cbafb3f..ac5c8f8c87 100644 --- a/framework/db/oci/Schema.php +++ b/framework/db/oci/Schema.php @@ -163,7 +163,7 @@ SQL; * Sequence name of table * * @param $tableName - * @internal param \yii\db\TableSchema $table ->name the table schema + * @internal param \yii\db\TableSchema $table->name the table schema * @return string whether the sequence exists */ protected function getTableSequenceName($tableName) @@ -426,9 +426,9 @@ SQL; */ protected function extractColumnSize($column, $dbType, $precision, $scale, $length) { - $column->size = trim($length) == '' ? null : (int)$length; - $column->precision = trim($precision) == '' ? null : (int)$precision; - $column->scale = trim($scale) == '' ? null : (int)$scale; + $column->size = trim($length) == '' ? null : (int) $length; + $column->precision = trim($precision) == '' ? null : (int) $precision; + $column->scale = trim($scale) == '' ? null : (int) $scale; } /** @@ -444,7 +444,7 @@ SQL; if (!empty($returnColumns)) { $columnSchemas = $tableSchema->columns; $returning = []; - foreach ((array)$returnColumns as $name) { + foreach ((array) $returnColumns as $name) { $phName = QueryBuilder::PARAM_PREFIX . (count($params) + count($returnParams)); $returnParams[$phName] = [ 'column' => $name, @@ -465,7 +465,7 @@ SQL; $command->prepare(false); foreach ($returnParams as $name => &$value) { - $command->pdoStatement->bindParam($name, $value['value'], $value['dataType'], $value['size'] ); + $command->pdoStatement->bindParam($name, $value['value'], $value['dataType'], $value['size']); } if (!$command->execute()) { diff --git a/framework/db/pgsql/Schema.php b/framework/db/pgsql/Schema.php index 94c0939936..dee6c00646 100644 --- a/framework/db/pgsql/Schema.php +++ b/framework/db/pgsql/Schema.php @@ -462,7 +462,7 @@ SQL; $returnColumns = $this->getTableSchema($table)->primaryKey; if (!empty($returnColumns)) { $returning = []; - foreach ((array)$returnColumns as $name) { + foreach ((array) $returnColumns as $name) { $returning[] = $this->quoteColumnName($name); } $sql .= ' RETURNING ' . implode(', ', $returning); diff --git a/framework/helpers/BaseConsole.php b/framework/helpers/BaseConsole.php index 2d35a314c5..0a10f36dd2 100644 --- a/framework/helpers/BaseConsole.php +++ b/framework/helpers/BaseConsole.php @@ -817,11 +817,11 @@ class BaseConsole return $default; } - if (!strcasecmp ($input, 'y') || !strcasecmp ($input, 'yes') ) { + if (!strcasecmp($input, 'y') || !strcasecmp($input, 'yes')) { return true; } - if (!strcasecmp ($input, 'n') || !strcasecmp ($input, 'no') ) { + if (!strcasecmp($input, 'n') || !strcasecmp($input, 'no')) { return false; } } diff --git a/framework/helpers/BaseFileHelper.php b/framework/helpers/BaseFileHelper.php index 0081e1d607..df14715975 100644 --- a/framework/helpers/BaseFileHelper.php +++ b/framework/helpers/BaseFileHelper.php @@ -602,7 +602,7 @@ class BaseFileHelper * @param string $pattern * @param boolean $caseSensitive * @throws \yii\base\InvalidParamException - * @return array with keys: (string) pattern, (int) flags, (int|boolean)firstWildcard + * @return array with keys: (string) pattern, (int) flags, (int|boolean) firstWildcard */ private static function parseExcludePattern($pattern, $caseSensitive) { @@ -655,7 +655,7 @@ class BaseFileHelper $wildcardSearch = function ($r, $c) use ($pattern) { $p = strpos($pattern, $c); - return $r===false ? $p : ($p===false ? $r : min($r, $p)); + return $r === false ? $p : ($p === false ? $r : min($r, $p)); }; return array_reduce($wildcards, $wildcardSearch, false); diff --git a/framework/helpers/BaseHtml.php b/framework/helpers/BaseHtml.php index b38b656aaa..39f16dc8ad 100644 --- a/framework/helpers/BaseHtml.php +++ b/framework/helpers/BaseHtml.php @@ -1801,10 +1801,10 @@ class BaseHtml { if (isset($options['class'])) { if (is_array($options['class'])) { - $options['class'] = self::mergeCssClasses($options['class'], (array)$class); + $options['class'] = self::mergeCssClasses($options['class'], (array) $class); } else { $classes = preg_split('/\s+/', $options['class'], -1, PREG_SPLIT_NO_EMPTY); - $options['class'] = implode(' ', self::mergeCssClasses($classes, (array)$class)); + $options['class'] = implode(' ', self::mergeCssClasses($classes, (array) $class)); } } else { $options['class'] = $class; @@ -1839,7 +1839,7 @@ class BaseHtml { if (isset($options['class'])) { if (is_array($options['class'])) { - $classes = array_diff($options['class'], (array)$class); + $classes = array_diff($options['class'], (array) $class); if (empty($classes)) { unset($options['class']); } else { @@ -1847,7 +1847,7 @@ class BaseHtml } } else { $classes = preg_split('/\s+/', $options['class'], -1, PREG_SPLIT_NO_EMPTY); - $classes = array_diff($classes, (array)$class); + $classes = array_diff($classes, (array) $class); if (empty($classes)) { unset($options['class']); } else { diff --git a/framework/helpers/BaseHtmlPurifier.php b/framework/helpers/BaseHtmlPurifier.php index db528d6775..9e02294337 100644 --- a/framework/helpers/BaseHtmlPurifier.php +++ b/framework/helpers/BaseHtmlPurifier.php @@ -46,7 +46,7 @@ class BaseHtmlPurifier { $configInstance = \HTMLPurifier_Config::create($config instanceof \Closure ? null : $config); $configInstance->autoFinalize = false; - $purifier=\HTMLPurifier::instance($configInstance); + $purifier = \HTMLPurifier::instance($configInstance); $purifier->config->set('Cache.SerializerPath', \Yii::$app->getRuntimePath()); if ($config instanceof \Closure) { diff --git a/framework/log/EmailTarget.php b/framework/log/EmailTarget.php index 1e449bbd92..659c645f75 100644 --- a/framework/log/EmailTarget.php +++ b/framework/log/EmailTarget.php @@ -24,7 +24,7 @@ use yii\mail\MailerInterface; * 'targets' => [ * [ * 'class' => 'yii\log\EmailTarget', - * 'mailer' =>'mailer', + * 'mailer' => 'mailer', * 'levels' => ['error', 'warning'], * 'message' => [ * 'from' => ['log@example.com'], diff --git a/framework/mutex/FileMutex.php b/framework/mutex/FileMutex.php index b58fe344c0..7619a4ddee 100644 --- a/framework/mutex/FileMutex.php +++ b/framework/mutex/FileMutex.php @@ -20,7 +20,7 @@ use yii\helpers\FileHelper; * ``` * [ * 'components' => [ - * 'mutex'=> [ + * 'mutex' => [ * 'class' => 'yii\mutex\FileMutex' * ], * ], diff --git a/framework/mutex/MysqlMutex.php b/framework/mutex/MysqlMutex.php index 6c45e250e7..e47a71b9de 100644 --- a/framework/mutex/MysqlMutex.php +++ b/framework/mutex/MysqlMutex.php @@ -18,11 +18,11 @@ use yii\base\InvalidConfigException; * ``` * [ * 'components' => [ - * 'db'=> [ + * 'db' => [ * 'class' => 'yii\db\Connection', * 'dsn' => 'mysql:host=127.0.0.1;dbname=demo', * ] - * 'mutex'=> [ + * 'mutex' => [ * 'class' => 'yii\mutex\MysqlMutex', * ], * ], diff --git a/framework/validators/DateValidator.php b/framework/validators/DateValidator.php index 87ac6721b3..85874f7aaf 100644 --- a/framework/validators/DateValidator.php +++ b/framework/validators/DateValidator.php @@ -181,10 +181,10 @@ class DateValidator extends Validator $this->tooBig = Yii::t('yii', '{attribute} must be no greater than {max}.'); } if ($this->maxString === null) { - $this->maxString = (string)$this->max; + $this->maxString = (string) $this->max; } if ($this->minString === null) { - $this->minString = (string)$this->min; + $this->minString = (string) $this->min; } if ($this->max !== null && is_string($this->max)) { $timestamp = $this->parseDateValue($this->max); diff --git a/framework/validators/EmailValidator.php b/framework/validators/EmailValidator.php index eec8e2de8a..8801716d48 100644 --- a/framework/validators/EmailValidator.php +++ b/framework/validators/EmailValidator.php @@ -101,7 +101,7 @@ class EmailValidator extends Validator 'message' => Yii::$app->getI18n()->format($this->message, [ 'attribute' => $model->getAttributeLabel($attribute), ], Yii::$app->language), - 'enableIDN' => (boolean) $this->enableIDN, + 'enableIDN' => (bool) $this->enableIDN, ]; if ($this->skipOnEmpty) { $options['skipOnEmpty'] = 1; diff --git a/framework/validators/FileValidator.php b/framework/validators/FileValidator.php index 4de9def002..337bc4b0ac 100644 --- a/framework/validators/FileValidator.php +++ b/framework/validators/FileValidator.php @@ -360,49 +360,49 @@ class FileValidator extends Validator $options['skipOnEmpty'] = $this->skipOnEmpty; - if ( !$this->skipOnEmpty ) { + if (!$this->skipOnEmpty) { $options['uploadRequired'] = Yii::$app->getI18n()->format($this->uploadRequired, [ 'attribute' => $label, ], Yii::$app->language); } - if ( $this->mimeTypes !== null ) { + if ($this->mimeTypes !== null) { $options['mimeTypes'] = $this->mimeTypes; $options['wrongMimeType'] = Yii::$app->getI18n()->format($this->wrongMimeType, [ 'attribute' => $label, - 'mimeTypes' => join(', ', $this->mimeTypes) + 'mimeTypes' => join(', ', $this->mimeTypes), ], Yii::$app->language); } - if ( $this->extensions !== null ) { + if ($this->extensions !== null) { $options['extensions'] = $this->extensions; $options['wrongExtension'] = Yii::$app->getI18n()->format($this->wrongExtension, [ 'attribute' => $label, - 'extensions' => join(', ', $this->extensions) + 'extensions' => join(', ', $this->extensions), ], Yii::$app->language); } - if ( $this->minSize !== null ) { + if ($this->minSize !== null) { $options['minSize'] = $this->minSize; $options['tooSmall'] = Yii::$app->getI18n()->format($this->tooSmall, [ 'attribute' => $label, - 'limit' => $this->minSize + 'limit' => $this->minSize, ], Yii::$app->language); } - if ( $this->maxSize !== null ) { + if ($this->maxSize !== null) { $options['maxSize'] = $this->maxSize; $options['tooBig'] = Yii::$app->getI18n()->format($this->tooBig, [ 'attribute' => $label, - 'limit' => $this->maxSize + 'limit' => $this->maxSize, ], Yii::$app->language); } - if ( $this->maxFiles !== null ) { + if ($this->maxFiles !== null) { $options['maxFiles'] = $this->maxFiles; $options['tooMany'] = Yii::$app->getI18n()->format($this->tooMany, [ 'attribute' => $label, - 'limit' => $this->maxFiles + 'limit' => $this->maxFiles, ], Yii::$app->language); } diff --git a/framework/validators/NumberValidator.php b/framework/validators/NumberValidator.php index 927bc12503..271040701a 100644 --- a/framework/validators/NumberValidator.php +++ b/framework/validators/NumberValidator.php @@ -133,7 +133,7 @@ class NumberValidator extends Validator if ($this->min !== null) { // ensure numeric value to make javascript comparison equal to PHP comparison // https://github.com/yiisoft/yii2/issues/3118 - $options['min'] = is_string($this->min) ? (float)$this->min : $this->min; + $options['min'] = is_string($this->min) ? (float) $this->min : $this->min; $options['tooSmall'] = Yii::$app->getI18n()->format($this->tooSmall, [ 'attribute' => $label, 'min' => $this->min, @@ -142,7 +142,7 @@ class NumberValidator extends Validator if ($this->max !== null) { // ensure numeric value to make javascript comparison equal to PHP comparison // https://github.com/yiisoft/yii2/issues/3118 - $options['max'] = is_string($this->max) ? (float)$this->max : $this->max; + $options['max'] = is_string($this->max) ? (float) $this->max : $this->max; $options['tooBig'] = Yii::$app->getI18n()->format($this->tooBig, [ 'attribute' => $label, 'max' => $this->max, diff --git a/framework/validators/UrlValidator.php b/framework/validators/UrlValidator.php index 4913e69c3a..aeac04969f 100644 --- a/framework/validators/UrlValidator.php +++ b/framework/validators/UrlValidator.php @@ -124,7 +124,7 @@ class UrlValidator extends Validator 'message' => Yii::$app->getI18n()->format($this->message, [ 'attribute' => $model->getAttributeLabel($attribute), ], Yii::$app->language), - 'enableIDN' => (boolean) $this->enableIDN, + 'enableIDN' => (bool) $this->enableIDN, ]; if ($this->skipOnEmpty) { $options['skipOnEmpty'] = 1; diff --git a/framework/web/Controller.php b/framework/web/Controller.php index 757805ed2b..b3721a71d1 100644 --- a/framework/web/Controller.php +++ b/framework/web/Controller.php @@ -73,7 +73,7 @@ class Controller extends \yii\base\Controller $name = $param->getName(); if (array_key_exists($name, $params)) { if ($param->isArray()) { - $args[] = $actionParams[$name] = (array)$params[$name]; + $args[] = $actionParams[$name] = (array) $params[$name]; } elseif (!is_array($params[$name])) { $args[] = $actionParams[$name] = $params[$name]; } else { diff --git a/framework/web/Request.php b/framework/web/Request.php index d6253b8d6a..a4956941be 100644 --- a/framework/web/Request.php +++ b/framework/web/Request.php @@ -1224,7 +1224,7 @@ class Request extends \yii\base\Request $cookies[$name] = new Cookie([ 'name' => $name, 'value' => $data[1], - 'expire'=> null + 'expire' => null, ]); } } @@ -1233,7 +1233,7 @@ class Request extends \yii\base\Request $cookies[$name] = new Cookie([ 'name' => $name, 'value' => $value, - 'expire'=> null + 'expire' => null, ]); } } diff --git a/framework/web/User.php b/framework/web/User.php index 7dd4879905..28ec491bb3 100644 --- a/framework/web/User.php +++ b/framework/web/User.php @@ -423,7 +423,7 @@ class User extends Component $this->setReturnUrl($request->getUrl()); } if ($this->loginUrl !== null) { - $loginUrl = (array)$this->loginUrl; + $loginUrl = (array) $this->loginUrl; if ($loginUrl[0] !== Yii::$app->requestedRoute) { return Yii::$app->getResponse()->redirect($this->loginUrl); } From d34d890a325bbc0efda7cdd8eea677ee13104bfc Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Tue, 9 Jun 2015 00:10:09 +0300 Subject: [PATCH 21/23] PSR-2 if-else statement --- framework/base/Widget.php | 2 +- framework/console/controllers/CacheController.php | 2 +- framework/helpers/BaseStringHelper.php | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/framework/base/Widget.php b/framework/base/Widget.php index 3e3f40a925..8281902b49 100644 --- a/framework/base/Widget.php +++ b/framework/base/Widget.php @@ -98,7 +98,7 @@ class Widget extends Component implements ViewContextInterface $out = $widget->run(); } catch (\Exception $e) { // close the output buffer opened above if it has not been closed already - if(ob_get_level() > 0) { + if (ob_get_level() > 0) { ob_end_clean(); } throw $e; diff --git a/framework/console/controllers/CacheController.php b/framework/console/controllers/CacheController.php index 782a99c6fc..2fdb8f1dbd 100644 --- a/framework/console/controllers/CacheController.php +++ b/framework/console/controllers/CacheController.php @@ -150,7 +150,7 @@ class CacheController extends Controller if (!$connection instanceof \yii\db\Connection) { $this->stdout("\"$db\" component doesn't inherit \\yii\\db\\Connection.\n", Console::FG_RED); return self::EXIT_CODE_ERROR; - } else if (!$this->confirm("Flush cache schema for \"$db\" connection?")) { + } elseif (!$this->confirm("Flush cache schema for \"$db\" connection?")) { return static::EXIT_CODE_NORMAL; } diff --git a/framework/helpers/BaseStringHelper.php b/framework/helpers/BaseStringHelper.php index 674828af85..c9114404f5 100644 --- a/framework/helpers/BaseStringHelper.php +++ b/framework/helpers/BaseStringHelper.php @@ -161,7 +161,7 @@ class BaseStringHelper if ($token instanceof \HTMLPurifier_Token_Start) { //Tag begins $openTokens++; $truncated[] = $token; - } else if ($token instanceof \HTMLPurifier_Token_Text && $totalCount <= $count) { //Text + } elseif ($token instanceof \HTMLPurifier_Token_Text && $totalCount <= $count) { //Text if (false === $encoding) { $token->data = self::truncateWords($token->data, $count - $totalCount, ''); $currentCount = str_word_count($token->data); @@ -174,10 +174,10 @@ class BaseStringHelper $token->data = ' ' . $token->data; } $truncated[] = $token; - } else if ($token instanceof \HTMLPurifier_Token_End) { //Tag ends + } elseif ($token instanceof \HTMLPurifier_Token_End) { //Tag ends $openTokens--; $truncated[] = $token; - } else if ($token instanceof \HTMLPurifier_Token_Empty) { //Self contained tags, i.e. etc. + } elseif ($token instanceof \HTMLPurifier_Token_Empty) { //Self contained tags, i.e. etc. $truncated[] = $token; } if (0 === $openTokens && $totalCount >= $count) { From afe21a986a468286f9b4153a811f72491d848ca6 Mon Sep 17 00:00:00 2001 From: Alexander Mohorev Date: Tue, 9 Jun 2015 00:14:44 +0300 Subject: [PATCH 22/23] PSR-2 anonymous functions --- framework/db/Connection.php | 4 ++-- framework/grid/CheckboxColumn.php | 2 +- framework/helpers/BaseHtmlPurifier.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/db/Connection.php b/framework/db/Connection.php index 5cf61a9309..674a5027e4 100644 --- a/framework/db/Connection.php +++ b/framework/db/Connection.php @@ -80,7 +80,7 @@ use yii\caching\Cache; * You also can use shortcut for the above like the following: * * ~~~ - * $connection->transaction(function() { + * $connection->transaction(function () { * $order = new Order($customer); * $order->save(); * $order->addItems($items); @@ -90,7 +90,7 @@ use yii\caching\Cache; * If needed you can pass transaction isolation level as a second parameter: * * ~~~ - * $connection->transaction(function(Connection $db) { + * $connection->transaction(function (Connection $db) { * //return $db->... * }, Transaction::READ_UNCOMMITTED); * ~~~ diff --git a/framework/grid/CheckboxColumn.php b/framework/grid/CheckboxColumn.php index d5ee00eb57..7adfc68b4c 100644 --- a/framework/grid/CheckboxColumn.php +++ b/framework/grid/CheckboxColumn.php @@ -54,7 +54,7 @@ class CheckboxColumn extends Column * you can use this option in the following way (in this example using the `name` attribute of the model): * * ```php - * 'checkboxOptions' => function($model, $key, $index, $column) { + * 'checkboxOptions' => function ($model, $key, $index, $column) { * return ['value' => $model->name]; * } * ``` diff --git a/framework/helpers/BaseHtmlPurifier.php b/framework/helpers/BaseHtmlPurifier.php index 9e02294337..d7ae14a695 100644 --- a/framework/helpers/BaseHtmlPurifier.php +++ b/framework/helpers/BaseHtmlPurifier.php @@ -34,7 +34,7 @@ class BaseHtmlPurifier * * ~~~ * // Allow the HTML5 data attribute `data-type` on `img` elements. - * $content = HtmlPurifier::process($content, function($config) { + * $content = HtmlPurifier::process($content, function ($config) { * $config->getHTMLDefinition(true) * ->addAttribute('img', 'data-type', 'Text'); * }); From eebe1662582d014ca9143ee7a5bd5738fbf85499 Mon Sep 17 00:00:00 2001 From: abeleev Date: Tue, 9 Jun 2015 15:43:16 +0700 Subject: [PATCH 23/23] Update test-fixtures.md --- docs/guide-ru/test-fixtures.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/guide-ru/test-fixtures.md b/docs/guide-ru/test-fixtures.md index bbeb4781ae..d376ca6b30 100644 --- a/docs/guide-ru/test-fixtures.md +++ b/docs/guide-ru/test-fixtures.md @@ -22,7 +22,7 @@ Первый лучше всего подходит для фикстур общего назначения, в то время как последний имеет расширенные функции, специально предназначенные для работы с базой данных и ActiveRecord. -Следующий код показывает как объявить фикстуру для модели ActiveRecord `User`, которая соответствует таблицы пользователей. +Следующий код показывает как объявить фикстуру для модели ActiveRecord `User`, которая соответствует таблице пользователей. ```php @@ -96,7 +96,7 @@ class UserProfileFixture extends ActiveFixture ``` Зависимость также гарантирует, что фикстуры загружаются и выгружаются в определенном порядке. В предыдущем примере `UserFixture` -будет автоматически загружена до `UserProfileFixture`, тем самым гарантирую существование всех внешних ключей, и будет выгружена +будет автоматически загружена до `UserProfileFixture`, тем самым гарантируя существование всех внешних ключей, и будет выгружена после того как выгрузится `UserProfileFixture` по тем же причинам. Выше мы показали как объявить фикстуру для таблицы базы данных. Для объявления фикстуры не связанной с базой данных (например, @@ -107,7 +107,7 @@ class UserProfileFixture extends ActiveFixture Использование фикстур --------------------- -Если вы используете [CodeCeption](http://codeception.com/) для тестирование вашего кода, вам следует рассмотреть вопрос +Если вы используете [CodeCeption](http://codeception.com/) для тестирования вашего кода, вам следует рассмотреть вопрос об использовании расширения `yii2-codeception`, которое имеет встроенную поддержку загрузки фикстур и доступа к ним. Если вы используете другой фреймворк для тестирования, вы можете использовать [[yii\test\FixtureTrait]] в ваших тестах для этих целей. @@ -380,4 +380,4 @@ Yii также может автоматически генерировать д различных набором данных на разных языках и в разных форматах. Данная возможность основана на использовании библиотеки [Faker](https://github.com/fzaninotto/Faker) и расширения `yii2-faker`. -Для получения дополнительной информации ознакомьтесь с [руководством](https://github.com/yiisoft/yii2-faker). \ No newline at end of file +Для получения дополнительной информации ознакомьтесь с [руководством](https://github.com/yiisoft/yii2-faker).