mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-11 19:20:01 +08:00
Merge pull request #2411 from schmunk42/feature/gii-extension-generator
first draft of the extension generator
This commit is contained in:
@@ -141,6 +141,7 @@ class Module extends \yii\base\Module
|
|||||||
'controller' => ['class' => 'yii\gii\generators\controller\Generator'],
|
'controller' => ['class' => 'yii\gii\generators\controller\Generator'],
|
||||||
'form' => ['class' => 'yii\gii\generators\form\Generator'],
|
'form' => ['class' => 'yii\gii\generators\form\Generator'],
|
||||||
'module' => ['class' => 'yii\gii\generators\module\Generator'],
|
'module' => ['class' => 'yii\gii\generators\module\Generator'],
|
||||||
|
'extension' => ['class' => 'yii\gii\generators\extension\Generator'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
266
extensions/gii/generators/extension/Generator.php
Normal file
266
extensions/gii/generators/extension/Generator.php
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link http://www.yiiframework.com/
|
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||||
|
* @license http://www.yiiframework.com/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace yii\gii\generators\extension;
|
||||||
|
|
||||||
|
use yii\gii\CodeFile;
|
||||||
|
use yii\helpers\Html;
|
||||||
|
use Yii;
|
||||||
|
use yii\helpers\StringHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This generator will generate the skeleton files needed by an extension.
|
||||||
|
*
|
||||||
|
* @author Tobias Munk <schmunk@usrbin.de>
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class Generator extends \yii\gii\Generator
|
||||||
|
{
|
||||||
|
public $vendorName;
|
||||||
|
public $packageName = "yii2-";
|
||||||
|
public $namespace;
|
||||||
|
public $type = "yii2-extension";
|
||||||
|
public $keywords = "yii2,extension";
|
||||||
|
public $title;
|
||||||
|
public $description;
|
||||||
|
public $outputPath = "@app/runtime/tmp-extensions";
|
||||||
|
public $license;
|
||||||
|
public $authorName;
|
||||||
|
public $authorEmail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'Extension Generator';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getDescription()
|
||||||
|
{
|
||||||
|
return 'This generator helps you to generate the files needed by a Yii extension.';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::rules(),
|
||||||
|
[
|
||||||
|
[['vendorName', 'packageName'], 'filter', 'filter' => 'trim'],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'vendorName',
|
||||||
|
'packageName',
|
||||||
|
'namespace',
|
||||||
|
'type',
|
||||||
|
'license',
|
||||||
|
'title',
|
||||||
|
'description',
|
||||||
|
'authorName',
|
||||||
|
'authorEmail',
|
||||||
|
'outputPath'
|
||||||
|
],
|
||||||
|
'required'
|
||||||
|
],
|
||||||
|
[['keywords'], 'safe'],
|
||||||
|
[['authorEmail'], 'email'],
|
||||||
|
[
|
||||||
|
['vendorName', 'packageName'],
|
||||||
|
'match',
|
||||||
|
'pattern' => '/^[a-z0-9\-\.]+$/',
|
||||||
|
'message' => 'Only lowercase word characters, dashes and dots are allowed.'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
['namespace'],
|
||||||
|
'match',
|
||||||
|
'pattern' => '/^[a-zA-Z0-9\\\]+\\\$/',
|
||||||
|
'message' => 'Only letters, numbers and backslashes are allowed. PSR-4 namespaces must end with a namespace separator.'
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'vendorName' => 'Vendor Name',
|
||||||
|
'packageName' => 'Package Name',
|
||||||
|
'license' => 'License',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function hints()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'vendorName' => 'This refers to the name of the publisher, your GitHub user name is usually a good choice, eg. <code>myself</code>.',
|
||||||
|
'packageName' => 'This is the name of the extension on packagist, eg. <code>yii2-foobar</code>.',
|
||||||
|
'namespace' => 'PSR-4, eg. <code>myself\foobar\</code> This will be added to your autoloading by composer. Do not use yii or yii2 in the namespace.',
|
||||||
|
'keywords' => 'Comma separated keywords for this extension.',
|
||||||
|
'outputPath' => 'The temporary location of the generated files.',
|
||||||
|
'title' => 'A more descriptive name of your application for the README file.',
|
||||||
|
'description' => 'A sentence or subline describing the main purpose of the extension.',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function stickyAttributes()
|
||||||
|
{
|
||||||
|
return ['vendorName', 'outputPath', 'authorName', 'authorEmail'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function successMessage()
|
||||||
|
{
|
||||||
|
$outputPath = realpath(\Yii::getAlias($this->outputPath));
|
||||||
|
$output1 = <<<EOD
|
||||||
|
<p><em>The extension has been generated successfully.</em></p>
|
||||||
|
<p>To enable it in your application, you need to create a git repository
|
||||||
|
and require it via composer.</p>
|
||||||
|
EOD;
|
||||||
|
$code1 = <<<EOD
|
||||||
|
cd {$outputPath}/{$this->packageName}
|
||||||
|
|
||||||
|
git init
|
||||||
|
git add -A
|
||||||
|
git commit
|
||||||
|
git remote add origin https://path.to/your/repo
|
||||||
|
git push -u origin master
|
||||||
|
EOD;
|
||||||
|
$output2 = <<<EOD
|
||||||
|
<p>The next step is just for <em>initial development</em>, skip it if you directly publish the extension on packagist.org</p>
|
||||||
|
<p>Add the newly created repo to your composer.json.</p>
|
||||||
|
EOD;
|
||||||
|
$code2 = <<<EOD
|
||||||
|
"repositories":[
|
||||||
|
{
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://path.to/your/repo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
EOD;
|
||||||
|
$output3 = <<<EOD
|
||||||
|
<p class="well">Note: You may use the url <code>file://{$outputPath}/{$this->packageName}</code> for testing.</p>
|
||||||
|
<p>Require the package with composer</p>
|
||||||
|
EOD;
|
||||||
|
$code3 = <<<EOD
|
||||||
|
composer.phar require {$this->vendorName}/{$this->packageName}:dev-master
|
||||||
|
EOD;
|
||||||
|
$output4 = <<<EOD
|
||||||
|
<p>And use it in your application.</p>
|
||||||
|
EOD;
|
||||||
|
$code4 = <<<EOD
|
||||||
|
\\{$this->namespace}AutoloadExample::widget();
|
||||||
|
EOD;
|
||||||
|
$output5 = <<<EOD
|
||||||
|
<p>When you have finished development register your extension at <a href='https://packagist.org/' target='_blank'>packagist.org</a>.</p>
|
||||||
|
EOD;
|
||||||
|
|
||||||
|
$return = $output1 . '<pre>' . highlight_string($code1, true) . '</pre>';
|
||||||
|
$return .= $output2 . '<pre>' . highlight_string($code2, true) . '</pre>';
|
||||||
|
$return .= $output3 . '<pre>' . highlight_string($code3, true) . '</pre>';
|
||||||
|
$return .= $output4 . '<pre>' . highlight_string($code4, true) . '</pre>';
|
||||||
|
$return .= $output5;
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function requiredTemplates()
|
||||||
|
{
|
||||||
|
return ['composer.json', 'AutoloadExample.php', 'README.md'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function generate()
|
||||||
|
{
|
||||||
|
$files = [];
|
||||||
|
$modulePath = $this->getOutputPath();
|
||||||
|
$files[] = new CodeFile(
|
||||||
|
$modulePath . '/' . $this->packageName . '/composer.json',
|
||||||
|
$this->render("composer.json")
|
||||||
|
);
|
||||||
|
$files[] = new CodeFile(
|
||||||
|
$modulePath . '/' . $this->packageName . '/AutoloadExample.php',
|
||||||
|
$this->render("AutoloadExample.php")
|
||||||
|
);
|
||||||
|
$files[] = new CodeFile(
|
||||||
|
$modulePath . '/' . $this->packageName . '/README.md',
|
||||||
|
$this->render("README.md")
|
||||||
|
);
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return boolean the directory that contains the module class
|
||||||
|
*/
|
||||||
|
public function getOutputPath()
|
||||||
|
{
|
||||||
|
return Yii::getAlias($this->outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a json encoded array with the given keywords
|
||||||
|
*/
|
||||||
|
public function getKeywordsArrayJson()
|
||||||
|
{
|
||||||
|
return json_encode(explode(',', $this->keywords));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array options for type drop-down
|
||||||
|
*/
|
||||||
|
public function optsType()
|
||||||
|
{
|
||||||
|
$licenses = [
|
||||||
|
'yii2-extension',
|
||||||
|
'library',
|
||||||
|
];
|
||||||
|
return array_combine($licenses, $licenses);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array options for license drop-down
|
||||||
|
*/
|
||||||
|
public function optsLicense()
|
||||||
|
{
|
||||||
|
$licenses = [
|
||||||
|
'Apache-2.0',
|
||||||
|
'BSD-2-Clause',
|
||||||
|
'BSD-3-Clause',
|
||||||
|
'BSD-4-Clause',
|
||||||
|
'GPL-2.0',
|
||||||
|
'GPL-2.0+',
|
||||||
|
'GPL-3.0',
|
||||||
|
'GPL-3.0+',
|
||||||
|
'LGPL-2.1',
|
||||||
|
'LGPL-2.1+',
|
||||||
|
'LGPL-3.0',
|
||||||
|
'LGPL-3.0+',
|
||||||
|
'MIT'
|
||||||
|
];
|
||||||
|
return array_combine($licenses, $licenses);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
extensions/gii/generators/extension/form.php
Normal file
27
extensions/gii/generators/extension/form.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @var yii\web\View $this
|
||||||
|
* @var yii\widgets\ActiveForm $form
|
||||||
|
* @var yii\gii\generators\module\Generator $generator
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<div class="alert alert-info">
|
||||||
|
Please read the
|
||||||
|
<?= \yii\helpers\Html::a('Extension Guidelines', 'https://github.com/yiisoft/yii2/blob/master/docs/guide/extensions.md', ['target'=>'new']) ?>
|
||||||
|
before creating an extension.
|
||||||
|
</div>
|
||||||
|
<div class="module-form">
|
||||||
|
<?php
|
||||||
|
echo $form->field($generator, 'vendorName');
|
||||||
|
echo $form->field($generator, 'packageName');
|
||||||
|
echo $form->field($generator, 'namespace');
|
||||||
|
echo $form->field($generator, 'type')->dropDownList($generator->optsType());
|
||||||
|
echo $form->field($generator, 'keywords');
|
||||||
|
echo $form->field($generator, 'license')->dropDownList($generator->optsLicense(), ['prompt'=>'Choose...']);
|
||||||
|
echo $form->field($generator, 'title');
|
||||||
|
echo $form->field($generator, 'description');
|
||||||
|
echo $form->field($generator, 'authorName');
|
||||||
|
echo $form->field($generator, 'authorEmail');
|
||||||
|
echo $form->field($generator, 'outputPath');
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This is just an example. *
|
||||||
|
*/
|
||||||
|
echo "<?php\n";
|
||||||
|
?>
|
||||||
|
|
||||||
|
namespace <?= substr($generator->namespace, 0, -1) ?>;
|
||||||
|
|
||||||
|
class AutoloadExample extends \yii\base\widget {
|
||||||
|
function run() {
|
||||||
|
return "Hello!";
|
||||||
|
}
|
||||||
|
}
|
||||||
35
extensions/gii/generators/extension/templates/README.md
Normal file
35
extensions/gii/generators/extension/templates/README.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?= $generator->title ?>
|
||||||
|
===
|
||||||
|
|
||||||
|
<?= $generator->description ?>
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
The preferred way to install this extension is through [composer](http://getcomposer.org/download/).
|
||||||
|
|
||||||
|
Either run
|
||||||
|
|
||||||
|
```
|
||||||
|
php composer.phar require --prefer-dist <?= $generator->vendorName ?>/<?= $generator->packageName ?> "*"
|
||||||
|
```
|
||||||
|
|
||||||
|
or add
|
||||||
|
|
||||||
|
```
|
||||||
|
"<?= $generator->vendorName ?>/<?= $generator->packageName ?>": "*"
|
||||||
|
```
|
||||||
|
|
||||||
|
to the require section of your `composer.json` file.
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
Once the extension is installed, simply use it in your code by :
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?= "<?= \\{$generator->namespace}\\AutoloadExample::wiget(); ?>" ?>
|
||||||
|
];
|
||||||
|
```
|
||||||
18
extensions/gii/generators/extension/templates/composer.json
Normal file
18
extensions/gii/generators/extension/templates/composer.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "<?= $generator->vendorName ?>/<?= $generator->packageName ?>",
|
||||||
|
"description": "<?= $generator->description ?>",
|
||||||
|
"type": "<?= $generator->type ?>",
|
||||||
|
"keywords": <?= $generator->keywordsArrayJson ?>,
|
||||||
|
"license": "<?= $generator->license ?>",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "<?= $generator->authorName ?>",
|
||||||
|
"email": "<?= $generator->authorEmail ?>"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"<?= str_replace('\\','\\\\',$generator->namespace) ?>": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -118,9 +118,10 @@ Yii Framework 2 Change Log
|
|||||||
- Enh #2364: Take into account current error reporting level in error handler (gureedo)
|
- Enh #2364: Take into account current error reporting level in error handler (gureedo)
|
||||||
- Enh #2387: Added support for fetching data from database in batches (nineinchnick, qiangxue)
|
- Enh #2387: Added support for fetching data from database in batches (nineinchnick, qiangxue)
|
||||||
- Enh #2392: Added `addCssStyle()`, `removeCssStyle()`, `cssStyleFromArray()` and `cssStyleToArray()` to `Html` (qiangxue, kartik-v, Alex-Code)
|
- Enh #2392: Added `addCssStyle()`, `removeCssStyle()`, `cssStyleFromArray()` and `cssStyleToArray()` to `Html` (qiangxue, kartik-v, Alex-Code)
|
||||||
|
- Enh #2411: Added Gii extension generator (schmunk42)
|
||||||
|
- Enh #2415: Added support for inverse relations (qiangxue)
|
||||||
- Enh #2417: Added possibility to set `dataType` for `$.ajax` call in yii.activeForm.js (Borales)
|
- Enh #2417: Added possibility to set `dataType` for `$.ajax` call in yii.activeForm.js (Borales)
|
||||||
- Enh #2436: Label of the attribute, which looks like `relatedModel.attribute`, will be received from the related model if it available (djagya)
|
- Enh #2436: Label of the attribute, which looks like `relatedModel.attribute`, will be received from the related model if it available (djagya)
|
||||||
- Enh #2415: Added support for inverse relations (qiangxue)
|
|
||||||
- Enh #2490: `yii\db\Query::count()` and other query scalar methods now properly handle queries with GROUP BY clause (qiangxue)
|
- Enh #2490: `yii\db\Query::count()` and other query scalar methods now properly handle queries with GROUP BY clause (qiangxue)
|
||||||
- Enh #2491: Added support for using the same base class name of search model and data model in Gii (qiangxue)
|
- Enh #2491: Added support for using the same base class name of search model and data model in Gii (qiangxue)
|
||||||
- Enh #2499: Added ability to downgrade migrations by their absolute apply time (resurtm, gorcer)
|
- Enh #2499: Added ability to downgrade migrations by their absolute apply time (resurtm, gorcer)
|
||||||
|
|||||||
Reference in New Issue
Block a user