Файл: framework/gii/generators/model/ModelCode.php
Строк: 520
<?php
class ModelCode extends CCodeModel
{
public $connectionId='db';
public $tablePrefix;
public $tableName;
public $modelClass;
public $modelPath='application.models';
public $baseClass='CActiveRecord';
public $buildRelations=true;
public $commentsAsLabels=false;
/**
* @var array list of candidate relation code. The array are indexed by AR class names and relation names.
* Each element represents the code of the one relation in one AR class.
*/
protected $relations;
public function rules()
{
return array_merge(parent::rules(), array(
array('tablePrefix, baseClass, tableName, modelClass, modelPath, connectionId', 'filter', 'filter'=>'trim'),
array('connectionId, tableName, modelPath, baseClass', 'required'),
array('tablePrefix, tableName, modelPath', 'match', 'pattern'=>'/^(w+[w.]*|*?|w+.*)$/', 'message'=>'{attribute} should only contain word characters, dots, and an optional ending asterisk.'),
array('connectionId', 'validateConnectionId', 'skipOnError'=>true),
array('tableName', 'validateTableName', 'skipOnError'=>true),
array('tablePrefix, modelClass', 'match', 'pattern'=>'/^[a-zA-Z_]w*$/', 'message'=>'{attribute} should only contain word characters.'),
array('baseClass', 'match', 'pattern'=>'/^[a-zA-Z_\\][w\\]*$/', 'message'=>'{attribute} should only contain word characters and backslashes.'),
array('modelPath', 'validateModelPath', 'skipOnError'=>true),
array('baseClass, modelClass', 'validateReservedWord', 'skipOnError'=>true),
array('baseClass', 'validateBaseClass', 'skipOnError'=>true),
array('connectionId, tablePrefix, modelPath, baseClass, buildRelations, commentsAsLabels', 'sticky'),
));
}
public function attributeLabels()
{
return array_merge(parent::attributeLabels(), array(
'tablePrefix'=>'Table Prefix',
'tableName'=>'Table Name',
'modelPath'=>'Model Path',
'modelClass'=>'Model Class',
'baseClass'=>'Base Class',
'buildRelations'=>'Build Relations',
'commentsAsLabels'=>'Use Column Comments as Attribute Labels',
'connectionId'=>'Database Connection',
));
}
public function requiredTemplates()
{
return array(
'model.php',
);
}
public function init()
{
if(Yii::app()->{$this->connectionId}===null)
throw new CHttpException(500,'A valid database connection is required to run this generator.');
$this->tablePrefix=Yii::app()->{$this->connectionId}->tablePrefix;
parent::init();
}
public function prepare()
{
if(($pos=strrpos($this->tableName,'.'))!==false)
{
$schema=substr($this->tableName,0,$pos);
$tableName=substr($this->tableName,$pos+1);
}
else
{
$schema='';
$tableName=$this->tableName;
}
if($tableName[strlen($tableName)-1]==='*')
{
$tables=Yii::app()->{$this->connectionId}->schema->getTables($schema);
if($this->tablePrefix!='')
{
foreach($tables as $i=>$table)
{
if(strpos($table->name,$this->tablePrefix)!==0)
unset($tables[$i]);
}
}
}
else
$tables=array($this->getTableSchema($this->tableName));
$this->files=array();
$templatePath=$this->templatePath;
$this->relations=$this->generateRelations();
foreach($tables as $table)
{
$tableName=$this->removePrefix($table->name);
$className=$this->generateClassName($table->name);
$params=array(
'tableName'=>$schema==='' ? $tableName : $schema.'.'.$tableName,
'modelClass'=>$className,
'columns'=>$table->columns,
'labels'=>$this->generateLabels($table),
'rules'=>$this->generateRules($table),
'relations'=>isset($this->relations[$className]) ? $this->relations[$className] : array(),
'connectionId'=>$this->connectionId,
);
$this->files[]=new CCodeFile(
Yii::getPathOfAlias($this->modelPath).'/'.$className.'.php',
$this->render($templatePath.'/model.php', $params)
);
}
}
public function validateTableName($attribute,$params)
{
if($this->hasErrors())
return;
$invalidTables=array();
$invalidColumns=array();
if($this->tableName[strlen($this->tableName)-1]==='*')
{
if(($pos=strrpos($this->tableName,'.'))!==false)
$schema=substr($this->tableName,0,$pos);
else
$schema='';
$this->modelClass='';
$tables=Yii::app()->{$this->connectionId}->schema->getTables($schema);
foreach($tables as $table)
{
if($this->tablePrefix=='' || strpos($table->name,$this->tablePrefix)===0)
{
if(in_array(strtolower($table->name),self::$keywords))
$invalidTables[]=$table->name;
if(($invalidColumn=$this->checkColumns($table))!==null)
$invalidColumns[]=$invalidColumn;
}
}
}
else
{
if(($table=$this->getTableSchema($this->tableName))===null)
$this->addError('tableName',"Table '{$this->tableName}' does not exist.");
if($this->modelClass==='')
$this->addError('modelClass','Model Class cannot be blank.');
if(!$this->hasErrors($attribute) && ($invalidColumn=$this->checkColumns($table))!==null)
$invalidColumns[]=$invalidColumn;
}
if($invalidTables!=array())
$this->addError('tableName', 'Model class cannot take a reserved PHP keyword! Table name: '.implode(', ', $invalidTables).".");
if($invalidColumns!=array())
$this->addError('tableName', 'Column names that does not follow PHP variable naming convention: '.implode(', ', $invalidColumns).".");
}
/*
* Check that all database field names conform to PHP variable naming rules
* For example mysql allows field name like "2011aa", but PHP does not allow variable like "$model->2011aa"
* @param CDbTableSchema $table the table schema object
* @return string the invalid table column name. Null if no error.
*/
public function checkColumns($table)
{
foreach($table->columns as $column)
{
if(!preg_match('/^[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*$/',$column->name))
return $table->name.'.'.$column->name;
}
}
public function validateModelPath($attribute,$params)
{
if(Yii::getPathOfAlias($this->modelPath)===false)
$this->addError('modelPath','Model Path must be a valid path alias.');
}
public function validateBaseClass($attribute,$params)
{
$class=@Yii::import($this->baseClass,true);
if(!is_string($class) || !$this->classExists($class))
$this->addError('baseClass', "Class '{$this->baseClass}' does not exist or has syntax error.");
elseif($class!=='CActiveRecord' && !is_subclass_of($class,'CActiveRecord'))
$this->addError('baseClass', "'{$this->baseClass}' must extend from CActiveRecord.");
}
public function getTableSchema($tableName)
{
$connection=Yii::app()->{$this->connectionId};
return $connection->getSchema()->getTable($tableName, $connection->schemaCachingDuration!==0);
}
public function generateLabels($table)
{
$labels=array();
foreach($table->columns as $column)
{
if($this->commentsAsLabels && $column->comment)
$labels[$column->name]=$column->comment;
else
{
$label=ucwords(trim(strtolower(str_replace(array('-','_'),' ',preg_replace('/(?<![A-Z])[A-Z]/', '