Browse Source

refactored generators.

tags/2.0.0-beta
Qiang Xue 11 years ago
parent
commit
95bc36c2e6
  1. 22
      framework/yii/gii/Generator.php
  2. 21
      framework/yii/gii/generators/form/Generator.php
  3. 124
      framework/yii/gii/generators/model/Generator.php
  4. 2
      framework/yii/gii/generators/model/form.php
  5. 6
      framework/yii/gii/generators/model/templates/model.php

22
framework/yii/gii/Generator.php

@ -294,6 +294,28 @@ abstract class Generator extends Model
}
/**
* An inline validator that checks if the attribute value refers to an existing class name.
* If the `extends` option is specified, it will also check if the class is a child class
* of the class represented by the `extends` option.
* @param string $attribute the attribute being validated
* @param array $params the validation options
*/
public function validateClass($attribute, $params)
{
try {
if (class_exists($this->$attribute)) {
if (isset($params['extends']) && !is_subclass_of($this->$attribute, $params['extends'])) {
$this->addError($attribute, "'{$this->$attribute}' must extend from {$params['extends']} or its child class.");
}
} else {
$this->addError($attribute, "Class '{$this->$attribute}' does not exist or has syntax error.");
}
} catch (\Exception $e) {
$this->addError($attribute, "Class '{$this->$attribute}' does not exist or has syntax error.");
}
}
/**
* @param string $value the attribute to be validated
* @return boolean whether the value is a reserved PHP keyword.
*/

21
framework/yii/gii/generators/form/Generator.php

@ -63,7 +63,7 @@ class Generator extends \yii\gii\Generator
array('modelClass, viewName, scenarioName, viewPath', 'filter', 'filter' => 'trim'),
array('modelClass, viewName, viewPath', 'required'),
array('modelClass', 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'),
array('modelClass', 'validateModel'),
array('modelClass', 'validateClass', 'extends' => Model::className()),
array('viewName', 'match', 'pattern' => '/^\w+[\\-\\/\w]*$/', 'message' => 'Only word characters, dashes and slashes are allowed.'),
array('viewPath', 'match', 'pattern' => '/^@?\w+[\\-\\/\w]*$/', 'message' => 'Only word characters, dashes, slashes and @ are allowed.'),
array('viewPath', 'validateViewPath'),
@ -130,25 +130,6 @@ EOD;
}
/**
* Validates the model class to make sure it exists and is valid.
*/
public function validateModel()
{
try {
if (class_exists($this->modelClass)) {
if (!is_subclass_of($this->modelClass, Model::className())) {
$this->addError('modelClass', "'{$this->modelClass}' must extend from Model or its child class.");
}
} else {
$this->addError('modelClass', "Class '{$this->modelClass}' does not exist or has syntax error.");
}
} catch (\Exception $e) {
$this->addError('modelClass', "Class '{$this->modelClass}' does not exist or has syntax error.");
return;
}
}
/**
* Validates [[viewPath]] to make sure it is a valid path or path alias and exists.
*/
public function validateViewPath()

124
framework/yii/gii/generators/model/Generator.php

@ -8,6 +8,7 @@
namespace yii\gii\generators\model;
use Yii;
use yii\db\ActiveRecord;
use yii\db\Connection;
use yii\gii\CodeFile;
use yii\helpers\Inflector;
@ -50,7 +51,7 @@ class Generator extends \yii\gii\Generator
array('ns', 'validateNamespace'),
array('tableName', 'validateTableName'),
array('modelClass', 'validateModelClass'),
array('baseClass', 'validateBaseClass'),
array('baseClass', 'validateClass', 'params' => array('extends' => ActiveRecord::className())),
array('generateRelations, generateLabelsFromComments', 'boolean'),
));
}
@ -101,6 +102,9 @@ class Generator extends \yii\gii\Generator
return array('ns', 'db', 'baseClass', 'generateRelations', 'generateLabelsFromComments');
}
/**
* @return Connection
*/
public function getDbConnection()
{
return Yii::$app->{$this->db};
@ -108,33 +112,18 @@ class Generator extends \yii\gii\Generator
public function generate()
{
$db = $this->getDbConnection();
if (($pos = strrpos($this->tableName, '.')) !== false) {
$schema = substr($this->tableName, 0, $pos);
$tableName = substr($this->tableName, $pos + 1);
} else {
$schema = '';
$tableName = $this->tableName;
}
if (strpos($tableName, '*') !== false) {
$tables = $db->getSchema()->getTableNames($schema);
} else {
$tables = array($db->getTableSchema($this->tableName, true));
}
$files = array();
foreach ($tables as $table) {
$className = $this->generateClassName($table->name);
foreach ($this->getTableNames() as $tableName) {
$className = $this->generateClassName($tableName);
$tableSchema = $this->getTableSchema($tableName);
$params = array(
'tableName' => $schema === '' ? $tableName : $schema . '.' . $tableName,
'tableName' => $tableName,
'className' => $className,
'columns' => $table->columns,
'labels' => $this->generateLabels($table),
'tableSchema' => $tableSchema,
'labels' => $this->generateLabels($tableSchema),
);
$files[] = new CodeFile(
Yii::getAlias($this->modelPath) . '/' . $className . '.php',
Yii::getAlias('@' . $this->ns) . '/' . $className . '.php',
$this->render('model.php', $params)
);
}
@ -142,25 +131,9 @@ class Generator extends \yii\gii\Generator
return $files;
}
/*
* 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 getTableSchema($tableName)
{
$db = $this->getDbConnection();
return $db->getSchema()->getTable($tableName, true);
return $this->getDbConnection()->getTableSchema($tableName, true);
}
public function generateLabels($table)
@ -403,18 +376,22 @@ class Generator extends \yii\gii\Generator
public function validateDb()
{
if (Yii::$app->hasComponent($this->db) === false || !(Yii::$app->getComponent($this->db) instanceof Connection)) {
$this->addError('db', 'A valid database connection is required to run this generator.');
$this->addError('db', 'Database Connection ID must refer to a valid application component.');
}
}
public function validateNamespace()
{
$path = Yii::getAlias('@' . ltrim($this->ns, '\\'), false);
if ($path === false) {
$this->addError('ns', 'Namespace must be associated with an existing directory.');
}
}
public function validateModelClass()
{
if ($this->isReservedKeyword($this->modelClass)) {
$this->addError('modelClass', 'The name is a reserved PHP keyword.');
$this->addError('modelClass', 'Class name cannot be a reserved PHP keyword.');
}
if (strpos($this->tableName, '*') === false && $this->modelClass == '') {
$this->addError('modelClass', 'Model Class cannot be blank.');
@ -423,56 +400,41 @@ class Generator extends \yii\gii\Generator
public function validateTableName()
{
$invalidTables = array();
$invalidColumns = array();
if ($this->tableName[strlen($this->tableName) - 1] === '*') {
if (($pos = strrpos($this->tableName, '.')) !== false) {
$schema = substr($this->tableName, 0, $pos);
$tables = $this->getTableNames();
if (empty($tables)) {
$this->addError('tableName', "Table '{$this->tableName}' does not exist.'");
} else {
$schema = '';
}
$this->modelClass = '';
$tables = $this->getDbConnection()->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;
$class = $this->generateClassName($table);
if ($this->isReservedKeyword($class)) {
$this->addError('tableName', "Table '$table' would generate a class which is a reserved PHP keyword.");
break;
}
}
}
} 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;
}
protected function getTableNames()
{
$db = $this->getDbConnection();
$tableNames = array();
if ($this->tableName[strlen($this->tableName) - 1] === '*') {
if (($pos = strrpos($this->tableName, '.')) !== false) {
$schema = substr($this->tableName, 0, $pos);
$pattern = '/' . str_replace('*', '\w+', substr($this->tableName, $pos + 1)) . '/';
} else {
$schema = '';
$pattern = '/' . str_replace('*', '\w+', $this->tableName) . '/';
}
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) . ".");
foreach ($db->schema->getTableNames($schema) as $table) {
if (preg_match($pattern, $table)) {
$tableNames[] = $schema === '' ? $table : ($schema . '.' . $table);
}
}
public function validateBaseClass()
{
$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.");
} elseif (($table = $db->getTableSchema($this->tableName, true)) !== null) {
$tableNames[] = $this->tableName;
}
return $tableNames;
}
}

2
framework/yii/gii/generators/model/form.php

@ -5,7 +5,7 @@
* @var yii\gii\generators\form\Generator $generator
*/
echo $form->field($generator, 'tableName');
echo $form->field($generator, 'tableNamess');
echo $form->field($generator, 'modelClass');
echo $form->field($generator, 'ns');
echo $form->field($generator, 'baseClass');

6
framework/yii/gii/generators/model/templates/model.php

@ -6,12 +6,12 @@
* @var yii\gii\generators\model\Generator $generator
* @var string $tableName
* @var string $className
* @var yii\db\ColumnSchema[] $columns
* @var yii\db\TableSchema $tableSchema
* @var string[] $labels
*
* - $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)
* - $tableSchema: 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)
@ -31,7 +31,7 @@ namespace <?php echo $ns; ?>;
*
* Attributes:
*
<?php foreach ($columns as $column): ?>
<?php foreach ($tableSchema->columns as $column): ?>
* @property <?php echo "{$column->phpType} \${$column->name}\n"; ?>
<?php endforeach; ?>
*/

Loading…
Cancel
Save