Generator.php 6.33 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 23 24 25 26
 * @property array $actionIDs An array of action IDs entered by the user. This property is read-only.
 * @property string $controllerClass The controller class name without the namespace part. This property is
 * read-only.
 * @property string $controllerFile The controller class file path. This property is read-only.
 * @property string $controllerID The controller ID (without the module ID prefix). This property is
 * read-only.
 * @property \yii\base\Module $module The module that the new controller belongs to. This property is
 * read-only.
 *
Qiang Xue committed
27 28 29 30 31
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class Generator extends \yii\gii\Generator
{
32 33 34
	/**
	 * @var string the controller ID
	 */
Qiang Xue committed
35
	public $controller;
36 37 38
	/**
	 * @var string the base class of the controller
	 */
Qiang Xue committed
39
	public $baseClass = 'yii\web\Controller';
40 41 42
	/**
	 * @var string the namespace of the controller class
	 */
43
	public $ns;
44 45 46
	/**
	 * @var string list of action IDs separated by commas or spaces
	 */
Qiang Xue committed
47 48
	public $actions = 'index';

49
	/**
Qiang Xue committed
50
	 * @inheritdoc
51 52 53 54 55 56 57
	 */
	public function init()
	{
		parent::init();
		$this->ns = \Yii::$app->controllerNamespace;
	}

58
	/**
Qiang Xue committed
59
	 * @inheritdoc
60
	 */
Qiang Xue committed
61 62 63 64 65
	public function getName()
	{
		return 'Controller Generator';
	}

66
	/**
Qiang Xue committed
67
	 * @inheritdoc
68
	 */
Qiang Xue committed
69 70 71 72 73 74
	public function getDescription()
	{
		return 'This generator helps you to quickly generate a new controller class,
			one or several controller actions and their corresponding views.';
	}

75
	/**
Qiang Xue committed
76
	 * @inheritdoc
77
	 */
Qiang Xue committed
78 79
	public function rules()
	{
Alexander Makarov committed
80
		return array_merge(parent::rules(), [
81 82
			[['controller', 'actions', 'baseClass', 'ns'], 'filter', 'filter' => 'trim'],
			[['controller', 'baseClass'], 'required'],
83 84
			[['controller'], 'match', 'pattern' => '/^[a-z][a-z0-9\\-\\/]*$/', 'message' => 'Only a-z, 0-9, dashes (-) and slashes (/) are allowed.'],
			[['actions'], 'match', 'pattern' => '/^[a-z][a-z0-9\\-,\\s]*$/', 'message' => 'Only a-z, 0-9, dashes (-), spaces and commas are allowed.'],
85 86
			[['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
87
		]);
Qiang Xue committed
88 89
	}

90
	/**
Qiang Xue committed
91
	 * @inheritdoc
92
	 */
Qiang Xue committed
93 94
	public function attributeLabels()
	{
Alexander Makarov committed
95
		return [
Qiang Xue committed
96 97 98
			'baseClass' => 'Base Class',
			'controller' => 'Controller ID',
			'actions' => 'Action IDs',
Qiang Xue committed
99
			'ns' => 'Controller Namespace',
Alexander Makarov committed
100
		];
Qiang Xue committed
101 102
	}

103
	/**
Qiang Xue committed
104
	 * @inheritdoc
105
	 */
Qiang Xue committed
106 107
	public function requiredTemplates()
	{
Alexander Makarov committed
108
		return [
Qiang Xue committed
109 110
			'controller.php',
			'view.php',
Alexander Makarov committed
111
		];
Qiang Xue committed
112 113
	}

114
	/**
Qiang Xue committed
115
	 * @inheritdoc
116
	 */
Qiang Xue committed
117 118
	public function stickyAttributes()
	{
Alexander Makarov committed
119
		return ['ns', 'baseClass'];
Qiang Xue committed
120 121
	}

122
	/**
Qiang Xue committed
123
	 * @inheritdoc
124
	 */
Qiang Xue committed
125 126
	public function hints()
	{
Alexander Makarov committed
127
		return [
128
			'controller' => 'Controller ID should be in lower case and may contain module ID(s) separated by slashes. For example:
Qiang Xue committed
129 130 131 132 133
				<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>',
134 135 136 137 138 139
			'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
140
			'ns' => 'This is the namespace that the new controller class will use.',
Qiang Xue committed
141
			'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
142
		];
Qiang Xue committed
143 144
	}

145
	/**
Qiang Xue committed
146
	 * @inheritdoc
147
	 */
Qiang Xue committed
148 149
	public function successMessage()
	{
Qiang Xue committed
150 151 152 153 154 155
		$actions = $this->getActionIDs();
		if (in_array('index', $actions)) {
			$route = $this->controller . '/index';
		} else {
			$route = $this->controller . '/' . reset($actions);
		}
Alexander Makarov committed
156
		$link = Html::a('try it now', Yii::$app->getUrlManager()->createUrl($route), ['target' => '_blank']);
Qiang Xue committed
157 158 159
		return "The controller has been generated successfully. You may $link.";
	}

160
	/**
Qiang Xue committed
161
	 * @inheritdoc
162 163
	 */
	public function generate()
Qiang Xue committed
164
	{
Alexander Makarov committed
165
		$files = [];
Qiang Xue committed
166

Qiang Xue committed
167 168
		$files[] = new CodeFile(
			$this->getControllerFile(),
Qiang Xue committed
169
			$this->render('controller.php')
Qiang Xue committed
170 171 172
		);

		foreach ($this->getActionIDs() as $action) {
Qiang Xue committed
173
			$files[] = new CodeFile(
Qiang Xue committed
174
				$this->getViewFile($action),
Alexander Makarov committed
175
				$this->render('view.php', ['action' => $action])
Qiang Xue committed
176 177
			);
		}
Qiang Xue committed
178 179

		return $files;
Qiang Xue committed
180 181
	}

182 183 184 185
	/**
	 * Normalizes [[actions]] into an array of action IDs.
	 * @return array an array of action IDs entered by the user
	 */
Qiang Xue committed
186 187
	public function getActionIDs()
	{
Qiang Xue committed
188
		$actions = array_unique(preg_split('/[\s,]+/', $this->actions, -1, PREG_SPLIT_NO_EMPTY));
Qiang Xue committed
189 190 191 192
		sort($actions);
		return $actions;
	}

Qiang Xue committed
193 194 195
	/**
	 * @return string the controller class name without the namespace part.
	 */
Qiang Xue committed
196
	public function getControllerClass()
197 198 199 200
	{
		return Inflector::id2camel($this->getControllerID()) . 'Controller';
	}

Qiang Xue committed
201 202 203
	/**
	 * @return string the controller ID (without the module ID prefix)
	 */
204
	public function getControllerID()
Qiang Xue committed
205 206
	{
		if (($pos = strrpos($this->controller, '/')) !== false) {
207
			return substr($this->controller, $pos + 1);
Qiang Xue committed
208
		} else {
209
			return $this->controller;
Qiang Xue committed
210 211 212
		}
	}

Qiang Xue committed
213 214 215
	/**
	 * @return \yii\base\Module the module that the new controller belongs to
	 */
Qiang Xue committed
216 217
	public function getModule()
	{
218
		if (($pos = strrpos($this->controller, '/')) !== false) {
Qiang Xue committed
219
			$id = substr($this->controller, 0, $pos);
Qiang Xue committed
220
			if (($module = Yii::$app->getModule($id)) !== null) {
Qiang Xue committed
221 222 223
				return $module;
			}
		}
Qiang Xue committed
224
		return Yii::$app;
Qiang Xue committed
225 226
	}

Qiang Xue committed
227 228 229
	/**
	 * @return string the controller class file path
	 */
Qiang Xue committed
230 231 232
	public function getControllerFile()
	{
		$module = $this->getModule();
233
		return $module->getControllerPath() . '/' . $this->getControllerClass() . '.php';
Qiang Xue committed
234
	}
Qiang Xue committed
235

Qiang Xue committed
236 237 238 239
	/**
	 * @param string $action the action ID
	 * @return string the action view file path
	 */
Qiang Xue committed
240 241
	public function getViewFile($action)
	{
242 243
		$module = $this->getModule();
		return $module->getViewPath() . '/' . $this->getControllerID() . '/' . $action . '.php';
Qiang Xue committed
244
	}
Qiang Xue committed
245
}