yii: загрузка фикстур
18.03.2013
Часто в проекте сайта необходимо загрузить тестовые данные, для проверки бизнес-логики, тестирования либо внешнего вида страниц. Собственно стандартной возможности в Yii 1.1.13 я не нашел. Для этого написал небольшую консольную утилиту (документация):
<?php class FixturesCommand extends CConsoleCommand { public $fixturesPath; public function __construct($name,$runner){ parent::__construct($name,$runner); $this->fixturesPath = Yii::getPathOfAlias('root').'/console/fixtures'; } public function getHelp(){ echo <<<'EOF' Usage: yiic fixtures [load | loadall | list] --type=<name> Option "load": This command include fixture class file ( ROOT/console/fixtures/<name>Fixture.php ) and call load() method. Require --type option. Option "loadall": Load all fixtures at ( ROOT/console/fixtures/ ). Option "list": Show all availible fixtures. EOF; echo "n"; } public function actionIndex(){ $this->getHelp(); } public function actionLoad($type) { $fixturesPath = $this->fixturesPath; $fixtureClass = ucfirst($type).'Fixture'; $fixtureFile = $fixtureClass.'.php'; $fixtureFullPath = $fixturesPath.'/'.$fixtureFile; if( file_exists($fixtureFullPath) ){ return $this->loadFromFile($fixtureFullPath, $fixtureClass); }else{ echo '*** fail: fixture file does not exists '.$fixtureFile.'('.$fixtureFullPath.')'."n"; return 1; } } public function actionList() { echo "*** availible fixtures:n"; $allFixtures = $this->getFixturesList(); foreach($allFixtures as $fixture ){ echo '-> '.$fixture['class']."n"; } echo "*** total:".count($allFixtures)."n"; } public function actionLoadall(){ echo "*** load all fixtures:n"; $allFixtures = $this->getFixturesList(); foreach($allFixtures as $fixture ){ echo '*** load - '.$fixture['class']; $ret = $this->loadFromFile($fixture['path'], $fixture['class']); if($ret==0){ echo " - successn"; }else{ echo " - fail(".$ret.") n"; } } echo "*** total:".count($allFixtures)."n"; } protected function loadFromFile($fixtureFullPath, $fixtureClass){ if(!file_exists($fixtureFullPath)){ echo '*** fail: fixture file not found '.$fixtureClass.' ('.$fixtureFullPath.')'."n"; return 2; } Yii::import('root.console.fixtures.'.$fixtureClass); if(class_exists($fixtureClass)){ $fixt = new $fixtureClass; if( method_exists($fixt, 'load') ){ $fixt->load(); }else{ echo '*** fail: fixture method not found at '.$fixtureClass.' ('.$fixtureFullPath.')'."n"; return 3; } }else{ echo '*** fail: fixture class not found '.$fixtureClass.' at '.$fixtureFullPath."n"; return 4; } return 0; } protected function getFixturesList(){ $fixturesPath = $this->fixturesPath; $allFixtures = array(); $hdir = opendir($fixturesPath); while ( ($fname=readdir($hdir))!==false ) { if( preg_match('/([[:alnum:]]+Fixture).php$/s', $fname, $pockets) ){ $filePath = $fixturesPath.'/'.$fname; $fixtureClass = $pockets[1]; $allFixtures[] = array( 'name'=>$fname, 'path'=>$filePath, 'class'=>$fixtureClass, ); } } closedir($hdir); return $allFixtures; } }
Пример класса фикстур (ROOT/console/fixtures/ArticleFixture.php)
<?php class ArticleFixture { public function load(){ for($i=1; $i<10; $i++){ $art = new Article(); $art->content = 'article content - #'.$i; $art->short_content = 'short content '.$i; $art->name = 'article - #'.$i; $art->is_visible = 1; $art->created_at = time(); $art->updated_at = time(); } } }
Комментарии