CrudCode.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php
  2. class CrudCode extends CCodeModel
  3. {
  4. public $model;
  5. public $controller;
  6. public $baseControllerClass='Controller';
  7. private $_modelClass;
  8. private $_table;
  9. public function rules()
  10. {
  11. return array_merge(parent::rules(), array(
  12. array('model, controller', 'filter', 'filter'=>'trim'),
  13. array('model, controller, baseControllerClass', 'required'),
  14. array('model', 'match', 'pattern'=>'/^\w+[\w+\\.]*$/', 'message'=>'{attribute} should only contain word characters and dots.'),
  15. array('controller', 'match', 'pattern'=>'/^\w+[\w+\\/]*$/', 'message'=>'{attribute} should only contain word characters and slashes.'),
  16. array('baseControllerClass', 'match', 'pattern'=>'/^[a-zA-Z_\\\\][\w\\\\]*$/', 'message'=>'{attribute} should only contain word characters and backslashes.'),
  17. array('baseControllerClass', 'validateReservedWord', 'skipOnError'=>true),
  18. array('model', 'validateModel'),
  19. array('baseControllerClass', 'sticky'),
  20. ));
  21. }
  22. public function attributeLabels()
  23. {
  24. return array_merge(parent::attributeLabels(), array(
  25. 'model'=>'Model Class',
  26. 'controller'=>'Controller ID',
  27. 'baseControllerClass'=>'Base Controller Class',
  28. ));
  29. }
  30. public function requiredTemplates()
  31. {
  32. return array(
  33. 'controller.php',
  34. );
  35. }
  36. public function init()
  37. {
  38. if(Yii::app()->db===null)
  39. throw new CHttpException(500,'An active "db" connection is required to run this generator.');
  40. parent::init();
  41. }
  42. public function successMessage()
  43. {
  44. $link=CHtml::link('try it now', Yii::app()->createUrl($this->controller), array('target'=>'_blank'));
  45. return "The controller has been generated successfully. You may $link.";
  46. }
  47. public function validateModel($attribute,$params)
  48. {
  49. if($this->hasErrors('model'))
  50. return;
  51. $class=@Yii::import($this->model,true);
  52. if(!is_string($class) || !$this->classExists($class))
  53. $this->addError('model', "Class '{$this->model}' does not exist or has syntax error.");
  54. elseif(!is_subclass_of($class,'CActiveRecord'))
  55. $this->addError('model', "'{$this->model}' must extend from CActiveRecord.");
  56. else
  57. {
  58. $table=CActiveRecord::model($class)->tableSchema;
  59. if($table->primaryKey===null)
  60. $this->addError('model',"Table '{$table->name}' does not have a primary key.");
  61. elseif(is_array($table->primaryKey))
  62. $this->addError('model',"Table '{$table->name}' has a composite primary key which is not supported by crud generator.");
  63. else
  64. {
  65. $this->_modelClass=$class;
  66. $this->_table=$table;
  67. }
  68. }
  69. }
  70. public function prepare()
  71. {
  72. $this->files=array();
  73. $templatePath=$this->templatePath;
  74. $controllerTemplateFile=$templatePath.DIRECTORY_SEPARATOR.'controller.php';
  75. $this->files[]=new CCodeFile(
  76. $this->controllerFile,
  77. $this->render($controllerTemplateFile)
  78. );
  79. $files=scandir($templatePath);
  80. foreach($files as $file)
  81. {
  82. if(is_file($templatePath.'/'.$file) && CFileHelper::getExtension($file)==='php' && $file!=='controller.php')
  83. {
  84. $this->files[]=new CCodeFile(
  85. $this->viewPath.DIRECTORY_SEPARATOR.$file,
  86. $this->render($templatePath.'/'.$file)
  87. );
  88. }
  89. }
  90. }
  91. public function getModelClass()
  92. {
  93. return $this->_modelClass;
  94. }
  95. public function getControllerClass()
  96. {
  97. if(($pos=strrpos($this->controller,'/'))!==false)
  98. return ucfirst(substr($this->controller,$pos+1)).'Controller';
  99. else
  100. return ucfirst($this->controller).'Controller';
  101. }
  102. public function getModule()
  103. {
  104. if(($pos=strpos($this->controller,'/'))!==false)
  105. {
  106. $id=substr($this->controller,0,$pos);
  107. if(($module=Yii::app()->getModule($id))!==null)
  108. return $module;
  109. }
  110. return Yii::app();
  111. }
  112. public function getControllerID()
  113. {
  114. if($this->getModule()!==Yii::app())
  115. $id=substr($this->controller,strpos($this->controller,'/')+1);
  116. else
  117. $id=$this->controller;
  118. if(($pos=strrpos($id,'/'))!==false)
  119. $id[$pos+1]=strtolower($id[$pos+1]);
  120. else
  121. $id[0]=strtolower($id[0]);
  122. return $id;
  123. }
  124. public function getUniqueControllerID()
  125. {
  126. $id=$this->controller;
  127. if(($pos=strrpos($id,'/'))!==false)
  128. $id[$pos+1]=strtolower($id[$pos+1]);
  129. else
  130. $id[0]=strtolower($id[0]);
  131. return $id;
  132. }
  133. public function getControllerFile()
  134. {
  135. $module=$this->getModule();
  136. $id=$this->getControllerID();
  137. if(($pos=strrpos($id,'/'))!==false)
  138. $id[$pos+1]=strtoupper($id[$pos+1]);
  139. else
  140. $id[0]=strtoupper($id[0]);
  141. return $module->getControllerPath().'/'.$id.'Controller.php';
  142. }
  143. public function getViewPath()
  144. {
  145. return $this->getModule()->getViewPath().'/'.$this->getControllerID();
  146. }
  147. public function getTableSchema()
  148. {
  149. return $this->_table;
  150. }
  151. public function generateInputLabel($modelClass,$column)
  152. {
  153. return "CHtml::activeLabelEx(\$model,'{$column->name}')";
  154. }
  155. public function generateInputField($modelClass,$column)
  156. {
  157. if($column->type==='boolean')
  158. return "CHtml::activeCheckBox(\$model,'{$column->name}')";
  159. elseif(stripos($column->dbType,'text')!==false)
  160. return "CHtml::activeTextArea(\$model,'{$column->name}',array('rows'=>6, 'cols'=>50))";
  161. else
  162. {
  163. if(preg_match('/^(password|pass|passwd|passcode)$/i',$column->name))
  164. $inputField='activePasswordField';
  165. else
  166. $inputField='activeTextField';
  167. if($column->type!=='string' || $column->size===null)
  168. return "CHtml::{$inputField}(\$model,'{$column->name}')";
  169. else
  170. {
  171. if(($size=$maxLength=$column->size)>60)
  172. $size=60;
  173. return "CHtml::{$inputField}(\$model,'{$column->name}',array('size'=>$size,'maxlength'=>$maxLength))";
  174. }
  175. }
  176. }
  177. public function generateActiveLabel($modelClass,$column)
  178. {
  179. return "\$form->labelEx(\$model,'{$column->name}')";
  180. }
  181. public function generateActiveField($modelClass,$column)
  182. {
  183. if($column->type==='boolean')
  184. return "\$form->checkBox(\$model,'{$column->name}')";
  185. elseif(stripos($column->dbType,'text')!==false)
  186. return "\$form->textArea(\$model,'{$column->name}',array('rows'=>6, 'cols'=>50))";
  187. else
  188. {
  189. if(preg_match('/^(password|pass|passwd|passcode)$/i',$column->name))
  190. $inputField='passwordField';
  191. else
  192. $inputField='textField';
  193. if($column->type!=='string' || $column->size===null)
  194. return "\$form->{$inputField}(\$model,'{$column->name}')";
  195. else
  196. {
  197. if(($size=$maxLength=$column->size)>60)
  198. $size=60;
  199. return "\$form->{$inputField}(\$model,'{$column->name}',array('size'=>$size,'maxlength'=>$maxLength))";
  200. }
  201. }
  202. }
  203. public function guessNameColumn($columns)
  204. {
  205. foreach($columns as $column)
  206. {
  207. if(!strcasecmp($column->name,'name'))
  208. return $column->name;
  209. }
  210. foreach($columns as $column)
  211. {
  212. if(!strcasecmp($column->name,'title'))
  213. return $column->name;
  214. }
  215. foreach($columns as $column)
  216. {
  217. if($column->isPrimaryKey)
  218. return $column->name;
  219. }
  220. return 'id';
  221. }
  222. }