From a3071fd90dd392de5da4e424e50e72b85ddfe3be Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 2 Jan 2014 23:46:08 +0400 Subject: [PATCH 01/13] added faker integration --- composer.json | 2 + extensions/yii/faker/CHANGELOG.md | 12 + extensions/yii/faker/FixtureController.php | 335 ++++++++++++++++++ extensions/yii/faker/LICENSE.md | 32 ++ extensions/yii/faker/README.md | 134 +++++++ extensions/yii/faker/composer.json | 27 ++ .../console/controllers/FixtureController.php | 150 ++++++++ 7 files changed, 692 insertions(+) create mode 100644 extensions/yii/faker/CHANGELOG.md create mode 100644 extensions/yii/faker/FixtureController.php create mode 100644 extensions/yii/faker/LICENSE.md create mode 100644 extensions/yii/faker/README.md create mode 100644 extensions/yii/faker/composer.json create mode 100644 framework/yii/console/controllers/FixtureController.php diff --git a/composer.json b/composer.json index 2c807aab04..83ee504783 100644 --- a/composer.json +++ b/composer.json @@ -55,6 +55,7 @@ "yiisoft/yii2-codeception": "self.version", "yiisoft/yii2-debug": "self.version", "yiisoft/yii2-elasticsearch": "self.version", + "yiisoft/yii2-faker": "self.version", "yiisoft/yii2-imagine": "self.version", "yiisoft/yii2-gii": "self.version", "yiisoft/yii2-jui": "self.version", @@ -97,6 +98,7 @@ "yii\\codeception\\": "extensions/", "yii\\debug\\": "extensions/", "yii\\elasticsearch\\": "extensions/", + "yii\\faker\\": "extensions/", "yii\\gii\\": "extensions/", "yii\\imagine\\" : "extensions/", "yii\\jui\\": "extensions/", diff --git a/extensions/yii/faker/CHANGELOG.md b/extensions/yii/faker/CHANGELOG.md new file mode 100644 index 0000000000..9643b4bfa5 --- /dev/null +++ b/extensions/yii/faker/CHANGELOG.md @@ -0,0 +1,12 @@ +Yii Framework 2 faker extension Change Log +============================================== + +2.0.0 beta under development +---------------------------- + +- no changes in this release. + +2.0.0 alpha, December 1, 2013 +----------------------------- + +- Initial release. \ No newline at end of file diff --git a/extensions/yii/faker/FixtureController.php b/extensions/yii/faker/FixtureController.php new file mode 100644 index 0000000000..ddbc514029 --- /dev/null +++ b/extensions/yii/faker/FixtureController.php @@ -0,0 +1,335 @@ + [ + * 'faker' => [ + * 'class' => 'yii\faker\FixtureController', + * ], + * ], + * ~~~ + * + * To start using this command you need to be familiar (read guide) for the Faker library and + * generate fixtures template files, according to the given format: + * + * ~~~ + * #users.php file under $templatePath + * + * return [ + * [ + * 'table_column0' => 'faker_formatter', + * ... + * 'table_columnN' => 'other_faker_formatter + * 'table_columnN+1' => function ($fixture, $faker, $index) { + * //set needed fixture fields based on different conditions + * return $fixture; + * } + * ], + * ]; + * ~~~ + * + * If you use callback as a attribute value, then it will be called as shown with three parameters: + * * $fixture - current fixture array. + * * $faker - faker generator instance + * * $index - current fixture index. For example if user need to generate 3 fixtures for tbl_user, it will be 0..2 + * After you set all needed fields in callback, you need to return $fixture array back from the callback. + * + * After you prepared needed templates for tables you can simply generate your fixtures via command + * + * ~~~ + * php yii faker/generate users + * + * #also a short version of this command (generate action is default) + * php yii faker users + * ~~~ + * + * In the code above "users" is template name, after this command run, new file named same as template + * will be created under the $fixturesPath folder. + * You can generate fixtures for all templates by specifying keyword "all_fixtures" + * + * ~~~ + * php yii faker/generate all_fixtures + * ~~~ + * + * This command will generate fixtures for all template files that are stored under $templatePath and + * store fixtures under $fixturesPath with file names same as templates names. + * + * You can specify how many fixtures per file you need by the second parameter. In the code below we generate + * all fixtures and in each file there will be 3 rows (fixtures). + * + * ~~~ + * php yii faker/generate all_fixtures 3 + * ~~~ + * + * You can specify different options of this command: + * + * ~~~ + * #generate fixtures in russian languge + * php yii faker/generate users 5 --language='ru_RU' + * + * #read templates from the other path + * php yii faker/generate all_fixtures --templatePath='@app/path/to/my/custom/templates' + * + * #generate fixtures into other folders, but be sure that this folders exists or you will get notice about that. + * php yii faker/generate all_fixtures --fixturesPath='@tests/unit/fixtures/subfolder1/subfolder2/subfolder3' + * ~~~ + * + * You also can create your own data providers for custom tables fields, see Faker library guide for more info (https://github.com/fzaninotto/Faker); + * After you created custom provider, for example: + * + * ~~~ + * + * class Book extends \Faker\Provider\Base + * { + * public function title($nbWords = 5) + * { + * $sentence = $this->generator->sentence($nbWords); + * return mb_substr($sentence, 0, mb_strlen($sentence) - 1); + * } + * + * public function ISBN() + * { + * return $this->generator->randomNumber(13); + * } + * } + * ~~~ + * + * you can use it by adding it to the $providers property of the current command. In your console.php config: + * + * ~~~ + * 'controllerMap' => [ + * 'faker' => [ + * 'class' => 'yii\faker\FixtureController', + * 'providers' => [ + * 'app\tests\unit\faker\providers\Book', + * ], + * ], + * ], + * ~~~ + * + * @property \Faker\Generator $generator + * + * @since 2.0.0 + */ +class FixtureController extends \yii\console\controllers\FixtureController +{ + + /** + * type of fixture generating + */ + const GENERATE_ALL = 'all_fixtures'; + + /** + * @var string controller default action ID. + */ + public $defaultAction = 'generate'; + + /** + * Alias to the template path, where all tables templates are stored. + * @var string + */ + public $templatePath = '@tests/unit/templates/fixtures'; + + /** + * Language to use when generating fixtures data. + * @var string + */ + public $language; + + /** + * Additional data providers that can be created by user and will be added to the Faker generator. + * More info in [Faker](https://github.com/fzaninotto/Faker.) library docs. + * @var array + */ + public $providers = array(); + + /** + * Faker generator instance + * @var \Faker\Generator + */ + private $_generator; + + /** + * Returns the names of the global options for this command. + * @return array the names of the global options for this command. + */ + public function globalOptions() + { + return array_merge(parent::globalOptions(), [ + 'templatePath','language' + ]); + } + + public function beforeAction($action) + { + if (parent::beforeAction($action)) { + $this->checkPaths(); + $this->addProviders(); + return true; + } else { + return false; + } + } + + /** + * Generates fixtures and fill them with Faker data. + * @param string $file filename for the table template. You can generate all fixtures for all tables + * by specifiyng keyword "all_fixtures" as filename. + * @param integer $times how much fixtures do you want per table + */ + public function actionGenerate($file, $times = 2) + { + $templatePath = Yii::getAlias($this->templatePath); + $fixturesPath = Yii::getAlias($this->fixturesPath); + + if ($this->needToGenerateAll($file)) + $files = FileHelper::findFiles($templatePath, ['only' => ['.php']]); + else + $files = FileHelper::findFiles($templatePath, ['only' => [$file.'.php']]); + + foreach ($files as $templateFile) + { + $fixtureFileName = basename($templateFile); + $template = $this->getTemplate($templateFile); + $fixtures = []; + + for ($i = 0; $i < $times; $i++) { + $fixtures[$i] = $this->generateFixture($template, $i); + } + + $content = $this->getExportedFormat($fixtures); + file_put_contents($fixturesPath.'/'.$fixtureFileName, $content); + $this->stdout("Fixture file was generated under: " . realpath($fixturesPath . "/" . $fixtureFileName) . "\n", Console::FG_GREEN); + } + } + + /** + * Returns Faker generator instance. Getter for private property. + * @return \Faker\Generator + */ + public function getGenerator() + { + if (is_null($this->_generator)) + { + #replacing - on _ because Faker support only en_US format and not intl + + $language = is_null($this->language) ? str_replace('-','_', Yii::$app->language) : $this->language; + $this->_generator = \Faker\Factory::create($language); + } + + return $this->_generator; + } + + /** + * Check if the template path and migrations path exists and writable. + */ + public function checkPaths() + { + $path = Yii::getAlias($this->templatePath); + + if (!is_dir($path)) + throw new Exception("The template path \"{$this->templatePath}\" not exist"); + } + + /** + * Adds users providers to the faker generator. + */ + public function addProviders() + { + foreach($this->providers as $provider) + $this->generator->addProvider(new $provider($this->generator)); + } + + /** + * Checks if needed to generate all fixtures. + * @param string $file + * @return bool + */ + public function needToGenerateAll($file) + { + return $file == self::GENERATE_ALL; + } + + /** + * Returns generator template for the given fixture name + * @param string $file template file + * @return array generator template + * @throws \yii\console\Exception if wrong file format + */ + public function getTemplate($file) + { + $template = require($file); + + if (!is_array($template)) { + throw new Exception("The template file \"$file\" has wrong format. It should return valid template array"); + } + + return $template; + } + + /** + * Returns exported to the string representation of given fixtures array. + * @param type $fixtures + * @return string exported fixtures format + */ + public function getExportedFormat($fixtures) + { + $content = "$value) { + $content .= "\n\t\t'{$name}' => '{$value}',"; + } + + $content .= "\n\t],"; + + } + $content .= "\n];\n"; + return $content; + } + + /** + * Generates fixture from given template + * @param array $template fixture template + * @param integer $index current fixture index + * @return array fixture + */ + public function generateFixture($template, $index) + { + $fixture = []; + + foreach($template as $attribute => $fakerProperty) { + if (!is_string($fakerProperty)) { + $fixture = call_user_func_array($fakerProperty,[$fixture,$this->generator, $index]); + } else { + $fixture[$attribute] = $this->generator->$fakerProperty; + } + } + + return $fixture; + } + +} diff --git a/extensions/yii/faker/LICENSE.md b/extensions/yii/faker/LICENSE.md new file mode 100644 index 0000000000..6edcc4f571 --- /dev/null +++ b/extensions/yii/faker/LICENSE.md @@ -0,0 +1,32 @@ +The Yii framework is free software. It is released under the terms of +the following BSD License. + +Copyright © 2008-2013 by Yii Software LLC (http://www.yiisoft.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Yii Software LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md new file mode 100644 index 0000000000..27529e8fd3 --- /dev/null +++ b/extensions/yii/faker/README.md @@ -0,0 +1,134 @@ +Faker Extension for Yii 2 +=============================== + +This extension provides a [`Faker`](https://github.com/fzaninotto/Faker) fixture command for Yii 2. + +Installation +------------ + +The preferred way to install this extension is through [composer](http://getcomposer.org/download/). + +Either run + +``` +php composer.phar require yiisoft/yii2-faker "*" +``` + +or add + +```json +"yiisoft/yii2-faker": "*" +``` + +to the require section of your composer.json. + +Usage +----- + +To use this extension, simply add the following code in your application configuration (console.php): + +```php +'controllerMap' => [ + 'faker' => [ + 'class' => 'yii\faker\FixtureController', + ], +], +``` +To start using this command you need to be familiar (read guide) for the Faker library and +generate fixtures template files, according to the given format: + +```php +#users.php file under template path (by default @tests/unit/fixtures/templates) +return [ + [ + 'table_column0' => 'faker_formatter', + ... + 'table_columnN' => 'other_faker_formatter + 'table_columnN+1' => function ($fixture, $faker, $index) { + //set needed fixture fields based on different conditions + return $fixture; + } + ], +]; +~~~ +``` + +If you use callback as a attribute value, then it will be called as shown with three parameters: + +* $fixture - current fixture array. +* $faker - faker generator instance +* $index - current fixture index. For example if user need to generate 3 fixtures for tbl_user, it will be 0..2. + +After you set all needed fields in callback, you need to return $fixture array back from the callback. + +After you prepared needed templates for tables you can simply generate your fixtures via command + +```php +#generate fixtures for the users table based on users fixture template +php yii faker/generate users + +#also a short version of this command ("generate" action is default) +php yii faker users +``` + +In the code above "users" is template name, after this command run, new file named same as template +will be created under the fixtures path (by default ```@tests/unit/fixtures```) folder. +You can generate fixtures for all templates by specifying keyword "all_fixtures" + +```php +php yii faker/generate all_fixtures +``` + +This command will generate fixtures for all template files that are stored under template path and +store fixtures under fixtures path with file names same as templates names. +You can specify how many fixtures per file you need by the second parameter. In the code below we generate +all fixtures and in each file there will be 3 rows (fixtures). + +```php +php yii faker/generate all_fixtures 3 +``` +You can specify different options of this command: + +```php +#generate fixtures in russian language +php yii faker/generate users 5 --language='ru_RU' + +#read templates from the other path +php yii faker/generate all_fixtures --templatePath='@app/path/to/my/custom/templates' + +#generate fixtures into other folders, but be sure that this folders exists or you will get notice about that. +php yii faker/generate all_fixtures --fixturesPath='@tests/unit/fixtures/subfolder1/subfolder2/subfolder3' +``` + +You also can create your own data providers for custom tables fields, see [Faker]((https://github.com/fzaninotto/Faker)) library guide for more info; +After you created custom provider, for example: + +```php +class Book extends \Faker\Provider\Base +{ + public function title($nbWords = 5) + { + $sentence = $this->generator->sentence($nbWords); + return mb_substr($sentence, 0, mb_strlen($sentence) - 1); + } + + public function ISBN() + { + return $this->generator->randomNumber(13); + } + + } +``` + +You can use it by adding it to the $providers property of the current command. In your console.php config: + +```php +'controllerMap' => [ + 'faker:fixture' => [ + 'class' => 'yii\faker\FixtureController', + 'providers' => [ + 'app\tests\unit\faker\providers\Book', + ], + ], +] +``` \ No newline at end of file diff --git a/extensions/yii/faker/composer.json b/extensions/yii/faker/composer.json new file mode 100644 index 0000000000..526aa1d65d --- /dev/null +++ b/extensions/yii/faker/composer.json @@ -0,0 +1,27 @@ +{ + "name": "yiisoft/yii2-faker", + "description": "Fixture generator. The Faker integration for the Yii framework.", + "keywords": ["yii", "faker", "fixture"], + "type": "yii2-extension", + "license": "BSD-3-Clause", + "support": { + "forum": "http://www.yiiframework.com/forum/", + "wiki": "http://www.yiiframework.com/wiki/", + "irc": "irc://irc.freenode.net/yii", + "source": "https://github.com/yiisoft/yii2" + }, + "authors": [ + { + "name": "Mark Jebri", + "email": "mark.github@yandex.ru" + } + ], + "require": { + "yiisoft/yii2": "*", + "fzaninotto/faker": "*" + }, + "autoload": { + "psr-0": { "yii\\faker\\": "" } + }, + "target-dir": "yii/faker" +} \ No newline at end of file diff --git a/framework/yii/console/controllers/FixtureController.php b/framework/yii/console/controllers/FixtureController.php new file mode 100644 index 0000000000..9ef8aa8855 --- /dev/null +++ b/framework/yii/console/controllers/FixtureController.php @@ -0,0 +1,150 @@ + [ + * 'class' => 'yii\db\Connection', + * 'dsn' => 'mysql:host=localhost;dbname={your_database}', + * 'username' => '{your_db_user}', + * 'password' => '', + * 'charset' => 'utf8', + * ], + * 'fixture' => [ + * 'class' => 'yii\test\DbFixtureManager', + * ], + * ~~~ + * + * ~~~ + * #load fixtures under $fixturesPath to the "users" table + * php yii fixture/apply users + * + * #also a short version of this command (generate action is default) + * php yii fixture users + * + * #load fixtures under $fixturesPath to the "users" table to the different connection + * php yii fixture/apply users --db='someOtherDbConneciton' + * + * #load fixtures under different $fixturesPath to the "users" table. + * php yii fixture/apply users --fixturesPath='@app/some/other/path/to/fixtures' + * ~~~ + * + * @author Mark Jebri + * @since 2.0 + */ +class FixtureController extends Controller +{ + + use \yii\test\DbTestTrait; + + /** + * @var string controller default action ID. + */ + public $defaultAction = 'apply'; + + /** + * Alias to the path, where all fixtures are stored. + * @var string + */ + public $fixturesPath = '@tests/unit/fixtures'; + + /** + * Id of the database connection component of the application. + * @var string + */ + public $db = 'db'; + + /** + * Returns the names of the global options for this command. + * @return array the names of the global options for this command. + */ + public function globalOptions() + { + return array_merge(parent::globalOptions(), [ + 'db','fixturesPath' + ]); + } + + /** + * This method is invoked right before an action is to be executed (after all possible filters.) + * It checks that fixtures path and database connection are available. + * @param type $action + * @return boolean + */ + public function beforeAction($action) + { + if (parent::beforeAction($action)) { + $this->checkRequirements(); + return true; + } else { + return false; + } + } + + /** + * Apply given fixture to the table. Fixture name can be the same as the table name or + * you can specify table name as a second parameter. + * @param string $fixture + */ + public function actionApply($fixture) + { + $this->fixtureManager->basePath = $this->fixturesPath; + $this->fixtureManager->db = $this->db; + $this->loadFixtures([$fixture]); + } + + /** + * Truncate given table and clear all fixtures from it. + * @param string $table + */ + public function actionClear($table) + { + $this->dbConnection->createCommand()->truncateTable($table)->execute(); + echo "Table \"{$table}\" was successfully cleared. \n"; + } + + /** + * Checks if the database and fixtures path are available. + * @throws Exception + */ + public function checkRequirements() + { + $path = Yii::getAlias($this->fixturesPath, false); + + if (!is_dir($path) || !is_writable($path)) { + throw new Exception("The fixtures path \"{$this->fixturesPath}\" not exist or is not writable"); + } + + } + + /** + * Returns database connection component + * @return yii\db\Connection|null + */ + public function getDbConnection() + { + $db = Yii::$app->getComponent($this->db); + + if ($db == null) { + throw new Exception("There is no database connection component with id \"{$this->db}\"."); + } + + return $db; + } + +} From 60c305fa3f30612e5c7eb41da61ff6922b1aa8a3 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 2 Jan 2014 23:48:52 +0400 Subject: [PATCH 02/13] docs improved --- extensions/yii/faker/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index 27529e8fd3..a916061ddb 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -34,6 +34,8 @@ To use this extension, simply add the following code in your application config ], ], ``` +Set valid ```test``` alias in your console config, for example for ```basic``` application template, this should be added +to ```console.php``` config: ```Yii::setAlias('tests', __DIR__ . '/../tests');``` To start using this command you need to be familiar (read guide) for the Faker library and generate fixtures template files, according to the given format: From 9666bc6cedfbcd2f519cc36c0efffeab59be72f9 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 2 Jan 2014 23:53:20 +0400 Subject: [PATCH 03/13] docs fix --- extensions/yii/faker/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index a916061ddb..a83cfa08dc 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -36,16 +36,17 @@ To use this extension, simply add the following code in your application config ``` Set valid ```test``` alias in your console config, for example for ```basic``` application template, this should be added to ```console.php``` config: ```Yii::setAlias('tests', __DIR__ . '/../tests');``` -To start using this command you need to be familiar (read guide) for the Faker library and +To start using this command you need to be familiar (read guide) for the [Faker](https://github.com/fzaninotto/Faker) library and generate fixtures template files, according to the given format: ```php +~~~ #users.php file under template path (by default @tests/unit/fixtures/templates) return [ [ 'table_column0' => 'faker_formatter', ... - 'table_columnN' => 'other_faker_formatter + 'table_columnN' => 'other_faker_formatter' 'table_columnN+1' => function ($fixture, $faker, $index) { //set needed fixture fields based on different conditions return $fixture; @@ -75,7 +76,7 @@ php yii faker users In the code above "users" is template name, after this command run, new file named same as template will be created under the fixtures path (by default ```@tests/unit/fixtures```) folder. -You can generate fixtures for all templates by specifying keyword "all_fixtures" +You can generate fixtures for all templates by specifying keyword ```all_fixtures```. ```php php yii faker/generate all_fixtures From 34b03428ed97e72aece2e4b12d83f7c64d9e920d Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 2 Jan 2014 23:55:05 +0400 Subject: [PATCH 04/13] formatting fix --- extensions/yii/faker/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index a83cfa08dc..db9602bd90 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -40,7 +40,6 @@ To start using this command you need to be familiar (read guide) for the [Faker] generate fixtures template files, according to the given format: ```php -~~~ #users.php file under template path (by default @tests/unit/fixtures/templates) return [ [ @@ -53,7 +52,6 @@ return [ } ], ]; -~~~ ``` If you use callback as a attribute value, then it will be called as shown with three parameters: From 1bf1a34f6fd13fba6ce232fe56a0ad28c62fb180 Mon Sep 17 00:00:00 2001 From: Mark Date: Thu, 2 Jan 2014 23:59:13 +0400 Subject: [PATCH 05/13] new docs added --- extensions/yii/faker/README.md | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index db9602bd90..487180165a 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -40,7 +40,7 @@ To start using this command you need to be familiar (read guide) for the [Faker] generate fixtures template files, according to the given format: ```php -#users.php file under template path (by default @tests/unit/fixtures/templates) +#users.php file under template path (by default @tests/unit/templates/fixtures) return [ [ 'table_column0' => 'faker_formatter', @@ -48,6 +48,8 @@ return [ 'table_columnN' => 'other_faker_formatter' 'table_columnN+1' => function ($fixture, $faker, $index) { //set needed fixture fields based on different conditions + + $fixture['body] = $faker->sentence(7,true); #generate sentence exact with 7 words. return $fixture; } ], @@ -56,12 +58,32 @@ return [ If you use callback as a attribute value, then it will be called as shown with three parameters: -* $fixture - current fixture array. -* $faker - faker generator instance -* $index - current fixture index. For example if user need to generate 3 fixtures for tbl_user, it will be 0..2. +* ```$fixture``` - current fixture array. +* ```$faker``` - faker generator instance +* ```$index``` - current fixture index. For example if user need to generate 3 fixtures for tbl_user, it will be 0..2. After you set all needed fields in callback, you need to return $fixture array back from the callback. +Another example of valid template: + +```php +use yii\helpers\Security; + +return [ + 'name' => 'firstName', + 'phone' => 'phoneNumber', + 'city' => 'city', + 'password' => function ($fixture, $faker, $index) { + $fixture['password'] = Security::generatePasswordHash('password_' . $index); + return $fixture; + }, + 'auth_key' => function ($fixture, $faker, $index) { + $fixture['auth_key'] = Security::generateRandomKey(); + return $fixture; + }, +]; +``` + After you prepared needed templates for tables you can simply generate your fixtures via command ```php From 319d0aef82f944dbb9b4c127436edfc129779e51 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 3 Jan 2014 00:01:49 +0400 Subject: [PATCH 06/13] quotation added. --- extensions/yii/faker/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index 487180165a..0cef652dd0 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -49,7 +49,7 @@ return [ 'table_columnN+1' => function ($fixture, $faker, $index) { //set needed fixture fields based on different conditions - $fixture['body] = $faker->sentence(7,true); #generate sentence exact with 7 words. + $fixture['body'] = $faker->sentence(7,true); #generate sentence exact with 7 words. return $fixture; } ], @@ -143,7 +143,7 @@ class Book extends \Faker\Provider\Base } ``` -You can use it by adding it to the $providers property of the current command. In your console.php config: +You can use it by adding it to the ```$providers``` property of the current command. In your console.php config: ```php 'controllerMap' => [ From 2ae2d57512d60cb89b58e46541e3e0f570312be5 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 3 Jan 2014 00:03:23 +0400 Subject: [PATCH 07/13] readme guide improved --- extensions/yii/faker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index 0cef652dd0..c673bcc5f9 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -46,7 +46,7 @@ return [ 'table_column0' => 'faker_formatter', ... 'table_columnN' => 'other_faker_formatter' - 'table_columnN+1' => function ($fixture, $faker, $index) { + 'body' => function ($fixture, $faker, $index) { //set needed fixture fields based on different conditions $fixture['body'] = $faker->sentence(7,true); #generate sentence exact with 7 words. From aa9049719695fdc830988ce46699c528bf1af588 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 3 Jan 2014 00:05:12 +0400 Subject: [PATCH 08/13] docs fix --- extensions/yii/faker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index c673bcc5f9..341be6eab5 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -147,7 +147,7 @@ You can use it by adding it to the ```$providers``` property of the current comm ```php 'controllerMap' => [ - 'faker:fixture' => [ + 'faker' => [ 'class' => 'yii\faker\FixtureController', 'providers' => [ 'app\tests\unit\faker\providers\Book', From 467254a30e4cc1a6b6f6ba29ba187790a5f067c5 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 3 Jan 2014 00:48:10 +0400 Subject: [PATCH 09/13] fixed CS, added exception check --- extensions/yii/faker/FixtureController.php | 36 +++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/extensions/yii/faker/FixtureController.php b/extensions/yii/faker/FixtureController.php index ddbc514029..174d22e6d0 100644 --- a/extensions/yii/faker/FixtureController.php +++ b/extensions/yii/faker/FixtureController.php @@ -16,7 +16,7 @@ use yii\helpers\Console; * This command manage fixtures creations based on given template. * * Fixtures are one of the important paths in unit testing. To speed up developers - * work this fixtures can be generated automatically, based on prepared template. + * work these fixtures can be generated automatically, based on prepared template. * This command is a simple wrapper for the fixtures library [Faker](https://github.com/fzaninotto/Faker). * * You should configure this command as follows (you can use any alias, not only "faker:fixture"): @@ -49,9 +49,9 @@ use yii\helpers\Console; * ~~~ * * If you use callback as a attribute value, then it will be called as shown with three parameters: - * * $fixture - current fixture array. - * * $faker - faker generator instance - * * $index - current fixture index. For example if user need to generate 3 fixtures for tbl_user, it will be 0..2 + * - $fixture - current fixture array. + * - $faker - faker generator instance + * - $index - current fixture index. For example if user need to generate 3 fixtures for tbl_user, it will be 0..2 * After you set all needed fields in callback, you need to return $fixture array back from the callback. * * After you prepared needed templates for tables you can simply generate your fixtures via command @@ -161,7 +161,7 @@ class FixtureController extends \yii\console\controllers\FixtureController * More info in [Faker](https://github.com/fzaninotto/Faker.) library docs. * @var array */ - public $providers = array(); + public $providers = []; /** * Faker generator instance @@ -202,13 +202,20 @@ class FixtureController extends \yii\console\controllers\FixtureController $templatePath = Yii::getAlias($this->templatePath); $fixturesPath = Yii::getAlias($this->fixturesPath); - if ($this->needToGenerateAll($file)) + if ($this->needToGenerateAll($file)) { $files = FileHelper::findFiles($templatePath, ['only' => ['.php']]); - else + } else { $files = FileHelper::findFiles($templatePath, ['only' => [$file.'.php']]); + } - foreach ($files as $templateFile) - { + if (empty($files)) { + throw new Exception( + "No files were found by name: \"{$file}\". \n" + . "Check that template with these name exists, under template path: \n\"{$templatePath}\"." + ); + } + + foreach ($files as $templateFile) { $fixtureFileName = basename($templateFile); $template = $this->getTemplate($templateFile); $fixtures = []; @@ -229,9 +236,8 @@ class FixtureController extends \yii\console\controllers\FixtureController */ public function getGenerator() { - if (is_null($this->_generator)) - { - #replacing - on _ because Faker support only en_US format and not intl + if (is_null($this->_generator)) { + //replacing - on _ because Faker support only en_US format and not intl $language = is_null($this->language) ? str_replace('-','_', Yii::$app->language) : $this->language; $this->_generator = \Faker\Factory::create($language); @@ -247,8 +253,9 @@ class FixtureController extends \yii\console\controllers\FixtureController { $path = Yii::getAlias($this->templatePath); - if (!is_dir($path)) + if (!is_dir($path)) { throw new Exception("The template path \"{$this->templatePath}\" not exist"); + } } /** @@ -256,8 +263,9 @@ class FixtureController extends \yii\console\controllers\FixtureController */ public function addProviders() { - foreach($this->providers as $provider) + foreach($this->providers as $provider) { $this->generator->addProvider(new $provider($this->generator)); + } } /** From 4204f896af1c5141577b30d0df2627db7bca6325 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 3 Jan 2014 01:44:23 +0400 Subject: [PATCH 10/13] added prompt for the user, interface improved, multiply generation added --- extensions/yii/faker/FixtureController.php | 38 ++++++++++++++++++---- extensions/yii/faker/README.md | 14 ++++---- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/extensions/yii/faker/FixtureController.php b/extensions/yii/faker/FixtureController.php index 174d22e6d0..3ad458ebee 100644 --- a/extensions/yii/faker/FixtureController.php +++ b/extensions/yii/faker/FixtureController.php @@ -59,7 +59,7 @@ use yii\helpers\Console; * ~~~ * php yii faker/generate users * - * #also a short version of this command (generate action is default) + * //also a short version of this command (generate action is default) * php yii faker users * ~~~ * @@ -84,13 +84,13 @@ use yii\helpers\Console; * You can specify different options of this command: * * ~~~ - * #generate fixtures in russian languge + * //generate fixtures in russian languge * php yii faker/generate users 5 --language='ru_RU' * - * #read templates from the other path + * //read templates from the other path * php yii faker/generate all_fixtures --templatePath='@app/path/to/my/custom/templates' * - * #generate fixtures into other folders, but be sure that this folders exists or you will get notice about that. + * //generate fixtures into other folders, but be sure that this folders exists or you will get notice about that. * php yii faker/generate all_fixtures --fixturesPath='@tests/unit/fixtures/subfolder1/subfolder2/subfolder3' * ~~~ * @@ -204,8 +204,12 @@ class FixtureController extends \yii\console\controllers\FixtureController if ($this->needToGenerateAll($file)) { $files = FileHelper::findFiles($templatePath, ['only' => ['.php']]); - } else { - $files = FileHelper::findFiles($templatePath, ['only' => [$file.'.php']]); + } + else { + foreach(explode(',', $file) as $fileName) { + $filesToSearch[] = $fileName . '.php'; + } + $files = FileHelper::findFiles($templatePath, ['only' => $filesToSearch]); } if (empty($files)) { @@ -215,6 +219,10 @@ class FixtureController extends \yii\console\controllers\FixtureController ); } + if (!$this->confirmGeneration($files)) { + return; + } + foreach ($files as $templateFile) { $fixtureFileName = basename($templateFile); $template = $this->getTemplate($templateFile); @@ -340,4 +348,22 @@ class FixtureController extends \yii\console\controllers\FixtureController return $fixture; } + /** + * Prompts user with message if he confirm generation with given fixture templates files. + * @param array $files + * @return boolean + */ + public function confirmGeneration($files) + { + $this->stdout("Fixtures will be generated under the path: \n", Console::FG_YELLOW); + $this->stdout(realpath(Yii::getAlias($this->fixturesPath, false)) ."\n\n", Console::FG_GREEN); + $this->stdout("Templates will be taken from path: \n", Console::FG_YELLOW); + $this->stdout(realpath(Yii::getAlias($this->templatePath, false)) . "\n\n", Console::FG_GREEN); + + foreach ($files as $index => $fileName) { + $this->stdout(" " . $index +1 . ". " . basename($fileName) . "\n",Console::FG_GREEN); + } + return $this->confirm('Generate above fixtures?'); + } + } diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index 341be6eab5..2e2700f46a 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -40,7 +40,7 @@ To start using this command you need to be familiar (read guide) for the [Faker] generate fixtures template files, according to the given format: ```php -#users.php file under template path (by default @tests/unit/templates/fixtures) +//users.php file under template path (by default @tests/unit/templates/fixtures) return [ [ 'table_column0' => 'faker_formatter', @@ -49,7 +49,7 @@ return [ 'body' => function ($fixture, $faker, $index) { //set needed fixture fields based on different conditions - $fixture['body'] = $faker->sentence(7,true); #generate sentence exact with 7 words. + $fixture['body'] = $faker->sentence(7,true); //generate sentence exact with 7 words. return $fixture; } ], @@ -87,10 +87,10 @@ return [ After you prepared needed templates for tables you can simply generate your fixtures via command ```php -#generate fixtures for the users table based on users fixture template +//generate fixtures for the users table based on users fixture template php yii faker/generate users -#also a short version of this command ("generate" action is default) +//also a short version of this command ("generate" action is default) php yii faker users ``` @@ -113,13 +113,13 @@ php yii faker/generate all_fixtures 3 You can specify different options of this command: ```php -#generate fixtures in russian language +//generate fixtures in russian language php yii faker/generate users 5 --language='ru_RU' -#read templates from the other path +//read templates from the other path php yii faker/generate all_fixtures --templatePath='@app/path/to/my/custom/templates' -#generate fixtures into other folders, but be sure that this folders exists or you will get notice about that. +//generate fixtures into other folders, but be sure that this folders exists or you will get notice about that. php yii faker/generate all_fixtures --fixturesPath='@tests/unit/fixtures/subfolder1/subfolder2/subfolder3' ``` From 8dc5c5cfdd98e27701cd582d3cd8ca5e5db7c87e Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 3 Jan 2014 01:46:30 +0400 Subject: [PATCH 11/13] docs improved --- extensions/yii/faker/FixtureController.php | 3 +++ extensions/yii/faker/README.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/extensions/yii/faker/FixtureController.php b/extensions/yii/faker/FixtureController.php index 3ad458ebee..a6e232d8dd 100644 --- a/extensions/yii/faker/FixtureController.php +++ b/extensions/yii/faker/FixtureController.php @@ -61,6 +61,9 @@ use yii\helpers\Console; * * //also a short version of this command (generate action is default) * php yii faker users + * + * //to generate fixtures for several tables, use "," as a separator, for example: + * php yii faker users,profile * ~~~ * * In the code above "users" is template name, after this command run, new file named same as template diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index 2e2700f46a..068b29b995 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -92,6 +92,9 @@ php yii faker/generate users //also a short version of this command ("generate" action is default) php yii faker users + +//to generate fixtures for several tables, use "," as a separator, for example: +php yii faker users,profile,some_other_table ``` In the code above "users" is template name, after this command run, new file named same as template From 02bfea4f5c92aec8ef5cd659feea16347732dc18 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 3 Jan 2014 01:58:26 +0400 Subject: [PATCH 12/13] method renamed --- extensions/yii/faker/FixtureController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/yii/faker/FixtureController.php b/extensions/yii/faker/FixtureController.php index a6e232d8dd..cbc71bd6fb 100644 --- a/extensions/yii/faker/FixtureController.php +++ b/extensions/yii/faker/FixtureController.php @@ -235,7 +235,7 @@ class FixtureController extends \yii\console\controllers\FixtureController $fixtures[$i] = $this->generateFixture($template, $i); } - $content = $this->getExportedFormat($fixtures); + $content = $this->exportFixtures($fixtures); file_put_contents($fixturesPath.'/'.$fixtureFileName, $content); $this->stdout("Fixture file was generated under: " . realpath($fixturesPath . "/" . $fixtureFileName) . "\n", Console::FG_GREEN); } @@ -311,7 +311,7 @@ class FixtureController extends \yii\console\controllers\FixtureController * @param type $fixtures * @return string exported fixtures format */ - public function getExportedFormat($fixtures) + public function exportFixtures($fixtures) { $content = " Date: Fri, 3 Jan 2014 07:31:16 +0400 Subject: [PATCH 13/13] changed command signature, docs improved. --- extensions/yii/faker/FixtureController.php | 30 +++++++++++----------- extensions/yii/faker/README.md | 22 ++++++++-------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/extensions/yii/faker/FixtureController.php b/extensions/yii/faker/FixtureController.php index cbc71bd6fb..715294df80 100644 --- a/extensions/yii/faker/FixtureController.php +++ b/extensions/yii/faker/FixtureController.php @@ -23,7 +23,7 @@ use yii\helpers\Console; * * ~~~ * 'controllerMap' => [ - * 'faker' => [ + * 'fixture' => [ * 'class' => 'yii\faker\FixtureController', * ], * ], @@ -57,13 +57,13 @@ use yii\helpers\Console; * After you prepared needed templates for tables you can simply generate your fixtures via command * * ~~~ - * php yii faker/generate users + * php yii fixture/generate users * * //also a short version of this command (generate action is default) - * php yii faker users + * php yii fixture users * * //to generate fixtures for several tables, use "," as a separator, for example: - * php yii faker users,profile + * php yii fixture users,profile * ~~~ * * In the code above "users" is template name, after this command run, new file named same as template @@ -71,7 +71,7 @@ use yii\helpers\Console; * You can generate fixtures for all templates by specifying keyword "all_fixtures" * * ~~~ - * php yii faker/generate all_fixtures + * php yii fixture/generate all * ~~~ * * This command will generate fixtures for all template files that are stored under $templatePath and @@ -81,20 +81,20 @@ use yii\helpers\Console; * all fixtures and in each file there will be 3 rows (fixtures). * * ~~~ - * php yii faker/generate all_fixtures 3 + * php yii fixture/generate all 3 * ~~~ * * You can specify different options of this command: * * ~~~ * //generate fixtures in russian languge - * php yii faker/generate users 5 --language='ru_RU' + * php yii fixture/generate users 5 --language='ru_RU' * * //read templates from the other path - * php yii faker/generate all_fixtures --templatePath='@app/path/to/my/custom/templates' + * php yii fixture/generate all --templatePath='@app/path/to/my/custom/templates' * * //generate fixtures into other folders, but be sure that this folders exists or you will get notice about that. - * php yii faker/generate all_fixtures --fixturesPath='@tests/unit/fixtures/subfolder1/subfolder2/subfolder3' + * php yii fixture/generate all --fixturesPath='@tests/unit/fixtures/subfolder1/subfolder2/subfolder3' * ~~~ * * You also can create your own data providers for custom tables fields, see Faker library guide for more info (https://github.com/fzaninotto/Faker); @@ -121,7 +121,7 @@ use yii\helpers\Console; * * ~~~ * 'controllerMap' => [ - * 'faker' => [ + * 'fixture' => [ * 'class' => 'yii\faker\FixtureController', * 'providers' => [ * 'app\tests\unit\faker\providers\Book', @@ -140,7 +140,7 @@ class FixtureController extends \yii\console\controllers\FixtureController /** * type of fixture generating */ - const GENERATE_ALL = 'all_fixtures'; + const GENERATE_ALL = 'all'; /** * @var string controller default action ID. @@ -197,19 +197,19 @@ class FixtureController extends \yii\console\controllers\FixtureController /** * Generates fixtures and fill them with Faker data. * @param string $file filename for the table template. You can generate all fixtures for all tables - * by specifiyng keyword "all_fixtures" as filename. + * by specifiyng keyword "all" as filename. * @param integer $times how much fixtures do you want per table */ - public function actionGenerate($file, $times = 2) + public function actionGenerate(array $file, $times = 2) { $templatePath = Yii::getAlias($this->templatePath); $fixturesPath = Yii::getAlias($this->fixturesPath); - if ($this->needToGenerateAll($file)) { + if ($this->needToGenerateAll($file[0])) { $files = FileHelper::findFiles($templatePath, ['only' => ['.php']]); } else { - foreach(explode(',', $file) as $fileName) { + foreach($file as $fileName) { $filesToSearch[] = $fileName . '.php'; } $files = FileHelper::findFiles($templatePath, ['only' => $filesToSearch]); diff --git a/extensions/yii/faker/README.md b/extensions/yii/faker/README.md index 068b29b995..0199ec098c 100644 --- a/extensions/yii/faker/README.md +++ b/extensions/yii/faker/README.md @@ -29,7 +29,7 @@ To use this extension, simply add the following code in your application config ```php 'controllerMap' => [ - 'faker' => [ + 'fixture' => [ 'class' => 'yii\faker\FixtureController', ], ], @@ -88,21 +88,21 @@ After you prepared needed templates for tables you can simply generate your fixt ```php //generate fixtures for the users table based on users fixture template -php yii faker/generate users +php yii fixture/generate users //also a short version of this command ("generate" action is default) -php yii faker users +php yii fixture users //to generate fixtures for several tables, use "," as a separator, for example: -php yii faker users,profile,some_other_table +php yii fixture users,profile,some_other_table ``` In the code above "users" is template name, after this command run, new file named same as template will be created under the fixtures path (by default ```@tests/unit/fixtures```) folder. -You can generate fixtures for all templates by specifying keyword ```all_fixtures```. +You can generate fixtures for all templates by specifying keyword ```all```. ```php -php yii faker/generate all_fixtures +php yii fixture/generate all_fixtures ``` This command will generate fixtures for all template files that are stored under template path and @@ -111,19 +111,19 @@ You can specify how many fixtures per file you need by the second parameter. In all fixtures and in each file there will be 3 rows (fixtures). ```php -php yii faker/generate all_fixtures 3 +php yii fixture/generate all 3 ``` You can specify different options of this command: ```php //generate fixtures in russian language -php yii faker/generate users 5 --language='ru_RU' +php yii fixture/generate users 5 --language='ru_RU' //read templates from the other path -php yii faker/generate all_fixtures --templatePath='@app/path/to/my/custom/templates' +php yii fixture/generate all --templatePath='@app/path/to/my/custom/templates' //generate fixtures into other folders, but be sure that this folders exists or you will get notice about that. -php yii faker/generate all_fixtures --fixturesPath='@tests/unit/fixtures/subfolder1/subfolder2/subfolder3' +php yii fixture/generate all --fixturesPath='@tests/unit/fixtures/subfolder1/subfolder2/subfolder3' ``` You also can create your own data providers for custom tables fields, see [Faker]((https://github.com/fzaninotto/Faker)) library guide for more info; @@ -150,7 +150,7 @@ You can use it by adding it to the ```$providers``` property of the current comm ```php 'controllerMap' => [ - 'faker' => [ + 'fixture' => [ 'class' => 'yii\faker\FixtureController', 'providers' => [ 'app\tests\unit\faker\providers\Book',