diff --git a/.travis.yml b/.travis.yml index 957efad..8134e21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,12 +13,17 @@ services: install: - composer self-update && composer --version +# core framework: # - composer require satooshi/php-coveralls 0.6.* --dev --prefer-dist - composer install --prefer-dist - tests/unit/data/travis/mongodb-setup.sh - tests/unit/data/travis/apc-setup.sh - tests/unit/data/travis/memcache-setup.sh - tests/unit/data/travis/cubrid-setup.sh +# basic application: + - composer install --dev --prefer-dist -d apps/basic + - cd apps/basic && php vendor/bin/codecept build && cd ../.. + - cd apps && php -S localhost:8080 & before_script: - echo 'elasticsearch version ' && curl http://localhost:9200/ @@ -28,7 +33,9 @@ before_script: - mongo yii2test --eval 'db.addUser("travis", "test");' script: - - vendor/bin/phpunit --coverage-text --coverage-clover tests/unit/runtime/coveralls/clover.xml --verbose --exclude-group mssql,oci,wincache,xcache,zenddata,vendor +# - vendor/bin/phpunit --coverage-clover tests/unit/runtime/coveralls/clover.xml --verbose --exclude-group mssql,oci,wincache,xcache,zenddata,vendor + - vendor/bin/phpunit --verbose --exclude-group mssql,oci,wincache,xcache,zenddata,vendor + - cd apps/basic && php vendor/bin/codecept run #after_script: # - php vendor/bin/coveralls diff --git a/apps/advanced/backend/web/css/site.css b/apps/advanced/backend/web/css/site.css index f460b45..66be560 100644 --- a/apps/advanced/backend/web/css/site.css +++ b/apps/advanced/backend/web/css/site.css @@ -60,6 +60,10 @@ a.desc:after { content: "\e156"; } +.grid-view th { + white-space: nowrap; +} + .hint-block { display: block; margin-top: 5px; diff --git a/apps/advanced/frontend/web/css/site.css b/apps/advanced/frontend/web/css/site.css index f460b45..66be560 100644 --- a/apps/advanced/frontend/web/css/site.css +++ b/apps/advanced/frontend/web/css/site.css @@ -60,6 +60,10 @@ a.desc:after { content: "\e156"; } +.grid-view th { + white-space: nowrap; +} + .hint-block { display: block; margin-top: 5px; diff --git a/apps/basic/.travis.yml b/apps/basic/.travis.yml deleted file mode 100644 index 9b11e83..0000000 --- a/apps/basic/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: php - -php: - - 5.5 - - 5.4 - -install: - - composer require --prefer-dist --dev 'codeception/codeception \*' 'codeception/specify \*' - -before_script: - - php vendor/bin/codecept build - -script: - - php vendor/bin/codecept run \ No newline at end of file diff --git a/apps/basic/composer.json b/apps/basic/composer.json index 6170429..e45c994 100644 --- a/apps/basic/composer.json +++ b/apps/basic/composer.json @@ -22,7 +22,9 @@ "require-dev": { "yiisoft/yii2-codeception": "*", "yiisoft/yii2-debug": "*", - "yiisoft/yii2-gii": "*" + "yiisoft/yii2-gii": "*", + "codeception/codeception": "*", + "codeception/specify": "*" }, "scripts": { "post-create-project-cmd": [ diff --git a/apps/basic/tests/acceptance.suite.yml b/apps/basic/tests/acceptance.suite.yml index f4d36f5..34e4397 100644 --- a/apps/basic/tests/acceptance.suite.yml +++ b/apps/basic/tests/acceptance.suite.yml @@ -18,7 +18,7 @@ modules: # - WebDriver config: PhpBrowser: - url: 'http://localhost' + url: 'http://localhost:8080' # WebDriver: # url: 'http://localhost' # browser: firefox diff --git a/apps/basic/web/css/site.css b/apps/basic/web/css/site.css index f460b45..66be560 100644 --- a/apps/basic/web/css/site.css +++ b/apps/basic/web/css/site.css @@ -60,6 +60,10 @@ a.desc:after { content: "\e156"; } +.grid-view th { + white-space: nowrap; +} + .hint-block { display: block; margin-top: 5px; diff --git a/docs/guide/README.md b/docs/guide/README.md new file mode 100644 index 0000000..60ee8fb --- /dev/null +++ b/docs/guide/README.md @@ -0,0 +1,8 @@ +This folder contains official Yii 2 guides documentation. + +To add new guide, take the following steps: + +1. Create `guide-name` and put there relevant documentation; +2. If guide has more then one word in name, then it should be with dashes, like: `console-fixture.md`, `module-debug.md`; +3. If your guide is for console commands, than its name should follow convention: `console-{command}.md`; +4. If your guide is for custom modules, than its name should follow convention: `module-{moduleName}.md`. diff --git a/docs/guide/console-fixture.md b/docs/guide/console-fixture.md new file mode 100644 index 0000000..17b7c85 --- /dev/null +++ b/docs/guide/console-fixture.md @@ -0,0 +1,115 @@ +Database Fixtures +================= + +Fixtures are important part of testing. Their main purpose is to populate you with data that needed by testing +different cases. With this data using your tests becoming more efficient and useful. + +Yii supports database fixtures via the `yii fixture` command line tool. This tool supports: + +* Applying new fixtures to database tables; +* Clearing, database tables (with sequences); +* Auto-generating fixtures and populating it with random data. + +Fixtures format +--------------- + +Fixtures are just plain php files returning array. These files are usually stored under `@tests/unit/fixtures` path, but it +can be [configured](#configure-command-globally) in other way. Example of fixture file: + +``` +#users.php file under fixtures path + +return [ + [ + 'name' => 'Chase', + 'login' => 'lmayert', + 'email' => 'strosin.vernice@jerde.com', + 'auth_key' => 'K3nF70it7tzNsHddEiq0BZ0i-OU8S3xV', + 'password' => '$2y$13$WSyE5hHsG1rWN2jV8LRHzubilrCLI5Ev/iK0r3jRuwQEs2ldRu.a2', + ], + [ + 'name' => 'Celestine', + 'login' => 'napoleon69', + 'email' => 'aileen.barton@heaneyschumm.com', + 'auth_key' => 'dZlXsVnIDgIzFgX4EduAqkEPuphhOh9q', + 'password' => '$2y$13$kkgpvJ8lnjKo8RuoR30ay.RjDf15bMcHIF7Vz1zz/6viYG5xJExU6', + ], +]; +``` + +This data will be loaded to the `users`, but before it will be loaded table `users` will be cleared: all data deleted, sequence reseted. +Above fixture example was auto-generated by `yii2-faker` extension, read more about it in these [section](#auto-generating-fixtures). + +Applying fixtures +----------------- + +To apply fixture to the table, run the following command: + +``` +yii fixture/apply +``` + +The required `tbl_name` parameter specifies a database table to which data will be loaded. You can load data to several tables at once. +Below are correct formats of this command: + +``` +// apply fixtures to the "users" table of database +yii fixture/apply users + +// same as above, because default action of "fixture" command is "apply" +yii fixture users + +// apply several fixtures to several tables. Note that there should not be any whitespace between ",", it should be one string. +yii fixture users,users_profiles + +// apply all fixtures +yii fixture/apply all + +// same as above +yii fixture all + +// apply fixtures to the table users, but fixtures will be taken from different path. +yii fixture users --fixturePath='@app/my/custom/path/to/fixtures' + +// apply fixtures to the table users, but for other database connection. +yii fixtures users --db='customDbConnectionId' +``` + +Clearing tables +--------------- + +To clear table, run the following command: + +``` +// clear given table: delete all data and reset sequence. +yii fixture/clear users + +// clear several tables. Note that there should not be any whitespace between ",", it should be one string. +yii fixture/clear users,users_profile + +// clear all tables of current connection in current schema +yii fixture/clear all +``` + +Configure Command Globally +-------------------------- +While command line options allow us to configure the migration command +on-the-fly, sometimes we may want to configure the command once for all. For example you can configure +different migration path as follows: + +``` +'controllerMap' => [ + 'fixture' => [ + 'class' => 'yii\console\FixtureController', + 'fixturePath' => '@app/my/custom/path/to/fixtures', + 'db' => 'customDbConnectionId', + ], +] +``` + +Auto-generating fixtures +------------------------ + +Yii also can auto-generate fixtures for you based on some template. You can generate your fixtures with different data on different languages and formats. +These feature is done by [Faker](https://github.com/fzaninotto/Faker) library and `yii2-faker` extension. +See extension [guide](https://github.com/yiisoft/yii2/tree/master/extensions/yii/faker) for more docs. diff --git a/docs/guide/migration.md b/docs/guide/console-migrate.md similarity index 100% rename from docs/guide/migration.md rename to docs/guide/console-migrate.md diff --git a/docs/guide/index.md b/docs/guide/index.md index a560a3c..65436ad 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -32,13 +32,13 @@ Database - [Basics](database-basics.md) - Connecting to a database, basic queries, transactions and schema manipulation - [Query Builder](query-builder.md) - Querying the database using a simple abstraction layer - [ActiveRecord](active-record.md) - The active record ORM, retrieving and manipulatings records and defining relations -- [Database Migration](migration.md) - Versioning your database with database migrations +- [Database Migration](console-migrate.md) - Versioning your database with database migrations Developers Toolbox ================== - [Automatic Code Generation](gii.md) -- [Debug toolbar and debugger](debugger.md) +- [Debug toolbar and debugger](module-debug.md) - [Error Handling](error.md) - [Logging](logging.md) diff --git a/docs/guide/installation.md b/docs/guide/installation.md index eab0046..099ebb8 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -81,6 +81,8 @@ If you are using Linux you can create a hard link to make it accessable, using t ln requirements.php ../requirements.php ``` +For the advanded app the `requirements.php` is two levels up so you have to use `ln requirements.php ../../requirements.php`. + Yii 2 requires PHP 5.4.0 or higher. Yii has been tested with the [Apache HTTP server](http://httpd.apache.org/) and [Nginx HTTP server](http://nginx.org/) on Windows and Linux. Yii may also be usable on other web servers and platforms, provided that PHP 5.4 or higher is supported. diff --git a/docs/guide/model.md b/docs/guide/model.md index a02e1ad..643ce5f 100644 --- a/docs/guide/model.md +++ b/docs/guide/model.md @@ -112,6 +112,21 @@ class User extends \yii\db\ActiveRecord } ``` +If you want to keep the default scenario available besides your own scenarios, use inheritance to include it: +```php +class User extends \yii\db\ActiveRecord +{ + public function scenarios() + { + $scenarios = parent::scenarios(); + $scenarios['login'] = ['username', 'password']; + $scenarios['register'] = ['username', 'email', 'password']; + return $scenarios; + } +} +``` + + Sometimes, we want to mark an attribute as not safe for massive assignment (but we still want the attribute to be validated). We may do so by prefixing an exclamation character to the attribute name when declaring it in `scenarios()`. For example: diff --git a/docs/guide/debugger.md b/docs/guide/module-debug.md similarity index 100% rename from docs/guide/debugger.md rename to docs/guide/module-debug.md diff --git a/extensions/yii/authclient/clients/GitHub.php b/extensions/yii/authclient/clients/GitHub.php index 57f430d..ed7b6a5 100644 --- a/extensions/yii/authclient/clients/GitHub.php +++ b/extensions/yii/authclient/clients/GitHub.php @@ -73,4 +73,20 @@ class GitHub extends OAuth2 { return $this->api('user', 'GET'); } + + /** + * @inheritdoc + */ + protected function defaultName() + { + return 'github'; + } + + /** + * @inheritdoc + */ + protected function defaultTitle() + { + return 'GitHub'; + } } \ No newline at end of file diff --git a/extensions/yii/debug/assets/bg.png b/extensions/yii/debug/assets/bg.png new file mode 100644 index 0000000..459dd78 Binary files /dev/null and b/extensions/yii/debug/assets/bg.png differ diff --git a/extensions/yii/debug/assets/main.css b/extensions/yii/debug/assets/main.css index 63df423..dd100e0 100644 --- a/extensions/yii/debug/assets/main.css +++ b/extensions/yii/debug/assets/main.css @@ -1,7 +1,3 @@ -body { - padding-top: 62px; -} - span.indent { color: #ccc; } @@ -28,12 +24,12 @@ ul.trace { float: right; } -td { +td, th { white-space: pre-line; word-wrap: break-word; } -th { +.detail-grid-view th { white-space: nowrap; } diff --git a/extensions/yii/debug/assets/toolbar.css b/extensions/yii/debug/assets/toolbar.css index 3c136b5..5946675 100644 --- a/extensions/yii/debug/assets/toolbar.css +++ b/extensions/yii/debug/assets/toolbar.css @@ -1,15 +1,10 @@ #yii-debug-toolbar { - position: fixed; - left: 0; - right: 0; - z-index: 1000000; padding: 0; font: 11px Verdana, Arial, sans-serif; text-align: left; min-height: 40px; overflow: auto; - background: rgb(237,237,237); - background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2VkZWRlZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUzJSIgc3RvcC1jb2xvcj0iI2Y2ZjZmNiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); + background: rgb(246,246,246); background: -moz-linear-gradient(top, rgba(237,237,237,1) 0%, rgba(246,246,246,1) 53%, rgba(255,255,255,1) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(237,237,237,1)), color-stop(53%,rgba(246,246,246,1)), color-stop(100%,rgba(255,255,255,1))); background: -webkit-linear-gradient(top, rgba(237,237,237,1) 0%,rgba(246,246,246,1) 53%,rgba(255,255,255,1) 100%); @@ -17,18 +12,21 @@ background: -ms-linear-gradient(top, rgba(237,237,237,1) 0%,rgba(246,246,246,1) 53%,rgba(255,255,255,1) 100%); background: linear-gradient(to bottom, rgba(237,237,237,1) 0%,rgba(246,246,246,1) 53%,rgba(255,255,255,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ededed', endColorstr='#ffffff',GradientType=0 ); + background: rgb(246,246,246) url(data:image/svg+xml;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAoCAYAAAA/tpB3AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BBQwuINct3v0AAAAjSURBVAjXY3j79u1/JgYGBgYkgpGRkYEYMSpKUGLK+/fvGQAaDAb6F86IsAAAAABJRU5ErkJggg==); /* generated using "cat assets/bg.png | base64" */ } .yii-debug-toolbar-top { - top: 0; margin: 0 0 20px 0; - height: 42px; border-bottom: 1px solid #e4e4e4; } .yii-debug-toolbar-bottom { + position: fixed; + left: 0; + right: 0; bottom: 0; margin: 0; + z-index: 1000000; border-top: 1px solid #ccc; } diff --git a/extensions/yii/debug/views/default/panels/db/detail.php b/extensions/yii/debug/views/default/panels/db/detail.php index 826c045..ee5b2a5 100644 --- a/extensions/yii/debug/views/default/panels/db/detail.php +++ b/extensions/yii/debug/views/default/panels/db/detail.php @@ -9,6 +9,7 @@ use yii\grid\GridView; echo GridView::widget([ 'dataProvider' => $dataProvider, 'id' => 'db-panel-detailed-grid', + 'options' => ['class' => 'detail-grid-view'], 'filterModel' => $searchModel, 'filterUrl' => $panel->getUrl(), 'columns' => [ diff --git a/extensions/yii/debug/views/default/panels/log/detail.php b/extensions/yii/debug/views/default/panels/log/detail.php index 7460516..83f9817 100644 --- a/extensions/yii/debug/views/default/panels/log/detail.php +++ b/extensions/yii/debug/views/default/panels/log/detail.php @@ -10,6 +10,7 @@ use yii\log\Logger; echo GridView::widget([ 'dataProvider' => $dataProvider, 'id' => 'log-panel-detailed-grid', + 'options' => ['class' => 'detail-grid-view'], 'filterModel' => $searchModel, 'filterUrl' => $panel->getUrl(), 'rowOptions' => function ($model, $key, $index, $grid) { @@ -43,7 +44,6 @@ echo GridView::widget([ Logger::LEVEL_INFO => ' Info ', Logger::LEVEL_WARNING => ' Warning ', Logger::LEVEL_ERROR => ' Error ', - Logger::LEVEL_PROFILE => ' Profile ', ], ], 'category', diff --git a/extensions/yii/debug/views/default/panels/profile/detail.php b/extensions/yii/debug/views/default/panels/profile/detail.php index 842795a..95c50e1 100644 --- a/extensions/yii/debug/views/default/panels/profile/detail.php +++ b/extensions/yii/debug/views/default/panels/profile/detail.php @@ -8,6 +8,7 @@ use yii\helpers\Html; echo GridView::widget([ 'dataProvider' => $dataProvider, 'id' => 'profile-panel-detailed-grid', + 'options' => ['class' => 'detail-grid-view'], 'filterModel' => $searchModel, 'filterUrl' => $panel->getUrl(), 'columns' => [ diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index 70f5456..38d640f 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -104,7 +104,7 @@ will be created under the fixtures path (by default ```@tests/unit/fixtures```) You can generate fixtures for all templates by specifying keyword ```all```. ```php -php yii fixture/generate all_fixtures +php yii fixture/generate all ``` This command will generate fixtures for all template files that are stored under template path and diff --git a/framework/yii/console/controllers/FixtureController.php b/framework/yii/console/controllers/FixtureController.php index d5aa8e9..0b400e8 100644 --- a/framework/yii/console/controllers/FixtureController.php +++ b/framework/yii/console/controllers/FixtureController.php @@ -10,6 +10,7 @@ namespace yii\console\controllers; use Yii; use yii\console\Controller; use yii\console\Exception; +use yii\helpers\FileHelper; use yii\test\DbTestTrait; use yii\helpers\Console; @@ -53,6 +54,11 @@ use yii\helpers\Console; class FixtureController extends Controller { use DbTestTrait; + + /** + * type of fixture apply to database + */ + const APPLY_ALL = 'all'; /** * @var string controller default action ID. @@ -110,14 +116,41 @@ class FixtureController extends Controller throw new Exception('Fixture manager is not configured properly. Please refer to official documentation for this purposes.'); } - if (!$this->confirmApply($fixtures)) { + $foundFixtures = $this->findFixtures($fixtures); + + if (!$this->needToApplyAll($fixtures[0])) { + $notFoundFixtures = array_diff($fixtures, $foundFixtures); + + if ($notFoundFixtures) { + $this->notifyNotFound($notFoundFixtures); + } + } + + if (!$foundFixtures) { + throw new Exception("No files were found by name: \"" . implode(', ', $fixtures) . "\".\n" + . "Check that fixtures with these name exists, under fixtures path: \n\"" . Yii::getAlias($this->fixturePath) . "\"." + ); + } + + if (!$this->confirmApply($foundFixtures)) { return; } $this->getFixtureManager()->basePath = $this->fixturePath; $this->getFixtureManager()->db = $this->db; - $this->loadFixtures($fixtures); - $this->notifySuccess($fixtures); + + $transaction = Yii::$app->db->beginTransaction(); + + try { + $this->loadFixtures($foundFixtures); + $transaction->commit(); + + } catch (\Exception $e) { + $transaction->rollback(); + $this->stdout("Exception occured, transaction rollback. Tables will be in same state.\n", Console::BG_RED); + throw $e; + } + $this->notifySuccess($foundFixtures); } /** @@ -127,14 +160,33 @@ class FixtureController extends Controller * @param array|string $tables */ public function actionClear(array $tables) - { + { + if ($this->needToApplyAll($tables[0])) { + $tables = $this->getDbConnection()->schema->getTableNames(); + } + if (!$this->confirmClear($tables)) { return; } - foreach($tables as $table) { - $this->getDbConnection()->createCommand()->truncateTable($table)->execute(); - $this->stdout("Table \"{$table}\" was successfully cleared. \n", Console::FG_GREEN); + $transaction = Yii::$app->db->beginTransaction(); + + try { + $this->getDbConnection()->createCommand()->checkIntegrity(false)->execute(); + + foreach($tables as $table) { + $this->getDbConnection()->createCommand()->truncateTable($table)->execute(); + $this->getDbConnection()->createCommand()->resetSequence($table)->execute(); + $this->stdout(" Table \"{$table}\" was successfully cleared. \n", Console::FG_GREEN); + } + + $this->getDbConnection()->createCommand()->checkIntegrity(true)->execute(); + $transaction->commit(); + + } catch (\Exception $e) { + $transaction->rollback(); + $this->stdout("Exception occured, transaction rollback. Tables will be in same state.\n", Console::BG_RED); + throw $e; } } @@ -180,6 +232,18 @@ class FixtureController extends Controller } /** + * Notifies user that fixtures were not found under fixtures path. + * @param array $fixtures + */ + private function notifyNotFound($fixtures) + { + $this->stdout("Some fixtures were not found under path:\n", Console::BG_RED); + $this->stdout(Yii::getAlias($this->fixturePath) . "\n\n", Console::FG_GREEN); + $this->outputList($fixtures); + $this->stdout("\n"); + } + + /** * Prompts user with confirmation if fixtures should be loaded. * @param array $fixtures * @return boolean @@ -211,7 +275,47 @@ class FixtureController extends Controller private function outputList($data) { foreach($data as $index => $item) { - $this->stdout(($index + 1) . ". {$item}\n", Console::FG_GREEN); + $this->stdout(" " . ($index + 1) . ". {$item}\n", Console::FG_GREEN); } } + + /** + * Checks if needed to apply all fixtures. + * @param string $fixture + * @return bool + */ + public function needToApplyAll($fixture) + { + return $fixture == self::APPLY_ALL; + } + + /** + * Returns array of found fixtures. These may differer from input parameter as not all fixtures may exists. + * @param array $fixtures + */ + private function findFixtures(array $fixtures) + { + $fixturesPath = Yii::getAlias($this->fixturePath); + + $files = []; + + if ($this->needToApplyAll($fixtures[0])) { + $files = FileHelper::findFiles($fixturesPath, ['only' => ['.php']]); + } else { + $filesToSearch = []; + foreach ($fixtures as $fileName) { + $filesToSearch[] = $fileName . '.php'; + } + $files = FileHelper::findFiles($fixturesPath, ['only' => $filesToSearch]); + } + + $foundFixtures = []; + + foreach($files as $fixture) { + $foundFixtures[] = basename($fixture , '.php'); + } + + return $foundFixtures; + } + } diff --git a/framework/yii/console/controllers/HelpController.php b/framework/yii/console/controllers/HelpController.php index eee1923..49ee2c8 100644 --- a/framework/yii/console/controllers/HelpController.php +++ b/framework/yii/console/controllers/HelpController.php @@ -42,11 +42,6 @@ class HelpController extends Controller * Displays available commands or the detailed information * about a particular command. For example, * - * ~~~ - * yii help # list available commands - * yii help message # display help info about "message" - * ~~~ - * * @param string $command The name of the command to show help about. * If not provided, all available commands will be displayed. * @return integer the exit status @@ -149,8 +144,9 @@ class HelpController extends Controller foreach ($commands as $command) { echo "- " . $this->ansiFormat($command, Console::FG_YELLOW) . "\n"; } + $scriptName = $this->getScriptName(); $this->stdout("\nTo see the help of each command, enter:\n", Console::BOLD); - echo "\n yii " . $this->ansiFormat('help', Console::FG_YELLOW) . ' ' + echo "\n $scriptName " . $this->ansiFormat('help', Console::FG_YELLOW) . ' ' . $this->ansiFormat('', Console::FG_CYAN) . "\n\n"; } else { $this->stdout("\nNo commands are found.\n\n", Console::BOLD); @@ -189,8 +185,9 @@ class HelpController extends Controller } echo "\n"; } + $scriptName = $this->getScriptName(); echo "\nTo see the detailed information about individual sub-commands, enter:\n"; - echo "\n yii " . $this->ansiFormat('help', Console::FG_YELLOW) . ' ' + echo "\n $scriptName " . $this->ansiFormat('help', Console::FG_YELLOW) . ' ' . $this->ansiFormat('', Console::FG_CYAN) . "\n\n"; } } @@ -261,10 +258,11 @@ class HelpController extends Controller } $this->stdout("\nUSAGE\n\n", Console::BOLD); + $scriptName = $this->getScriptName(); if ($action->id === $controller->defaultAction) { - echo 'yii ' . $this->ansiFormat($controller->getUniqueId(), Console::FG_YELLOW); + echo $scriptName . ' ' . $this->ansiFormat($controller->getUniqueId(), Console::FG_YELLOW); } else { - echo 'yii ' . $this->ansiFormat($action->getUniqueId(), Console::FG_YELLOW); + echo $scriptName . ' ' . $this->ansiFormat($action->getUniqueId(), Console::FG_YELLOW); } list ($required, $optional) = $this->getArgHelps($method, isset($tags['param']) ? $tags['param'] : []); foreach ($required as $arg => $description) { @@ -425,4 +423,12 @@ class HelpController extends Controller $name = $required ? "$name (required)" : $name; return $doc === '' ? $name : "$name: $doc"; } + + /** + * @return string the name of the cli script currently running. + */ + protected function getScriptName() + { + return basename(Yii::$app->request->scriptFile); + } } diff --git a/framework/yii/db/ActiveQuery.php b/framework/yii/db/ActiveQuery.php index a9a1b19..dc00661 100644 --- a/framework/yii/db/ActiveQuery.php +++ b/framework/yii/db/ActiveQuery.php @@ -326,19 +326,27 @@ class ActiveQuery extends Query implements ActiveQueryInterface } /** - * Returns the table name used by the specified active query. + * Returns the table alias (or table name) that can be used to prefix column names. * @param ActiveQuery $query - * @return string the table name + * @return string the table alias (or table name) enclosed within double curly brackets. */ - private function getQueryTableName($query) + private function getQueryTableAlias($query) { if (empty($query->from)) { /** @var ActiveRecord $modelClass */ $modelClass = $query->modelClass; - return $modelClass::tableName(); + $tableName = $modelClass::tableName(); } else { - return reset($query->from); + $tableName = reset($query->from); } + + if (preg_match('/^(.*?)\s+({{\w+}}|\w+)$/', $tableName, $matches)) { + $tableName = $matches[2]; + } + if (strpos($tableName, '{{') === false) { + $tableName = '{{' . $tableName . '}}'; + } + return $tableName; } /** @@ -364,15 +372,8 @@ class ActiveQuery extends Query implements ActiveQueryInterface return; } - $parentTable = $this->getQueryTableName($parent); - $childTable = $this->getQueryTableName($child); - if (strpos($parentTable, '{{') === false) { - $parentTable = '{{' . $parentTable . '}}'; - } - if (strpos($childTable, '{{') === false) { - $childTable = '{{' . $childTable . '}}'; - } - + $parentTable = $this->getQueryTableAlias($parent); + $childTable = $this->getQueryTableAlias($child); if (!empty($child->link)) { $on = []; diff --git a/framework/yii/grid/GridView.php b/framework/yii/grid/GridView.php index 35d89b2..e270974 100644 --- a/framework/yii/grid/GridView.php +++ b/framework/yii/grid/GridView.php @@ -49,6 +49,11 @@ class GridView extends BaseListView */ public $tableOptions = ['class' => 'table table-striped table-bordered']; /** + * @var array the HTML attributes for the container tag of the grid view. + * The "tag" element specifies the tag name of the container element and defaults to "div". + */ + public $options = ['class' => 'grid-view']; + /** * @var array the HTML attributes for the table header row */ public $headerRowOptions = []; diff --git a/framework/yii/helpers/BaseConsole.php b/framework/yii/helpers/BaseConsole.php index c78ed67..307fb00 100644 --- a/framework/yii/helpers/BaseConsole.php +++ b/framework/yii/helpers/BaseConsole.php @@ -861,7 +861,7 @@ class BaseConsole } $width -= mb_strlen($prefix); - $percent = $done / $total; + $percent = ($total == 0) ? 1 : $done / $total; $info = sprintf("%d%% (%d/%d)", $percent * 100, $done, $total); if ($done > $total || $done == 0) { diff --git a/framework/yii/widgets/DetailView.php b/framework/yii/widgets/DetailView.php index 8ced307..3a45a4e 100644 --- a/framework/yii/widgets/DetailView.php +++ b/framework/yii/widgets/DetailView.php @@ -90,7 +90,7 @@ class DetailView extends Widget * @var array the HTML attributes for the container tag of this widget. The "tag" option specifies * what container tag should be used. It defaults to "table" if not set. */ - public $options = ['class' => 'table table-striped table-bordered']; + public $options = ['class' => 'table table-striped table-bordered detail-view']; /** * @var array|Formatter the formatter used to format model attribute values into displayable texts. * This can be either an instance of [[Formatter]] or an configuration array for creating the [[Formatter]] diff --git a/framework/yii/widgets/ListView.php b/framework/yii/widgets/ListView.php index c112554..43eaab4 100644 --- a/framework/yii/widgets/ListView.php +++ b/framework/yii/widgets/ListView.php @@ -52,6 +52,11 @@ class ListView extends BaseListView * @var string the HTML code to be displayed between any two consecutive items. */ public $separator = "\n"; + /** + * @var array the HTML attributes for the container tag of the list view. + * The "tag" element specifies the tag name of the container element and defaults to "div". + */ + public $options = ['class' => 'list-view']; /**