Commit 97e48139 by Qiang Xue

Fixes #5070: Gii controller generator should use controller class name instead…

Fixes #5070: Gii controller generator should use controller class name instead of controller ID to specify new controller
parent 379319d1
...@@ -4,6 +4,7 @@ Yii Framework 2 gii extension Change Log ...@@ -4,6 +4,7 @@ Yii Framework 2 gii extension Change Log
2.0.1 under development 2.0.1 under development
----------------------- -----------------------
- Bug #5070: Gii controller generator should use controller class name instead of controller ID to specify new controller (qiangxue)
- Bug #5745: Gii and debug modules may cause 404 exception when the route contains dashes (qiangxue) - Bug #5745: Gii and debug modules may cause 404 exception when the route contains dashes (qiangxue)
- Bug: Gii console command help information does not contain global options (qiangxue) - Bug: Gii console command help information does not contain global options (qiangxue)
- Enh #5613: Added `--overwrite` option to Gii console command to support overwriting all files (motin, qiangxue) - Enh #5613: Added `--overwrite` option to Gii console command to support overwriting all files (motin, qiangxue)
......
...@@ -146,13 +146,24 @@ yii.gii = (function ($) { ...@@ -146,13 +146,24 @@ yii.gii = (function ($) {
initConfirmationCheckboxes(); initConfirmationCheckboxes();
initToggleActions(); initToggleActions();
// hide message category when I18N is disabled
$('form #generator-enablei18n').change(function () {
$('form .field-generator-messagecategory').toggle($(this).is(':checked'));
}).change();
// hide Generate button if any input is changed
$('.default-view .form-group input,select,textarea').change(function () {
$('.default-view-results,.default-view-files').hide();
$('.default-view button[name="generate"]').hide();
});
// model generator: hide class name input when table name input contains * // model generator: hide class name input when table name input contains *
$('#model-generator #generator-tablename').change(function () { $('#model-generator #generator-tablename').change(function () {
$('#model-generator .field-generator-modelclass').toggle($(this).val().indexOf('*') == -1); $('.field-generator-modelclass').toggle($(this).val().indexOf('*') == -1);
}).change(); }).change();
// model generator: translate table name to model class // model generator: translate table name to model class
$('#generator-tablename').on('blur', function () { $('#model-generator #generator-tablename').on('blur', function () {
var tableName = $(this).val(); var tableName = $(this).val();
if ($('#generator-modelclass').val()=='' && tableName && tableName.indexOf('*') === -1){ if ($('#generator-modelclass').val()=='' && tableName && tableName.indexOf('*') === -1){
var modelClass=''; var modelClass='';
...@@ -164,17 +175,6 @@ yii.gii = (function ($) { ...@@ -164,17 +175,6 @@ yii.gii = (function ($) {
} }
}); });
// hide message category when I18N is disabled
$('form #generator-enablei18n').change(function () {
$('form .field-generator-messagecategory').toggle($(this).is(':checked'));
}).change();
// hide Generate button if any input is changed
$('.default-view .form-group input,select,textarea').change(function () {
$('.default-view-results,.default-view-files').hide();
$('.default-view button[name="generate"]').hide();
});
$('.module-form #generator-moduleclass').change(function () { $('.module-form #generator-moduleclass').change(function () {
var value = $(this).val().match(/(\w+)\\\w+$/); var value = $(this).val().match(/(\w+)\\\w+$/);
var $idInput = $('#generator-moduleid'); var $idInput = $('#generator-moduleid');
......
...@@ -11,13 +11,12 @@ use Yii; ...@@ -11,13 +11,12 @@ use Yii;
use yii\gii\CodeFile; use yii\gii\CodeFile;
use yii\helpers\Html; use yii\helpers\Html;
use yii\helpers\Inflector; use yii\helpers\Inflector;
use yii\helpers\StringHelper;
/** /**
* This generator will generate a controller and one or a few action view files. * This generator will generate a controller and one or a few action view files.
* *
* @property array $actionIDs An array of action IDs entered by the user. This property is read-only. * @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 $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 * @property string $controllerID The controller ID (without the module ID prefix). This property is
* read-only. * read-only.
...@@ -30,17 +29,17 @@ use yii\helpers\Inflector; ...@@ -30,17 +29,17 @@ use yii\helpers\Inflector;
class Generator extends \yii\gii\Generator class Generator extends \yii\gii\Generator
{ {
/** /**
* @var string the controller ID * @var string the controller class name
*/ */
public $controller; public $controllerClass;
/** /**
* @var string the base class of the controller * @var string the controller's view path
*/ */
public $baseClass = 'yii\web\Controller'; public $viewPath;
/** /**
* @var string the namespace of the controller class * @var string the base class of the controller
*/ */
public $ns; public $baseClass = 'yii\web\Controller';
/** /**
* @var string list of action IDs separated by commas or spaces * @var string list of action IDs separated by commas or spaces
*/ */
...@@ -50,15 +49,6 @@ class Generator extends \yii\gii\Generator ...@@ -50,15 +49,6 @@ class Generator extends \yii\gii\Generator
/** /**
* @inheritdoc * @inheritdoc
*/ */
public function init()
{
parent::init();
$this->ns = \Yii::$app->controllerNamespace;
}
/**
* @inheritdoc
*/
public function getName() public function getName()
{ {
return 'Controller Generator'; return 'Controller Generator';
...@@ -69,7 +59,7 @@ class Generator extends \yii\gii\Generator ...@@ -69,7 +59,7 @@ class Generator extends \yii\gii\Generator
*/ */
public function getDescription() public function getDescription()
{ {
return 'This generator helps you to quickly generate a new controller class, return 'This generator helps you to quickly generate a new controller class with
one or several controller actions and their corresponding views.'; one or several controller actions and their corresponding views.';
} }
...@@ -79,12 +69,12 @@ class Generator extends \yii\gii\Generator ...@@ -79,12 +69,12 @@ class Generator extends \yii\gii\Generator
public function rules() public function rules()
{ {
return array_merge(parent::rules(), [ return array_merge(parent::rules(), [
[['controller', 'actions', 'baseClass', 'ns'], 'filter', 'filter' => 'trim'], [['controllerClass', 'actions', 'baseClass'], 'filter', 'filter' => 'trim'],
[['controller', 'baseClass'], 'required'], [['controllerClass', 'baseClass'], 'required'],
[['controller'], 'match', 'pattern' => '/^[a-z][a-z0-9\\-\\/]*$/', 'message' => 'Only a-z, 0-9, dashes (-) and slashes (/) are allowed.'], ['controllerClass', 'match', 'pattern' => '/^[\w\\\\]*Controller$/', 'message' => 'Only word characters and backslashes are allowed, and the class name must end with "Controller".'],
[['actions'], 'match', 'pattern' => '/^[a-z][a-z0-9\\-,\\s]*$/', 'message' => 'Only a-z, 0-9, dashes (-), spaces and commas are allowed.'], ['controllerClass', 'validateNewClass'],
[['baseClass'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes 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.'], ['actions', 'match', 'pattern' => '/^[a-z][a-z0-9\\-,\\s]*$/', 'message' => 'Only a-z, 0-9, dashes (-), spaces and commas are allowed.'],
]); ]);
} }
...@@ -95,9 +85,9 @@ class Generator extends \yii\gii\Generator ...@@ -95,9 +85,9 @@ class Generator extends \yii\gii\Generator
{ {
return [ return [
'baseClass' => 'Base Class', 'baseClass' => 'Base Class',
'controller' => 'Controller ID', 'controllerClass' => 'Controller Class',
'viewPath' => 'View Path',
'actions' => 'Action IDs', 'actions' => 'Action IDs',
'ns' => 'Controller Namespace',
]; ];
} }
...@@ -117,7 +107,7 @@ class Generator extends \yii\gii\Generator ...@@ -117,7 +107,7 @@ class Generator extends \yii\gii\Generator
*/ */
public function stickyAttributes() public function stickyAttributes()
{ {
return ['ns', 'baseClass']; return ['baseClass'];
} }
/** /**
...@@ -126,19 +116,19 @@ class Generator extends \yii\gii\Generator ...@@ -126,19 +116,19 @@ class Generator extends \yii\gii\Generator
public function hints() public function hints()
{ {
return [ return [
'controller' => 'Controller ID should be in lower case and may contain module ID(s) separated by slashes. For example: 'controllerClass' => 'This is the name of the controller class to be generated. You should
<ul> provide a fully qualified namespaced class (e.g. <code>app\controllers\PostController</code>),
<li><code>order</code> generates <code>OrderController.php</code></li> and class name should be in CamelCase ending with the word <code>Controller</code>. Make sure the class
<li><code>order-item</code> generates <code>OrderItemController.php</code></li> is using the same namespace as specified by your application\'s controllerNamespace property.',
<li><code>admin/user</code> generates <code>UserController.php</code> within the <code>admin</code> module.</li>
</ul>',
'actions' => 'Provide one or multiple action IDs to generate empty action method(s) in the controller. Separate multiple action IDs with commas or spaces. '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: Action IDs should be in lower case. For example:
<ul> <ul>
<li><code>index</code> generates <code>actionIndex()</code></li> <li><code>index</code> generates <code>actionIndex()</code></li>
<li><code>create-order</code> generates <code>actionCreateOrder()</code></li> <li><code>create-order</code> generates <code>actionCreateOrder()</code></li>
</ul>', </ul>',
'ns' => 'This is the namespace that the new controller class will use.', 'viewPath' => 'Specify the directory for storing the view scripts for the controller. You may use path alias here, e.g.,
<code>/var/www/basic/controllers/views/order</code>, <code>@app/views/order</code>. If not set, it will default
to <code>@app/views/ControllerID</code>',
'baseClass' => 'This is the class that the new controller class will extend from. Please make sure the class exists and can be autoloaded.', 'baseClass' => 'This is the class that the new controller class will extend from. Please make sure the class exists and can be autoloaded.',
]; ];
} }
...@@ -150,9 +140,9 @@ class Generator extends \yii\gii\Generator ...@@ -150,9 +140,9 @@ class Generator extends \yii\gii\Generator
{ {
$actions = $this->getActionIDs(); $actions = $this->getActionIDs();
if (in_array('index', $actions)) { if (in_array('index', $actions)) {
$route = $this->controller . '/index'; $route = $this->getControllerID() . '/index';
} else { } else {
$route = $this->controller . '/' . reset($actions); $route = $this->getControllerID() . '/' . reset($actions);
} }
$link = Html::a('try it now', Yii::$app->getUrlManager()->createUrl($route), ['target' => '_blank']); $link = Html::a('try it now', Yii::$app->getUrlManager()->createUrl($route), ['target' => '_blank']);
...@@ -194,58 +184,41 @@ class Generator extends \yii\gii\Generator ...@@ -194,58 +184,41 @@ class Generator extends \yii\gii\Generator
} }
/** /**
* @return string the controller class name without the namespace part. * @return string the controller class file path
*/ */
public function getControllerClass() public function getControllerFile()
{ {
return Inflector::id2camel($this->getControllerID()) . 'Controller'; return Yii::getAlias('@' . str_replace('\\', '/', $this->controllerClass)) . '.php';
} }
/** /**
* @return string the controller ID (without the module ID prefix) * @return string the controller ID
*/ */
public function getControllerID() public function getControllerID()
{ {
if (($pos = strrpos($this->controller, '/')) !== false) { $name = StringHelper::basename($this->controllerClass);
return substr($this->controller, $pos + 1); return Inflector::camel2id(substr($name, 0, strlen($name) - 10));
} else {
return $this->controller;
}
} }
/** /**
* @return \yii\base\Module the module that the new controller belongs to * @param string $action the action ID
* @return string the action view file path
*/ */
public function getModule() public function getViewFile($action)
{ {
if (($pos = strrpos($this->controller, '/')) !== false) { if (empty($this->viewPath)) {
$id = substr($this->controller, 0, $pos); return Yii::getAlias('@app/views/' . $this->getControllerID() . "/$action.php");
if (($module = Yii::$app->getModule($id)) !== null) { } else {
return $module; return Yii::getAlias($this->viewPath . "/$action.php");
}
} }
return Yii::$app;
} }
/** /**
* @return string the controller class file path * @return string the namespace of the controller class
*/ */
public function getControllerFile() public function getControllerNamespace()
{ {
$module = $this->getModule(); $name = StringHelper::basename($this->controllerClass);
return ltrim(substr($this->controllerClass, 0, strlen($name) + 1), '\\');
return $module->getControllerPath() . '/' . $this->getControllerClass() . '.php';
}
/**
* @param string $action the action ID
* @return string the action view file path
*/
public function getViewFile($action)
{
$module = $this->getModule();
return $module->getViewPath() . '/' . $this->getControllerID() . '/' . $action . '.php';
} }
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
use yii\helpers\Inflector; use yii\helpers\Inflector;
use yii\helpers\StringHelper;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $generator yii\gii\generators\controller\Generator */ /* @var $generator yii\gii\generators\controller\Generator */
...@@ -11,11 +12,9 @@ use yii\helpers\Inflector; ...@@ -11,11 +12,9 @@ use yii\helpers\Inflector;
echo "<?php\n"; echo "<?php\n";
?> ?>
<?php if (!empty($generator->ns)): ?> namespace <?= $generator->getControllerNamespace() ?>;
namespace <?= $generator->ns ?>;
<?php endif; ?>
class <?= $generator->getControllerClass() ?> extends <?= '\\' . trim($generator->baseClass, '\\') . "\n" ?> class <?= StringHelper::basename($generator->controllerClass) ?> extends <?= '\\' . trim($generator->baseClass, '\\') . "\n" ?>
{ {
<?php foreach ($generator->getActionIDs() as $action): ?> <?php foreach ($generator->getActionIDs() as $action): ?>
public function action<?= Inflector::id2camel($action) ?>() public function action<?= Inflector::id2camel($action) ?>()
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
/* @var $form yii\widgets\ActiveForm */ /* @var $form yii\widgets\ActiveForm */
/* @var $generator yii\gii\generators\controller\Generator */ /* @var $generator yii\gii\generators\controller\Generator */
echo $form->field($generator, 'controller'); echo $form->field($generator, 'controllerClass');
echo $form->field($generator, 'actions'); echo $form->field($generator, 'actions');
echo $form->field($generator, 'ns'); echo $form->field($generator, 'viewPath');
echo $form->field($generator, 'baseClass'); echo $form->field($generator, 'baseClass');
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
?> ?>
<div class="alert alert-info"> <div class="alert alert-info">
Please read the Please read the
<?= \yii\helpers\Html::a('Extension Guidelines', 'https://github.com/yiisoft/yii2/blob/master/docs/guide/structure-extensions.md', ['target'=>'new']) ?> <?= \yii\helpers\Html::a('Extension Guidelines', 'http://www.yiiframework.com/doc-2.0/guide-structure-extensions.html', ['target'=>'new']) ?>
before creating an extension. before creating an extension.
</div> </div>
<div class="module-form"> <div class="module-form">
......
...@@ -7,6 +7,7 @@ Yii Framework 2 Change Log ...@@ -7,6 +7,7 @@ Yii Framework 2 Change Log
- Bug #4471: `yii\caching\ApcCache::getValues()` now returns array in case of APC is installed but not enabled in CLI mode (samdark, cebe) - Bug #4471: `yii\caching\ApcCache::getValues()` now returns array in case of APC is installed but not enabled in CLI mode (samdark, cebe)
- Bug #4823: `yii message` accuracy and error handling were improved (samdark) - Bug #4823: `yii message` accuracy and error handling were improved (samdark)
- Bug #4889: Application was getting into redirect loop when user wasn't allowed accessing login page. Now shows 403 (samdark) - Bug #4889: Application was getting into redirect loop when user wasn't allowed accessing login page. Now shows 403 (samdark)
- Bug #5070: Gii controller generator should use controller class name instead of controller ID to specify new controller (qiangxue)
- Bug #5402: Debugger was not loading when there were closures in asset classes (samdark) - Bug #5402: Debugger was not loading when there were closures in asset classes (samdark)
- Bug #5448: Date formatter was doing timezone conversion on date only values resulting in different date displayed than provided (cebe) - Bug #5448: Date formatter was doing timezone conversion on date only values resulting in different date displayed than provided (cebe)
- Bug #5452: Errors occurring after the response is sent are not displayed (qiangxue) - Bug #5452: Errors occurring after the response is sent are not displayed (qiangxue)
......
...@@ -18,7 +18,7 @@ class GeneratorsTest extends GiiTestCase ...@@ -18,7 +18,7 @@ class GeneratorsTest extends GiiTestCase
{ {
$generator = new ControllerGenerator(); $generator = new ControllerGenerator();
$generator->template = 'default'; $generator->template = 'default';
$generator->controller = 'test'; $generator->controllerClass = 'test';
if ($generator->validate()) { if ($generator->validate()) {
$generator->generate(); $generator->generate();
...@@ -107,4 +107,4 @@ class GeneratorsTest extends GiiTestCase ...@@ -107,4 +107,4 @@ class GeneratorsTest extends GiiTestCase
print_r($generator->getErrors()); print_r($generator->getErrors());
} }
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment