1
0

Added new (clean) yii boilerplate

This commit is contained in:
2014-05-13 12:40:42 +02:00
parent 1d6d975a16
commit 99d29b432b
1983 changed files with 653465 additions and 17 deletions

View File

@@ -0,0 +1,431 @@
<?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->model}' 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]/', ' \0', $column->name)))));
$label=preg_replace('/\s+/',' ',$label);
if(strcasecmp(substr($label,-3),' id')===0)
$label=substr($label,0,-3);
if($label==='Id')
$label='ID';
$label=str_replace("'","\\'",$label);
$labels[$column->name]=$label;
}
}
return $labels;
}
public function generateRules($table)
{
$rules=array();
$required=array();
$integers=array();
$numerical=array();
$length=array();
$safe=array();
foreach($table->columns as $column)
{
if($column->autoIncrement)
continue;
$r=!$column->allowNull && $column->defaultValue===null;
if($r)
$required[]=$column->name;
if($column->type==='integer')
$integers[]=$column->name;
elseif($column->type==='double')
$numerical[]=$column->name;
elseif($column->type==='string' && $column->size>0)
$length[$column->size][]=$column->name;
elseif(!$column->isPrimaryKey && !$r)
$safe[]=$column->name;
}
if($required!==array())
$rules[]="array('".implode(', ',$required)."', 'required')";
if($integers!==array())
$rules[]="array('".implode(', ',$integers)."', 'numerical', 'integerOnly'=>true)";
if($numerical!==array())
$rules[]="array('".implode(', ',$numerical)."', 'numerical')";
if($length!==array())
{
foreach($length as $len=>$cols)
$rules[]="array('".implode(', ',$cols)."', 'length', 'max'=>$len)";
}
if($safe!==array())
$rules[]="array('".implode(', ',$safe)."', 'safe')";
return $rules;
}
public function getRelations($className)
{
return isset($this->relations[$className]) ? $this->relations[$className] : array();
}
protected function removePrefix($tableName,$addBrackets=true)
{
if($addBrackets && Yii::app()->{$this->connectionId}->tablePrefix=='')
return $tableName;
$prefix=$this->tablePrefix!='' ? $this->tablePrefix : Yii::app()->{$this->connectionId}->tablePrefix;
if($prefix!='')
{
if($addBrackets && Yii::app()->{$this->connectionId}->tablePrefix!='')
{
$prefix=Yii::app()->{$this->connectionId}->tablePrefix;
$lb='{{';
$rb='}}';
}
else
$lb=$rb='';
if(($pos=strrpos($tableName,'.'))!==false)
{
$schema=substr($tableName,0,$pos);
$name=substr($tableName,$pos+1);
if(strpos($name,$prefix)===0)
return $schema.'.'.$lb.substr($name,strlen($prefix)).$rb;
}
elseif(strpos($tableName,$prefix)===0)
return $lb.substr($tableName,strlen($prefix)).$rb;
}
return $tableName;
}
protected function generateRelations()
{
if(!$this->buildRelations)
return array();
$schemaName='';
if(($pos=strpos($this->tableName,'.'))!==false)
$schemaName=substr($this->tableName,0,$pos);
$relations=array();
foreach(Yii::app()->{$this->connectionId}->schema->getTables($schemaName) as $table)
{
if($this->tablePrefix!='' && strpos($table->name,$this->tablePrefix)!==0)
continue;
$tableName=$table->name;
if ($this->isRelationTable($table))
{
$pks=$table->primaryKey;
$fks=$table->foreignKeys;
$table0=$fks[$pks[0]][0];
$table1=$fks[$pks[1]][0];
$className0=$this->generateClassName($table0);
$className1=$this->generateClassName($table1);
$unprefixedTableName=$this->removePrefix($tableName);
$relationName=$this->generateRelationName($table0, $table1, true);
$relations[$className0][$relationName]="array(self::MANY_MANY, '$className1', '$unprefixedTableName($pks[0], $pks[1])')";
$relationName=$this->generateRelationName($table1, $table0, true);
$i=1;
$rawName=$relationName;
while(isset($relations[$className1][$relationName]))
$relationName=$rawName.$i++;
$relations[$className1][$relationName]="array(self::MANY_MANY, '$className0', '$unprefixedTableName($pks[1], $pks[0])')";
}
else
{
$className=$this->generateClassName($tableName);
foreach ($table->foreignKeys as $fkName => $fkEntry)
{
// Put table and key name in variables for easier reading
$refTable=$fkEntry[0]; // Table name that current fk references to
$refKey=$fkEntry[1]; // Key in that table being referenced
$refClassName=$this->generateClassName($refTable);
// Add relation for this table
$relationName=$this->generateRelationName($tableName, $fkName, false);
$relations[$className][$relationName]="array(self::BELONGS_TO, '$refClassName', '$fkName')";
// Add relation for the referenced table
$relationType=$table->primaryKey === $fkName ? 'HAS_ONE' : 'HAS_MANY';
$relationName=$this->generateRelationName($refTable, $this->removePrefix($tableName,false), $relationType==='HAS_MANY');
$i=1;
$rawName=$relationName;
while(isset($relations[$refClassName][$relationName]))
$relationName=$rawName.($i++);
$relations[$refClassName][$relationName]="array(self::$relationType, '$className', '$fkName')";
}
}
}
return $relations;
}
/**
* Checks if the given table is a "many to many" pivot table.
* Their PK has 2 fields, and both of those fields are also FK to other separate tables.
* @param CDbTableSchema table to inspect
* @return boolean true if table matches description of helpter table.
*/
protected function isRelationTable($table)
{
$pk=$table->primaryKey;
return (count($pk) === 2 // we want 2 columns
&& isset($table->foreignKeys[$pk[0]]) // pk column 1 is also a foreign key
&& isset($table->foreignKeys[$pk[1]]) // pk column 2 is also a foriegn key
&& $table->foreignKeys[$pk[0]][0] !== $table->foreignKeys[$pk[1]][0]); // and the foreign keys point different tables
}
protected function generateClassName($tableName)
{
if($this->tableName===$tableName || ($pos=strrpos($this->tableName,'.'))!==false && substr($this->tableName,$pos+1)===$tableName)
return $this->modelClass;
$tableName=$this->removePrefix($tableName,false);
if(($pos=strpos($tableName,'.'))!==false) // remove schema part (e.g. remove 'public2.' from 'public2.post')
$tableName=substr($tableName,$pos+1);
$className='';
foreach(explode('_',$tableName) as $name)
{
if($name!=='')
$className.=ucfirst($name);
}
return $className;
}
/**
* Generate a name for use as a relation name (inside relations() function in a model).
* @param string the name of the table to hold the relation
* @param string the foreign key name
* @param boolean whether the relation would contain multiple objects
* @return string the relation name
*/
protected function generateRelationName($tableName, $fkName, $multiple)
{
if(strcasecmp(substr($fkName,-2),'id')===0 && strcasecmp($fkName,'id'))
$relationName=rtrim(substr($fkName, 0, -2),'_');
else
$relationName=$fkName;
$relationName[0]=strtolower($relationName);
if($multiple)
$relationName=$this->pluralize($relationName);
$names=preg_split('/_+/',$relationName,-1,PREG_SPLIT_NO_EMPTY);
if(empty($names)) return $relationName; // unlikely
for($name=$names[0], $i=1;$i<count($names);++$i)
$name.=ucfirst($names[$i]);
$rawName=$name;
$table=Yii::app()->{$this->connectionId}->schema->getTable($tableName);
$i=0;
while(isset($table->columns[$name]))
$name=$rawName.($i++);
return $name;
}
public function validateConnectionId($attribute, $params)
{
if(Yii::app()->hasComponent($this->connectionId)===false || !(Yii::app()->getComponent($this->connectionId) instanceof CDbConnection))
$this->addError('connectionId','A valid database connection is required to run this generator.');
}
}

View File

@@ -0,0 +1,25 @@
<?php
class ModelGenerator extends CCodeGenerator
{
public $codeModel='gii.generators.model.ModelCode';
/**
* Provides autocomplete table names
* @param string $db the database connection component id
* @return string the json array of tablenames that contains the entered term $q
*/
public function actionGetTableNames($db)
{
if(Yii::app()->getRequest()->getIsAjaxRequest())
{
$all = array();
if(!empty($db) && Yii::app()->hasComponent($db)!==false && (Yii::app()->getComponent($db) instanceof CDbConnection))
$all=array_keys(Yii::app()->{$db}->schema->getTables());
echo json_encode($all);
}
else
throw new CHttpException(404,'The requested page does not exist.');
}
}

View File

@@ -0,0 +1,163 @@
<?php
/**
* This is the template for generating the model class of a specified table.
* - $this: the ModelCode object
* - $tableName: the table name for this class (prefix is already removed if necessary)
* - $modelClass: the model class name
* - $columns: list of table columns (name=>CDbColumnSchema)
* - $labels: list of attribute labels (name=>label)
* - $rules: list of validation rules
* - $relations: list of relations (name=>relation declaration)
*/
?>
<?php echo "<?php\n"; ?>
/**
* This is the model class for table "<?php echo $tableName; ?>".
*
* The followings are the available columns in table '<?php echo $tableName; ?>':
<?php foreach($columns as $column): ?>
* @property <?php echo $column->type.' $'.$column->name."\n"; ?>
<?php endforeach; ?>
<?php if(!empty($relations)): ?>
*
* The followings are the available model relations:
<?php foreach($relations as $name=>$relation): ?>
* @property <?php
if (preg_match("~^array\(self::([^,]+), '([^']+)', '([^']+)'\)$~", $relation, $matches))
{
$relationType = $matches[1];
$relationModel = $matches[2];
switch($relationType){
case 'HAS_ONE':
echo $relationModel.' $'.$name."\n";
break;
case 'BELONGS_TO':
echo $relationModel.' $'.$name."\n";
break;
case 'HAS_MANY':
echo $relationModel.'[] $'.$name."\n";
break;
case 'MANY_MANY':
echo $relationModel.'[] $'.$name."\n";
break;
default:
echo 'mixed $'.$name."\n";
}
}
?>
<?php endforeach; ?>
<?php endif; ?>
*/
class <?php echo $modelClass; ?> extends <?php echo $this->baseClass."\n"; ?>
{
/**
* @return string the associated database table name
*/
public function tableName()
{
return '<?php echo $tableName; ?>';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
<?php foreach($rules as $rule): ?>
<?php echo $rule.",\n"; ?>
<?php endforeach; ?>
// The following rule is used by search().
// @todo Please remove those attributes that should not be searched.
array('<?php echo implode(', ', array_keys($columns)); ?>', 'safe', 'on'=>'search'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
<?php foreach($relations as $name=>$relation): ?>
<?php echo "'$name' => $relation,\n"; ?>
<?php endforeach; ?>
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
<?php foreach($labels as $name=>$label): ?>
<?php echo "'$name' => '$label',\n"; ?>
<?php endforeach; ?>
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
*
* Typical usecase:
* - Initialize the model fields with values from filter form.
* - Execute this method to get CActiveDataProvider instance which will filter
* models according to data in model fields.
* - Pass data provider to CGridView, CListView or any similar widget.
*
* @return CActiveDataProvider the data provider that can return the models
* based on the search/filter conditions.
*/
public function search()
{
// @todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
<?php
foreach($columns as $name=>$column)
{
if($column->type==='string')
{
echo "\t\t\$criteria->compare('$name',\$this->$name,true);\n";
}
else
{
echo "\t\t\$criteria->compare('$name',\$this->$name);\n";
}
}
?>
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
<?php if($connectionId!='db'):?>
/**
* @return CDbConnection the database connection used for this class
*/
public function getDbConnection()
{
return Yii::app()-><?php echo $connectionId ?>;
}
<?php endif?>
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* @param string $className active record class name.
* @return <?php echo $modelClass; ?> the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}

View File

@@ -0,0 +1,149 @@
<?php
$class=get_class($model);
Yii::app()->clientScript->registerScript('gii.model',"
$('#{$class}_connectionId').change(function(){
var tableName=$('#{$class}_tableName');
tableName.autocomplete('option', 'source', []);
$.ajax({
url: '".Yii::app()->getUrlManager()->createUrl('gii/model/getTableNames')."',
data: {db: this.value},
dataType: 'json'
}).done(function(data){
tableName.autocomplete('option', 'source', data);
});
});
$('#{$class}_modelClass').change(function(){
$(this).data('changed',$(this).val()!='');
});
$('#{$class}_tableName').bind('keyup change', function(){
var model=$('#{$class}_modelClass');
var tableName=$(this).val();
if(tableName.substring(tableName.length-1)!='*') {
$('.form .row.model-class').show();
}
else {
$('#{$class}_modelClass').val('');
$('.form .row.model-class').hide();
}
if(!model.data('changed')) {
var i=tableName.lastIndexOf('.');
if(i>=0)
tableName=tableName.substring(i+1);
var tablePrefix=$('#{$class}_tablePrefix').val();
if(tablePrefix!='' && tableName.indexOf(tablePrefix)==0)
tableName=tableName.substring(tablePrefix.length);
var modelClass='';
$.each(tableName.split('_'), function() {
if(this.length>0)
modelClass+=this.substring(0,1).toUpperCase()+this.substring(1);
});
model.val(modelClass);
}
});
$('.form .row.model-class').toggle($('#{$class}_tableName').val().substring($('#{$class}_tableName').val().length-1)!='*');
");
?>
<h1>Model Generator</h1>
<p>This generator generates a model class for the specified database table.</p>
<?php $form=$this->beginWidget('CCodeForm', array('model'=>$model)); ?>
<div class="row sticky">
<?php echo $form->labelEx($model, 'connectionId')?>
<?php echo $form->textField($model, 'connectionId', array('size'=>65))?>
<div class="tooltip">
The database component that should be used.
</div>
<?php echo $form->error($model,'connectionId'); ?>
</div>
<div class="row sticky">
<?php echo $form->labelEx($model,'tablePrefix'); ?>
<?php echo $form->textField($model,'tablePrefix', array('size'=>65)); ?>
<div class="tooltip">
This refers to the prefix name that is shared by all database tables.
Setting this property mainly affects how model classes are named based on
the table names. For example, a table prefix <code>tbl_</code> with a table name <code>tbl_post</code>
will generate a model class named <code>Post</code>.
<br/>
Leave this field empty if your database tables do not use common prefix.
</div>
<?php echo $form->error($model,'tablePrefix'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'tableName'); ?>
<?php $this->widget('zii.widgets.jui.CJuiAutoComplete',array(
'model'=>$model,
'attribute'=>'tableName',
'name'=>'tableName',
'source'=>Yii::app()->hasComponent($model->connectionId) ? array_keys(Yii::app()->{$model->connectionId}->schema->getTables()) : array(),
'options'=>array(
'minLength'=>'0',
'focus'=>new CJavaScriptExpression('function(event,ui) {
$("#'.CHtml::activeId($model,'tableName').'").val(ui.item.label).change();
return false;
}')
),
'htmlOptions'=>array(
'id'=>CHtml::activeId($model,'tableName'),
'size'=>'65',
'data-tooltip'=>'#tableName-tooltip'
),
)); ?>
<div class="tooltip" id="tableName-tooltip">
This refers to the table name that a new model class should be generated for
(e.g. <code>tbl_user</code>). It can contain schema name, if needed (e.g. <code>public.tbl_post</code>).
You may also enter <code>*</code> (or <code>schemaName.*</code> for a particular DB schema)
to generate a model class for EVERY table.
</div>
<?php echo $form->error($model,'tableName'); ?>
</div>
<div class="row model-class">
<?php echo $form->label($model,'modelClass',array('required'=>true)); ?>
<?php echo $form->textField($model,'modelClass', array('size'=>65)); ?>
<div class="tooltip">
This is the name of the model class to be generated (e.g. <code>Post</code>, <code>Comment</code>).
It is case-sensitive.
</div>
<?php echo $form->error($model,'modelClass'); ?>
</div>
<div class="row sticky">
<?php echo $form->labelEx($model,'baseClass'); ?>
<?php echo $form->textField($model,'baseClass',array('size'=>65)); ?>
<div class="tooltip">
This is the class that the new model class will extend from.
Please make sure the class exists and can be autoloaded.
</div>
<?php echo $form->error($model,'baseClass'); ?>
</div>
<div class="row sticky">
<?php echo $form->labelEx($model,'modelPath'); ?>
<?php echo $form->textField($model,'modelPath', array('size'=>65)); ?>
<div class="tooltip">
This refers to the directory that the new model class file should be generated under.
It should be specified in the form of a path alias, for example, <code>application.models</code>.
</div>
<?php echo $form->error($model,'modelPath'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'buildRelations'); ?>
<?php echo $form->checkBox($model,'buildRelations'); ?>
<div class="tooltip">
Whether relations should be generated for the model class.
In order to generate relations, full scan of the whole database is needed.
You should disable this option if your database contains too many tables.
</div>
<?php echo $form->error($model,'buildRelations'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'commentsAsLabels'); ?>
<?php echo $form->checkBox($model,'commentsAsLabels'); ?>
<div class="tooltip">
Whether comments specified for the table columns should be used as the new model's attribute labels.
In case your RDBMS doesn't support feature of commenting columns or column comment wasn't set,
column name would be used as the attribute name base.
</div>
<?php echo $form->error($model,'commentsAsLabels'); ?>
</div>
<?php $this->endWidget(); ?>