Yii2 Bootstrap 3
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
6.9 KiB

12 years ago
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\gii;
use Yii;
12 years ago
use ReflectionClass;
use yii\base\InvalidConfigException;
12 years ago
use yii\base\Model;
12 years ago
use yii\base\View;
12 years ago
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
12 years ago
abstract class Generator extends Model
12 years ago
{
12 years ago
public $templates = array();
12 years ago
/**
12 years ago
* @var string the name of the code template that the user has selected.
* The value of this property is internally managed by this class and {@link CCodeGenerator}.
12 years ago
*/
12 years ago
public $template;
12 years ago
/**
* @return string name of the code generator
*/
12 years ago
abstract public function getName();
public function init()
12 years ago
{
12 years ago
parent::init();
if (!isset($this->templates['default'])) {
12 years ago
$this->templates['default'] = $this->defaultTemplate();
12 years ago
}
12 years ago
}
12 years ago
/**
* Prepares the code files to be generated.
* This is the main method that child classes should implement. It should contain the logic
* that populates the {@link files} property with a list of code files to be generated.
*/
public function prepare()
12 years ago
{
12 years ago
return array();
12 years ago
}
12 years ago
/**
* Returns a list of code templates that are required.
* Derived classes usually should override this method.
* @return array list of code templates that are required. They should be file paths
* relative to {@link templatePath}.
*/
public function requiredTemplates()
12 years ago
{
12 years ago
return array();
12 years ago
}
12 years ago
public function formView()
12 years ago
{
12 years ago
$class = new ReflectionClass($this);
return dirname($class->getFileName()) . '/views/form.php';
12 years ago
}
12 years ago
public function defaultTemplate()
12 years ago
{
12 years ago
$class = new ReflectionClass($this);
return dirname($class->getFileName()) . '/templates';
12 years ago
}
12 years ago
public function getDescription()
12 years ago
{
12 years ago
return '';
12 years ago
}
/**
* Declares the model validation rules.
* Child classes must override this method in the following format:
* <pre>
* return array_merge(parent::rules(), array(
* ...rules for the child class...
* ));
* </pre>
* @return array validation rules
*/
public function rules()
{
return array(
12 years ago
array('template', 'required', 'message' => 'A code template must be selected.'),
12 years ago
array('template', 'validateTemplate', 'skipOnError' => true),
);
}
/**
* Checks if the named class exists (in a case sensitive manner).
* @param string $name class name to be checked
* @return boolean whether the class exists
*/
public function classExists($name)
{
return class_exists($name, false) && in_array($name, get_declared_classes());
}
/**
* Saves the generated code into files.
*/
12 years ago
public function save($files, $answers = array())
12 years ago
{
$result = true;
12 years ago
foreach ($files as $file) {
12 years ago
if ($this->confirmed($file)) {
$result = $file->save() && $result;
}
}
return $result;
}
/**
* @return string the directory that contains the template files.
12 years ago
* @throws InvalidConfigException if {@link templates} is empty or template selection is invalid
12 years ago
*/
public function getTemplatePath()
{
12 years ago
if (isset($this->templates[$this->template])) {
return $this->templates[$this->template];
12 years ago
} else {
12 years ago
throw new InvalidConfigException("Unknown template: {$this->template}");
12 years ago
}
}
/**
12 years ago
* @param CodeFile $file whether the code file should be saved
12 years ago
* @return bool whether the confirmation is found in {@link answers} with appropriate {@link operation}
*/
public function confirmed($file)
{
12 years ago
return $this->answers === null && $file->operation === CodeFile::OP_NEW
12 years ago
|| is_array($this->answers) && isset($this->answers[md5($file->path)]);
}
/**
* Generates the code using the specified code template file.
* This method is manly used in {@link generate} to generate code.
* @param string $templateFile the code template file path
* @param array $_params_ a set of parameters to be extracted and made available in the code template
* @return string the generated code
*/
12 years ago
public function render($templateFile, $params = array())
12 years ago
{
12 years ago
$view = new View;
return $view->renderFile($templateFile, $params, $this);
12 years ago
}
/**
* @return string the code generation result log.
*/
public function renderResults()
{
$output = 'Generating code using template "' . $this->templatePath . "\"...\n";
foreach ($this->files as $file) {
if ($file->error !== null) {
$output .= "<span class=\"error\">generating {$file->relativePath}<br/> {$file->error}</span>\n";
12 years ago
} elseif ($file->operation === CodeFile::OP_NEW && $this->confirmed($file)) {
12 years ago
$output .= ' generated ' . $file->relativePath . "\n";
12 years ago
} elseif ($file->operation === CodeFile::OP_OVERWRITE && $this->confirmed($file)) {
12 years ago
$output .= ' overwrote ' . $file->relativePath . "\n";
} else {
$output .= ' skipped ' . $file->relativePath . "\n";
}
}
$output .= "done!\n";
return $output;
}
/**
12 years ago
* Validates the template selection.
* This method validates whether the user selects an existing template
* and the template contains all required template files as specified in {@link requiredTemplates}.
12 years ago
*/
12 years ago
public function validateTemplate()
12 years ago
{
12 years ago
$templates = $this->templates;
if (!isset($templates[$this->template])) {
$this->addError('template', 'Invalid template selection.');
} else {
$templatePath = $this->templates[$this->template];
foreach ($this->requiredTemplates() as $template) {
if (!is_file($templatePath . '/' . $template)) {
$this->addError('template', "Unable to find the required code template file '$template'.");
12 years ago
}
}
}
}
/**
* Validates an attribute to make sure it is not taking a PHP reserved keyword.
* @param string $attribute the attribute to be validated
* @param array $params validation parameters
*/
public function validateReservedWord($attribute, $params)
{
12 years ago
static $keywords = array(
'__class__',
'__dir__',
'__file__',
'__function__',
'__line__',
'__method__',
'__namespace__',
'__trait__',
12 years ago
'abstract',
'and',
'array',
'as',
'break',
'case',
'catch',
'callable',
12 years ago
'cfunction',
'class',
'clone',
'const',
'continue',
'declare',
'default',
'die',
'do',
'echo',
'else',
'elseif',
'empty',
'enddeclare',
'endfor',
'endforeach',
'endif',
'endswitch',
'endwhile',
'eval',
'exception',
'exit',
'extends',
'final',
'finally',
12 years ago
'for',
'foreach',
'function',
'global',
'goto',
'if',
'implements',
'include',
'include_once',
'instanceof',
'insteadof',
12 years ago
'interface',
'isset',
'list',
'namespace',
'new',
'old_function',
'or',
'parent',
'php_user_filter',
'print',
'private',
'protected',
'public',
'require',
'require_once',
'return',
'static',
'switch',
'this',
'throw',
'trait',
12 years ago
'try',
'unset',
'use',
'var',
'while',
'xor',
);
12 years ago
$value = $this->$attribute;
12 years ago
if (in_array(strtolower($value), $keywords)) {
12 years ago
$this->addError($attribute, $this->getAttributeLabel($attribute) . ' cannot take a reserved PHP keyword.');
}
}
}