Generator.php 5.76 KB
Newer Older
Qiang Xue committed
1 2 3 4 5 6 7 8 9 10
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\gii\generators\controller;

use Yii;
Qiang Xue committed
11 12
use yii\gii\CodeFile;
use yii\helpers\Html;
13
use yii\helpers\Inflector;
Qiang Xue committed
14 15

/**
16
 * This generator will generate a controller and one or a few action view files.
Qiang Xue committed
17 18 19 20 21 22
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class Generator extends \yii\gii\Generator
{
23 24 25
	/**
	 * @var string the controller ID
	 */
Qiang Xue committed
26
	public $controller;
27 28 29
	/**
	 * @var string the base class of the controller
	 */
Qiang Xue committed
30
	public $baseClass = 'yii\web\Controller';
31 32 33
	/**
	 * @var string the namespace of the controller class
	 */
34
	public $ns;
35 36 37
	/**
	 * @var string list of action IDs separated by commas or spaces
	 */
Qiang Xue committed
38 39
	public $actions = 'index';

40
	/**
Qiang Xue committed
41
	 * @inheritdoc
42 43 44 45 46 47 48
	 */
	public function init()
	{
		parent::init();
		$this->ns = \Yii::$app->controllerNamespace;
	}

49
	/**
Qiang Xue committed
50
	 * @inheritdoc
51
	 */
Qiang Xue committed
52 53 54 55 56
	public function getName()
	{
		return 'Controller Generator';
	}

57
	/**
Qiang Xue committed
58
	 * @inheritdoc
59
	 */
Qiang Xue committed
60 61 62 63 64 65
	public function getDescription()
	{
		return 'This generator helps you to quickly generate a new controller class,
			one or several controller actions and their corresponding views.';
	}

66
	/**
Qiang Xue committed
67
	 * @inheritdoc
68
	 */
Qiang Xue committed
69 70
	public function rules()
	{
Alexander Makarov committed
71
		return array_merge(parent::rules(), [
72 73 74 75 76 77
			[['controller', 'actions', 'baseClass', 'ns'], 'filter', 'filter' => 'trim'],
			[['controller', 'baseClass'], 'required'],
			[['controller'], 'match', 'pattern' => '/^[a-z\\-\\/]*$/', 'message' => 'Only a-z, dashes (-) and slashes (/) are allowed.'],
			[['actions'], 'match', 'pattern' => '/^[a-z\\-,\\s]*$/', 'message' => 'Only a-z, dashes (-), spaces and commas are allowed.'],
			[['baseClass'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'],
			[['ns'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'],
Alexander Makarov committed
78
		]);
Qiang Xue committed
79 80
	}

81
	/**
Qiang Xue committed
82
	 * @inheritdoc
83
	 */
Qiang Xue committed
84 85
	public function attributeLabels()
	{
Alexander Makarov committed
86
		return [
Qiang Xue committed
87 88 89
			'baseClass' => 'Base Class',
			'controller' => 'Controller ID',
			'actions' => 'Action IDs',
Qiang Xue committed
90
			'ns' => 'Controller Namespace',
Alexander Makarov committed
91
		];
Qiang Xue committed
92 93
	}

94
	/**
Qiang Xue committed
95
	 * @inheritdoc
96
	 */
Qiang Xue committed
97 98
	public function requiredTemplates()
	{
Alexander Makarov committed
99
		return [
Qiang Xue committed
100 101
			'controller.php',
			'view.php',
Alexander Makarov committed
102
		];
Qiang Xue committed
103 104
	}

105
	/**
Qiang Xue committed
106
	 * @inheritdoc
107
	 */
Qiang Xue committed
108 109
	public function stickyAttributes()
	{
Alexander Makarov committed
110
		return ['ns', 'baseClass'];
Qiang Xue committed
111 112
	}

113
	/**
Qiang Xue committed
114
	 * @inheritdoc
115
	 */
Qiang Xue committed
116 117
	public function hints()
	{
Alexander Makarov committed
118
		return [
119
			'controller' => 'Controller ID should be in lower case and may contain module ID(s) separated by slashes. For example:
Qiang Xue committed
120 121 122 123 124
				<ul>
					<li><code>order</code> generates <code>OrderController.php</code></li>
					<li><code>order-item</code> generates <code>OrderItemController.php</code></li>
					<li><code>admin/user</code> generates <code>UserController.php</code> within the <code>admin</code> module.</li>
				</ul>',
125 126 127 128 129 130
			'actions' => 'Provide one or multiple action IDs to generate empty action method(s) in the controller. Separate multiple action IDs with commas or spaces.
				Action IDs should be in lower case. For example:
				<ul>
					<li><code>index</code> generates <code>actionIndex()</code></li>
					<li><code>create-order</code> generates <code>actionCreateOrder()</code></li>
				</ul>',
Qiang Xue committed
131
			'ns' => 'This is the namespace that the new controller class will use.',
Qiang Xue committed
132
			'baseClass' => 'This is the class that the new controller class will extend from. Please make sure the class exists and can be autoloaded.',
Alexander Makarov committed
133
		];
Qiang Xue committed
134 135
	}

136
	/**
Qiang Xue committed
137
	 * @inheritdoc
138
	 */
Qiang Xue committed
139 140
	public function successMessage()
	{
Qiang Xue committed
141 142 143 144 145 146
		$actions = $this->getActionIDs();
		if (in_array('index', $actions)) {
			$route = $this->controller . '/index';
		} else {
			$route = $this->controller . '/' . reset($actions);
		}
Alexander Makarov committed
147
		$link = Html::a('try it now', Yii::$app->getUrlManager()->createUrl($route), ['target' => '_blank']);
Qiang Xue committed
148 149 150
		return "The controller has been generated successfully. You may $link.";
	}

151
	/**
Qiang Xue committed
152
	 * @inheritdoc
153 154
	 */
	public function generate()
Qiang Xue committed
155
	{
Alexander Makarov committed
156
		$files = [];
Qiang Xue committed
157

Qiang Xue committed
158 159
		$files[] = new CodeFile(
			$this->getControllerFile(),
Qiang Xue committed
160
			$this->render('controller.php')
Qiang Xue committed
161 162 163
		);

		foreach ($this->getActionIDs() as $action) {
Qiang Xue committed
164
			$files[] = new CodeFile(
Qiang Xue committed
165
				$this->getViewFile($action),
Alexander Makarov committed
166
				$this->render('view.php', ['action' => $action])
Qiang Xue committed
167 168
			);
		}
Qiang Xue committed
169 170

		return $files;
Qiang Xue committed
171 172
	}

173 174 175 176
	/**
	 * Normalizes [[actions]] into an array of action IDs.
	 * @return array an array of action IDs entered by the user
	 */
Qiang Xue committed
177 178
	public function getActionIDs()
	{
Qiang Xue committed
179
		$actions = array_unique(preg_split('/[\s,]+/', $this->actions, -1, PREG_SPLIT_NO_EMPTY));
Qiang Xue committed
180 181 182 183
		sort($actions);
		return $actions;
	}

Qiang Xue committed
184 185 186
	/**
	 * @return string the controller class name without the namespace part.
	 */
Qiang Xue committed
187
	public function getControllerClass()
188 189 190 191
	{
		return Inflector::id2camel($this->getControllerID()) . 'Controller';
	}

Qiang Xue committed
192 193 194
	/**
	 * @return string the controller ID (without the module ID prefix)
	 */
195
	public function getControllerID()
Qiang Xue committed
196 197
	{
		if (($pos = strrpos($this->controller, '/')) !== false) {
198
			return substr($this->controller, $pos + 1);
Qiang Xue committed
199
		} else {
200
			return $this->controller;
Qiang Xue committed
201 202 203
		}
	}

Qiang Xue committed
204 205 206
	/**
	 * @return \yii\base\Module the module that the new controller belongs to
	 */
Qiang Xue committed
207 208
	public function getModule()
	{
209
		if (($pos = strrpos($this->controller, '/')) !== false) {
Qiang Xue committed
210
			$id = substr($this->controller, 0, $pos);
Qiang Xue committed
211
			if (($module = Yii::$app->getModule($id)) !== null) {
Qiang Xue committed
212 213 214
				return $module;
			}
		}
Qiang Xue committed
215
		return Yii::$app;
Qiang Xue committed
216 217
	}

Qiang Xue committed
218 219 220
	/**
	 * @return string the controller class file path
	 */
Qiang Xue committed
221 222 223
	public function getControllerFile()
	{
		$module = $this->getModule();
224
		return $module->getControllerPath() . '/' . $this->getControllerClass() . '.php';
Qiang Xue committed
225
	}
Qiang Xue committed
226

Qiang Xue committed
227 228 229 230
	/**
	 * @param string $action the action ID
	 * @return string the action view file path
	 */
Qiang Xue committed
231 232
	public function getViewFile($action)
	{
233 234
		$module = $this->getModule();
		return $module->getViewPath() . '/' . $this->getControllerID() . '/' . $action . '.php';
Qiang Xue committed
235
	}
Qiang Xue committed
236
}