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();
}
}
}
Комментарии