Generator.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\gii\generators\controller;
  8. use Yii;
  9. use yii\gii\CodeFile;
  10. use yii\helpers\Html;
  11. use yii\helpers\Inflector;
  12. /**
  13. * This generator will generate a controller and one or a few action view files.
  14. *
  15. * @property array $actionIDs An array of action IDs entered by the user. This property is read-only.
  16. * @property string $controllerClass The controller class name without the namespace part. This property is
  17. * read-only.
  18. * @property string $controllerFile The controller class file path. This property is read-only.
  19. * @property string $controllerID The controller ID (without the module ID prefix). This property is
  20. * read-only.
  21. * @property \yii\base\Module $module The module that the new controller belongs to. This property is
  22. * read-only.
  23. *
  24. * @author Qiang Xue <qiang.xue@gmail.com>
  25. * @since 2.0
  26. */
  27. class Generator extends \yii\gii\Generator
  28. {
  29. /**
  30. * @var string the controller ID
  31. */
  32. public $controller;
  33. /**
  34. * @var string the base class of the controller
  35. */
  36. public $baseClass = 'yii\web\Controller';
  37. /**
  38. * @var string the namespace of the controller class
  39. */
  40. public $ns;
  41. /**
  42. * @var string list of action IDs separated by commas or spaces
  43. */
  44. public $actions = 'index';
  45. /**
  46. * @inheritdoc
  47. */
  48. public function init()
  49. {
  50. parent::init();
  51. $this->ns = \Yii::$app->controllerNamespace;
  52. }
  53. /**
  54. * @inheritdoc
  55. */
  56. public function getName()
  57. {
  58. return 'Controller Generator';
  59. }
  60. /**
  61. * @inheritdoc
  62. */
  63. public function getDescription()
  64. {
  65. return 'This generator helps you to quickly generate a new controller class,
  66. one or several controller actions and their corresponding views.';
  67. }
  68. /**
  69. * @inheritdoc
  70. */
  71. public function rules()
  72. {
  73. return array_merge(parent::rules(), [
  74. [['controller', 'actions', 'baseClass', 'ns'], 'filter', 'filter' => 'trim'],
  75. [['controller', 'baseClass'], 'required'],
  76. [['controller'], 'match', 'pattern' => '/^[a-z][a-z0-9\\-\\/]*$/', 'message' => 'Only a-z, 0-9, dashes (-) and slashes (/) are allowed.'],
  77. [['actions'], 'match', 'pattern' => '/^[a-z][a-z0-9\\-,\\s]*$/', 'message' => 'Only a-z, 0-9, dashes (-), spaces and commas are allowed.'],
  78. [['baseClass'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'],
  79. [['ns'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'],
  80. ]);
  81. }
  82. /**
  83. * @inheritdoc
  84. */
  85. public function attributeLabels()
  86. {
  87. return [
  88. 'baseClass' => 'Base Class',
  89. 'controller' => 'Controller ID',
  90. 'actions' => 'Action IDs',
  91. 'ns' => 'Controller Namespace',
  92. ];
  93. }
  94. /**
  95. * @inheritdoc
  96. */
  97. public function requiredTemplates()
  98. {
  99. return [
  100. 'controller.php',
  101. 'view.php',
  102. ];
  103. }
  104. /**
  105. * @inheritdoc
  106. */
  107. public function stickyAttributes()
  108. {
  109. return ['ns', 'baseClass'];
  110. }
  111. /**
  112. * @inheritdoc
  113. */
  114. public function hints()
  115. {
  116. return [
  117. 'controller' => 'Controller ID should be in lower case and may contain module ID(s) separated by slashes. For example:
  118. <ul>
  119. <li><code>order</code> generates <code>OrderController.php</code></li>
  120. <li><code>order-item</code> generates <code>OrderItemController.php</code></li>
  121. <li><code>admin/user</code> generates <code>UserController.php</code> within the <code>admin</code> module.</li>
  122. </ul>',
  123. 'actions' => 'Provide one or multiple action IDs to generate empty action method(s) in the controller. Separate multiple action IDs with commas or spaces.
  124. Action IDs should be in lower case. For example:
  125. <ul>
  126. <li><code>index</code> generates <code>actionIndex()</code></li>
  127. <li><code>create-order</code> generates <code>actionCreateOrder()</code></li>
  128. </ul>',
  129. 'ns' => 'This is the namespace that the new controller class will use.',
  130. 'baseClass' => 'This is the class that the new controller class will extend from. Please make sure the class exists and can be autoloaded.',
  131. ];
  132. }
  133. /**
  134. * @inheritdoc
  135. */
  136. public function successMessage()
  137. {
  138. $actions = $this->getActionIDs();
  139. if (in_array('index', $actions)) {
  140. $route = $this->controller . '/index';
  141. } else {
  142. $route = $this->controller . '/' . reset($actions);
  143. }
  144. $link = Html::a('try it now', Yii::$app->getUrlManager()->createUrl($route), ['target' => '_blank']);
  145. return "The controller has been generated successfully. You may $link.";
  146. }
  147. /**
  148. * @inheritdoc
  149. */
  150. public function generate()
  151. {
  152. $files = [];
  153. $files[] = new CodeFile(
  154. $this->getControllerFile(),
  155. $this->render('controller.php')
  156. );
  157. foreach ($this->getActionIDs() as $action) {
  158. $files[] = new CodeFile(
  159. $this->getViewFile($action),
  160. $this->render('view.php', ['action' => $action])
  161. );
  162. }
  163. return $files;
  164. }
  165. /**
  166. * Normalizes [[actions]] into an array of action IDs.
  167. * @return array an array of action IDs entered by the user
  168. */
  169. public function getActionIDs()
  170. {
  171. $actions = array_unique(preg_split('/[\s,]+/', $this->actions, -1, PREG_SPLIT_NO_EMPTY));
  172. sort($actions);
  173. return $actions;
  174. }
  175. /**
  176. * @return string the controller class name without the namespace part.
  177. */
  178. public function getControllerClass()
  179. {
  180. return Inflector::id2camel($this->getControllerID()) . 'Controller';
  181. }
  182. /**
  183. * @return string the controller ID (without the module ID prefix)
  184. */
  185. public function getControllerID()
  186. {
  187. if (($pos = strrpos($this->controller, '/')) !== false) {
  188. return substr($this->controller, $pos + 1);
  189. } else {
  190. return $this->controller;
  191. }
  192. }
  193. /**
  194. * @return \yii\base\Module the module that the new controller belongs to
  195. */
  196. public function getModule()
  197. {
  198. if (($pos = strrpos($this->controller, '/')) !== false) {
  199. $id = substr($this->controller, 0, $pos);
  200. if (($module = Yii::$app->getModule($id)) !== null) {
  201. return $module;
  202. }
  203. }
  204. return Yii::$app;
  205. }
  206. /**
  207. * @return string the controller class file path
  208. */
  209. public function getControllerFile()
  210. {
  211. $module = $this->getModule();
  212. return $module->getControllerPath() . '/' . $this->getControllerClass() . '.php';
  213. }
  214. /**
  215. * @param string $action the action ID
  216. * @return string the action view file path
  217. */
  218. public function getViewFile($action)
  219. {
  220. $module = $this->getModule();
  221. return $module->getViewPath() . '/' . $this->getControllerID() . '/' . $action . '.php';
  222. }
  223. }