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.
		
		
		
		
		
			
		
			
				
					
					
						
							288 lines
						
					
					
						
							6.9 KiB
						
					
					
				
			
		
		
	
	
							288 lines
						
					
					
						
							6.9 KiB
						
					
					
				| <?php | |
| /** | |
|  * @link http://www.yiiframework.com/ | |
|  * @copyright Copyright (c) 2008 Yii Software LLC | |
|  * @license http://www.yiiframework.com/license/ | |
|  */ | |
|  | |
| namespace yii\gii; | |
|  | |
| use Yii; | |
| use ReflectionClass; | |
| use yii\base\InvalidConfigException; | |
| use yii\base\Model; | |
| use yii\base\View; | |
|  | |
| /** | |
|  * @author Qiang Xue <qiang.xue@gmail.com> | |
|  * @since 2.0 | |
|  */ | |
| abstract class Generator extends Model | |
| { | |
| 	public $templates = array(); | |
| 	/** | |
| 	 * @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}. | |
| 	 */ | |
| 	public $template; | |
|  | |
| 	/** | |
| 	 * @return string name of the code generator | |
| 	 */ | |
| 	abstract public function getName(); | |
|  | |
| 	public function init() | |
| 	{ | |
| 		parent::init(); | |
| 		if (!isset($this->templates['default'])) { | |
| 			$this->templates['default'] = $this->defaultTemplate(); | |
| 		} | |
| 	} | |
|  | |
| 	/** | |
| 	 * 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() | |
| 	{ | |
| 		return array(); | |
| 	} | |
|  | |
| 	/** | |
| 	 * 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() | |
| 	{ | |
| 		return array(); | |
| 	} | |
|  | |
| 	public function formView() | |
| 	{ | |
| 		$class = new ReflectionClass($this); | |
| 		return dirname($class->getFileName()) . '/views/form.php'; | |
| 	} | |
|  | |
| 	public function defaultTemplate() | |
| 	{ | |
| 		$class = new ReflectionClass($this); | |
| 		return dirname($class->getFileName()) . '/templates'; | |
| 	} | |
|  | |
| 	public function getDescription() | |
| 	{ | |
| 		return ''; | |
| 	} | |
|  | |
| 	/** | |
| 	 * 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( | |
| 			array('template', 'required', 'message' => 'A code template must be selected.'), | |
| 			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. | |
| 	 */ | |
| 	public function save($files, $answers = array()) | |
| 	{ | |
| 		$result = true; | |
| 		foreach ($files as $file) { | |
| 			if ($this->confirmed($file)) { | |
| 				$result = $file->save() && $result; | |
| 			} | |
| 		} | |
| 		return $result; | |
| 	} | |
|  | |
| 	/** | |
| 	 * @return string the directory that contains the template files. | |
| 	 * @throws InvalidConfigException if {@link templates} is empty or template selection is invalid | |
| 	 */ | |
| 	public function getTemplatePath() | |
| 	{ | |
| 		if (isset($this->templates[$this->template])) { | |
| 			return $this->templates[$this->template]; | |
| 		} else { | |
| 			throw new InvalidConfigException("Unknown template: {$this->template}"); | |
| 		} | |
| 	} | |
|  | |
| 	/** | |
| 	 * @param CodeFile $file whether the code file should be saved | |
| 	 * @return bool whether the confirmation is found in {@link answers} with appropriate {@link operation} | |
| 	 */ | |
| 	public function confirmed($file) | |
| 	{ | |
| 		return $this->answers === null && $file->operation === CodeFile::OP_NEW | |
| 		|| 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 | |
| 	 */ | |
| 	public function render($templateFile, $params = array()) | |
| 	{ | |
| 		$view = new View; | |
| 		return $view->renderFile($templateFile, $params, $this); | |
| 	} | |
|  | |
| 	/** | |
| 	 * @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"; | |
| 			} elseif ($file->operation === CodeFile::OP_NEW && $this->confirmed($file)) { | |
| 				$output .= ' generated ' . $file->relativePath . "\n"; | |
| 			} elseif ($file->operation === CodeFile::OP_OVERWRITE && $this->confirmed($file)) { | |
| 				$output .= ' overwrote ' . $file->relativePath . "\n"; | |
| 			} else { | |
| 				$output .= '   skipped ' . $file->relativePath . "\n"; | |
| 			} | |
| 		} | |
| 		$output .= "done!\n"; | |
| 		return $output; | |
| 	} | |
|  | |
| 	/** | |
| 	 * 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}. | |
| 	 */ | |
| 	public function validateTemplate() | |
| 	{ | |
| 		$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'."); | |
| 				} | |
| 			} | |
| 		} | |
| 	} | |
|  | |
| 	/** | |
| 	 * 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) | |
| 	{ | |
| 		static $keywords = array( | |
| 			'__class__', | |
| 			'__dir__', | |
| 			'__file__', | |
| 			'__function__', | |
| 			'__line__', | |
| 			'__method__', | |
| 			'__namespace__', | |
| 			'abstract', | |
| 			'and', | |
| 			'array', | |
| 			'as', | |
| 			'break', | |
| 			'case', | |
| 			'catch', | |
| 			'cfunction', | |
| 			'class', | |
| 			'clone', | |
| 			'const', | |
| 			'continue', | |
| 			'declare', | |
| 			'default', | |
| 			'die', | |
| 			'do', | |
| 			'echo', | |
| 			'else', | |
| 			'elseif', | |
| 			'empty', | |
| 			'enddeclare', | |
| 			'endfor', | |
| 			'endforeach', | |
| 			'endif', | |
| 			'endswitch', | |
| 			'endwhile', | |
| 			'eval', | |
| 			'exception', | |
| 			'exit', | |
| 			'extends', | |
| 			'final', | |
| 			'final', | |
| 			'for', | |
| 			'foreach', | |
| 			'function', | |
| 			'global', | |
| 			'goto', | |
| 			'if', | |
| 			'implements', | |
| 			'include', | |
| 			'include_once', | |
| 			'instanceof', | |
| 			'interface', | |
| 			'isset', | |
| 			'list', | |
| 			'namespace', | |
| 			'new', | |
| 			'old_function', | |
| 			'or', | |
| 			'parent', | |
| 			'php_user_filter', | |
| 			'print', | |
| 			'private', | |
| 			'protected', | |
| 			'public', | |
| 			'require', | |
| 			'require_once', | |
| 			'return', | |
| 			'static', | |
| 			'switch', | |
| 			'this', | |
| 			'throw', | |
| 			'try', | |
| 			'unset', | |
| 			'use', | |
| 			'var', | |
| 			'while', | |
| 			'xor', | |
| 		); | |
| 		$value = $this->$attribute; | |
| 		if (in_array(strtolower($value), $keywords)) { | |
| 			$this->addError($attribute, $this->getAttributeLabel($attribute) . ' cannot take a reserved PHP keyword.'); | |
| 		} | |
| 	} | |
| }
 | |
| 
 |