init
This commit is contained in:
155
vendor/yiisoft/yii2-gii/CHANGELOG.md
vendored
Normal file
155
vendor/yiisoft/yii2-gii/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
Yii Framework 2 gii extension Change Log
|
||||
========================================
|
||||
|
||||
2.0.7 May 3, 2018
|
||||
-----------------
|
||||
|
||||
- Bug #185: Fixed bug in Model generators when FKs pointing to non-existing tables (adipriyantobpn)
|
||||
- Bug #328: Fixed bug in CRUD update view generator (ricpelo)
|
||||
- Bug #333: Fixed incorrect validation rule for TINYINT column type (nostop8)
|
||||
- Bug #340: Fixed bug in CRUD SearchModel generator (JeanWolf)
|
||||
- Bug #351: Fixed incorrect validation rule for JSON column type (silverfire)
|
||||
|
||||
|
||||
2.0.6 December 23, 2017
|
||||
-----------------------
|
||||
|
||||
- Bug #97: Fixed errors and wrong directories created when using backslash in view paths and output paths of CRUD, Controller and Extension generators (lubosdz, samdark)
|
||||
- Bug #100, #102: Fixed "Check This File" button in the preview modal (Insensus, thiagotalma)
|
||||
- Bug #126, #139: Fixed model generator form validation when "ActiveQuery Class" is invalid but unused (kikimor)
|
||||
- Bug #149: Relation names no longer override existing methods and properties (Faryshta)
|
||||
- Bug #152: Fixed generating model without any rules (and800)
|
||||
- Bug #166: Fixed "Trying to get property of non-object" during model generation (zlakomanoff)
|
||||
- Bug #179: Fixed indentation and newlines for Pjax widget in CRUD index view (nkovacs)
|
||||
- Bug #182: Fixed wrong link after generating controller located in sub-namespace of controllers namespace (MKiselev)
|
||||
- Bug #186: Fixed incorrect database name exception (zlakomanoff, shirase)
|
||||
- Bug #198: Fixed false-positive detection of URL fields in CRUD generator (cebe)
|
||||
- Bug #200: Fixed Pjax and Listview with CRUD generator (ariestattoo)
|
||||
- Bug #224: Add default validator with `null` value for integers when db is PostgreSQL (MKiselev)
|
||||
- Bug #232: Fixed Help documentation link (drdim)
|
||||
- Bug #255: Fixed error when getting database driver name when db is not an instance of `yii\db\Connection` (MKiselev)
|
||||
- Bug #271: Fixed absolute namespace of model class in form generator (CeBe, amin3mej)
|
||||
- Bug #274: Added `useTablePrefix` and `generateQuery` to `stickyAttributes` (luyi61)
|
||||
- Bug #290: Fixed model generator to work properly with `schema.table` as table name (SwoDs)
|
||||
- Bug #317: Force HTML content type in response to display HTML when app is configured for REST API (microThread)
|
||||
- Bug #318: Use `yii\base\BaseObject` instead `yii\base\Object` in `CodeFile.php` (MKiselev)
|
||||
- Enh #131: Allow using table comments for PHPdoc property description (stmswitcher, michaelarnauts)
|
||||
- Enh #153: Added filename filter to generated files list preview (thiagotalma)
|
||||
- Enh #162: Model generator now detects foreign keys named as `id_*` (mootensai, samdark)
|
||||
- Enh #167: Added "generating relations from current schema" option to model generator (zlakomanoff)
|
||||
- Enh #174: `NotFoundHttpException` message in CRUD now uses i18n (bscheshirwork)
|
||||
- Enh #223: Use `ilike` operator when generating search model for PostgreSQL (MKiselev, arogachev)
|
||||
- Enh #230: Allowed underscores for extension namespaces (Nex Otaku)
|
||||
- Enh #234: Changed submit button label from "Update" and "Create" to "Save" (MKiselev)
|
||||
- Enh #238: Use `int`/`bool` instead of `integer`/`boolean` in phpdoc blocks generated (MKiselev)
|
||||
- Enh #241: Remove message for unique validator (MKiselev)
|
||||
- Enh #249: unique validation rule is now generated for tables with multiple primary keys (dmirogin)
|
||||
- Enh #252: Added meta tag to prevent indexing of debug by search engines in case it's exposed (bashkarev)
|
||||
- Enh #293: Do not generate redundant `else` after `return` (bscheshirwork)
|
||||
- Enh #295: Allowed to use aliases in generator's templates (dmirogin)
|
||||
- Enh #300: Removed space from commented out code so when uncommenting in IDEs there's no extra spacing (bscheshirwork)
|
||||
- Enh #315: Make `yii\gii\generators\model\Generator` `generateProperties` protected (claudejanz)
|
||||
- Enh #319: Added `@throws` tags for 404 exceptions in CRUD actions (and800)
|
||||
- Enh: `yii\gii\Module::defaultVersion()` implemented to pick up 'yiisoft/yii2-gii' extension version (klimov-paul)
|
||||
- Chg #246: Changed the way CRUD generator translates "Update X id". Now it's a whole string because of translation difficulties (bscheshirwork)
|
||||
|
||||
|
||||
2.0.5 March 18, 2016
|
||||
--------------------
|
||||
|
||||
- Bug #66: It was impossible to use tables with spaces (cornernote)
|
||||
- Bug #79: There was no form element to toggle using schema name for class name (phpniki)
|
||||
- Bug #83: Files were overwritten regardless of answers in console Gii (chernyshev, jeicd)
|
||||
- Bug #104: Allow reuse of the Gii Module for running multiple actions (cebe)
|
||||
- Bug #109: Exception was thrown when `yii\rest\UrlRule` was used in `UrlManager::ruleConfig` (lichunqiang)
|
||||
- Bug #116: Added table prefix autoremoving from the generated model className (umanamente, silverfire)
|
||||
- Bug #134: Model generator was not validating ActiveQuery namespace (zetamen)
|
||||
- Enh #20: Added support for composite (multi-column) foreign keys in junction tables (nineinchnick)
|
||||
- Enh #34: Model generator now skips FKs pointing to non-existing tables (samdark)
|
||||
- Enh #42: Entire preview code now can be copied by pressing CTRL+C (thiagotalma, samdark)
|
||||
- Enh #54: Model generator is now able to generate reverse relations (nineinchnick)
|
||||
- Enh #56: Model generator now generates exist rules based on table foreign keys (Faryshta, samdark)
|
||||
- Enh #95: More parameters are now available in `query.php` view of model generator (demisang)
|
||||
- Enh #99: Added `enablePjax` option to wrap GridView with Pjax (Faryshta, silverfire)
|
||||
- Enh #135: Footer now sticks to the bottom of the page (zetamen)
|
||||
- Chg #38: Added compatibility with latest Typeahead version (razvanphp)
|
||||
|
||||
|
||||
2.0.4 May 10, 2015
|
||||
------------------
|
||||
|
||||
- Bug #5098: Properly detect hasOne relations (nineinchnick)
|
||||
- Bug #6667: Gii form generator rendering mistake view (pana1990)
|
||||
- Bug (CVE-2015-3397): Using `Json::htmlEncode()` for safer JSON data encoding in HTML code (samdark, Tomasz Tokarski)
|
||||
- Enh #2109: Added ability to generate ActiveQuery class for model (klimov-paul)
|
||||
- Enh #7830: Added ability to detect relations between multiple schemas (nineinchnick)
|
||||
|
||||
|
||||
2.0.3 March 01, 2015
|
||||
--------------------
|
||||
|
||||
- Chg #7328: Changed the way CRUD generator translates "Create X". Now it's a whole string because of translation difficulties (samdark)
|
||||
|
||||
|
||||
2.0.2 January 11, 2015
|
||||
----------------------
|
||||
|
||||
- Bug #6463: The Gii controller generator generates incorrect controller namespace (pana1990)
|
||||
- Enh #3665: Better default behavior for ModelSearch generated by the crud generator (qiangxue, mdmunir)
|
||||
|
||||
|
||||
2.0.1 December 07, 2014
|
||||
-----------------------
|
||||
|
||||
- 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 #6367: Added `yii\gii\generators\crud\Generator` to support customizing view path for the generated CRUD controller (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)
|
||||
|
||||
|
||||
2.0.0 October 12, 2014
|
||||
----------------------
|
||||
|
||||
- Bug #5408: Gii console command incorrectly reports errors when there is actually no error (qiangxue)
|
||||
- Bug: Fixed table name regression caused by changed introduced in #4971 (samdark)
|
||||
|
||||
|
||||
2.0.0-rc September 27, 2014
|
||||
---------------------------
|
||||
|
||||
- Bug #1263: Fixed the issue that Gii and Debug modules might be affected by incompatible asset manager configuration (qiangxue)
|
||||
- Bug #2314: Gii model generator does not generate correct relation type in some special case (qiangxue)
|
||||
- Bug #3265: Fixed incorrect controller class name validation (suralc)
|
||||
- Bug #3693: Fixed broken Gii preview when a file is unchanged (cebe)
|
||||
- Bug #4410: Fixed Gii to preserve database column order in generated _form.php (kmindi)
|
||||
- Bug #4971: Fixed hardcoded table names in `viaTable` expression in model generator (stepanselyuk)
|
||||
- Enh #2018: Search model is not required anymore in CRUD generator (johonunu)
|
||||
- Enh #3088: The gii module will manage their own URL rules now (qiangxue)
|
||||
- Enh #3222: Added `useTablePrefix` option to the model generator for Gii (horizons2)
|
||||
- Enh #3811: Now Gii model generator makes autocomplete for model class field (mitalcoi)
|
||||
- New #1280: Gii can now be run from command line (schmunk42, cebe, qiangxue)
|
||||
|
||||
|
||||
2.0.0-beta April 13, 2014
|
||||
-------------------------
|
||||
|
||||
- Bug #1405: fixed disambiguation of relation names generated by gii (qiangxue)
|
||||
- Bug #1904: Fixed autocomplete to work with underscore inputs "_" (tonydspaniard)
|
||||
- Bug #2298: Fixed the bug that Gii controller generator did not allow digit in the controller ID (qiangxue)
|
||||
- Bug #2712: Fixed missing id in code file preview url (klevron)
|
||||
- Bug: fixed controller in crud template to avoid returning query in findModel() (cebe)
|
||||
- Enh #1624: generate rules for unique indexes (lucianobaraglia)
|
||||
- Enh #1818: Do not display checkbox column if all rows are empty (johonunu)
|
||||
- Enh #1897: diff markup is now copy paste friendly (samdark)
|
||||
- Enh #2327: better visual representation of changed files, added header and refresh button to diff modal (thiagotalma)
|
||||
- Enh #2491: Added support for using the same base class name of search model and data model in Gii (qiangxue)
|
||||
- Enh #2595: Browse through all generated files using right and left arrows (thiagotalma)
|
||||
- Enh #2633: Keyboard shortcuts to browse through files (thiagotalma)
|
||||
- Enh #2822: possibility to generate I18N messages (lucianobaraglia)
|
||||
- Enh #2843: Option to filter files according to the action. (thiagotalma)
|
||||
|
||||
2.0.0-alpha, December 1, 2013
|
||||
-----------------------------
|
||||
|
||||
- Initial release.
|
||||
29
vendor/yiisoft/yii2-gii/LICENSE.md
vendored
Normal file
29
vendor/yiisoft/yii2-gii/LICENSE.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Yii Software LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
45
vendor/yiisoft/yii2-gii/Makefile
vendored
Normal file
45
vendor/yiisoft/yii2-gii/Makefile
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
# default versions to test against
|
||||
# these can be overridden by setting the environment variables in the shell
|
||||
PHP_VERSION=php-5.6.8
|
||||
YII_VERSION=dev-master
|
||||
PGSQL_VERSION=latest
|
||||
|
||||
# ensure all the configuration variables above are in environment of the shell commands below
|
||||
export
|
||||
|
||||
help:
|
||||
@echo "make test - run phpunit tests using a docker environment"
|
||||
@echo "make inspect - connect to the postrges docker container using psql"
|
||||
@echo "make clean - stop docker and remove container"
|
||||
|
||||
test: docker-php docker-pgsql adjust-config
|
||||
composer require "yiisoft/yii2:${YII_VERSION}" --prefer-dist
|
||||
composer install --prefer-dist
|
||||
docker run --rm=true -v $(shell pwd):/var/lib/postgresql/data --link $(shell cat tests/dockerids/pgsql):postgres postgres:${PGSQL_VERSION} sh -c 'psql -h postgres -U postgres -c "CREATE DATABASE yiitest;"; psql -h postgres -U postgres yiitest < /var/lib/postgresql/data/tests/data/pgsql.sql'
|
||||
docker run --rm=true -v $(shell pwd):/opt/test --link $(shell cat tests/dockerids/pgsql):postgres yiitest/php:${PHP_VERSION} phpunit --verbose --color
|
||||
|
||||
adjust-config:
|
||||
echo "<?php \$$config['databases']['pgsql']['dsn'] = 'pgsql:host=postgres;port=5432;dbname=yiitest'; \$$config['databases']['pgsql']['fixture'] = null;" > tests/data/config.local.php
|
||||
|
||||
docker-pgsql: dockerfiles
|
||||
docker pull postgres:${PGSQL_VERSION}
|
||||
docker run -d -P postgres:${PGSQL_VERSION} > tests/dockerids/pgsql
|
||||
sleep 2
|
||||
|
||||
docker-php: dockerfiles
|
||||
cd tests/docker/php && sh build.sh
|
||||
|
||||
dockerfiles:
|
||||
test -d tests/docker || git clone https://github.com/cebe/jenkins-test-docker tests/docker
|
||||
cd tests/docker && git checkout -- . && git pull
|
||||
mkdir -p tests/dockerids
|
||||
|
||||
inspect:
|
||||
docker run -it --rm=true --link $(shell cat tests/dockerids/pgsql):postgres postgres:${PGSQL_VERSION} sh -c 'exec psql -h postgres -U postgres yiitest'
|
||||
|
||||
clean:
|
||||
docker stop $(shell cat tests/dockerids/pgsql)
|
||||
docker rm $(shell cat tests/dockerids/pgsql)
|
||||
rm tests/dockerids/pgsql
|
||||
|
||||
86
vendor/yiisoft/yii2-gii/README.md
vendored
Normal file
86
vendor/yiisoft/yii2-gii/README.md
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
<p align="center">
|
||||
<a href="https://github.com/yiisoft" target="_blank">
|
||||
<img src="https://avatars0.githubusercontent.com/u/993323" height="100px">
|
||||
</a>
|
||||
<h1 align="center">Gii Extension for Yii 2</h1>
|
||||
<br>
|
||||
</p>
|
||||
|
||||
This extension provides a Web-based code generator, called Gii, for [Yii framework 2.0](http://www.yiiframework.com) applications.
|
||||
You can use Gii to quickly generate models, forms, modules, CRUD, etc.
|
||||
|
||||
For license information check the [LICENSE](LICENSE.md)-file.
|
||||
|
||||
Documentation is at [docs/guide/README.md](docs/guide/README.md).
|
||||
|
||||
[](https://packagist.org/packages/yiisoft/yii2-gii)
|
||||
[](https://packagist.org/packages/yiisoft/yii2-gii)
|
||||
[](https://travis-ci.org/yiisoft/yii2-gii)
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
The preferred way to install this extension is through [composer](http://getcomposer.org/download/).
|
||||
|
||||
Either run
|
||||
|
||||
```
|
||||
php composer.phar require --dev --prefer-dist yiisoft/yii2-gii
|
||||
```
|
||||
|
||||
or add
|
||||
|
||||
```
|
||||
"yiisoft/yii2-gii": "~2.0.0"
|
||||
```
|
||||
|
||||
to the require-dev section of your `composer.json` file.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Once the extension is installed, simply modify your application configuration as follows:
|
||||
|
||||
```php
|
||||
return [
|
||||
'bootstrap' => ['gii'],
|
||||
'modules' => [
|
||||
'gii' => [
|
||||
'class' => 'yii\gii\Module',
|
||||
],
|
||||
// ...
|
||||
],
|
||||
// ...
|
||||
];
|
||||
```
|
||||
|
||||
You can then access Gii through the following URL:
|
||||
|
||||
```
|
||||
http://localhost/path/to/index.php?r=gii
|
||||
```
|
||||
|
||||
or if you have enabled pretty URLs, you may use the following URL:
|
||||
|
||||
```
|
||||
http://localhost/path/to/index.php/gii
|
||||
```
|
||||
|
||||
Using the same configuration for your console application, you will also be able to access Gii via
|
||||
command line as follows,
|
||||
|
||||
```
|
||||
# change path to your application's base path
|
||||
cd path/to/AppBasePath
|
||||
|
||||
# show help information about Gii
|
||||
yii help gii
|
||||
|
||||
# show help information about the model generator in Gii
|
||||
yii help gii/model
|
||||
|
||||
# generate City model from city table
|
||||
yii gii/model --tableName=city --modelClass=City
|
||||
```
|
||||
47
vendor/yiisoft/yii2-gii/composer.json
vendored
Normal file
47
vendor/yiisoft/yii2-gii/composer.json
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "yiisoft/yii2-gii",
|
||||
"description": "The Gii extension for the Yii framework",
|
||||
"keywords": ["yii2", "gii", "code generator"],
|
||||
"type": "yii2-extension",
|
||||
"license": "BSD-3-Clause",
|
||||
"support": {
|
||||
"issues": "https://github.com/yiisoft/yii2-gii/issues",
|
||||
"forum": "http://www.yiiframework.com/forum/",
|
||||
"wiki": "http://www.yiiframework.com/wiki/",
|
||||
"irc": "irc://irc.freenode.net/yii",
|
||||
"source": "https://github.com/yiisoft/yii2-gii"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Qiang Xue",
|
||||
"email": "qiang.xue@gmail.com"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "dev",
|
||||
"require": {
|
||||
"yiisoft/yii2": "~2.0.14",
|
||||
"yiisoft/yii2-bootstrap": "~2.0.0",
|
||||
"phpspec/php-diff": ">=1.0.2",
|
||||
"bower-asset/typeahead.js": "0.10.* | ~0.11.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"yii\\gii\\": "src"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
},
|
||||
"asset-installer-paths": {
|
||||
"npm-asset-library": "vendor/npm",
|
||||
"bower-asset-library": "vendor/bower"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "https://asset-packagist.org"
|
||||
}
|
||||
]
|
||||
}
|
||||
197
vendor/yiisoft/yii2-gii/src/CodeFile.php
vendored
Normal file
197
vendor/yiisoft/yii2-gii/src/CodeFile.php
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii;
|
||||
|
||||
use Yii;
|
||||
use yii\base\BaseObject;
|
||||
use yii\gii\components\DiffRendererHtmlInline;
|
||||
use yii\helpers\Html;
|
||||
|
||||
/**
|
||||
* CodeFile represents a code file to be generated.
|
||||
*
|
||||
* @property string $relativePath The code file path relative to the application base path. This property is
|
||||
* read-only.
|
||||
* @property string $type The code file extension (e.g. php, txt). This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class CodeFile extends BaseObject
|
||||
{
|
||||
/**
|
||||
* The code file is new.
|
||||
*/
|
||||
const OP_CREATE = 'create';
|
||||
/**
|
||||
* The code file already exists, and the new one may need to overwrite it.
|
||||
*/
|
||||
const OP_OVERWRITE = 'overwrite';
|
||||
/**
|
||||
* The new code file and the existing one are identical.
|
||||
*/
|
||||
const OP_SKIP = 'skip';
|
||||
|
||||
/**
|
||||
* @var string an ID that uniquely identifies this code file.
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
* @var string the file path that the new code should be saved to.
|
||||
*/
|
||||
public $path;
|
||||
/**
|
||||
* @var string the newly generated code content
|
||||
*/
|
||||
public $content;
|
||||
/**
|
||||
* @var string the operation to be performed. This can be [[OP_CREATE]], [[OP_OVERWRITE]] or [[OP_SKIP]].
|
||||
*/
|
||||
public $operation;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param string $path the file path that the new code should be saved to.
|
||||
* @param string $content the newly generated code content.
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties
|
||||
*/
|
||||
public function __construct($path, $content, $config = [])
|
||||
{
|
||||
parent::__construct($config);
|
||||
|
||||
$this->path = strtr($path, '/\\', DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR);
|
||||
$this->content = $content;
|
||||
$this->id = md5($this->path);
|
||||
if (is_file($path)) {
|
||||
$this->operation = file_get_contents($path) === $content ? self::OP_SKIP : self::OP_OVERWRITE;
|
||||
} else {
|
||||
$this->operation = self::OP_CREATE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the code into the file specified by [[path]].
|
||||
* @return string|bool the error occurred while saving the code file, or true if no error.
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$module = Yii::$app->controller->module;
|
||||
if ($this->operation === self::OP_CREATE) {
|
||||
$dir = dirname($this->path);
|
||||
if (!is_dir($dir)) {
|
||||
$mask = @umask(0);
|
||||
$result = @mkdir($dir, $module->newDirMode, true);
|
||||
@umask($mask);
|
||||
if (!$result) {
|
||||
return "Unable to create the directory '$dir'.";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (@file_put_contents($this->path, $this->content) === false) {
|
||||
return "Unable to write the file '{$this->path}'.";
|
||||
} else {
|
||||
$mask = @umask(0);
|
||||
@chmod($this->path, $module->newFileMode);
|
||||
@umask($mask);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the code file path relative to the application base path.
|
||||
*/
|
||||
public function getRelativePath()
|
||||
{
|
||||
if (strpos($this->path, Yii::$app->basePath) === 0) {
|
||||
return substr($this->path, strlen(Yii::$app->basePath) + 1);
|
||||
} else {
|
||||
return $this->path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the code file extension (e.g. php, txt)
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
if (($pos = strrpos($this->path, '.')) !== false) {
|
||||
return substr($this->path, $pos + 1);
|
||||
} else {
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns preview or false if it cannot be rendered
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function preview()
|
||||
{
|
||||
if (($pos = strrpos($this->path, '.')) !== false) {
|
||||
$type = substr($this->path, $pos + 1);
|
||||
} else {
|
||||
$type = 'unknown';
|
||||
}
|
||||
|
||||
if ($type === 'php') {
|
||||
return highlight_string($this->content, true);
|
||||
} elseif (!in_array($type, ['jpg', 'gif', 'png', 'exe'])) {
|
||||
return nl2br(Html::encode($this->content));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns diff or false if it cannot be calculated
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function diff()
|
||||
{
|
||||
$type = strtolower($this->getType());
|
||||
if (in_array($type, ['jpg', 'gif', 'png', 'exe'])) {
|
||||
return false;
|
||||
} elseif ($this->operation === self::OP_OVERWRITE) {
|
||||
return $this->renderDiff(file($this->path), $this->content);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders diff between two sets of lines
|
||||
*
|
||||
* @param mixed $lines1
|
||||
* @param mixed $lines2
|
||||
* @return string
|
||||
*/
|
||||
private function renderDiff($lines1, $lines2)
|
||||
{
|
||||
if (!is_array($lines1)) {
|
||||
$lines1 = explode("\n", $lines1);
|
||||
}
|
||||
if (!is_array($lines2)) {
|
||||
$lines2 = explode("\n", $lines2);
|
||||
}
|
||||
foreach ($lines1 as $i => $line) {
|
||||
$lines1[$i] = rtrim($line, "\r\n");
|
||||
}
|
||||
foreach ($lines2 as $i => $line) {
|
||||
$lines2[$i] = rtrim($line, "\r\n");
|
||||
}
|
||||
|
||||
$renderer = new DiffRendererHtmlInline();
|
||||
$diff = new \Diff($lines1, $lines2);
|
||||
|
||||
return $diff->render($renderer);
|
||||
}
|
||||
}
|
||||
521
vendor/yiisoft/yii2-gii/src/Generator.php
vendored
Normal file
521
vendor/yiisoft/yii2-gii/src/Generator.php
vendored
Normal file
@@ -0,0 +1,521 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii;
|
||||
|
||||
use Yii;
|
||||
use ReflectionClass;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\base\Model;
|
||||
use yii\helpers\VarDumper;
|
||||
use yii\web\View;
|
||||
|
||||
/**
|
||||
* This is the base class for all generator classes.
|
||||
*
|
||||
* A generator instance is responsible for taking user inputs, validating them,
|
||||
* and using them to generate the corresponding code based on a set of code template files.
|
||||
*
|
||||
* A generator class typically needs to implement the following methods:
|
||||
*
|
||||
* - [[getName()]]: returns the name of the generator
|
||||
* - [[getDescription()]]: returns the detailed description of the generator
|
||||
* - [[generate()]]: generates the code based on the current user input and the specified code template files.
|
||||
* This is the place where main code generation code resides.
|
||||
*
|
||||
* @property string $description The detailed description of the generator. This property is read-only.
|
||||
* @property string $stickyDataFile The file path that stores the sticky attribute values. This property is
|
||||
* read-only.
|
||||
* @property string $templatePath The root path of the template files that are currently being used. This
|
||||
* property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class Generator extends Model
|
||||
{
|
||||
/**
|
||||
* @var array a list of available code templates. The array keys are the template names,
|
||||
* and the array values are the corresponding template paths or path aliases.
|
||||
*/
|
||||
public $templates = [];
|
||||
/**
|
||||
* @var string the name of the code template that the user has selected.
|
||||
* The value of this property is internally managed by this class.
|
||||
*/
|
||||
public $template = 'default';
|
||||
/**
|
||||
* @var bool whether the strings will be generated using `Yii::t()` or normal strings.
|
||||
*/
|
||||
public $enableI18N = false;
|
||||
/**
|
||||
* @var string the message category used by `Yii::t()` when `$enableI18N` is `true`.
|
||||
* Defaults to `app`.
|
||||
*/
|
||||
public $messageCategory = 'app';
|
||||
|
||||
|
||||
/**
|
||||
* @return string name of the code generator
|
||||
*/
|
||||
abstract public function getName();
|
||||
/**
|
||||
* Generates the code based on the current user input and the specified code template files.
|
||||
* This is the main method that child classes should implement.
|
||||
* Please refer to [[\yii\gii\generators\controller\Generator::generate()]] as an example
|
||||
* on how to implement this method.
|
||||
* @return CodeFile[] a list of code files to be created.
|
||||
*/
|
||||
abstract public function generate();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if (!isset($this->templates['default'])) {
|
||||
$this->templates['default'] = $this->defaultTemplate();
|
||||
}
|
||||
foreach ($this->templates as $i => $template) {
|
||||
$this->templates[$i] = Yii::getAlias($template);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributeLabels()
|
||||
{
|
||||
return [
|
||||
'enableI18N' => 'Enable I18N',
|
||||
'messageCategory' => 'Message Category',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of code template files that are required.
|
||||
* Derived classes usually should override this method if they require the existence of
|
||||
* certain template files.
|
||||
* @return array list of code template files that are required. They should be file paths
|
||||
* relative to [[templatePath]].
|
||||
*/
|
||||
public function requiredTemplates()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of sticky attributes.
|
||||
* A sticky attribute will remember its value and will initialize the attribute with this value
|
||||
* when the generator is restarted.
|
||||
* @return array list of sticky attributes
|
||||
*/
|
||||
public function stickyAttributes()
|
||||
{
|
||||
return ['template', 'enableI18N', 'messageCategory'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of hint messages.
|
||||
* The array keys are the attribute names, and the array values are the corresponding hint messages.
|
||||
* Hint messages will be displayed to end users when they are filling the form for the generator.
|
||||
* @return array the list of hint messages
|
||||
*/
|
||||
public function hints()
|
||||
{
|
||||
return [
|
||||
'enableI18N' => 'This indicates whether the generator should generate strings using <code>Yii::t()</code> method.
|
||||
Set this to <code>true</code> if you are planning to make your application translatable.',
|
||||
'messageCategory' => 'This is the category used by <code>Yii::t()</code> in case you enable I18N.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of auto complete values.
|
||||
* The array keys are the attribute names, and the array values are the corresponding auto complete values.
|
||||
* Auto complete values can also be callable typed in order one want to make postponed data generation.
|
||||
* @return array the list of auto complete values
|
||||
*/
|
||||
public function autoCompleteData()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message to be displayed when the newly generated code is saved successfully.
|
||||
* Child classes may override this method to customize the message.
|
||||
* @return string the message to be displayed when the newly generated code is saved successfully.
|
||||
*/
|
||||
public function successMessage()
|
||||
{
|
||||
return 'The code has been generated successfully.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view file for the input form of the generator.
|
||||
* The default implementation will return the "form.php" file under the directory
|
||||
* that contains the generator class file.
|
||||
* @return string the view file for the input form of the generator.
|
||||
*/
|
||||
public function formView()
|
||||
{
|
||||
$class = new ReflectionClass($this);
|
||||
|
||||
return dirname($class->getFileName()) . '/form.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root path to the default code template files.
|
||||
* The default implementation will return the "templates" subdirectory of the
|
||||
* directory containing the generator class file.
|
||||
* @return string the root path to the default code template files.
|
||||
*/
|
||||
public function defaultTemplate()
|
||||
{
|
||||
$class = new ReflectionClass($this);
|
||||
|
||||
return dirname($class->getFileName()) . '/default';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the detailed description of the generator.
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Child classes should override this method like the following so that the parent
|
||||
* rules are included:
|
||||
*
|
||||
* ~~~
|
||||
* return array_merge(parent::rules(), [
|
||||
* ...rules for the child class...
|
||||
* ]);
|
||||
* ~~~
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
[['template'], 'required', 'message' => 'A code template must be selected.'],
|
||||
[['template'], 'validateTemplate'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads sticky attributes from an internal file and populates them into the generator.
|
||||
* @internal
|
||||
*/
|
||||
public function loadStickyAttributes()
|
||||
{
|
||||
$stickyAttributes = $this->stickyAttributes();
|
||||
$path = $this->getStickyDataFile();
|
||||
if (is_file($path)) {
|
||||
$result = json_decode(file_get_contents($path), true);
|
||||
if (is_array($result)) {
|
||||
foreach ($stickyAttributes as $name) {
|
||||
if (isset($result[$name])) {
|
||||
$this->$name = $result[$name];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves sticky attributes into an internal file.
|
||||
* @internal
|
||||
*/
|
||||
public function saveStickyAttributes()
|
||||
{
|
||||
$stickyAttributes = $this->stickyAttributes();
|
||||
$stickyAttributes[] = 'template';
|
||||
$values = [];
|
||||
foreach ($stickyAttributes as $name) {
|
||||
$values[$name] = $this->$name;
|
||||
}
|
||||
$path = $this->getStickyDataFile();
|
||||
@mkdir(dirname($path), 0755, true);
|
||||
file_put_contents($path, json_encode($values));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the file path that stores the sticky attribute values.
|
||||
* @internal
|
||||
*/
|
||||
public function getStickyDataFile()
|
||||
{
|
||||
return Yii::$app->getRuntimePath() . '/gii-' . Yii::getVersion() . '/' . str_replace('\\', '-', get_class($this)) . '.json';
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the generated code into files.
|
||||
* @param CodeFile[] $files the code files to be saved
|
||||
* @param array $answers
|
||||
* @param string $results this parameter receives a value from this method indicating the log messages
|
||||
* generated while saving the code files.
|
||||
* @return bool whether files are successfully saved without any error.
|
||||
*/
|
||||
public function save($files, $answers, &$results)
|
||||
{
|
||||
$lines = ['Generating code using template "' . $this->getTemplatePath() . '"...'];
|
||||
$hasError = false;
|
||||
foreach ($files as $file) {
|
||||
$relativePath = $file->getRelativePath();
|
||||
if (isset($answers[$file->id]) && !empty($answers[$file->id]) && $file->operation !== CodeFile::OP_SKIP) {
|
||||
$error = $file->save();
|
||||
if (is_string($error)) {
|
||||
$hasError = true;
|
||||
$lines[] = "generating $relativePath\n<span class=\"error\">$error</span>";
|
||||
} else {
|
||||
$lines[] = $file->operation === CodeFile::OP_CREATE ? " generated $relativePath" : " overwrote $relativePath";
|
||||
}
|
||||
} else {
|
||||
$lines[] = " skipped $relativePath";
|
||||
}
|
||||
}
|
||||
$lines[] = "done!\n";
|
||||
$results = implode("\n", $lines);
|
||||
|
||||
return !$hasError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the root path of the template files that are currently being used.
|
||||
* @throws InvalidConfigException if [[template]] is invalid
|
||||
*/
|
||||
public function getTemplatePath()
|
||||
{
|
||||
if (isset($this->templates[$this->template])) {
|
||||
return $this->templates[$this->template];
|
||||
} else {
|
||||
throw new InvalidConfigException("Unknown template: {$this->template}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates code using the specified code template and parameters.
|
||||
* Note that the code template will be used as a PHP file.
|
||||
* @param string $template the code template file. This must be specified as a file path
|
||||
* relative to [[templatePath]].
|
||||
* @param array $params list of parameters to be passed to the template file.
|
||||
* @return string the generated code
|
||||
*/
|
||||
public function render($template, $params = [])
|
||||
{
|
||||
$view = new View();
|
||||
$params['generator'] = $this;
|
||||
|
||||
return $view->renderFile($this->getTemplatePath() . '/' . $template, $params, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the template selection.
|
||||
* This method validates whether the user selects an existing template
|
||||
* and the template contains all required template files as specified in [[requiredTemplates()]].
|
||||
*/
|
||||
public function validateTemplate()
|
||||
{
|
||||
$templates = $this->templates;
|
||||
if (!isset($templates[$this->template])) {
|
||||
$this->addError('template', 'Invalid template selection.');
|
||||
} else {
|
||||
$templatePath = $this->templates[$this->template];
|
||||
foreach ($this->requiredTemplates() as $template) {
|
||||
if (!is_file(Yii::getAlias($templatePath . '/' . $template))) {
|
||||
$this->addError('template', "Unable to find the required code template file '$template'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An inline validator that checks if the attribute value refers to an existing class name.
|
||||
* If the `extends` option is specified, it will also check if the class is a child class
|
||||
* of the class represented by the `extends` option.
|
||||
* @param string $attribute the attribute being validated
|
||||
* @param array $params the validation options
|
||||
*/
|
||||
public function validateClass($attribute, $params)
|
||||
{
|
||||
$class = $this->$attribute;
|
||||
try {
|
||||
if (class_exists($class)) {
|
||||
if (isset($params['extends'])) {
|
||||
if (ltrim($class, '\\') !== ltrim($params['extends'], '\\') && !is_subclass_of($class, $params['extends'])) {
|
||||
$this->addError($attribute, "'$class' must extend from {$params['extends']} or its child class.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->addError($attribute, "Class '$class' does not exist or has syntax error.");
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->addError($attribute, "Class '$class' does not exist or has syntax error.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An inline validator that checks if the attribute value refers to a valid namespaced class name.
|
||||
* The validator will check if the directory containing the new class file exist or not.
|
||||
* @param string $attribute the attribute being validated
|
||||
* @param array $params the validation options
|
||||
*/
|
||||
public function validateNewClass($attribute, $params)
|
||||
{
|
||||
$class = ltrim($this->$attribute, '\\');
|
||||
if (($pos = strrpos($class, '\\')) === false) {
|
||||
$this->addError($attribute, "The class name must contain fully qualified namespace name.");
|
||||
} else {
|
||||
$ns = substr($class, 0, $pos);
|
||||
$path = Yii::getAlias('@' . str_replace('\\', '/', $ns), false);
|
||||
if ($path === false) {
|
||||
$this->addError($attribute, "The class namespace is invalid: $ns");
|
||||
} elseif (!is_dir($path)) {
|
||||
$this->addError($attribute, "Please make sure the directory containing this class exists: $path");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if message category is not empty when I18N is enabled.
|
||||
*/
|
||||
public function validateMessageCategory()
|
||||
{
|
||||
if ($this->enableI18N && empty($this->messageCategory)) {
|
||||
$this->addError('messageCategory', "Message Category cannot be blank.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value the attribute to be validated
|
||||
* @return bool whether the value is a reserved PHP keyword.
|
||||
*/
|
||||
public function isReservedKeyword($value)
|
||||
{
|
||||
static $keywords = [
|
||||
'__class__',
|
||||
'__dir__',
|
||||
'__file__',
|
||||
'__function__',
|
||||
'__line__',
|
||||
'__method__',
|
||||
'__namespace__',
|
||||
'__trait__',
|
||||
'abstract',
|
||||
'and',
|
||||
'array',
|
||||
'as',
|
||||
'break',
|
||||
'case',
|
||||
'catch',
|
||||
'callable',
|
||||
'cfunction',
|
||||
'class',
|
||||
'clone',
|
||||
'const',
|
||||
'continue',
|
||||
'declare',
|
||||
'default',
|
||||
'die',
|
||||
'do',
|
||||
'echo',
|
||||
'else',
|
||||
'elseif',
|
||||
'empty',
|
||||
'enddeclare',
|
||||
'endfor',
|
||||
'endforeach',
|
||||
'endif',
|
||||
'endswitch',
|
||||
'endwhile',
|
||||
'eval',
|
||||
'exception',
|
||||
'exit',
|
||||
'extends',
|
||||
'final',
|
||||
'finally',
|
||||
'for',
|
||||
'foreach',
|
||||
'function',
|
||||
'global',
|
||||
'goto',
|
||||
'if',
|
||||
'implements',
|
||||
'include',
|
||||
'include_once',
|
||||
'instanceof',
|
||||
'insteadof',
|
||||
'interface',
|
||||
'isset',
|
||||
'list',
|
||||
'namespace',
|
||||
'new',
|
||||
'old_function',
|
||||
'or',
|
||||
'parent',
|
||||
'php_user_filter',
|
||||
'print',
|
||||
'private',
|
||||
'protected',
|
||||
'public',
|
||||
'require',
|
||||
'require_once',
|
||||
'return',
|
||||
'static',
|
||||
'switch',
|
||||
'this',
|
||||
'throw',
|
||||
'trait',
|
||||
'try',
|
||||
'unset',
|
||||
'use',
|
||||
'var',
|
||||
'while',
|
||||
'xor',
|
||||
];
|
||||
|
||||
return in_array(strtolower($value), $keywords, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string depending on enableI18N property
|
||||
*
|
||||
* @param string $string the text be generated
|
||||
* @param array $placeholders the placeholders to use by `Yii::t()`
|
||||
* @return string
|
||||
*/
|
||||
public function generateString($string = '', $placeholders = [])
|
||||
{
|
||||
$string = addslashes($string);
|
||||
if ($this->enableI18N) {
|
||||
// If there are placeholders, use them
|
||||
if (!empty($placeholders)) {
|
||||
$ph = ', ' . VarDumper::export($placeholders);
|
||||
} else {
|
||||
$ph = '';
|
||||
}
|
||||
$str = "Yii::t('" . $this->messageCategory . "', '" . $string . "'" . $ph . ")";
|
||||
} else {
|
||||
// No I18N, replace placeholders by real words, if any
|
||||
if (!empty($placeholders)) {
|
||||
$phKeys = array_map(function($word) {
|
||||
return '{' . $word . '}';
|
||||
}, array_keys($placeholders));
|
||||
$phValues = array_values($placeholders);
|
||||
$str = "'" . str_replace($phKeys, $phValues, $string) . "'";
|
||||
} else {
|
||||
// No placeholders, just the given string
|
||||
$str = "'" . $string . "'";
|
||||
}
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
33
vendor/yiisoft/yii2-gii/src/GiiAsset.php
vendored
Normal file
33
vendor/yiisoft/yii2-gii/src/GiiAsset.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii;
|
||||
|
||||
use yii\web\AssetBundle;
|
||||
|
||||
/**
|
||||
* This declares the asset files required by Gii.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class GiiAsset extends AssetBundle
|
||||
{
|
||||
public $sourcePath = '@yii/gii/assets';
|
||||
public $css = [
|
||||
'main.css',
|
||||
];
|
||||
public $js = [
|
||||
'gii.js',
|
||||
];
|
||||
public $depends = [
|
||||
'yii\web\YiiAsset',
|
||||
'yii\bootstrap\BootstrapAsset',
|
||||
'yii\bootstrap\BootstrapPluginAsset',
|
||||
'yii\gii\TypeAheadAsset',
|
||||
];
|
||||
}
|
||||
184
vendor/yiisoft/yii2-gii/src/Module.php
vendored
Normal file
184
vendor/yiisoft/yii2-gii/src/Module.php
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii;
|
||||
|
||||
use Yii;
|
||||
use yii\base\BootstrapInterface;
|
||||
use yii\helpers\Json;
|
||||
use yii\web\ForbiddenHttpException;
|
||||
|
||||
/**
|
||||
* This is the main module class for the Gii module.
|
||||
*
|
||||
* To use Gii, include it as a module in the application configuration like the following:
|
||||
*
|
||||
* ~~~
|
||||
* return [
|
||||
* 'bootstrap' => ['gii'],
|
||||
* 'modules' => [
|
||||
* 'gii' => ['class' => 'yii\gii\Module'],
|
||||
* ],
|
||||
* ]
|
||||
* ~~~
|
||||
*
|
||||
* Because Gii generates new code files on the server, you should only use it on your own
|
||||
* development machine. To prevent other people from using this module, by default, Gii
|
||||
* can only be accessed by localhost. You may configure its [[allowedIPs]] property if
|
||||
* you want to make it accessible on other machines.
|
||||
*
|
||||
* With the above configuration, you will be able to access GiiModule in your browser using
|
||||
* the URL `http://localhost/path/to/index.php?r=gii`
|
||||
*
|
||||
* If your application enables [[\yii\web\UrlManager::enablePrettyUrl|pretty URLs]],
|
||||
* you can then access Gii via URL: `http://localhost/path/to/index.php/gii`
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Module extends \yii\base\Module implements BootstrapInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $controllerNamespace = 'yii\gii\controllers';
|
||||
/**
|
||||
* @var array the list of IPs that are allowed to access this module.
|
||||
* Each array element represents a single IP filter which can be either an IP address
|
||||
* or an address with wildcard (e.g. 192.168.0.*) to represent a network segment.
|
||||
* The default value is `['127.0.0.1', '::1']`, which means the module can only be accessed
|
||||
* by localhost.
|
||||
*/
|
||||
public $allowedIPs = ['127.0.0.1', '::1'];
|
||||
/**
|
||||
* @var array|Generator[] a list of generator configurations or instances. The array keys
|
||||
* are the generator IDs (e.g. "crud"), and the array elements are the corresponding generator
|
||||
* configurations or the instances.
|
||||
*
|
||||
* After the module is initialized, this property will become an array of generator instances
|
||||
* which are created based on the configurations previously taken by this property.
|
||||
*
|
||||
* Newly assigned generators will be merged with the [[coreGenerators()|core ones]], and the former
|
||||
* takes precedence in case when they have the same generator ID.
|
||||
*/
|
||||
public $generators = [];
|
||||
/**
|
||||
* @var int the permission to be set for newly generated code files.
|
||||
* This value will be used by PHP chmod function.
|
||||
* Defaults to 0666, meaning the file is read-writable by all users.
|
||||
*/
|
||||
public $newFileMode = 0666;
|
||||
/**
|
||||
* @var int the permission to be set for newly generated directories.
|
||||
* This value will be used by PHP chmod function.
|
||||
* Defaults to 0777, meaning the directory can be read, written and executed by all users.
|
||||
*/
|
||||
public $newDirMode = 0777;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function bootstrap($app)
|
||||
{
|
||||
if ($app instanceof \yii\web\Application) {
|
||||
$app->getUrlManager()->addRules([
|
||||
['class' => 'yii\web\UrlRule', 'pattern' => $this->id, 'route' => $this->id . '/default/index'],
|
||||
['class' => 'yii\web\UrlRule', 'pattern' => $this->id . '/<id:\w+>', 'route' => $this->id . '/default/view'],
|
||||
['class' => 'yii\web\UrlRule', 'pattern' => $this->id . '/<controller:[\w\-]+>/<action:[\w\-]+>', 'route' => $this->id . '/<controller>/<action>'],
|
||||
], false);
|
||||
} elseif ($app instanceof \yii\console\Application) {
|
||||
$app->controllerMap[$this->id] = [
|
||||
'class' => 'yii\gii\console\GenerateController',
|
||||
'generators' => array_merge($this->coreGenerators(), $this->generators),
|
||||
'module' => $this,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function beforeAction($action)
|
||||
{
|
||||
if (!parent::beforeAction($action)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Yii::$app instanceof \yii\web\Application && !$this->checkAccess()) {
|
||||
throw new ForbiddenHttpException('You are not allowed to access this page.');
|
||||
}
|
||||
|
||||
foreach (array_merge($this->coreGenerators(), $this->generators) as $id => $config) {
|
||||
if (is_object($config)) {
|
||||
$this->generators[$id] = $config;
|
||||
} else {
|
||||
$this->generators[$id] = Yii::createObject($config);
|
||||
}
|
||||
}
|
||||
|
||||
$this->resetGlobalSettings();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets potentially incompatible global settings done in app config.
|
||||
*/
|
||||
protected function resetGlobalSettings()
|
||||
{
|
||||
if (Yii::$app instanceof \yii\web\Application) {
|
||||
Yii::$app->assetManager->bundles = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int whether the module can be accessed by the current user
|
||||
*/
|
||||
protected function checkAccess()
|
||||
{
|
||||
$ip = Yii::$app->getRequest()->getUserIP();
|
||||
foreach ($this->allowedIPs as $filter) {
|
||||
if ($filter === '*' || $filter === $ip || (($pos = strpos($filter, '*')) !== false && !strncmp($ip, $filter, $pos))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Yii::warning('Access to Gii is denied due to IP address restriction. The requested IP is ' . $ip, __METHOD__);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of the core code generator configurations.
|
||||
* @return array the list of the core code generator configurations.
|
||||
*/
|
||||
protected function coreGenerators()
|
||||
{
|
||||
return [
|
||||
'model' => ['class' => 'yii\gii\generators\model\Generator'],
|
||||
'crud' => ['class' => 'yii\gii\generators\crud\Generator'],
|
||||
'controller' => ['class' => 'yii\gii\generators\controller\Generator'],
|
||||
'form' => ['class' => 'yii\gii\generators\form\Generator'],
|
||||
'module' => ['class' => 'yii\gii\generators\module\Generator'],
|
||||
'extension' => ['class' => 'yii\gii\generators\extension\Generator'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @since 2.0.6
|
||||
*/
|
||||
protected function defaultVersion()
|
||||
{
|
||||
$packageInfo = Json::decode(file_get_contents(dirname(__DIR__) . DIRECTORY_SEPARATOR . 'composer.json'));
|
||||
$extensionName = $packageInfo['name'];
|
||||
if (isset(Yii::$app->extensions[$extensionName])) {
|
||||
return Yii::$app->extensions[$extensionName]['version'];
|
||||
}
|
||||
return parent::defaultVersion();
|
||||
}
|
||||
}
|
||||
30
vendor/yiisoft/yii2-gii/src/TypeAheadAsset.php
vendored
Normal file
30
vendor/yiisoft/yii2-gii/src/TypeAheadAsset.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii;
|
||||
|
||||
use yii\web\AssetBundle;
|
||||
|
||||
/**
|
||||
* Declares the asset files for jQuery 'typeahead' plugin.
|
||||
*
|
||||
* @see http://twitter.github.io/typeahead.js/
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class TypeAheadAsset extends AssetBundle
|
||||
{
|
||||
public $sourcePath = '@bower/typeahead.js/dist';
|
||||
public $js = [
|
||||
'typeahead.bundle.js',
|
||||
];
|
||||
public $depends = [
|
||||
'yii\bootstrap\BootstrapAsset',
|
||||
'yii\bootstrap\BootstrapPluginAsset',
|
||||
];
|
||||
}
|
||||
302
vendor/yiisoft/yii2-gii/src/assets/gii.js
vendored
Normal file
302
vendor/yiisoft/yii2-gii/src/assets/gii.js
vendored
Normal file
@@ -0,0 +1,302 @@
|
||||
yii.gii = (function ($) {
|
||||
|
||||
var $clipboardContainer = $("#clipboard-container"),
|
||||
valueToCopy = '',
|
||||
ajaxRequest = null,
|
||||
|
||||
onKeydown = function(e) {
|
||||
var $target;
|
||||
$target = $(e.target);
|
||||
|
||||
if ($target.is("input:visible, textarea:visible")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof window.getSelection === "function" && window.getSelection().toString()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.selection != null && document.selection.createRange().text) {
|
||||
return;
|
||||
}
|
||||
|
||||
$clipboardContainer.empty().show();
|
||||
return $("<textarea id='clipboard'></textarea>").val(valueToCopy).appendTo($clipboardContainer).focus().select();
|
||||
},
|
||||
|
||||
onKeyup = function(e) {
|
||||
if ($(e.target).is("#clipboard")) {
|
||||
$("#clipboard-container").empty().hide();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
var initHintBlocks = function () {
|
||||
$('.hint-block').each(function () {
|
||||
var $hint = $(this);
|
||||
$hint.parent().find('label').addClass('help').popover({
|
||||
html: true,
|
||||
trigger: 'hover',
|
||||
placement: 'right',
|
||||
content: $hint.html()
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var initStickyInputs = function () {
|
||||
$('.sticky:not(.error)').find('input[type="text"],select,textarea').each(function () {
|
||||
var value;
|
||||
if (this.tagName === 'SELECT') {
|
||||
value = this.options[this.selectedIndex].text;
|
||||
} else if (this.tagName === 'TEXTAREA') {
|
||||
value = $(this).html();
|
||||
} else {
|
||||
value = $(this).val();
|
||||
}
|
||||
if (value === '') {
|
||||
value = '[empty]';
|
||||
}
|
||||
$(this).before('<div class="sticky-value">' + value + '</div>').hide();
|
||||
});
|
||||
$('.sticky-value').on('click', function () {
|
||||
$(this).hide();
|
||||
$(this).next().show().get(0).focus();
|
||||
});
|
||||
};
|
||||
|
||||
var fillModal = function($link, data) {
|
||||
var $modal = $('#preview-modal'),
|
||||
$modalBody = $modal.find('.modal-body');
|
||||
if (!$link.hasClass('modal-refresh')) {
|
||||
var filesSelector = 'a.' + $modal.data('action') + ':visible';
|
||||
var $files = $(filesSelector);
|
||||
var index = $files.filter('[href="' + $link.attr('href') + '"]').index(filesSelector);
|
||||
var $prev = $files.eq(index - 1);
|
||||
var $next = $files.eq((index + 1 == $files.length ? 0 : index + 1));
|
||||
$modal.data('current', $files.eq(index));
|
||||
$modal.find('.modal-previous').attr('href', $prev.attr('href')).data('title', $prev.data('title'));
|
||||
$modal.find('.modal-next').attr('href', $next.attr('href')).data('title', $next.data('title'));
|
||||
}
|
||||
$modalBody.html(data);
|
||||
valueToCopy = $("<div/>").html(data.replace(/(<(br[^>]*)>)/ig, '\n').replace(/ /ig, ' ')).text().trim() + '\n';
|
||||
$modal.find('.content').css('max-height', ($(window).height() - 200) + 'px');
|
||||
};
|
||||
|
||||
var initPreviewDiffLinks = function () {
|
||||
$('.preview-code, .diff-code, .modal-refresh, .modal-previous, .modal-next').on('click', function () {
|
||||
if (ajaxRequest !== null) {
|
||||
if ($.isFunction(ajaxRequest.abort)) {
|
||||
ajaxRequest.abort();
|
||||
}
|
||||
}
|
||||
var that = this;
|
||||
var $modal = $('#preview-modal');
|
||||
var $link = $(this);
|
||||
$modal.find('.modal-refresh').attr('href', $link.attr('href'));
|
||||
if ($link.hasClass('preview-code') || $link.hasClass('diff-code')) {
|
||||
$modal.data('action', ($link.hasClass('preview-code') ? 'preview-code' : 'diff-code'))
|
||||
}
|
||||
$modal.find('.modal-title').text($link.data('title'));
|
||||
$modal.find('.modal-body').html('Loading ...');
|
||||
$modal.modal('show');
|
||||
var checkbox = $('a.' + $modal.data('action') + '[href="' + $link.attr('href') + '"]').closest('tr').find('input').get(0);
|
||||
var checked = false;
|
||||
if (checkbox) {
|
||||
checked = checkbox.checked;
|
||||
$modal.find('.modal-checkbox').removeClass('disabled');
|
||||
} else {
|
||||
$modal.find('.modal-checkbox').addClass('disabled');
|
||||
}
|
||||
$modal.find('.modal-checkbox span').toggleClass('glyphicon-check', checked).toggleClass('glyphicon-unchecked', !checked);
|
||||
|
||||
ajaxRequest = $.ajax({
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
url: $link.prop('href'),
|
||||
data: $('.default-view form').serializeArray(),
|
||||
success: function (data) {
|
||||
fillModal($(that), data);
|
||||
},
|
||||
error: function (XMLHttpRequest, textStatus, errorThrown) {
|
||||
$modal.find('.modal-body').html('<div class="error">' + XMLHttpRequest.responseText + '</div>');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#preview-modal').on('keydown', function (e) {
|
||||
if (e.keyCode === 37) {
|
||||
$('.modal-previous').trigger('click');
|
||||
} else if (e.keyCode === 39) {
|
||||
$('.modal-next').trigger('click');
|
||||
} else if (e.keyCode === 82) {
|
||||
$('.modal-refresh').trigger('click');
|
||||
} else if (e.keyCode === 32) {
|
||||
$('.modal-checkbox').trigger('click');
|
||||
}
|
||||
});
|
||||
|
||||
$('.modal-checkbox').on('click', checkFileToggle);
|
||||
};
|
||||
|
||||
var checkFileToggle = function () {
|
||||
var $modal = $('#preview-modal');
|
||||
var $checkbox = $modal.data('current').closest('tr').find('input');
|
||||
var checked = !$checkbox.prop('checked');
|
||||
$checkbox.trigger('click');
|
||||
$modal.find('.modal-checkbox span').toggleClass('glyphicon-check', checked).toggleClass('glyphicon-unchecked', !checked);
|
||||
return false;
|
||||
};
|
||||
|
||||
var checkAllToggle = function () {
|
||||
$('#check-all').prop('checked', !$('.default-view-files table .check input:enabled:not(:checked)').length);
|
||||
};
|
||||
|
||||
var initConfirmationCheckboxes = function () {
|
||||
var $checkAll = $('#check-all');
|
||||
$checkAll.click(function () {
|
||||
$('.default-view-files table .check input:enabled').prop('checked', this.checked);
|
||||
});
|
||||
$('.default-view-files table .check input').click(function () {
|
||||
checkAllToggle();
|
||||
});
|
||||
checkAllToggle();
|
||||
};
|
||||
|
||||
var initToggleActions = function () {
|
||||
$('#action-toggle').find(':input').change(function () {
|
||||
$(this).parent('label').toggleClass('active', this.checked);
|
||||
var $rows = $('.' + this.value, '.default-view-files table').toggleClass('action-hidden', !this.checked);
|
||||
if (this.checked) {
|
||||
$rows.not('.filter-hidden').show();
|
||||
} else {
|
||||
$rows.hide();
|
||||
}
|
||||
$rows.find('.check input').attr('disabled', !this.checked);
|
||||
checkAllToggle();
|
||||
});
|
||||
};
|
||||
|
||||
var initFilterRows = function () {
|
||||
$('#filter-input').on('input', function () {
|
||||
var that = this,
|
||||
$rows = $('#files-body').find('tr');
|
||||
|
||||
$rows.hide().toggleClass('filter-hidden', true).filter(function () {
|
||||
return $(this).text().toUpperCase().indexOf(that.value.toUpperCase()) > -1;
|
||||
}).toggleClass('filter-hidden', false).not('.action-hidden').show();
|
||||
|
||||
$rows.find('input').each(function(){
|
||||
$(this).prop('disabled', $(this).is(':hidden'));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$(document).on("keydown", function(e) {
|
||||
if (valueToCopy && (e.ctrlKey || e.metaKey) && (e.which === 67)) {
|
||||
return onKeydown(e);
|
||||
}
|
||||
}).on("keyup", onKeyup);
|
||||
|
||||
return {
|
||||
autocomplete: function (counter, data) {
|
||||
var datum = new Bloodhound({
|
||||
datumTokenizer: function (d) {
|
||||
return Bloodhound.tokenizers.whitespace(d.word);
|
||||
},
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
local: data
|
||||
});
|
||||
datum.initialize();
|
||||
jQuery('.typeahead-' + counter).typeahead(null, {displayKey: 'word', source: datum.ttAdapter()});
|
||||
},
|
||||
init: function () {
|
||||
initHintBlocks();
|
||||
initStickyInputs();
|
||||
initPreviewDiffLinks();
|
||||
initConfirmationCheckboxes();
|
||||
initToggleActions();
|
||||
initFilterRows();
|
||||
|
||||
// model generator: hide class name inputs when table name input contains *
|
||||
$('#model-generator #generator-tablename').change(function () {
|
||||
var show = ($(this).val().indexOf('*') === -1);
|
||||
$('.field-generator-modelclass').toggle(show);
|
||||
if ($('#generator-generatequery').is(':checked')) {
|
||||
$('.field-generator-queryclass').toggle(show);
|
||||
}
|
||||
}).change();
|
||||
|
||||
// model generator: translate table name to model class
|
||||
$('#model-generator #generator-tablename').on('blur', function () {
|
||||
var tableName = $(this).val();
|
||||
var tablePrefix = $(this).attr('table_prefix') || '';
|
||||
if (tablePrefix.length) {
|
||||
// if starts with prefix
|
||||
if (tableName.slice(0, tablePrefix.length) === tablePrefix) {
|
||||
// remove prefix
|
||||
tableName = tableName.slice(tablePrefix.length);
|
||||
}
|
||||
}
|
||||
if ($('#generator-modelclass').val() === '' && tableName && tableName.indexOf('*') === -1) {
|
||||
var modelClass = '';
|
||||
$.each(tableName.split(/\.|\_/), function() {
|
||||
if(this.length>0)
|
||||
modelClass+=this.substring(0,1).toUpperCase()+this.substring(1);
|
||||
});
|
||||
$('#generator-modelclass').val(modelClass).blur();
|
||||
}
|
||||
});
|
||||
|
||||
// model generator: translate model class to query class
|
||||
$('#model-generator #generator-modelclass').on('blur', function () {
|
||||
var modelClass = $(this).val();
|
||||
if (modelClass !== '') {
|
||||
var queryClass = $('#generator-queryclass').val();
|
||||
if (queryClass === '') {
|
||||
queryClass = modelClass + 'Query';
|
||||
$('#generator-queryclass').val(queryClass);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// model generator: synchronize query namespace with model namespace
|
||||
$('#model-generator #generator-ns').on('blur', function () {
|
||||
var stickyValue = $('#model-generator .field-generator-queryns .sticky-value');
|
||||
var input = $('#model-generator #generator-queryns');
|
||||
if (stickyValue.is(':visible') || !input.is(':visible')) {
|
||||
var ns = $(this).val();
|
||||
stickyValue.html(ns);
|
||||
input.val(ns);
|
||||
}
|
||||
});
|
||||
|
||||
// model generator: toggle query fields
|
||||
$('form #generator-generatequery').change(function () {
|
||||
$('form .field-generator-queryns').toggle($(this).is(':checked'));
|
||||
$('form .field-generator-queryclass').toggle($(this).is(':checked'));
|
||||
$('form .field-generator-querybaseclass').toggle($(this).is(':checked'));
|
||||
$('#generator-queryclass').prop('disabled', $(this).is(':not(:checked)'));
|
||||
}).change();
|
||||
|
||||
// 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
|
||||
$('#form-fields').find('input,select,textarea').change(function () {
|
||||
$('.default-view-results,.default-view-files').hide();
|
||||
$('.default-view button[name="generate"]').hide();
|
||||
});
|
||||
|
||||
$('.module-form #generator-moduleclass').change(function () {
|
||||
var value = $(this).val().match(/(\w+)\\\w+$/);
|
||||
var $idInput = $('#generator-moduleid');
|
||||
if (value && value[1] && $idInput.val() === '') {
|
||||
$idInput.val(value[1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
BIN
vendor/yiisoft/yii2-gii/src/assets/logo.png
vendored
Normal file
BIN
vendor/yiisoft/yii2-gii/src/assets/logo.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
294
vendor/yiisoft/yii2-gii/src/assets/main.css
vendored
Normal file
294
vendor/yiisoft/yii2-gii/src/assets/main.css
vendored
Normal file
@@ -0,0 +1,294 @@
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
padding-top: 70px;
|
||||
}
|
||||
|
||||
.footer-fix {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: -60px;
|
||||
border-top: 1px solid #ddd;
|
||||
height: 59px;
|
||||
line-height: 59px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.footer p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.jumbotron {
|
||||
text-align: center;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.jumbotron .btn {
|
||||
font-size: 21px;
|
||||
padding: 14px 24px;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.default-index .generator {
|
||||
min-height: 200px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.list-group .glyphicon {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.popover {
|
||||
max-width: 400px;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.hint-block {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.error-summary {
|
||||
color: #a94442;
|
||||
background: #fdf7f7;
|
||||
border-left: 3px solid #eed3d7;
|
||||
padding: 10px 20px;
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.default-view .sticky-value {
|
||||
padding: 6px 12px;
|
||||
background: lightyellow;
|
||||
white-space: pre;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.default-view .form-group label.help {
|
||||
border-bottom: 1px dashed #888;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.default-view .modal-dialog {
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.default-view .modal-dialog .error {
|
||||
color: #d9534f;
|
||||
}
|
||||
|
||||
.default-view .modal-dialog .content {
|
||||
background: #fafafa;
|
||||
border-left: #eee 5px solid;
|
||||
padding: 5px 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.default-view .modal-dialog code {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.default-view .modal-dialog .modal-copy-hint {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.default-view .modal-dialog .modal-copy-hint kbd {
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.default-view-files table .action {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.default-view-files table .check {
|
||||
width: 25px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.default-view-results pre {
|
||||
overflow: auto;
|
||||
background-color: #333;
|
||||
max-height: 300px;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border-radius: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.default-view-results pre .error {
|
||||
background: #FFE0E1;
|
||||
color: black;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.default-view-results .alert pre {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.default-diff pre {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.default-diff pre del {
|
||||
background: pink;
|
||||
}
|
||||
|
||||
.default-diff pre ins {
|
||||
background: lightgreen;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.Differences {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
empty-cells: show;
|
||||
}
|
||||
|
||||
.Differences thead {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.Differences tbody th {
|
||||
text-align: right;
|
||||
background: #FAFAFA;
|
||||
padding: 1px 2px;
|
||||
border-right: 1px solid #eee;
|
||||
vertical-align: top;
|
||||
font-size: 13px;
|
||||
font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;
|
||||
font-weight: normal;
|
||||
color: #999;
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.Differences td {
|
||||
padding: 1px 2px;
|
||||
font-size: 13px;
|
||||
font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;
|
||||
}
|
||||
|
||||
.DifferencesSideBySide .ChangeInsert td.Left {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.DifferencesSideBySide .ChangeInsert td.Right {
|
||||
background: #cfc;
|
||||
}
|
||||
|
||||
.DifferencesSideBySide .ChangeDelete td.Left {
|
||||
background: #f88;
|
||||
}
|
||||
|
||||
.DifferencesSideBySide .ChangeDelete td.Right {
|
||||
background: #faa;
|
||||
}
|
||||
|
||||
.DifferencesSideBySide .ChangeReplace .Left {
|
||||
background: #fe9;
|
||||
}
|
||||
|
||||
.DifferencesSideBySide .ChangeReplace .Right {
|
||||
background: #fd8;
|
||||
}
|
||||
|
||||
.Differences ins, .Differences del {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.DifferencesSideBySide .ChangeReplace ins, .DifferencesSideBySide .ChangeReplace del {
|
||||
background: #fc0;
|
||||
}
|
||||
|
||||
.Differences .Skipped {
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.DifferencesInline .ChangeReplace .Left,
|
||||
.DifferencesInline .ChangeDelete .Left {
|
||||
background: #fdd;
|
||||
}
|
||||
|
||||
.DifferencesInline .ChangeReplace .Right,
|
||||
.DifferencesInline .ChangeInsert .Right {
|
||||
background: #dfd;
|
||||
}
|
||||
|
||||
.DifferencesInline .ChangeReplace ins {
|
||||
background: #9e9;
|
||||
}
|
||||
|
||||
.DifferencesInline .ChangeReplace del {
|
||||
background: #e99;
|
||||
}
|
||||
|
||||
.DifferencesInline th[data-line-number]:before {
|
||||
content: attr(data-line-number);
|
||||
}
|
||||
|
||||
/* additional styles for typeahead.js, adapted from http://twitter.github.io/typeahead.js/examples/ */
|
||||
|
||||
.twitter-typeahead {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.tt-hint {
|
||||
color: #999
|
||||
}
|
||||
|
||||
.tt-dropdown-menu, .tt-menu {
|
||||
width: 422px;
|
||||
margin-top: 2px;
|
||||
padding: 8px 0;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
|
||||
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
|
||||
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
.tt-suggestion {
|
||||
padding: 3px 20px;
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.tt-suggestion.tt-cursor {
|
||||
color: #fff;
|
||||
background-color: #0097cf;
|
||||
}
|
||||
|
||||
.tt-suggestion p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#clipboard-container {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index: 100;
|
||||
/*display: none;*/
|
||||
opacity: 0;
|
||||
}
|
||||
#clipboard {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
}
|
||||
75
vendor/yiisoft/yii2-gii/src/components/ActiveField.php
vendored
Normal file
75
vendor/yiisoft/yii2-gii/src/components/ActiveField.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii\components;
|
||||
|
||||
use yii\gii\Generator;
|
||||
use yii\helpers\Json;
|
||||
|
||||
/**
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ActiveField extends \yii\widgets\ActiveField
|
||||
{
|
||||
/**
|
||||
* @var Generator
|
||||
*/
|
||||
public $model;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$stickyAttributes = $this->model->stickyAttributes();
|
||||
if (in_array($this->attribute, $stickyAttributes, true)) {
|
||||
$this->sticky();
|
||||
}
|
||||
$hints = $this->model->hints();
|
||||
if (isset($hints[$this->attribute])) {
|
||||
$this->hint($hints[$this->attribute]);
|
||||
}
|
||||
$autoCompleteData = $this->model->autoCompleteData();
|
||||
if (isset($autoCompleteData[$this->attribute])) {
|
||||
if (is_callable($autoCompleteData[$this->attribute])) {
|
||||
$this->autoComplete(call_user_func($autoCompleteData[$this->attribute]));
|
||||
} else {
|
||||
$this->autoComplete($autoCompleteData[$this->attribute]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes field remember its value between page reloads
|
||||
* @return $this the field object itself
|
||||
*/
|
||||
public function sticky()
|
||||
{
|
||||
$this->options['class'] .= ' sticky';
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes field auto completable
|
||||
* @param array $data auto complete data (array of callables or scalars)
|
||||
* @return $this the field object itself
|
||||
*/
|
||||
public function autoComplete($data)
|
||||
{
|
||||
static $counter = 0;
|
||||
$this->inputOptions['class'] .= ' typeahead typeahead-' . (++$counter);
|
||||
foreach ($data as &$item) {
|
||||
$item = ['word' => $item];
|
||||
}
|
||||
$this->form->getView()->registerJs("yii.gii.autocomplete($counter, " . Json::htmlEncode($data) . ");");
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
136
vendor/yiisoft/yii2-gii/src/components/DiffRendererHtmlInline.php
vendored
Normal file
136
vendor/yiisoft/yii2-gii/src/components/DiffRendererHtmlInline.php
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii\components;
|
||||
|
||||
/**
|
||||
* Renders diff to HTML. Output adjusted to be copy-paste friendly.
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @since 2.0
|
||||
*/
|
||||
class DiffRendererHtmlInline extends \Diff_Renderer_Html_Array
|
||||
{
|
||||
/**
|
||||
* Render a and return diff with changes between the two sequences
|
||||
* displayed inline (under each other)
|
||||
*
|
||||
* @return string The generated inline diff.
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$changes = parent::render();
|
||||
$html = '';
|
||||
if (empty($changes)) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$html .= <<<HTML
|
||||
<table class="Differences DifferencesInline">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Old</th>
|
||||
<th>New</th>
|
||||
<th>Differences</th>
|
||||
</tr>
|
||||
</thead>
|
||||
HTML;
|
||||
foreach ($changes as $i => $blocks) {
|
||||
// If this is a separate block, we're condensing code so output ...,
|
||||
// indicating a significant portion of the code has been collapsed as
|
||||
// it is the same
|
||||
if ($i > 0) {
|
||||
$html .= <<<HTML
|
||||
<tbody class="Skipped">
|
||||
<th data-line-number="…"></th>
|
||||
<th data-line-number="…"></th>
|
||||
<td> </td>
|
||||
</tbody>
|
||||
HTML;
|
||||
}
|
||||
|
||||
foreach ($blocks as $change) {
|
||||
$tag = ucfirst($change['tag']);
|
||||
$html .= <<<HTML
|
||||
<tbody class="Change{$tag}">
|
||||
HTML;
|
||||
// Equal changes should be shown on both sides of the diff
|
||||
if ($change['tag'] === 'equal') {
|
||||
foreach ($change['base']['lines'] as $no => $line) {
|
||||
$fromLine = $change['base']['offset'] + $no + 1;
|
||||
$toLine = $change['changed']['offset'] + $no + 1;
|
||||
$html .= <<<HTML
|
||||
<tr>
|
||||
<th data-line-number="{$fromLine}"></th>
|
||||
<th data-line-number="{$toLine}"></th>
|
||||
<td class="Left">{$line}</td>
|
||||
</tr>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
// Added lines only on the right side
|
||||
elseif ($change['tag'] === 'insert') {
|
||||
foreach ($change['changed']['lines'] as $no => $line) {
|
||||
$toLine = $change['changed']['offset'] + $no + 1;
|
||||
$html .= <<<HTML
|
||||
<tr>
|
||||
<th data-line-number=" "></th>
|
||||
<th data-line-number="{$toLine}"></th>
|
||||
<td class="Right"><ins>{$line}</ins> </td>
|
||||
</tr>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
// Show deleted lines only on the left side
|
||||
elseif ($change['tag'] === 'delete') {
|
||||
foreach ($change['base']['lines'] as $no => $line) {
|
||||
$fromLine = $change['base']['offset'] + $no + 1;
|
||||
$html .= <<<HTML
|
||||
<tr>
|
||||
<th data-line-number="{$fromLine}"></th>
|
||||
<th data-line-number=" "></th>
|
||||
<td class="Left"><del>{$line}</del> </td>
|
||||
</tr>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
// Show modified lines on both sides
|
||||
elseif ($change['tag'] === 'replace') {
|
||||
foreach ($change['base']['lines'] as $no => $line) {
|
||||
$fromLine = $change['base']['offset'] + $no + 1;
|
||||
$html .= <<<HTML
|
||||
<tr>
|
||||
<th data-line-number="{$fromLine}"></th>
|
||||
<th data-line-number=" "></th>
|
||||
<td class="Left"><span>{$line}</span></td>
|
||||
</tr>
|
||||
HTML;
|
||||
}
|
||||
|
||||
foreach ($change['changed']['lines'] as $no => $line) {
|
||||
$toLine = $change['changed']['offset'] + $no + 1;
|
||||
$html .= <<<HTML
|
||||
<tr>
|
||||
<th data-line-number="{$toLine}"></th>
|
||||
<th data-line-number=" "></th>
|
||||
<td class="Right"><span>{$line}</span></td>
|
||||
</tr>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
$html .= <<<HTML
|
||||
</tbody>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
$html .= <<<HTML
|
||||
</table>
|
||||
HTML;
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
113
vendor/yiisoft/yii2-gii/src/console/GenerateAction.php
vendored
Normal file
113
vendor/yiisoft/yii2-gii/src/console/GenerateAction.php
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii\console;
|
||||
|
||||
use yii\helpers\Console;
|
||||
|
||||
/**
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class GenerateAction extends \yii\base\Action
|
||||
{
|
||||
/**
|
||||
* @var \yii\gii\Generator
|
||||
*/
|
||||
public $generator;
|
||||
/**
|
||||
* @var GenerateController
|
||||
*/
|
||||
public $controller;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
echo "Running '{$this->generator->getName()}'...\n\n";
|
||||
|
||||
if ($this->generator->validate()) {
|
||||
$this->generateCode();
|
||||
} else {
|
||||
$this->displayValidationErrors();
|
||||
}
|
||||
}
|
||||
|
||||
protected function displayValidationErrors()
|
||||
{
|
||||
$this->controller->stdout("Code not generated. Please fix the following errors:\n\n", Console::FG_RED);
|
||||
foreach ($this->generator->errors as $attribute => $errors) {
|
||||
echo ' - ' . $this->controller->ansiFormat($attribute, Console::FG_CYAN) . ': ' . implode('; ', $errors) . "\n";
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
protected function generateCode()
|
||||
{
|
||||
$files = $this->generator->generate();
|
||||
$n = count($files);
|
||||
if ($n === 0) {
|
||||
echo "No code to be generated.\n";
|
||||
return;
|
||||
}
|
||||
echo "The following files will be generated:\n";
|
||||
$skipAll = $this->controller->interactive ? null : !$this->controller->overwrite;
|
||||
$answers = [];
|
||||
foreach ($files as $file) {
|
||||
$path = $file->getRelativePath();
|
||||
if (is_file($file->path)) {
|
||||
if (file_get_contents($file->path) === $file->content) {
|
||||
echo ' ' . $this->controller->ansiFormat('[unchanged]', Console::FG_GREY);
|
||||
echo $this->controller->ansiFormat(" $path\n", Console::FG_CYAN);
|
||||
$answers[$file->id] = false;
|
||||
} else {
|
||||
echo ' ' . $this->controller->ansiFormat('[changed]', Console::FG_RED);
|
||||
echo $this->controller->ansiFormat(" $path\n", Console::FG_CYAN);
|
||||
if ($skipAll !== null) {
|
||||
$answers[$file->id] = !$skipAll;
|
||||
} else {
|
||||
$answer = $this->controller->select("Do you want to overwrite this file?", [
|
||||
'y' => 'Overwrite this file.',
|
||||
'n' => 'Skip this file.',
|
||||
'ya' => 'Overwrite this and the rest of the changed files.',
|
||||
'na' => 'Skip this and the rest of the changed files.',
|
||||
]);
|
||||
$answers[$file->id] = $answer === 'y' || $answer === 'ya';
|
||||
if ($answer === 'ya') {
|
||||
$skipAll = false;
|
||||
} elseif ($answer === 'na') {
|
||||
$skipAll = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echo ' ' . $this->controller->ansiFormat('[new]', Console::FG_GREEN);
|
||||
echo $this->controller->ansiFormat(" $path\n", Console::FG_CYAN);
|
||||
$answers[$file->id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!array_sum($answers)) {
|
||||
$this->controller->stdout("\nNo files were chosen to be generated.\n", Console::FG_CYAN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->controller->confirm("\nReady to generate the selected files?", true)) {
|
||||
$this->controller->stdout("\nNo file was generated.\n", Console::FG_CYAN);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->generator->save($files, (array) $answers, $results)) {
|
||||
$this->controller->stdout("\nFiles were generated successfully!\n", Console::FG_GREEN);
|
||||
} else {
|
||||
$this->controller->stdout("\nSome errors occurred while generating the files.", Console::FG_RED);
|
||||
}
|
||||
echo preg_replace('%<span class="error">(.*?)</span>%', '\1', $results) . "\n";
|
||||
}
|
||||
}
|
||||
207
vendor/yiisoft/yii2-gii/src/console/GenerateController.php
vendored
Normal file
207
vendor/yiisoft/yii2-gii/src/console/GenerateController.php
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii\console;
|
||||
|
||||
use Yii;
|
||||
use yii\base\InlineAction;
|
||||
use yii\console\Controller;
|
||||
|
||||
/**
|
||||
* This is the command line version of Gii - a code generator.
|
||||
*
|
||||
* You can use this command to generate models, controllers, etc. For example,
|
||||
* to generate an ActiveRecord model based on a DB table, you can run:
|
||||
*
|
||||
* ```
|
||||
* $ ./yii gii/model --tableName=city --modelClass=City
|
||||
* ```
|
||||
*
|
||||
* @author Tobias Munk <schmunk@usrbin.de>
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class GenerateController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \yii\gii\Module
|
||||
*/
|
||||
public $module;
|
||||
/**
|
||||
* @var bool whether to overwrite all existing code files when in non-interactive mode.
|
||||
* Defaults to false, meaning none of the existing code files will be overwritten.
|
||||
* This option is used only when `--interactive=0`.
|
||||
*/
|
||||
public $overwrite = false;
|
||||
/**
|
||||
* @var array a list of the available code generators
|
||||
*/
|
||||
public $generators = [];
|
||||
|
||||
/**
|
||||
* @var array generator option values
|
||||
*/
|
||||
private $_options = [];
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return isset($this->_options[$name]) ? $this->_options[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$this->_options[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
foreach ($this->generators as $id => $config) {
|
||||
$this->generators[$id] = Yii::createObject($config);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createAction($id)
|
||||
{
|
||||
/** @var $action GenerateAction */
|
||||
$action = parent::createAction($id);
|
||||
foreach ($this->_options as $name => $value) {
|
||||
$action->generator->$name = $value;
|
||||
}
|
||||
return $action;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function actions()
|
||||
{
|
||||
$actions = [];
|
||||
foreach ($this->generators as $name => $generator) {
|
||||
$actions[$name] = [
|
||||
'class' => 'yii\gii\console\GenerateAction',
|
||||
'generator' => $generator,
|
||||
];
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
public function actionIndex()
|
||||
{
|
||||
$this->run('/help', ['gii']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUniqueID()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function options($id)
|
||||
{
|
||||
$options = parent::options($id);
|
||||
$options[] = 'overwrite';
|
||||
|
||||
if (!isset($this->generators[$id])) {
|
||||
return $options;
|
||||
}
|
||||
|
||||
$attributes = $this->generators[$id]->attributes;
|
||||
unset($attributes['templates']);
|
||||
return array_merge(
|
||||
$options,
|
||||
array_keys($attributes)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getActionHelpSummary($action)
|
||||
{
|
||||
if ($action instanceof InlineAction) {
|
||||
return parent::getActionHelpSummary($action);
|
||||
} else {
|
||||
/** @var $action GenerateAction */
|
||||
return $action->generator->getName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getActionHelp($action)
|
||||
{
|
||||
if ($action instanceof InlineAction) {
|
||||
return parent::getActionHelp($action);
|
||||
} else {
|
||||
/** @var $action GenerateAction */
|
||||
$description = $action->generator->getDescription();
|
||||
return wordwrap(preg_replace('/\s+/', ' ', $description));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getActionArgsHelp($action)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getActionOptionsHelp($action)
|
||||
{
|
||||
if ($action instanceof InlineAction) {
|
||||
return parent::getActionOptionsHelp($action);
|
||||
}
|
||||
/** @var $action GenerateAction */
|
||||
$attributes = $action->generator->attributes;
|
||||
unset($attributes['templates']);
|
||||
$hints = $action->generator->hints();
|
||||
|
||||
$options = parent::getActionOptionsHelp($action);
|
||||
foreach ($attributes as $name => $value) {
|
||||
$type = gettype($value);
|
||||
$options[$name] = [
|
||||
'type' => $type === 'NULL' ? 'string' : $type,
|
||||
'required' => $value === null && $action->generator->isAttributeRequired($name),
|
||||
'default' => $value,
|
||||
'comment' => isset($hints[$name]) ? $this->formatHint($hints[$name]) : '',
|
||||
];
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
protected function formatHint($hint)
|
||||
{
|
||||
$hint = preg_replace('%<code>(.*?)</code>%', '\1', $hint);
|
||||
$hint = preg_replace('/\s+/', ' ', $hint);
|
||||
return wordwrap($hint);
|
||||
}
|
||||
}
|
||||
146
vendor/yiisoft/yii2-gii/src/controllers/DefaultController.php
vendored
Normal file
146
vendor/yiisoft/yii2-gii/src/controllers/DefaultController.php
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii\controllers;
|
||||
|
||||
use Yii;
|
||||
use yii\web\Controller;
|
||||
use yii\web\NotFoundHttpException;
|
||||
use yii\web\Response;
|
||||
|
||||
/**
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class DefaultController extends Controller
|
||||
{
|
||||
public $layout = 'generator';
|
||||
/**
|
||||
* @var \yii\gii\Module
|
||||
*/
|
||||
public $module;
|
||||
/**
|
||||
* @var \yii\gii\Generator
|
||||
*/
|
||||
public $generator;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function beforeAction($action)
|
||||
{
|
||||
Yii::$app->response->format = Response::FORMAT_HTML;
|
||||
return parent::beforeAction($action);
|
||||
}
|
||||
|
||||
|
||||
public function actionIndex()
|
||||
{
|
||||
$this->layout = 'main';
|
||||
|
||||
return $this->render('index');
|
||||
}
|
||||
|
||||
public function actionView($id)
|
||||
{
|
||||
$generator = $this->loadGenerator($id);
|
||||
$params = ['generator' => $generator, 'id' => $id];
|
||||
|
||||
$preview = Yii::$app->request->post('preview');
|
||||
$generate = Yii::$app->request->post('generate');
|
||||
$answers = Yii::$app->request->post('answers');
|
||||
|
||||
if ($preview !== null || $generate !== null) {
|
||||
if ($generator->validate()) {
|
||||
$generator->saveStickyAttributes();
|
||||
$files = $generator->generate();
|
||||
if ($generate !== null && !empty($answers)) {
|
||||
$params['hasError'] = !$generator->save($files, (array) $answers, $results);
|
||||
$params['results'] = $results;
|
||||
} else {
|
||||
$params['files'] = $files;
|
||||
$params['answers'] = $answers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render('view', $params);
|
||||
}
|
||||
|
||||
public function actionPreview($id, $file)
|
||||
{
|
||||
$generator = $this->loadGenerator($id);
|
||||
if ($generator->validate()) {
|
||||
foreach ($generator->generate() as $f) {
|
||||
if ($f->id === $file) {
|
||||
$content = $f->preview();
|
||||
if ($content !== false) {
|
||||
return '<div class="content">' . $content . '</div>';
|
||||
} else {
|
||||
return '<div class="error">Preview is not available for this file type.</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException("Code file not found: $file");
|
||||
}
|
||||
|
||||
public function actionDiff($id, $file)
|
||||
{
|
||||
$generator = $this->loadGenerator($id);
|
||||
if ($generator->validate()) {
|
||||
foreach ($generator->generate() as $f) {
|
||||
if ($f->id === $file) {
|
||||
return $this->renderPartial('diff', [
|
||||
'diff' => $f->diff(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new NotFoundHttpException("Code file not found: $file");
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an action defined in the generator.
|
||||
* Given an action named "xyz", the method "actionXyz()" in the generator will be called.
|
||||
* If the method does not exist, a 400 HTTP exception will be thrown.
|
||||
* @param string $id the ID of the generator
|
||||
* @param string $name the action name
|
||||
* @return mixed the result of the action.
|
||||
* @throws NotFoundHttpException if the action method does not exist.
|
||||
*/
|
||||
public function actionAction($id, $name)
|
||||
{
|
||||
$generator = $this->loadGenerator($id);
|
||||
$method = 'action' . $name;
|
||||
if (method_exists($generator, $method)) {
|
||||
return $generator->$method();
|
||||
} else {
|
||||
throw new NotFoundHttpException("Unknown generator action: $name");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the generator with the specified ID.
|
||||
* @param string $id the ID of the generator to be loaded.
|
||||
* @return \yii\gii\Generator the loaded generator
|
||||
* @throws NotFoundHttpException
|
||||
*/
|
||||
protected function loadGenerator($id)
|
||||
{
|
||||
if (isset($this->module->generators[$id])) {
|
||||
$this->generator = $this->module->generators[$id];
|
||||
$this->generator->loadStickyAttributes();
|
||||
$this->generator->load(Yii::$app->request->post());
|
||||
|
||||
return $this->generator;
|
||||
} else {
|
||||
throw new NotFoundHttpException("Code generator not found: $id");
|
||||
}
|
||||
}
|
||||
}
|
||||
255
vendor/yiisoft/yii2-gii/src/generators/controller/Generator.php
vendored
Normal file
255
vendor/yiisoft/yii2-gii/src/generators/controller/Generator.php
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
<?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;
|
||||
use yii\gii\CodeFile;
|
||||
use yii\helpers\Html;
|
||||
use yii\helpers\Inflector;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/**
|
||||
* 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 string $controllerFile The controller class file path. This property is read-only.
|
||||
* @property string $controllerID The controller ID. This property is read-only.
|
||||
* @property string $controllerNamespace The namespace of the controller class. This property is read-only.
|
||||
* @property string $controllerSubPath The controller sub path. This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Generator extends \yii\gii\Generator
|
||||
{
|
||||
/**
|
||||
* @var string the controller class name
|
||||
*/
|
||||
public $controllerClass;
|
||||
/**
|
||||
* @var string the controller's view path
|
||||
*/
|
||||
public $viewPath;
|
||||
/**
|
||||
* @var string the base class of the controller
|
||||
*/
|
||||
public $baseClass = 'yii\web\Controller';
|
||||
/**
|
||||
* @var string list of action IDs separated by commas or spaces
|
||||
*/
|
||||
public $actions = 'index';
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Controller Generator';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return 'This generator helps you to quickly generate a new controller class with
|
||||
one or several controller actions and their corresponding views.';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return array_merge(parent::rules(), [
|
||||
[['controllerClass', 'actions', 'baseClass'], 'filter', 'filter' => 'trim'],
|
||||
[['controllerClass', 'baseClass'], 'required'],
|
||||
['controllerClass', 'match', 'pattern' => '/^[\w\\\\]*Controller$/', 'message' => 'Only word characters and backslashes are allowed, and the class name must end with "Controller".'],
|
||||
['controllerClass', 'validateNewClass'],
|
||||
['baseClass', '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.'],
|
||||
['viewPath', 'safe'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributeLabels()
|
||||
{
|
||||
return [
|
||||
'baseClass' => 'Base Class',
|
||||
'controllerClass' => 'Controller Class',
|
||||
'viewPath' => 'View Path',
|
||||
'actions' => 'Action IDs',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function requiredTemplates()
|
||||
{
|
||||
return [
|
||||
'controller.php',
|
||||
'view.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function stickyAttributes()
|
||||
{
|
||||
return ['baseClass'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hints()
|
||||
{
|
||||
return [
|
||||
'controllerClass' => 'This is the name of the controller class to be generated. You should
|
||||
provide a fully qualified namespaced class (e.g. <code>app\controllers\PostController</code>),
|
||||
and class name should be in CamelCase ending with the word <code>Controller</code>. Make sure the class
|
||||
is using the same namespace as specified by your application\'s controllerNamespace property.',
|
||||
'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>',
|
||||
'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.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function successMessage()
|
||||
{
|
||||
return 'The controller has been generated successfully.' . $this->getLinkToTry();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a link to try controller generated
|
||||
* @see https://github.com/yiisoft/yii2-gii/issues/182
|
||||
* @return string
|
||||
* @since 2.0.6
|
||||
*/
|
||||
private function getLinkToTry()
|
||||
{
|
||||
if (strpos($this->controllerNamespace, Yii::$app->controllerNamespace) !== 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$actions = $this->getActionIDs();
|
||||
if (in_array('index', $actions, true)) {
|
||||
$route = $this->getControllerSubPath() . $this->getControllerID() . '/index';
|
||||
} else {
|
||||
$route = $this->getControllerSubPath() . $this->getControllerID() . '/' . reset($actions);
|
||||
}
|
||||
return ' You may ' . Html::a('try it now', Yii::$app->getUrlManager()->createUrl($route), ['target' => '_blank', 'rel' => 'noopener noreferrer']) . '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate()
|
||||
{
|
||||
$files = [];
|
||||
|
||||
$files[] = new CodeFile(
|
||||
$this->getControllerFile(),
|
||||
$this->render('controller.php')
|
||||
);
|
||||
|
||||
foreach ($this->getActionIDs() as $action) {
|
||||
$files[] = new CodeFile(
|
||||
$this->getViewFile($action),
|
||||
$this->render('view.php', ['action' => $action])
|
||||
);
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes [[actions]] into an array of action IDs.
|
||||
* @return array an array of action IDs entered by the user
|
||||
*/
|
||||
public function getActionIDs()
|
||||
{
|
||||
$actions = array_unique(preg_split('/[\s,]+/', $this->actions, -1, PREG_SPLIT_NO_EMPTY));
|
||||
sort($actions);
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the controller class file path
|
||||
*/
|
||||
public function getControllerFile()
|
||||
{
|
||||
return Yii::getAlias('@' . str_replace('\\', '/', $this->controllerClass)) . '.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the controller ID
|
||||
*/
|
||||
public function getControllerID()
|
||||
{
|
||||
$name = StringHelper::basename($this->controllerClass);
|
||||
return Inflector::camel2id(substr($name, 0, strlen($name) - 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return sub path for controller if it
|
||||
* is located in subdirectory of application controllers dir
|
||||
* @see https://github.com/yiisoft/yii2-gii/issues/182
|
||||
* @since 2.0.6
|
||||
* @return string the controller sub path
|
||||
*/
|
||||
public function getControllerSubPath()
|
||||
{
|
||||
$subPath = '';
|
||||
$controllerNamespace = $this->getControllerNamespace();
|
||||
if (strpos($controllerNamespace, Yii::$app->controllerNamespace) === 0) {
|
||||
$subPath = substr($controllerNamespace, strlen(Yii::$app->controllerNamespace));
|
||||
$subPath = ($subPath !== '') ? str_replace('\\', '/', substr($subPath, 1)) . '/' : '';
|
||||
}
|
||||
return $subPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action the action ID
|
||||
* @return string the action view file path
|
||||
*/
|
||||
public function getViewFile($action)
|
||||
{
|
||||
if (empty($this->viewPath)) {
|
||||
return Yii::getAlias('@app/views/' . $this->getControllerSubPath() . $this->getControllerID() . "/$action.php");
|
||||
}
|
||||
|
||||
return Yii::getAlias(str_replace('\\', '/', $this->viewPath) . "/$action.php");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the namespace of the controller class
|
||||
*/
|
||||
public function getControllerNamespace()
|
||||
{
|
||||
$name = StringHelper::basename($this->controllerClass);
|
||||
return ltrim(substr($this->controllerClass, 0, - (strlen($name) + 1)), '\\');
|
||||
}
|
||||
}
|
||||
26
vendor/yiisoft/yii2-gii/src/generators/controller/default/controller.php
vendored
Normal file
26
vendor/yiisoft/yii2-gii/src/generators/controller/default/controller.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating a controller class file.
|
||||
*/
|
||||
|
||||
use yii\helpers\Inflector;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\controller\Generator */
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
namespace <?= $generator->getControllerNamespace() ?>;
|
||||
|
||||
class <?= StringHelper::basename($generator->controllerClass) ?> extends <?= '\\' . trim($generator->baseClass, '\\') . "\n" ?>
|
||||
{
|
||||
<?php foreach ($generator->getActionIDs() as $action): ?>
|
||||
public function action<?= Inflector::id2camel($action) ?>()
|
||||
{
|
||||
return $this->render('<?= $action ?>');
|
||||
}
|
||||
|
||||
<?php endforeach; ?>
|
||||
}
|
||||
20
vendor/yiisoft/yii2-gii/src/generators/controller/default/view.php
vendored
Normal file
20
vendor/yiisoft/yii2-gii/src/generators/controller/default/view.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating an action view file.
|
||||
*/
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\controller\Generator */
|
||||
/* @var $action string the action ID */
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
/* @var $this yii\web\View */
|
||||
<?= "?>" ?>
|
||||
|
||||
<h1><?= $generator->getControllerSubPath() . $generator->getControllerID() . '/' . $action ?></h1>
|
||||
|
||||
<p>
|
||||
You may change the content of this page by modifying
|
||||
the file <code><?= '<?=' ?> __FILE__; ?></code>.
|
||||
</p>
|
||||
9
vendor/yiisoft/yii2-gii/src/generators/controller/form.php
vendored
Normal file
9
vendor/yiisoft/yii2-gii/src/generators/controller/form.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
/* @var $generator yii\gii\generators\controller\Generator */
|
||||
|
||||
echo $form->field($generator, 'controllerClass');
|
||||
echo $form->field($generator, 'actions');
|
||||
echo $form->field($generator, 'viewPath');
|
||||
echo $form->field($generator, 'baseClass');
|
||||
585
vendor/yiisoft/yii2-gii/src/generators/crud/Generator.php
vendored
Normal file
585
vendor/yiisoft/yii2-gii/src/generators/crud/Generator.php
vendored
Normal file
@@ -0,0 +1,585 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii\generators\crud;
|
||||
|
||||
use Yii;
|
||||
use yii\db\ActiveRecord;
|
||||
use yii\db\BaseActiveRecord;
|
||||
use yii\db\Schema;
|
||||
use yii\gii\CodeFile;
|
||||
use yii\helpers\Inflector;
|
||||
use yii\helpers\VarDumper;
|
||||
use yii\web\Controller;
|
||||
|
||||
/**
|
||||
* Generates CRUD
|
||||
*
|
||||
* @property array $columnNames Model column names. This property is read-only.
|
||||
* @property string $controllerID The controller ID (without the module ID prefix). This property is
|
||||
* read-only.
|
||||
* @property string $nameAttribute This property is read-only.
|
||||
* @property array $searchAttributes Searchable attributes. This property is read-only.
|
||||
* @property bool|\yii\db\TableSchema $tableSchema This property is read-only.
|
||||
* @property string $viewPath The controller view path. This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Generator extends \yii\gii\Generator
|
||||
{
|
||||
public $modelClass;
|
||||
public $controllerClass;
|
||||
public $viewPath;
|
||||
public $baseControllerClass = 'yii\web\Controller';
|
||||
public $indexWidgetType = 'grid';
|
||||
public $searchModelClass = '';
|
||||
/**
|
||||
* @var bool whether to wrap the `GridView` or `ListView` widget with the `yii\widgets\Pjax` widget
|
||||
* @since 2.0.5
|
||||
*/
|
||||
public $enablePjax = false;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'CRUD Generator';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return 'This generator generates a controller and views that implement CRUD (Create, Read, Update, Delete)
|
||||
operations for the specified data model.';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return array_merge(parent::rules(), [
|
||||
[['controllerClass', 'modelClass', 'searchModelClass', 'baseControllerClass'], 'filter', 'filter' => 'trim'],
|
||||
[['modelClass', 'controllerClass', 'baseControllerClass', 'indexWidgetType'], 'required'],
|
||||
[['searchModelClass'], 'compare', 'compareAttribute' => 'modelClass', 'operator' => '!==', 'message' => 'Search Model Class must not be equal to Model Class.'],
|
||||
[['modelClass', 'controllerClass', 'baseControllerClass', 'searchModelClass'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'],
|
||||
[['modelClass'], 'validateClass', 'params' => ['extends' => BaseActiveRecord::className()]],
|
||||
[['baseControllerClass'], 'validateClass', 'params' => ['extends' => Controller::className()]],
|
||||
[['controllerClass'], 'match', 'pattern' => '/Controller$/', 'message' => 'Controller class name must be suffixed with "Controller".'],
|
||||
[['controllerClass'], 'match', 'pattern' => '/(^|\\\\)[A-Z][^\\\\]+Controller$/', 'message' => 'Controller class name must start with an uppercase letter.'],
|
||||
[['controllerClass', 'searchModelClass'], 'validateNewClass'],
|
||||
[['indexWidgetType'], 'in', 'range' => ['grid', 'list']],
|
||||
[['modelClass'], 'validateModelClass'],
|
||||
[['enableI18N', 'enablePjax'], 'boolean'],
|
||||
[['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false],
|
||||
['viewPath', 'safe'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributeLabels()
|
||||
{
|
||||
return array_merge(parent::attributeLabels(), [
|
||||
'modelClass' => 'Model Class',
|
||||
'controllerClass' => 'Controller Class',
|
||||
'viewPath' => 'View Path',
|
||||
'baseControllerClass' => 'Base Controller Class',
|
||||
'indexWidgetType' => 'Widget Used in Index Page',
|
||||
'searchModelClass' => 'Search Model Class',
|
||||
'enablePjax' => 'Enable Pjax',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hints()
|
||||
{
|
||||
return array_merge(parent::hints(), [
|
||||
'modelClass' => 'This is the ActiveRecord class associated with the table that CRUD will be built upon.
|
||||
You should provide a fully qualified class name, e.g., <code>app\models\Post</code>.',
|
||||
'controllerClass' => 'This is the name of the controller class to be generated. You should
|
||||
provide a fully qualified namespaced class (e.g. <code>app\controllers\PostController</code>),
|
||||
and class name should be in CamelCase with an uppercase first letter. Make sure the class
|
||||
is using the same namespace as specified by your application\'s controllerNamespace property.',
|
||||
'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/post</code>, <code>@app/views/post</code>. If not set, it will default
|
||||
to <code>@app/views/ControllerID</code>',
|
||||
'baseControllerClass' => 'This is the class that the new CRUD controller class will extend from.
|
||||
You should provide a fully qualified class name, e.g., <code>yii\web\Controller</code>.',
|
||||
'indexWidgetType' => 'This is the widget type to be used in the index page to display list of the models.
|
||||
You may choose either <code>GridView</code> or <code>ListView</code>',
|
||||
'searchModelClass' => 'This is the name of the search model class to be generated. You should provide a fully
|
||||
qualified namespaced class name, e.g., <code>app\models\PostSearch</code>.',
|
||||
'enablePjax' => 'This indicates whether the generator should wrap the <code>GridView</code> or <code>ListView</code>
|
||||
widget on the index page with <code>yii\widgets\Pjax</code> widget. Set this to <code>true</code> if you want to get
|
||||
sorting, filtering and pagination without page refreshing.',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function requiredTemplates()
|
||||
{
|
||||
return ['controller.php'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function stickyAttributes()
|
||||
{
|
||||
return array_merge(parent::stickyAttributes(), ['baseControllerClass', 'indexWidgetType']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if model class is valid
|
||||
*/
|
||||
public function validateModelClass()
|
||||
{
|
||||
/* @var $class ActiveRecord */
|
||||
$class = $this->modelClass;
|
||||
$pk = $class::primaryKey();
|
||||
if (empty($pk)) {
|
||||
$this->addError('modelClass', "The table associated with $class must have primary key(s).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate()
|
||||
{
|
||||
$controllerFile = Yii::getAlias('@' . str_replace('\\', '/', ltrim($this->controllerClass, '\\')) . '.php');
|
||||
|
||||
$files = [
|
||||
new CodeFile($controllerFile, $this->render('controller.php')),
|
||||
];
|
||||
|
||||
if (!empty($this->searchModelClass)) {
|
||||
$searchModel = Yii::getAlias('@' . str_replace('\\', '/', ltrim($this->searchModelClass, '\\') . '.php'));
|
||||
$files[] = new CodeFile($searchModel, $this->render('search.php'));
|
||||
}
|
||||
|
||||
$viewPath = $this->getViewPath();
|
||||
$templatePath = $this->getTemplatePath() . '/views';
|
||||
foreach (scandir($templatePath) as $file) {
|
||||
if (empty($this->searchModelClass) && $file === '_search.php') {
|
||||
continue;
|
||||
}
|
||||
if (is_file($templatePath . '/' . $file) && pathinfo($file, PATHINFO_EXTENSION) === 'php') {
|
||||
$files[] = new CodeFile("$viewPath/$file", $this->render("views/$file"));
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the controller ID (without the module ID prefix)
|
||||
*/
|
||||
public function getControllerID()
|
||||
{
|
||||
$pos = strrpos($this->controllerClass, '\\');
|
||||
$class = substr(substr($this->controllerClass, $pos + 1), 0, -10);
|
||||
|
||||
return Inflector::camel2id($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the controller view path
|
||||
*/
|
||||
public function getViewPath()
|
||||
{
|
||||
if (empty($this->viewPath)) {
|
||||
return Yii::getAlias('@app/views/' . $this->getControllerID());
|
||||
}
|
||||
|
||||
return Yii::getAlias(str_replace('\\', '/', $this->viewPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute()
|
||||
{
|
||||
foreach ($this->getColumnNames() as $name) {
|
||||
if (!strcasecmp($name, 'name') || !strcasecmp($name, 'title')) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
/* @var $class \yii\db\ActiveRecord */
|
||||
$class = $this->modelClass;
|
||||
$pk = $class::primaryKey();
|
||||
|
||||
return $pk[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates code for active field
|
||||
* @param string $attribute
|
||||
* @return string
|
||||
*/
|
||||
public function generateActiveField($attribute)
|
||||
{
|
||||
$tableSchema = $this->getTableSchema();
|
||||
if ($tableSchema === false || !isset($tableSchema->columns[$attribute])) {
|
||||
if (preg_match('/^(password|pass|passwd|passcode)$/i', $attribute)) {
|
||||
return "\$form->field(\$model, '$attribute')->passwordInput()";
|
||||
}
|
||||
|
||||
return "\$form->field(\$model, '$attribute')";
|
||||
}
|
||||
$column = $tableSchema->columns[$attribute];
|
||||
if ($column->phpType === 'boolean') {
|
||||
return "\$form->field(\$model, '$attribute')->checkbox()";
|
||||
}
|
||||
|
||||
if ($column->type === 'text') {
|
||||
return "\$form->field(\$model, '$attribute')->textarea(['rows' => 6])";
|
||||
}
|
||||
|
||||
if (preg_match('/^(password|pass|passwd|passcode)$/i', $column->name)) {
|
||||
$input = 'passwordInput';
|
||||
} else {
|
||||
$input = 'textInput';
|
||||
}
|
||||
|
||||
if (is_array($column->enumValues) && count($column->enumValues) > 0) {
|
||||
$dropDownOptions = [];
|
||||
foreach ($column->enumValues as $enumValue) {
|
||||
$dropDownOptions[$enumValue] = Inflector::humanize($enumValue);
|
||||
}
|
||||
return "\$form->field(\$model, '$attribute')->dropDownList("
|
||||
. preg_replace("/\n\s*/", ' ', VarDumper::export($dropDownOptions)).", ['prompt' => ''])";
|
||||
}
|
||||
|
||||
if ($column->phpType !== 'string' || $column->size === null) {
|
||||
return "\$form->field(\$model, '$attribute')->$input()";
|
||||
}
|
||||
|
||||
return "\$form->field(\$model, '$attribute')->$input(['maxlength' => true])";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates code for active search field
|
||||
* @param string $attribute
|
||||
* @return string
|
||||
*/
|
||||
public function generateActiveSearchField($attribute)
|
||||
{
|
||||
$tableSchema = $this->getTableSchema();
|
||||
if ($tableSchema === false) {
|
||||
return "\$form->field(\$model, '$attribute')";
|
||||
}
|
||||
|
||||
$column = $tableSchema->columns[$attribute];
|
||||
if ($column->phpType === 'boolean') {
|
||||
return "\$form->field(\$model, '$attribute')->checkbox()";
|
||||
}
|
||||
|
||||
return "\$form->field(\$model, '$attribute')";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates column format
|
||||
* @param \yii\db\ColumnSchema $column
|
||||
* @return string
|
||||
*/
|
||||
public function generateColumnFormat($column)
|
||||
{
|
||||
if ($column->phpType === 'boolean') {
|
||||
return 'boolean';
|
||||
}
|
||||
|
||||
if ($column->type === 'text') {
|
||||
return 'ntext';
|
||||
}
|
||||
|
||||
if (stripos($column->name, 'time') !== false && $column->phpType === 'integer') {
|
||||
return 'datetime';
|
||||
}
|
||||
|
||||
if (stripos($column->name, 'email') !== false) {
|
||||
return 'email';
|
||||
}
|
||||
|
||||
if (preg_match('/(\b|[_-])url(\b|[_-])/i', $column->name)) {
|
||||
return 'url';
|
||||
}
|
||||
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates validation rules for the search model.
|
||||
* @return array the generated validation rules
|
||||
*/
|
||||
public function generateSearchRules()
|
||||
{
|
||||
if (($table = $this->getTableSchema()) === false) {
|
||||
return ["[['" . implode("', '", $this->getColumnNames()) . "'], 'safe']"];
|
||||
}
|
||||
$types = [];
|
||||
foreach ($table->columns as $column) {
|
||||
switch ($column->type) {
|
||||
case Schema::TYPE_TINYINT:
|
||||
case Schema::TYPE_SMALLINT:
|
||||
case Schema::TYPE_INTEGER:
|
||||
case Schema::TYPE_BIGINT:
|
||||
$types['integer'][] = $column->name;
|
||||
break;
|
||||
case Schema::TYPE_BOOLEAN:
|
||||
$types['boolean'][] = $column->name;
|
||||
break;
|
||||
case Schema::TYPE_FLOAT:
|
||||
case Schema::TYPE_DOUBLE:
|
||||
case Schema::TYPE_DECIMAL:
|
||||
case Schema::TYPE_MONEY:
|
||||
$types['number'][] = $column->name;
|
||||
break;
|
||||
case Schema::TYPE_DATE:
|
||||
case Schema::TYPE_TIME:
|
||||
case Schema::TYPE_DATETIME:
|
||||
case Schema::TYPE_TIMESTAMP:
|
||||
default:
|
||||
$types['safe'][] = $column->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$rules = [];
|
||||
foreach ($types as $type => $columns) {
|
||||
$rules[] = "[['" . implode("', '", $columns) . "'], '$type']";
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array searchable attributes
|
||||
*/
|
||||
public function getSearchAttributes()
|
||||
{
|
||||
return $this->getColumnNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the attribute labels for the search model.
|
||||
* @return array the generated attribute labels (name => label)
|
||||
*/
|
||||
public function generateSearchLabels()
|
||||
{
|
||||
/* @var $model \yii\base\Model */
|
||||
$model = new $this->modelClass();
|
||||
$attributeLabels = $model->attributeLabels();
|
||||
$labels = [];
|
||||
foreach ($this->getColumnNames() as $name) {
|
||||
if (isset($attributeLabels[$name])) {
|
||||
$labels[$name] = $attributeLabels[$name];
|
||||
} else {
|
||||
if (!strcasecmp($name, 'id')) {
|
||||
$labels[$name] = 'ID';
|
||||
} else {
|
||||
$label = Inflector::camel2words($name);
|
||||
if (!empty($label) && substr_compare($label, ' id', -3, 3, true) === 0) {
|
||||
$label = substr($label, 0, -3) . ' ID';
|
||||
}
|
||||
$labels[$name] = $label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates search conditions
|
||||
* @return array
|
||||
*/
|
||||
public function generateSearchConditions()
|
||||
{
|
||||
$columns = [];
|
||||
if (($table = $this->getTableSchema()) === false) {
|
||||
$class = $this->modelClass;
|
||||
/* @var $model \yii\base\Model */
|
||||
$model = new $class();
|
||||
foreach ($model->attributes() as $attribute) {
|
||||
$columns[$attribute] = 'unknown';
|
||||
}
|
||||
} else {
|
||||
foreach ($table->columns as $column) {
|
||||
$columns[$column->name] = $column->type;
|
||||
}
|
||||
}
|
||||
|
||||
$likeConditions = [];
|
||||
$hashConditions = [];
|
||||
foreach ($columns as $column => $type) {
|
||||
switch ($type) {
|
||||
case Schema::TYPE_TINYINT:
|
||||
case Schema::TYPE_SMALLINT:
|
||||
case Schema::TYPE_INTEGER:
|
||||
case Schema::TYPE_BIGINT:
|
||||
case Schema::TYPE_BOOLEAN:
|
||||
case Schema::TYPE_FLOAT:
|
||||
case Schema::TYPE_DOUBLE:
|
||||
case Schema::TYPE_DECIMAL:
|
||||
case Schema::TYPE_MONEY:
|
||||
case Schema::TYPE_DATE:
|
||||
case Schema::TYPE_TIME:
|
||||
case Schema::TYPE_DATETIME:
|
||||
case Schema::TYPE_TIMESTAMP:
|
||||
$hashConditions[] = "'{$column}' => \$this->{$column},";
|
||||
break;
|
||||
default:
|
||||
$likeKeyword = $this->getClassDbDriverName() === 'pgsql' ? 'ilike' : 'like';
|
||||
$likeConditions[] = "->andFilterWhere(['{$likeKeyword}', '{$column}', \$this->{$column}])";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$conditions = [];
|
||||
if (!empty($hashConditions)) {
|
||||
$conditions[] = "\$query->andFilterWhere([\n"
|
||||
. str_repeat(' ', 12) . implode("\n" . str_repeat(' ', 12), $hashConditions)
|
||||
. "\n" . str_repeat(' ', 8) . "]);\n";
|
||||
}
|
||||
if (!empty($likeConditions)) {
|
||||
$conditions[] = "\$query" . implode("\n" . str_repeat(' ', 12), $likeConditions) . ";\n";
|
||||
}
|
||||
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates URL parameters
|
||||
* @return string
|
||||
*/
|
||||
public function generateUrlParams()
|
||||
{
|
||||
/* @var $class ActiveRecord */
|
||||
$class = $this->modelClass;
|
||||
$pks = $class::primaryKey();
|
||||
if (count($pks) === 1) {
|
||||
if (is_subclass_of($class, 'yii\mongodb\ActiveRecord')) {
|
||||
return "'id' => (string)\$model->{$pks[0]}";
|
||||
}
|
||||
|
||||
return "'id' => \$model->{$pks[0]}";
|
||||
}
|
||||
|
||||
$params = [];
|
||||
foreach ($pks as $pk) {
|
||||
if (is_subclass_of($class, 'yii\mongodb\ActiveRecord')) {
|
||||
$params[] = "'$pk' => (string)\$model->$pk";
|
||||
} else {
|
||||
$params[] = "'$pk' => \$model->$pk";
|
||||
}
|
||||
}
|
||||
|
||||
return implode(', ', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates action parameters
|
||||
* @return string
|
||||
*/
|
||||
public function generateActionParams()
|
||||
{
|
||||
/* @var $class ActiveRecord */
|
||||
$class = $this->modelClass;
|
||||
$pks = $class::primaryKey();
|
||||
if (count($pks) === 1) {
|
||||
return '$id';
|
||||
}
|
||||
|
||||
return '$' . implode(', $', $pks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates parameter tags for phpdoc
|
||||
* @return array parameter tags for phpdoc
|
||||
*/
|
||||
public function generateActionParamComments()
|
||||
{
|
||||
/* @var $class ActiveRecord */
|
||||
$class = $this->modelClass;
|
||||
$pks = $class::primaryKey();
|
||||
if (($table = $this->getTableSchema()) === false) {
|
||||
$params = [];
|
||||
foreach ($pks as $pk) {
|
||||
$params[] = '@param ' . (strtolower(substr($pk, -2)) === 'id' ? 'integer' : 'string') . ' $' . $pk;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
if (count($pks) === 1) {
|
||||
return ['@param ' . $table->columns[$pks[0]]->phpType . ' $id'];
|
||||
}
|
||||
|
||||
$params = [];
|
||||
foreach ($pks as $pk) {
|
||||
$params[] = '@param ' . $table->columns[$pk]->phpType . ' $' . $pk;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns table schema for current model class or false if it is not an active record
|
||||
* @return bool|\yii\db\TableSchema
|
||||
*/
|
||||
public function getTableSchema()
|
||||
{
|
||||
/* @var $class ActiveRecord */
|
||||
$class = $this->modelClass;
|
||||
if (is_subclass_of($class, 'yii\db\ActiveRecord')) {
|
||||
return $class::getTableSchema();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array model column names
|
||||
*/
|
||||
public function getColumnNames()
|
||||
{
|
||||
/* @var $class ActiveRecord */
|
||||
$class = $this->modelClass;
|
||||
if (is_subclass_of($class, 'yii\db\ActiveRecord')) {
|
||||
return $class::getTableSchema()->getColumnNames();
|
||||
}
|
||||
|
||||
/* @var $model \yii\base\Model */
|
||||
$model = new $class();
|
||||
|
||||
return $model->attributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null driver name of modelClass db connection.
|
||||
* In case db is not instance of \yii\db\Connection null will be returned.
|
||||
* @since 2.0.6
|
||||
*/
|
||||
protected function getClassDbDriverName()
|
||||
{
|
||||
/* @var $class ActiveRecord */
|
||||
$class = $this->modelClass;
|
||||
$db = $class::getDb();
|
||||
return $db instanceof \yii\db\Connection ? $db->driverName : null;
|
||||
}
|
||||
}
|
||||
179
vendor/yiisoft/yii2-gii/src/generators/crud/default/controller.php
vendored
Normal file
179
vendor/yiisoft/yii2-gii/src/generators/crud/default/controller.php
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating a CRUD controller class file.
|
||||
*/
|
||||
|
||||
use yii\db\ActiveRecordInterface;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\crud\Generator */
|
||||
|
||||
$controllerClass = StringHelper::basename($generator->controllerClass);
|
||||
$modelClass = StringHelper::basename($generator->modelClass);
|
||||
$searchModelClass = StringHelper::basename($generator->searchModelClass);
|
||||
if ($modelClass === $searchModelClass) {
|
||||
$searchModelAlias = $searchModelClass . 'Search';
|
||||
}
|
||||
|
||||
/* @var $class ActiveRecordInterface */
|
||||
$class = $generator->modelClass;
|
||||
$pks = $class::primaryKey();
|
||||
$urlParams = $generator->generateUrlParams();
|
||||
$actionParams = $generator->generateActionParams();
|
||||
$actionParamComments = $generator->generateActionParamComments();
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
namespace <?= StringHelper::dirname(ltrim($generator->controllerClass, '\\')) ?>;
|
||||
|
||||
use Yii;
|
||||
use <?= ltrim($generator->modelClass, '\\') ?>;
|
||||
<?php if (!empty($generator->searchModelClass)): ?>
|
||||
use <?= ltrim($generator->searchModelClass, '\\') . (isset($searchModelAlias) ? " as $searchModelAlias" : "") ?>;
|
||||
<?php else: ?>
|
||||
use yii\data\ActiveDataProvider;
|
||||
<?php endif; ?>
|
||||
use <?= ltrim($generator->baseControllerClass, '\\') ?>;
|
||||
use yii\web\NotFoundHttpException;
|
||||
use yii\filters\VerbFilter;
|
||||
|
||||
/**
|
||||
* <?= $controllerClass ?> implements the CRUD actions for <?= $modelClass ?> model.
|
||||
*/
|
||||
class <?= $controllerClass ?> extends <?= StringHelper::basename($generator->baseControllerClass) . "\n" ?>
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function behaviors()
|
||||
{
|
||||
return [
|
||||
'verbs' => [
|
||||
'class' => VerbFilter::className(),
|
||||
'actions' => [
|
||||
'delete' => ['POST'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all <?= $modelClass ?> models.
|
||||
* @return mixed
|
||||
*/
|
||||
public function actionIndex()
|
||||
{
|
||||
<?php if (!empty($generator->searchModelClass)): ?>
|
||||
$searchModel = new <?= isset($searchModelAlias) ? $searchModelAlias : $searchModelClass ?>();
|
||||
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
|
||||
|
||||
return $this->render('index', [
|
||||
'searchModel' => $searchModel,
|
||||
'dataProvider' => $dataProvider,
|
||||
]);
|
||||
<?php else: ?>
|
||||
$dataProvider = new ActiveDataProvider([
|
||||
'query' => <?= $modelClass ?>::find(),
|
||||
]);
|
||||
|
||||
return $this->render('index', [
|
||||
'dataProvider' => $dataProvider,
|
||||
]);
|
||||
<?php endif; ?>
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a single <?= $modelClass ?> model.
|
||||
* <?= implode("\n * ", $actionParamComments) . "\n" ?>
|
||||
* @return mixed
|
||||
* @throws NotFoundHttpException if the model cannot be found
|
||||
*/
|
||||
public function actionView(<?= $actionParams ?>)
|
||||
{
|
||||
return $this->render('view', [
|
||||
'model' => $this->findModel(<?= $actionParams ?>),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <?= $modelClass ?> model.
|
||||
* If creation is successful, the browser will be redirected to the 'view' page.
|
||||
* @return mixed
|
||||
*/
|
||||
public function actionCreate()
|
||||
{
|
||||
$model = new <?= $modelClass ?>();
|
||||
|
||||
if ($model->load(Yii::$app->request->post()) && $model->save()) {
|
||||
return $this->redirect(['view', <?= $urlParams ?>]);
|
||||
}
|
||||
|
||||
return $this->render('create', [
|
||||
'model' => $model,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing <?= $modelClass ?> model.
|
||||
* If update is successful, the browser will be redirected to the 'view' page.
|
||||
* <?= implode("\n * ", $actionParamComments) . "\n" ?>
|
||||
* @return mixed
|
||||
* @throws NotFoundHttpException if the model cannot be found
|
||||
*/
|
||||
public function actionUpdate(<?= $actionParams ?>)
|
||||
{
|
||||
$model = $this->findModel(<?= $actionParams ?>);
|
||||
|
||||
if ($model->load(Yii::$app->request->post()) && $model->save()) {
|
||||
return $this->redirect(['view', <?= $urlParams ?>]);
|
||||
}
|
||||
|
||||
return $this->render('update', [
|
||||
'model' => $model,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing <?= $modelClass ?> model.
|
||||
* If deletion is successful, the browser will be redirected to the 'index' page.
|
||||
* <?= implode("\n * ", $actionParamComments) . "\n" ?>
|
||||
* @return mixed
|
||||
* @throws NotFoundHttpException if the model cannot be found
|
||||
*/
|
||||
public function actionDelete(<?= $actionParams ?>)
|
||||
{
|
||||
$this->findModel(<?= $actionParams ?>)->delete();
|
||||
|
||||
return $this->redirect(['index']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the <?= $modelClass ?> model based on its primary key value.
|
||||
* If the model is not found, a 404 HTTP exception will be thrown.
|
||||
* <?= implode("\n * ", $actionParamComments) . "\n" ?>
|
||||
* @return <?= $modelClass ?> the loaded model
|
||||
* @throws NotFoundHttpException if the model cannot be found
|
||||
*/
|
||||
protected function findModel(<?= $actionParams ?>)
|
||||
{
|
||||
<?php
|
||||
if (count($pks) === 1) {
|
||||
$condition = '$id';
|
||||
} else {
|
||||
$condition = [];
|
||||
foreach ($pks as $pk) {
|
||||
$condition[] = "'$pk' => \$$pk";
|
||||
}
|
||||
$condition = '[' . implode(', ', $condition) . ']';
|
||||
}
|
||||
?>
|
||||
if (($model = <?= $modelClass ?>::findOne(<?= $condition ?>)) !== null) {
|
||||
return $model;
|
||||
}
|
||||
|
||||
throw new NotFoundHttpException(<?= $generator->generateString('The requested page does not exist.') ?>);
|
||||
}
|
||||
}
|
||||
87
vendor/yiisoft/yii2-gii/src/generators/crud/default/search.php
vendored
Normal file
87
vendor/yiisoft/yii2-gii/src/generators/crud/default/search.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating CRUD search class of the specified model.
|
||||
*/
|
||||
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\crud\Generator */
|
||||
|
||||
$modelClass = StringHelper::basename($generator->modelClass);
|
||||
$searchModelClass = StringHelper::basename($generator->searchModelClass);
|
||||
if ($modelClass === $searchModelClass) {
|
||||
$modelAlias = $modelClass . 'Model';
|
||||
}
|
||||
$rules = $generator->generateSearchRules();
|
||||
$labels = $generator->generateSearchLabels();
|
||||
$searchAttributes = $generator->getSearchAttributes();
|
||||
$searchConditions = $generator->generateSearchConditions();
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
namespace <?= StringHelper::dirname(ltrim($generator->searchModelClass, '\\')) ?>;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Model;
|
||||
use yii\data\ActiveDataProvider;
|
||||
use <?= ltrim($generator->modelClass, '\\') . (isset($modelAlias) ? " as $modelAlias" : "") ?>;
|
||||
|
||||
/**
|
||||
* <?= $searchModelClass ?> represents the model behind the search form of `<?= $generator->modelClass ?>`.
|
||||
*/
|
||||
class <?= $searchModelClass ?> extends <?= isset($modelAlias) ? $modelAlias : $modelClass ?>
|
||||
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
<?= implode(",\n ", $rules) ?>,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function scenarios()
|
||||
{
|
||||
// bypass scenarios() implementation in the parent class
|
||||
return Model::scenarios();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates data provider instance with search query applied
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return ActiveDataProvider
|
||||
*/
|
||||
public function search($params)
|
||||
{
|
||||
$query = <?= isset($modelAlias) ? $modelAlias : $modelClass ?>::find();
|
||||
|
||||
// add conditions that should always apply here
|
||||
|
||||
$dataProvider = new ActiveDataProvider([
|
||||
'query' => $query,
|
||||
]);
|
||||
|
||||
$this->load($params);
|
||||
|
||||
if (!$this->validate()) {
|
||||
// uncomment the following line if you do not want to return any records when validation fails
|
||||
// $query->where('0=1');
|
||||
return $dataProvider;
|
||||
}
|
||||
|
||||
// grid filtering conditions
|
||||
<?= implode("\n ", $searchConditions) ?>
|
||||
|
||||
return $dataProvider;
|
||||
}
|
||||
}
|
||||
42
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/_form.php
vendored
Normal file
42
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/_form.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use yii\helpers\Inflector;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\crud\Generator */
|
||||
|
||||
/* @var $model \yii\db\ActiveRecord */
|
||||
$model = new $generator->modelClass();
|
||||
$safeAttributes = $model->safeAttributes();
|
||||
if (empty($safeAttributes)) {
|
||||
$safeAttributes = $model->attributes();
|
||||
}
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
use yii\helpers\Html;
|
||||
use yii\widgets\ActiveForm;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $model <?= ltrim($generator->modelClass, '\\') ?> */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
?>
|
||||
|
||||
<div class="<?= Inflector::camel2id(StringHelper::basename($generator->modelClass)) ?>-form">
|
||||
|
||||
<?= "<?php " ?>$form = ActiveForm::begin(); ?>
|
||||
|
||||
<?php foreach ($generator->getColumnNames() as $attribute) {
|
||||
if (in_array($attribute, $safeAttributes)) {
|
||||
echo " <?= " . $generator->generateActiveField($attribute) . " ?>\n\n";
|
||||
}
|
||||
} ?>
|
||||
<div class="form-group">
|
||||
<?= "<?= " ?>Html::submitButton(<?= $generator->generateString('Save') ?>, ['class' => 'btn btn-success']) ?>
|
||||
</div>
|
||||
|
||||
<?= "<?php " ?>ActiveForm::end(); ?>
|
||||
|
||||
</div>
|
||||
49
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/_search.php
vendored
Normal file
49
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/_search.php
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
use yii\helpers\Inflector;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\crud\Generator */
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
use yii\helpers\Html;
|
||||
use yii\widgets\ActiveForm;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $model <?= ltrim($generator->searchModelClass, '\\') ?> */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
?>
|
||||
|
||||
<div class="<?= Inflector::camel2id(StringHelper::basename($generator->modelClass)) ?>-search">
|
||||
|
||||
<?= "<?php " ?>$form = ActiveForm::begin([
|
||||
'action' => ['index'],
|
||||
'method' => 'get',
|
||||
<?php if ($generator->enablePjax): ?>
|
||||
'options' => [
|
||||
'data-pjax' => 1
|
||||
],
|
||||
<?php endif; ?>
|
||||
]); ?>
|
||||
|
||||
<?php
|
||||
$count = 0;
|
||||
foreach ($generator->getColumnNames() as $attribute) {
|
||||
if (++$count < 6) {
|
||||
echo " <?= " . $generator->generateActiveSearchField($attribute) . " ?>\n\n";
|
||||
} else {
|
||||
echo " <?php // echo " . $generator->generateActiveSearchField($attribute) . " ?>\n\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<div class="form-group">
|
||||
<?= "<?= " ?>Html::submitButton(<?= $generator->generateString('Search') ?>, ['class' => 'btn btn-primary']) ?>
|
||||
<?= "<?= " ?>Html::resetButton(<?= $generator->generateString('Reset') ?>, ['class' => 'btn btn-default']) ?>
|
||||
</div>
|
||||
|
||||
<?= "<?php " ?>ActiveForm::end(); ?>
|
||||
|
||||
</div>
|
||||
30
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/create.php
vendored
Normal file
30
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/create.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use yii\helpers\Inflector;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\crud\Generator */
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
use yii\helpers\Html;
|
||||
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $model <?= ltrim($generator->modelClass, '\\') ?> */
|
||||
|
||||
$this->title = <?= $generator->generateString('Create ' . Inflector::camel2words(StringHelper::basename($generator->modelClass))) ?>;
|
||||
$this->params['breadcrumbs'][] = ['label' => <?= $generator->generateString(Inflector::pluralize(Inflector::camel2words(StringHelper::basename($generator->modelClass)))) ?>, 'url' => ['index']];
|
||||
$this->params['breadcrumbs'][] = $this->title;
|
||||
?>
|
||||
<div class="<?= Inflector::camel2id(StringHelper::basename($generator->modelClass)) ?>-create">
|
||||
|
||||
<h1><?= "<?= " ?>Html::encode($this->title) ?></h1>
|
||||
|
||||
<?= "<?= " ?>$this->render('_form', [
|
||||
'model' => $model,
|
||||
]) ?>
|
||||
|
||||
</div>
|
||||
79
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/index.php
vendored
Normal file
79
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/index.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
use yii\helpers\Inflector;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\crud\Generator */
|
||||
|
||||
$urlParams = $generator->generateUrlParams();
|
||||
$nameAttribute = $generator->getNameAttribute();
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
use yii\helpers\Html;
|
||||
use <?= $generator->indexWidgetType === 'grid' ? "yii\\grid\\GridView" : "yii\\widgets\\ListView" ?>;
|
||||
<?= $generator->enablePjax ? 'use yii\widgets\Pjax;' : '' ?>
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
<?= !empty($generator->searchModelClass) ? "/* @var \$searchModel " . ltrim($generator->searchModelClass, '\\') . " */\n" : '' ?>
|
||||
/* @var $dataProvider yii\data\ActiveDataProvider */
|
||||
|
||||
$this->title = <?= $generator->generateString(Inflector::pluralize(Inflector::camel2words(StringHelper::basename($generator->modelClass)))) ?>;
|
||||
$this->params['breadcrumbs'][] = $this->title;
|
||||
?>
|
||||
<div class="<?= Inflector::camel2id(StringHelper::basename($generator->modelClass)) ?>-index">
|
||||
|
||||
<h1><?= "<?= " ?>Html::encode($this->title) ?></h1>
|
||||
<?= $generator->enablePjax ? " <?php Pjax::begin(); ?>\n" : '' ?>
|
||||
<?php if(!empty($generator->searchModelClass)): ?>
|
||||
<?= " <?php " . ($generator->indexWidgetType === 'grid' ? "// " : "") ?>echo $this->render('_search', ['model' => $searchModel]); ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<p>
|
||||
<?= "<?= " ?>Html::a(<?= $generator->generateString('Create ' . Inflector::camel2words(StringHelper::basename($generator->modelClass))) ?>, ['create'], ['class' => 'btn btn-success']) ?>
|
||||
</p>
|
||||
|
||||
<?php if ($generator->indexWidgetType === 'grid'): ?>
|
||||
<?= "<?= " ?>GridView::widget([
|
||||
'dataProvider' => $dataProvider,
|
||||
<?= !empty($generator->searchModelClass) ? "'filterModel' => \$searchModel,\n 'columns' => [\n" : "'columns' => [\n"; ?>
|
||||
['class' => 'yii\grid\SerialColumn'],
|
||||
|
||||
<?php
|
||||
$count = 0;
|
||||
if (($tableSchema = $generator->getTableSchema()) === false) {
|
||||
foreach ($generator->getColumnNames() as $name) {
|
||||
if (++$count < 6) {
|
||||
echo " '" . $name . "',\n";
|
||||
} else {
|
||||
echo " //'" . $name . "',\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($tableSchema->columns as $column) {
|
||||
$format = $generator->generateColumnFormat($column);
|
||||
if (++$count < 6) {
|
||||
echo " '" . $column->name . ($format === 'text' ? "" : ":" . $format) . "',\n";
|
||||
} else {
|
||||
echo " //'" . $column->name . ($format === 'text' ? "" : ":" . $format) . "',\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
['class' => 'yii\grid\ActionColumn'],
|
||||
],
|
||||
]); ?>
|
||||
<?php else: ?>
|
||||
<?= "<?= " ?>ListView::widget([
|
||||
'dataProvider' => $dataProvider,
|
||||
'itemOptions' => ['class' => 'item'],
|
||||
'itemView' => function ($model, $key, $index, $widget) {
|
||||
return Html::a(Html::encode($model-><?= $nameAttribute ?>), ['view', <?= $urlParams ?>]);
|
||||
},
|
||||
]) ?>
|
||||
<?php endif; ?>
|
||||
<?= $generator->enablePjax ? " <?php Pjax::end(); ?>\n" : '' ?>
|
||||
</div>
|
||||
36
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/update.php
vendored
Normal file
36
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/update.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use yii\helpers\Inflector;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\crud\Generator */
|
||||
|
||||
$urlParams = $generator->generateUrlParams();
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
use yii\helpers\Html;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $model <?= ltrim($generator->modelClass, '\\') ?> */
|
||||
|
||||
$this->title = <?= strtr($generator->generateString('Update ' .
|
||||
Inflector::camel2words(StringHelper::basename($generator->modelClass)) .
|
||||
': {nameAttribute}', ['nameAttribute' => '{nameAttribute}']), [
|
||||
'{nameAttribute}\'' => '\' . $model->' . $generator->getNameAttribute()
|
||||
]) ?>;
|
||||
$this->params['breadcrumbs'][] = ['label' => <?= $generator->generateString(Inflector::pluralize(Inflector::camel2words(StringHelper::basename($generator->modelClass)))) ?>, 'url' => ['index']];
|
||||
$this->params['breadcrumbs'][] = ['label' => $model-><?= $generator->getNameAttribute() ?>, 'url' => ['view', <?= $urlParams ?>]];
|
||||
$this->params['breadcrumbs'][] = <?= $generator->generateString('Update') ?>;
|
||||
?>
|
||||
<div class="<?= Inflector::camel2id(StringHelper::basename($generator->modelClass)) ?>-update">
|
||||
|
||||
<h1><?= '<?= ' ?>Html::encode($this->title) ?></h1>
|
||||
|
||||
<?= '<?= ' ?>$this->render('_form', [
|
||||
'model' => $model,
|
||||
]) ?>
|
||||
|
||||
</div>
|
||||
57
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/view.php
vendored
Normal file
57
vendor/yiisoft/yii2-gii/src/generators/crud/default/views/view.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
use yii\helpers\Inflector;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\crud\Generator */
|
||||
|
||||
$urlParams = $generator->generateUrlParams();
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
use yii\helpers\Html;
|
||||
use yii\widgets\DetailView;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $model <?= ltrim($generator->modelClass, '\\') ?> */
|
||||
|
||||
$this->title = $model-><?= $generator->getNameAttribute() ?>;
|
||||
$this->params['breadcrumbs'][] = ['label' => <?= $generator->generateString(Inflector::pluralize(Inflector::camel2words(StringHelper::basename($generator->modelClass)))) ?>, 'url' => ['index']];
|
||||
$this->params['breadcrumbs'][] = $this->title;
|
||||
?>
|
||||
<div class="<?= Inflector::camel2id(StringHelper::basename($generator->modelClass)) ?>-view">
|
||||
|
||||
<h1><?= "<?= " ?>Html::encode($this->title) ?></h1>
|
||||
|
||||
<p>
|
||||
<?= "<?= " ?>Html::a(<?= $generator->generateString('Update') ?>, ['update', <?= $urlParams ?>], ['class' => 'btn btn-primary']) ?>
|
||||
<?= "<?= " ?>Html::a(<?= $generator->generateString('Delete') ?>, ['delete', <?= $urlParams ?>], [
|
||||
'class' => 'btn btn-danger',
|
||||
'data' => [
|
||||
'confirm' => <?= $generator->generateString('Are you sure you want to delete this item?') ?>,
|
||||
'method' => 'post',
|
||||
],
|
||||
]) ?>
|
||||
</p>
|
||||
|
||||
<?= "<?= " ?>DetailView::widget([
|
||||
'model' => $model,
|
||||
'attributes' => [
|
||||
<?php
|
||||
if (($tableSchema = $generator->getTableSchema()) === false) {
|
||||
foreach ($generator->getColumnNames() as $name) {
|
||||
echo " '" . $name . "',\n";
|
||||
}
|
||||
} else {
|
||||
foreach ($generator->getTableSchema()->columns as $column) {
|
||||
$format = $generator->generateColumnFormat($column);
|
||||
echo " '" . $column->name . ($format === 'text' ? "" : ":" . $format) . "',\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
],
|
||||
]) ?>
|
||||
|
||||
</div>
|
||||
17
vendor/yiisoft/yii2-gii/src/generators/crud/form.php
vendored
Normal file
17
vendor/yiisoft/yii2-gii/src/generators/crud/form.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
/* @var $generator yii\gii\generators\crud\Generator */
|
||||
|
||||
echo $form->field($generator, 'modelClass');
|
||||
echo $form->field($generator, 'searchModelClass');
|
||||
echo $form->field($generator, 'controllerClass');
|
||||
echo $form->field($generator, 'viewPath');
|
||||
echo $form->field($generator, 'baseControllerClass');
|
||||
echo $form->field($generator, 'indexWidgetType')->dropDownList([
|
||||
'grid' => 'GridView',
|
||||
'list' => 'ListView',
|
||||
]);
|
||||
echo $form->field($generator, 'enableI18N')->checkbox();
|
||||
echo $form->field($generator, 'enablePjax')->checkbox();
|
||||
echo $form->field($generator, 'messageCategory');
|
||||
273
vendor/yiisoft/yii2-gii/src/generators/extension/Generator.php
vendored
Normal file
273
vendor/yiisoft/yii2-gii/src/generators/extension/Generator.php
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
<?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;
|
||||
use yii\gii\CodeFile;
|
||||
|
||||
/**
|
||||
* This generator will generate the skeleton files needed by an extension.
|
||||
*
|
||||
* @property string $keywordsArrayJson A json encoded array with the given keywords. This property is
|
||||
* read-only.
|
||||
* @property bool $outputPath The directory that contains the module class. This property is read-only.
|
||||
*
|
||||
* @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, underscores 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, yii2 or yiisoft 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 bool the directory that contains the module class
|
||||
*/
|
||||
public function getOutputPath()
|
||||
{
|
||||
return Yii::getAlias(str_replace('\\', '/', $this->outputPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string a json encoded array with the given keywords
|
||||
*/
|
||||
public function getKeywordsArrayJson()
|
||||
{
|
||||
return json_encode(explode(',', $this->keywords), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
14
vendor/yiisoft/yii2-gii/src/generators/extension/default/AutoloadExample.php
vendored
Normal file
14
vendor/yiisoft/yii2-gii/src/generators/extension/default/AutoloadExample.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= substr($generator->namespace, 0, -1) ?>;
|
||||
|
||||
/**
|
||||
* This is just an example.
|
||||
*/
|
||||
class AutoloadExample extends \yii\base\Widget
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return "Hello!";
|
||||
}
|
||||
}
|
||||
35
vendor/yiisoft/yii2-gii/src/generators/extension/default/README.md
vendored
Normal file
35
vendor/yiisoft/yii2-gii/src/generators/extension/default/README.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?= $generator->title ?>
|
||||
|
||||
<?= str_repeat('=', mb_strlen($generator->title, \Yii::$app->charset)) ?>
|
||||
|
||||
<?= $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::widget(); ?>" ?>
|
||||
```
|
||||
21
vendor/yiisoft/yii2-gii/src/generators/extension/default/composer.json
vendored
Normal file
21
vendor/yiisoft/yii2-gii/src/generators/extension/default/composer.json
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "<?= $generator->vendorName ?>/<?= $generator->packageName ?>",
|
||||
"description": "<?= $generator->description ?>",
|
||||
"type": "<?= $generator->type ?>",
|
||||
"keywords": <?= $generator->keywordsArrayJson ?>,
|
||||
"license": "<?= $generator->license ?>",
|
||||
"authors": [
|
||||
{
|
||||
"name": "<?= $generator->authorName ?>",
|
||||
"email": "<?= $generator->authorEmail ?>"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"yiisoft/yii2": "~2.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"<?= str_replace('\\','\\\\',$generator->namespace) ?>": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
26
vendor/yiisoft/yii2-gii/src/generators/extension/form.php
vendored
Normal file
26
vendor/yiisoft/yii2-gii/src/generators/extension/form.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
/* @var $generator yii\gii\generators\extension\Generator */
|
||||
|
||||
?>
|
||||
<div class="alert alert-info">
|
||||
Please read the
|
||||
<?= \yii\helpers\Html::a('Extension Guidelines', 'http://www.yiiframework.com/doc-2.0/guide-structure-extensions.html', ['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>
|
||||
159
vendor/yiisoft/yii2-gii/src/generators/form/Generator.php
vendored
Normal file
159
vendor/yiisoft/yii2-gii/src/generators/form/Generator.php
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii\generators\form;
|
||||
|
||||
use Yii;
|
||||
use yii\base\Model;
|
||||
use yii\gii\CodeFile;
|
||||
|
||||
/**
|
||||
* This generator will generate an action view file based on the specified model class.
|
||||
*
|
||||
* @property array $modelAttributes List of safe attributes of [[modelClass]]. This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Generator extends \yii\gii\Generator
|
||||
{
|
||||
public $modelClass;
|
||||
public $viewPath = '@app/views';
|
||||
public $viewName;
|
||||
public $scenarioName;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Form Generator';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return 'This generator generates a view script file that displays a form to collect input for the specified model class.';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate()
|
||||
{
|
||||
$files = [];
|
||||
$files[] = new CodeFile(
|
||||
Yii::getAlias($this->viewPath) . '/' . $this->viewName . '.php',
|
||||
$this->render('form.php')
|
||||
);
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return array_merge(parent::rules(), [
|
||||
[['modelClass', 'viewName', 'scenarioName', 'viewPath'], 'filter', 'filter' => 'trim'],
|
||||
[['modelClass', 'viewName', 'viewPath'], 'required'],
|
||||
[['modelClass'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'],
|
||||
[['modelClass'], 'validateClass', 'params' => ['extends' => Model::className()]],
|
||||
[['viewName'], 'match', 'pattern' => '/^\w+[\\-\\/\w]*$/', 'message' => 'Only word characters, dashes and slashes are allowed.'],
|
||||
[['viewPath'], 'match', 'pattern' => '/^@?\w+[\\-\\/\w]*$/', 'message' => 'Only word characters, dashes, slashes and @ are allowed.'],
|
||||
[['viewPath'], 'validateViewPath'],
|
||||
[['scenarioName'], 'match', 'pattern' => '/^[\w\\-]+$/', 'message' => 'Only word characters and dashes are allowed.'],
|
||||
[['enableI18N'], 'boolean'],
|
||||
[['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributeLabels()
|
||||
{
|
||||
return array_merge(parent::attributeLabels(), [
|
||||
'modelClass' => 'Model Class',
|
||||
'viewName' => 'View Name',
|
||||
'viewPath' => 'View Path',
|
||||
'scenarioName' => 'Scenario',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function requiredTemplates()
|
||||
{
|
||||
return ['form.php', 'action.php'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function stickyAttributes()
|
||||
{
|
||||
return array_merge(parent::stickyAttributes(), ['viewPath', 'scenarioName']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hints()
|
||||
{
|
||||
return array_merge(parent::hints(), [
|
||||
'modelClass' => 'This is the model class for collecting the form input. You should provide a fully qualified class name, e.g., <code>app\models\Post</code>.',
|
||||
'viewName' => 'This is the view name with respect to the view path. For example, <code>site/index</code> would generate a <code>site/index.php</code> view file under the view path.',
|
||||
'viewPath' => 'This is the root view path to keep the generated view files. You may provide either a directory or a path alias, e.g., <code>@app/views</code>.',
|
||||
'scenarioName' => 'This is the scenario to be used by the model when collecting the form input. If empty, the default scenario will be used.',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function successMessage()
|
||||
{
|
||||
$code = highlight_string($this->render('action.php'), true);
|
||||
|
||||
return <<<EOD
|
||||
<p>The form has been generated successfully.</p>
|
||||
<p>You may add the following code in an appropriate controller class to invoke the view:</p>
|
||||
<pre>$code</pre>
|
||||
EOD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates [[viewPath]] to make sure it is a valid path or path alias and exists.
|
||||
*/
|
||||
public function validateViewPath()
|
||||
{
|
||||
$path = Yii::getAlias($this->viewPath, false);
|
||||
if ($path === false || !is_dir($path)) {
|
||||
$this->addError('viewPath', 'View path does not exist.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array list of safe attributes of [[modelClass]]
|
||||
*/
|
||||
public function getModelAttributes()
|
||||
{
|
||||
/* @var $model Model */
|
||||
$model = new $this->modelClass();
|
||||
if (!empty($this->scenarioName)) {
|
||||
$model->setScenario($this->scenarioName);
|
||||
}
|
||||
|
||||
return $model->safeAttributes();
|
||||
}
|
||||
}
|
||||
28
vendor/yiisoft/yii2-gii/src/generators/form/default/action.php
vendored
Normal file
28
vendor/yiisoft/yii2-gii/src/generators/form/default/action.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating an action view file.
|
||||
*/
|
||||
|
||||
use yii\helpers\Inflector;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\form\Generator */
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
public function action<?= Inflector::id2camel(trim(basename($generator->viewName), '_')) ?>()
|
||||
{
|
||||
$model = new \<?= ltrim($generator->modelClass, '\\') ?><?= empty($generator->scenarioName) ? "()" : "(['scenario' => '{$generator->scenarioName}'])" ?>;
|
||||
|
||||
if ($model->load(Yii::$app->request->post())) {
|
||||
if ($model->validate()) {
|
||||
// form inputs are valid, do something here
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render('<?= basename($generator->viewName) ?>', [
|
||||
'model' => $model,
|
||||
]);
|
||||
}
|
||||
33
vendor/yiisoft/yii2-gii/src/generators/form/default/form.php
vendored
Normal file
33
vendor/yiisoft/yii2-gii/src/generators/form/default/form.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating an action view file.
|
||||
*/
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\form\Generator */
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
use yii\helpers\Html;
|
||||
use yii\widgets\ActiveForm;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $model <?= ltrim($generator->modelClass, '\\') ?> */
|
||||
/* @var $form ActiveForm */
|
||||
<?= "?>" ?>
|
||||
|
||||
<div class="<?= str_replace('/', '-', trim($generator->viewName, '_')) ?>">
|
||||
|
||||
<?= "<?php " ?>$form = ActiveForm::begin(); ?>
|
||||
|
||||
<?php foreach ($generator->getModelAttributes() as $attribute): ?>
|
||||
<?= "<?= " ?>$form->field($model, '<?= $attribute ?>') ?>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<div class="form-group">
|
||||
<?= "<?= " ?>Html::submitButton(<?= $generator->generateString('Submit') ?>, ['class' => 'btn btn-primary']) ?>
|
||||
</div>
|
||||
<?= "<?php " ?>ActiveForm::end(); ?>
|
||||
|
||||
</div><!-- <?= str_replace('/', '-', trim($generator->viewName, '-')) ?> -->
|
||||
11
vendor/yiisoft/yii2-gii/src/generators/form/form.php
vendored
Normal file
11
vendor/yiisoft/yii2-gii/src/generators/form/form.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
/* @var $generator yii\gii\generators\form\Generator */
|
||||
|
||||
echo $form->field($generator, 'viewName');
|
||||
echo $form->field($generator, 'modelClass');
|
||||
echo $form->field($generator, 'scenarioName');
|
||||
echo $form->field($generator, 'viewPath');
|
||||
echo $form->field($generator, 'enableI18N')->checkbox();
|
||||
echo $form->field($generator, 'messageCategory');
|
||||
936
vendor/yiisoft/yii2-gii/src/generators/model/Generator.php
vendored
Normal file
936
vendor/yiisoft/yii2-gii/src/generators/model/Generator.php
vendored
Normal file
@@ -0,0 +1,936 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii\generators\model;
|
||||
|
||||
use Yii;
|
||||
use yii\db\ActiveQuery;
|
||||
use yii\db\ActiveRecord;
|
||||
use yii\db\Connection;
|
||||
use yii\db\Schema;
|
||||
use yii\db\TableSchema;
|
||||
use yii\gii\CodeFile;
|
||||
use yii\helpers\Inflector;
|
||||
use yii\base\NotSupportedException;
|
||||
|
||||
/**
|
||||
* This generator will generate one or multiple ActiveRecord classes for the specified database table.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Generator extends \yii\gii\Generator
|
||||
{
|
||||
const RELATIONS_NONE = 'none';
|
||||
const RELATIONS_ALL = 'all';
|
||||
const RELATIONS_ALL_INVERSE = 'all-inverse';
|
||||
|
||||
public $db = 'db';
|
||||
public $ns = 'app\models';
|
||||
public $tableName;
|
||||
public $modelClass;
|
||||
public $baseClass = 'yii\db\ActiveRecord';
|
||||
public $generateRelations = self::RELATIONS_ALL;
|
||||
public $generateRelationsFromCurrentSchema = true;
|
||||
public $generateLabelsFromComments = false;
|
||||
public $useTablePrefix = false;
|
||||
public $useSchemaName = true;
|
||||
public $generateQuery = false;
|
||||
public $queryNs = 'app\models';
|
||||
public $queryClass;
|
||||
public $queryBaseClass = 'yii\db\ActiveQuery';
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Model Generator';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return 'This generator generates an ActiveRecord class for the specified database table.';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return array_merge(parent::rules(), [
|
||||
[['db', 'ns', 'tableName', 'modelClass', 'baseClass', 'queryNs', 'queryClass', 'queryBaseClass'], 'filter', 'filter' => 'trim'],
|
||||
[['ns', 'queryNs'], 'filter', 'filter' => function ($value) { return trim($value, '\\'); }],
|
||||
|
||||
[['db', 'ns', 'tableName', 'baseClass', 'queryNs', 'queryBaseClass'], 'required'],
|
||||
[['db', 'modelClass', 'queryClass'], 'match', 'pattern' => '/^\w+$/', 'message' => 'Only word characters are allowed.'],
|
||||
[['ns', 'baseClass', 'queryNs', 'queryBaseClass'], 'match', 'pattern' => '/^[\w\\\\]+$/', 'message' => 'Only word characters and backslashes are allowed.'],
|
||||
[['tableName'], 'match', 'pattern' => '/^([\w ]+\.)?([\w\* ]+)$/', 'message' => 'Only word characters, and optionally spaces, an asterisk and/or a dot are allowed.'],
|
||||
[['db'], 'validateDb'],
|
||||
[['ns', 'queryNs'], 'validateNamespace'],
|
||||
[['tableName'], 'validateTableName'],
|
||||
[['modelClass'], 'validateModelClass', 'skipOnEmpty' => false],
|
||||
[['baseClass'], 'validateClass', 'params' => ['extends' => ActiveRecord::className()]],
|
||||
[['queryBaseClass'], 'validateClass', 'params' => ['extends' => ActiveQuery::className()]],
|
||||
[['generateRelations'], 'in', 'range' => [self::RELATIONS_NONE, self::RELATIONS_ALL, self::RELATIONS_ALL_INVERSE]],
|
||||
[['generateLabelsFromComments', 'useTablePrefix', 'useSchemaName', 'generateQuery', 'generateRelationsFromCurrentSchema'], 'boolean'],
|
||||
[['enableI18N'], 'boolean'],
|
||||
[['messageCategory'], 'validateMessageCategory', 'skipOnEmpty' => false],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributeLabels()
|
||||
{
|
||||
return array_merge(parent::attributeLabels(), [
|
||||
'ns' => 'Namespace',
|
||||
'db' => 'Database Connection ID',
|
||||
'tableName' => 'Table Name',
|
||||
'modelClass' => 'Model Class Name',
|
||||
'baseClass' => 'Base Class',
|
||||
'generateRelations' => 'Generate Relations',
|
||||
'generateRelationsFromCurrentSchema' => 'Generate Relations from Current Schema',
|
||||
'generateLabelsFromComments' => 'Generate Labels from DB Comments',
|
||||
'generateQuery' => 'Generate ActiveQuery',
|
||||
'queryNs' => 'ActiveQuery Namespace',
|
||||
'queryClass' => 'ActiveQuery Class',
|
||||
'queryBaseClass' => 'ActiveQuery Base Class',
|
||||
'useSchemaName' => 'Use Schema Name',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hints()
|
||||
{
|
||||
return array_merge(parent::hints(), [
|
||||
'ns' => 'This is the namespace of the ActiveRecord class to be generated, e.g., <code>app\models</code>',
|
||||
'db' => 'This is the ID of the DB application component.',
|
||||
'tableName' => 'This is the name of the DB table that the new ActiveRecord class is associated with, e.g. <code>post</code>.
|
||||
The table name may consist of the DB schema part if needed, e.g. <code>public.post</code>.
|
||||
The table name may end with asterisk to match multiple table names, e.g. <code>tbl_*</code>
|
||||
will match tables who name starts with <code>tbl_</code>. In this case, multiple ActiveRecord classes
|
||||
will be generated, one for each matching table name; and the class names will be generated from
|
||||
the matching characters. For example, table <code>tbl_post</code> will generate <code>Post</code>
|
||||
class.',
|
||||
'modelClass' => 'This is the name of the ActiveRecord class to be generated. The class name should not contain
|
||||
the namespace part as it is specified in "Namespace". You do not need to specify the class name
|
||||
if "Table Name" ends with asterisk, in which case multiple ActiveRecord classes will be generated.',
|
||||
'baseClass' => 'This is the base class of the new ActiveRecord class. It should be a fully qualified namespaced class name.',
|
||||
'generateRelations' => 'This indicates whether the generator should generate relations based on
|
||||
foreign key constraints it detects in the database. Note that if your database contains too many tables,
|
||||
you may want to uncheck this option to accelerate the code generation process.',
|
||||
'generateRelationsFromCurrentSchema' => 'This indicates whether the generator should generate relations from current schema or from all available schemas.',
|
||||
'generateLabelsFromComments' => 'This indicates whether the generator should generate attribute labels
|
||||
by using the comments of the corresponding DB columns.',
|
||||
'useTablePrefix' => 'This indicates whether the table name returned by the generated ActiveRecord class
|
||||
should consider the <code>tablePrefix</code> setting of the DB connection. For example, if the
|
||||
table name is <code>tbl_post</code> and <code>tablePrefix=tbl_</code>, the ActiveRecord class
|
||||
will return the table name as <code>{{%post}}</code>.',
|
||||
'useSchemaName' => 'This indicates whether to include the schema name in the ActiveRecord class
|
||||
when it\'s auto generated. Only non default schema would be used.',
|
||||
'generateQuery' => 'This indicates whether to generate ActiveQuery for the ActiveRecord class.',
|
||||
'queryNs' => 'This is the namespace of the ActiveQuery class to be generated, e.g., <code>app\models</code>',
|
||||
'queryClass' => 'This is the name of the ActiveQuery class to be generated. The class name should not contain
|
||||
the namespace part as it is specified in "ActiveQuery Namespace". You do not need to specify the class name
|
||||
if "Table Name" ends with asterisk, in which case multiple ActiveQuery classes will be generated.',
|
||||
'queryBaseClass' => 'This is the base class of the new ActiveQuery class. It should be a fully qualified namespaced class name.',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function autoCompleteData()
|
||||
{
|
||||
$db = $this->getDbConnection();
|
||||
if ($db !== null) {
|
||||
return [
|
||||
'tableName' => function () use ($db) {
|
||||
return $db->getSchema()->getTableNames();
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function requiredTemplates()
|
||||
{
|
||||
// @todo make 'query.php' to be required before 2.1 release
|
||||
return ['model.php'/*, 'query.php'*/];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function stickyAttributes()
|
||||
{
|
||||
return array_merge(parent::stickyAttributes(), ['ns', 'db', 'baseClass', 'generateRelations', 'generateLabelsFromComments', 'queryNs', 'queryBaseClass', 'useTablePrefix', 'generateQuery']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the `tablePrefix` property of the DB connection as specified
|
||||
*
|
||||
* @return string
|
||||
* @since 2.0.5
|
||||
* @see getDbConnection
|
||||
*/
|
||||
public function getTablePrefix()
|
||||
{
|
||||
$db = $this->getDbConnection();
|
||||
if ($db !== null) {
|
||||
return $db->tablePrefix;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate()
|
||||
{
|
||||
$files = [];
|
||||
$relations = $this->generateRelations();
|
||||
$db = $this->getDbConnection();
|
||||
foreach ($this->getTableNames() as $tableName) {
|
||||
// model :
|
||||
$modelClassName = $this->generateClassName($tableName);
|
||||
$queryClassName = ($this->generateQuery) ? $this->generateQueryClassName($modelClassName) : false;
|
||||
$tableSchema = $db->getTableSchema($tableName);
|
||||
$params = [
|
||||
'tableName' => $tableName,
|
||||
'className' => $modelClassName,
|
||||
'queryClassName' => $queryClassName,
|
||||
'tableSchema' => $tableSchema,
|
||||
'properties' => $this->generateProperties($tableSchema),
|
||||
'labels' => $this->generateLabels($tableSchema),
|
||||
'rules' => $this->generateRules($tableSchema),
|
||||
'relations' => isset($relations[$tableName]) ? $relations[$tableName] : [],
|
||||
];
|
||||
$files[] = new CodeFile(
|
||||
Yii::getAlias('@' . str_replace('\\', '/', $this->ns)) . '/' . $modelClassName . '.php',
|
||||
$this->render('model.php', $params)
|
||||
);
|
||||
|
||||
// query :
|
||||
if ($queryClassName) {
|
||||
$params['className'] = $queryClassName;
|
||||
$params['modelClassName'] = $modelClassName;
|
||||
$files[] = new CodeFile(
|
||||
Yii::getAlias('@' . str_replace('\\', '/', $this->queryNs)) . '/' . $queryClassName . '.php',
|
||||
$this->render('query.php', $params)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the properties for the specified table.
|
||||
* @param \yii\db\TableSchema $table the table schema
|
||||
* @return array the generated properties (property => type)
|
||||
* @since 2.0.6
|
||||
*/
|
||||
protected function generateProperties($table)
|
||||
{
|
||||
$properties = [];
|
||||
foreach ($table->columns as $column) {
|
||||
$columnPhpType = $column->phpType;
|
||||
if ($columnPhpType === 'integer') {
|
||||
$type = 'int';
|
||||
} elseif ($columnPhpType === 'boolean') {
|
||||
$type = 'bool';
|
||||
} else {
|
||||
$type = $columnPhpType;
|
||||
}
|
||||
$properties[$column->name] = [
|
||||
'type' => $type,
|
||||
'name' => $column->name,
|
||||
'comment' => $column->comment,
|
||||
];
|
||||
}
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the attribute labels for the specified table.
|
||||
* @param \yii\db\TableSchema $table the table schema
|
||||
* @return array the generated attribute labels (name => label)
|
||||
*/
|
||||
public function generateLabels($table)
|
||||
{
|
||||
$labels = [];
|
||||
foreach ($table->columns as $column) {
|
||||
if ($this->generateLabelsFromComments && !empty($column->comment)) {
|
||||
$labels[$column->name] = $column->comment;
|
||||
} elseif (!strcasecmp($column->name, 'id')) {
|
||||
$labels[$column->name] = 'ID';
|
||||
} else {
|
||||
$label = Inflector::camel2words($column->name);
|
||||
if (!empty($label) && substr_compare($label, ' id', -3, 3, true) === 0) {
|
||||
$label = substr($label, 0, -3) . ' ID';
|
||||
}
|
||||
$labels[$column->name] = $label;
|
||||
}
|
||||
}
|
||||
|
||||
return $labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates validation rules for the specified table.
|
||||
* @param \yii\db\TableSchema $table the table schema
|
||||
* @return array the generated validation rules
|
||||
*/
|
||||
public function generateRules($table)
|
||||
{
|
||||
$types = [];
|
||||
$lengths = [];
|
||||
foreach ($table->columns as $column) {
|
||||
if ($column->autoIncrement) {
|
||||
continue;
|
||||
}
|
||||
if (!$column->allowNull && $column->defaultValue === null) {
|
||||
$types['required'][] = $column->name;
|
||||
}
|
||||
switch ($column->type) {
|
||||
case Schema::TYPE_SMALLINT:
|
||||
case Schema::TYPE_INTEGER:
|
||||
case Schema::TYPE_BIGINT:
|
||||
case Schema::TYPE_TINYINT:
|
||||
$types['integer'][] = $column->name;
|
||||
break;
|
||||
case Schema::TYPE_BOOLEAN:
|
||||
$types['boolean'][] = $column->name;
|
||||
break;
|
||||
case Schema::TYPE_FLOAT:
|
||||
case Schema::TYPE_DOUBLE:
|
||||
case Schema::TYPE_DECIMAL:
|
||||
case Schema::TYPE_MONEY:
|
||||
$types['number'][] = $column->name;
|
||||
break;
|
||||
case Schema::TYPE_DATE:
|
||||
case Schema::TYPE_TIME:
|
||||
case Schema::TYPE_DATETIME:
|
||||
case Schema::TYPE_TIMESTAMP:
|
||||
case Schema::TYPE_JSON:
|
||||
$types['safe'][] = $column->name;
|
||||
break;
|
||||
default: // strings
|
||||
if ($column->size > 0) {
|
||||
$lengths[$column->size][] = $column->name;
|
||||
} else {
|
||||
$types['string'][] = $column->name;
|
||||
}
|
||||
}
|
||||
}
|
||||
$rules = [];
|
||||
$driverName = $this->getDbDriverName();
|
||||
foreach ($types as $type => $columns) {
|
||||
if ($driverName === 'pgsql' && $type === 'integer') {
|
||||
$rules[] = "[['" . implode("', '", $columns) . "'], 'default', 'value' => null]";
|
||||
}
|
||||
$rules[] = "[['" . implode("', '", $columns) . "'], '$type']";
|
||||
}
|
||||
foreach ($lengths as $length => $columns) {
|
||||
$rules[] = "[['" . implode("', '", $columns) . "'], 'string', 'max' => $length]";
|
||||
}
|
||||
|
||||
$db = $this->getDbConnection();
|
||||
|
||||
// Unique indexes rules
|
||||
try {
|
||||
$uniqueIndexes = array_merge($db->getSchema()->findUniqueIndexes($table), [$table->primaryKey]);
|
||||
$uniqueIndexes = array_unique($uniqueIndexes, SORT_REGULAR);
|
||||
foreach ($uniqueIndexes as $uniqueColumns) {
|
||||
// Avoid validating auto incremental columns
|
||||
if (!$this->isColumnAutoIncremental($table, $uniqueColumns)) {
|
||||
$attributesCount = count($uniqueColumns);
|
||||
|
||||
if ($attributesCount === 1) {
|
||||
$rules[] = "[['" . $uniqueColumns[0] . "'], 'unique']";
|
||||
} elseif ($attributesCount > 1) {
|
||||
$columnsList = implode("', '", $uniqueColumns);
|
||||
$rules[] = "[['$columnsList'], 'unique', 'targetAttribute' => ['$columnsList']]";
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NotSupportedException $e) {
|
||||
// doesn't support unique indexes information...do nothing
|
||||
}
|
||||
|
||||
// Exist rules for foreign keys
|
||||
foreach ($table->foreignKeys as $refs) {
|
||||
$refTable = $refs[0];
|
||||
$refTableSchema = $db->getTableSchema($refTable);
|
||||
if ($refTableSchema === null) {
|
||||
// Foreign key could point to non-existing table: https://github.com/yiisoft/yii2-gii/issues/34
|
||||
continue;
|
||||
}
|
||||
$refClassName = $this->generateClassName($refTable);
|
||||
unset($refs[0]);
|
||||
$attributes = implode("', '", array_keys($refs));
|
||||
$targetAttributes = [];
|
||||
foreach ($refs as $key => $value) {
|
||||
$targetAttributes[] = "'$key' => '$value'";
|
||||
}
|
||||
$targetAttributes = implode(', ', $targetAttributes);
|
||||
$rules[] = "[['$attributes'], 'exist', 'skipOnError' => true, 'targetClass' => $refClassName::className(), 'targetAttribute' => [$targetAttributes]]";
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates relations using a junction table by adding an extra viaTable().
|
||||
* @param \yii\db\TableSchema the table being checked
|
||||
* @param array $fks obtained from the checkJunctionTable() method
|
||||
* @param array $relations
|
||||
* @return array modified $relations
|
||||
*/
|
||||
private function generateManyManyRelations($table, $fks, $relations)
|
||||
{
|
||||
$db = $this->getDbConnection();
|
||||
|
||||
foreach ($fks as $pair) {
|
||||
list($firstKey, $secondKey) = $pair;
|
||||
$table0 = $firstKey[0];
|
||||
$table1 = $secondKey[0];
|
||||
unset($firstKey[0], $secondKey[0]);
|
||||
$className0 = $this->generateClassName($table0);
|
||||
$className1 = $this->generateClassName($table1);
|
||||
$table0Schema = $db->getTableSchema($table0);
|
||||
$table1Schema = $db->getTableSchema($table1);
|
||||
|
||||
// @see https://github.com/yiisoft/yii2-gii/issues/166
|
||||
if ($table0Schema === null || $table1Schema === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$link = $this->generateRelationLink(array_flip($secondKey));
|
||||
$viaLink = $this->generateRelationLink($firstKey);
|
||||
$relationName = $this->generateRelationName($relations, $table0Schema, key($secondKey), true);
|
||||
$relations[$table0Schema->fullName][$relationName] = [
|
||||
"return \$this->hasMany($className1::className(), $link)->viaTable('"
|
||||
. $this->generateTableName($table->name) . "', $viaLink);",
|
||||
$className1,
|
||||
true,
|
||||
];
|
||||
|
||||
$link = $this->generateRelationLink(array_flip($firstKey));
|
||||
$viaLink = $this->generateRelationLink($secondKey);
|
||||
$relationName = $this->generateRelationName($relations, $table1Schema, key($firstKey), true);
|
||||
$relations[$table1Schema->fullName][$relationName] = [
|
||||
"return \$this->hasMany($className0::className(), $link)->viaTable('"
|
||||
. $this->generateTableName($table->name) . "', $viaLink);",
|
||||
$className0,
|
||||
true,
|
||||
];
|
||||
}
|
||||
|
||||
return $relations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] all db schema names or an array with a single empty string
|
||||
* @throws NotSupportedException
|
||||
* @since 2.0.5
|
||||
*/
|
||||
protected function getSchemaNames()
|
||||
{
|
||||
$db = $this->getDbConnection();
|
||||
|
||||
if ($this->generateRelationsFromCurrentSchema) {
|
||||
if ($db->schema->defaultSchema !== null) {
|
||||
return [$db->schema->defaultSchema];
|
||||
}
|
||||
return [''];
|
||||
}
|
||||
|
||||
$schema = $db->getSchema();
|
||||
if ($schema->hasMethod('getSchemaNames')) { // keep BC to Yii versions < 2.0.4
|
||||
try {
|
||||
$schemaNames = $schema->getSchemaNames();
|
||||
} catch (NotSupportedException $e) {
|
||||
// schema names are not supported by schema
|
||||
}
|
||||
}
|
||||
if (!isset($schemaNames)) {
|
||||
if (($pos = strpos($this->tableName, '.')) !== false) {
|
||||
$schemaNames = [substr($this->tableName, 0, $pos)];
|
||||
} else {
|
||||
$schemaNames = [''];
|
||||
}
|
||||
}
|
||||
return $schemaNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array the generated relation declarations
|
||||
*/
|
||||
protected function generateRelations()
|
||||
{
|
||||
if ($this->generateRelations === self::RELATIONS_NONE) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$db = $this->getDbConnection();
|
||||
$relations = [];
|
||||
$schemaNames = $this->getSchemaNames();
|
||||
foreach ($schemaNames as $schemaName) {
|
||||
foreach ($db->getSchema()->getTableSchemas($schemaName) as $table) {
|
||||
$className = $this->generateClassName($table->fullName);
|
||||
foreach ($table->foreignKeys as $refs) {
|
||||
$refTable = $refs[0];
|
||||
$refTableSchema = $db->getTableSchema($refTable);
|
||||
if ($refTableSchema === null) {
|
||||
// Foreign key could point to non-existing table: https://github.com/yiisoft/yii2-gii/issues/34
|
||||
continue;
|
||||
}
|
||||
unset($refs[0]);
|
||||
$fks = array_keys($refs);
|
||||
$refClassName = $this->generateClassName($refTable);
|
||||
|
||||
// Add relation for this table
|
||||
$link = $this->generateRelationLink(array_flip($refs));
|
||||
$relationName = $this->generateRelationName($relations, $table, $fks[0], false);
|
||||
$relations[$table->fullName][$relationName] = [
|
||||
"return \$this->hasOne($refClassName::className(), $link);",
|
||||
$refClassName,
|
||||
false,
|
||||
];
|
||||
|
||||
// Add relation for the referenced table
|
||||
$hasMany = $this->isHasManyRelation($table, $fks);
|
||||
$link = $this->generateRelationLink($refs);
|
||||
$relationName = $this->generateRelationName($relations, $refTableSchema, $className, $hasMany);
|
||||
$relations[$refTableSchema->fullName][$relationName] = [
|
||||
"return \$this->" . ($hasMany ? 'hasMany' : 'hasOne') . "($className::className(), $link);",
|
||||
$className,
|
||||
$hasMany,
|
||||
];
|
||||
}
|
||||
|
||||
if (($junctionFks = $this->checkJunctionTable($table)) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$relations = $this->generateManyManyRelations($table, $junctionFks, $relations);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->generateRelations === self::RELATIONS_ALL_INVERSE) {
|
||||
return $this->addInverseRelations($relations);
|
||||
}
|
||||
|
||||
return $relations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds inverse relations
|
||||
*
|
||||
* @param array $relations relation declarations
|
||||
* @return array relation declarations extended with inverse relation names
|
||||
* @since 2.0.5
|
||||
*/
|
||||
protected function addInverseRelations($relations)
|
||||
{
|
||||
$db = $this->getDbConnection();
|
||||
$relationNames = [];
|
||||
|
||||
$schemaNames = $this->getSchemaNames();
|
||||
foreach ($schemaNames as $schemaName) {
|
||||
foreach ($db->schema->getTableSchemas($schemaName) as $table) {
|
||||
$className = $this->generateClassName($table->fullName);
|
||||
foreach ($table->foreignKeys as $refs) {
|
||||
$refTable = $refs[0];
|
||||
$refTableSchema = $db->getTableSchema($refTable);
|
||||
if ($refTableSchema === null) {
|
||||
// Foreign key could point to non-existing table: https://github.com/yiisoft/yii2-gii/issues/34
|
||||
continue;
|
||||
}
|
||||
unset($refs[0]);
|
||||
$fks = array_keys($refs);
|
||||
|
||||
$leftRelationName = $this->generateRelationName($relationNames, $table, $fks[0], false);
|
||||
$relationNames[$table->fullName][$leftRelationName] = true;
|
||||
$hasMany = $this->isHasManyRelation($table, $fks);
|
||||
$rightRelationName = $this->generateRelationName(
|
||||
$relationNames,
|
||||
$refTableSchema,
|
||||
$className,
|
||||
$hasMany
|
||||
);
|
||||
$relationNames[$refTableSchema->fullName][$rightRelationName] = true;
|
||||
|
||||
$relations[$table->fullName][$leftRelationName][0] =
|
||||
rtrim($relations[$table->fullName][$leftRelationName][0], ';')
|
||||
. "->inverseOf('".lcfirst($rightRelationName)."');";
|
||||
$relations[$refTableSchema->fullName][$rightRelationName][0] =
|
||||
rtrim($relations[$refTableSchema->fullName][$rightRelationName][0], ';')
|
||||
. "->inverseOf('".lcfirst($leftRelationName)."');";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $relations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if relation is of has many type
|
||||
*
|
||||
* @param TableSchema $table
|
||||
* @param array $fks
|
||||
* @return bool
|
||||
* @since 2.0.5
|
||||
*/
|
||||
protected function isHasManyRelation($table, $fks)
|
||||
{
|
||||
$uniqueKeys = [$table->primaryKey];
|
||||
try {
|
||||
$uniqueKeys = array_merge($uniqueKeys, $this->getDbConnection()->getSchema()->findUniqueIndexes($table));
|
||||
} catch (NotSupportedException $e) {
|
||||
// ignore
|
||||
}
|
||||
foreach ($uniqueKeys as $uniqueKey) {
|
||||
if (count(array_diff(array_merge($uniqueKey, $fks), array_intersect($uniqueKey, $fks))) === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the link parameter to be used in generating the relation declaration.
|
||||
* @param array $refs reference constraint
|
||||
* @return string the generated link parameter.
|
||||
*/
|
||||
protected function generateRelationLink($refs)
|
||||
{
|
||||
$pairs = [];
|
||||
foreach ($refs as $a => $b) {
|
||||
$pairs[] = "'$a' => '$b'";
|
||||
}
|
||||
|
||||
return '[' . implode(', ', $pairs) . ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given table is a junction table, that is it has at least one pair of unique foreign keys.
|
||||
* @param \yii\db\TableSchema the table being checked
|
||||
* @return array|bool all unique foreign key pairs if the table is a junction table,
|
||||
* or false if the table is not a junction table.
|
||||
*/
|
||||
protected function checkJunctionTable($table)
|
||||
{
|
||||
if (count($table->foreignKeys) < 2) {
|
||||
return false;
|
||||
}
|
||||
$uniqueKeys = [$table->primaryKey];
|
||||
try {
|
||||
$uniqueKeys = array_merge($uniqueKeys, $this->getDbConnection()->getSchema()->findUniqueIndexes($table));
|
||||
} catch (NotSupportedException $e) {
|
||||
// ignore
|
||||
}
|
||||
$result = [];
|
||||
// find all foreign key pairs that have all columns in an unique constraint
|
||||
$foreignKeys = array_values($table->foreignKeys);
|
||||
$foreignKeysCount = count($foreignKeys);
|
||||
|
||||
for ($i = 0; $i < $foreignKeysCount; $i++) {
|
||||
$firstColumns = $foreignKeys[$i];
|
||||
unset($firstColumns[0]);
|
||||
|
||||
for ($j = $i + 1; $j < $foreignKeysCount; $j++) {
|
||||
$secondColumns = $foreignKeys[$j];
|
||||
unset($secondColumns[0]);
|
||||
|
||||
$fks = array_merge(array_keys($firstColumns), array_keys($secondColumns));
|
||||
foreach ($uniqueKeys as $uniqueKey) {
|
||||
if (count(array_diff(array_merge($uniqueKey, $fks), array_intersect($uniqueKey, $fks))) === 0) {
|
||||
// save the foreign key pair
|
||||
$result[] = [$foreignKeys[$i], $foreignKeys[$j]];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return empty($result) ? false : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a relation name for the specified table and a base name.
|
||||
* @param array $relations the relations being generated currently.
|
||||
* @param \yii\db\TableSchema $table the table schema
|
||||
* @param string $key a base name that the relation name may be generated from
|
||||
* @param bool $multiple whether this is a has-many relation
|
||||
* @return string the relation name
|
||||
*/
|
||||
protected function generateRelationName($relations, $table, $key, $multiple)
|
||||
{
|
||||
static $baseModel;
|
||||
/* @var $baseModel \yii\db\ActiveRecord */
|
||||
if ($baseModel === null) {
|
||||
$baseClass = $this->baseClass;
|
||||
$baseModel = new $baseClass();
|
||||
$baseModel->setAttributes([]);
|
||||
}
|
||||
if (!empty($key) && strcasecmp($key, 'id')) {
|
||||
if (substr_compare($key, 'id', -2, 2, true) === 0) {
|
||||
$key = rtrim(substr($key, 0, -2), '_');
|
||||
} elseif (substr_compare($key, 'id', 0, 2, true) === 0) {
|
||||
$key = ltrim(substr($key, 2, strlen($key)), '_');
|
||||
}
|
||||
}
|
||||
if ($multiple) {
|
||||
$key = Inflector::pluralize($key);
|
||||
}
|
||||
$name = $rawName = Inflector::id2camel($key, '_');
|
||||
$i = 0;
|
||||
while ($baseModel->hasProperty(lcfirst($name))) {
|
||||
$name = $rawName . ($i++);
|
||||
}
|
||||
while (isset($table->columns[lcfirst($name)])) {
|
||||
$name = $rawName . ($i++);
|
||||
}
|
||||
while (isset($relations[$table->fullName][$name])) {
|
||||
$name = $rawName . ($i++);
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the [[db]] attribute.
|
||||
*/
|
||||
public function validateDb()
|
||||
{
|
||||
if (!Yii::$app->has($this->db)) {
|
||||
$this->addError('db', 'There is no application component named "db".');
|
||||
} elseif (!Yii::$app->get($this->db) instanceof Connection) {
|
||||
$this->addError('db', 'The "db" application component must be a DB connection instance.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the namespace.
|
||||
*
|
||||
* @param string $attribute Namespace variable.
|
||||
*/
|
||||
public function validateNamespace($attribute)
|
||||
{
|
||||
$value = $this->$attribute;
|
||||
$value = ltrim($value, '\\');
|
||||
$path = Yii::getAlias('@' . str_replace('\\', '/', $value), false);
|
||||
if ($path === false) {
|
||||
$this->addError($attribute, 'Namespace must be associated with an existing directory.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the [[modelClass]] attribute.
|
||||
*/
|
||||
public function validateModelClass()
|
||||
{
|
||||
if ($this->isReservedKeyword($this->modelClass)) {
|
||||
$this->addError('modelClass', 'Class name cannot be a reserved PHP keyword.');
|
||||
}
|
||||
if ((empty($this->tableName) || substr_compare($this->tableName, '*', -1, 1)) && $this->modelClass == '') {
|
||||
$this->addError('modelClass', 'Model Class cannot be blank if table name does not end with asterisk.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the [[tableName]] attribute.
|
||||
*/
|
||||
public function validateTableName()
|
||||
{
|
||||
if (strpos($this->tableName, '*') !== false && substr_compare($this->tableName, '*', -1, 1)) {
|
||||
$this->addError('tableName', 'Asterisk is only allowed as the last character.');
|
||||
|
||||
return;
|
||||
}
|
||||
$tables = $this->getTableNames();
|
||||
if (empty($tables)) {
|
||||
$this->addError('tableName', "Table '{$this->tableName}' does not exist.");
|
||||
} else {
|
||||
foreach ($tables as $table) {
|
||||
$class = $this->generateClassName($table);
|
||||
if ($this->isReservedKeyword($class)) {
|
||||
$this->addError('tableName', "Table '$table' will generate a class which is a reserved PHP keyword.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected $tableNames;
|
||||
protected $classNames;
|
||||
|
||||
/**
|
||||
* @return array the table names that match the pattern specified by [[tableName]].
|
||||
*/
|
||||
protected function getTableNames()
|
||||
{
|
||||
if ($this->tableNames !== null) {
|
||||
return $this->tableNames;
|
||||
}
|
||||
$db = $this->getDbConnection();
|
||||
if ($db === null) {
|
||||
return [];
|
||||
}
|
||||
$tableNames = [];
|
||||
if (strpos($this->tableName, '*') !== false) {
|
||||
if (($pos = strrpos($this->tableName, '.')) !== false) {
|
||||
$schema = substr($this->tableName, 0, $pos);
|
||||
$pattern = '/^' . str_replace('*', '\w+', substr($this->tableName, $pos + 1)) . '$/';
|
||||
} else {
|
||||
$schema = '';
|
||||
$pattern = '/^' . str_replace('*', '\w+', $this->tableName) . '$/';
|
||||
}
|
||||
|
||||
foreach ($db->schema->getTableNames($schema) as $table) {
|
||||
if (preg_match($pattern, $table)) {
|
||||
$tableNames[] = $schema === '' ? $table : ($schema . '.' . $table);
|
||||
}
|
||||
}
|
||||
} elseif (($table = $db->getTableSchema($this->tableName, true)) !== null) {
|
||||
$tableNames[] = $this->tableName;
|
||||
$this->classNames[$this->tableName] = $this->modelClass;
|
||||
}
|
||||
|
||||
return $this->tableNames = $tableNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the table name by considering table prefix.
|
||||
* If [[useTablePrefix]] is false, the table name will be returned without change.
|
||||
* @param string $tableName the table name (which may contain schema prefix)
|
||||
* @return string the generated table name
|
||||
*/
|
||||
public function generateTableName($tableName)
|
||||
{
|
||||
if (!$this->useTablePrefix) {
|
||||
return $tableName;
|
||||
}
|
||||
|
||||
$db = $this->getDbConnection();
|
||||
if (preg_match("/^{$db->tablePrefix}(.*?)$/", $tableName, $matches)) {
|
||||
$tableName = '{{%' . $matches[1] . '}}';
|
||||
} elseif (preg_match("/^(.*?){$db->tablePrefix}$/", $tableName, $matches)) {
|
||||
$tableName = '{{' . $matches[1] . '%}}';
|
||||
}
|
||||
return $tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a class name from the specified table name.
|
||||
* @param string $tableName the table name (which may contain schema prefix)
|
||||
* @param bool $useSchemaName should schema name be included in the class name, if present
|
||||
* @return string the generated class name
|
||||
*/
|
||||
protected function generateClassName($tableName, $useSchemaName = null)
|
||||
{
|
||||
if (isset($this->classNames[$tableName])) {
|
||||
return $this->classNames[$tableName];
|
||||
}
|
||||
|
||||
$schemaName = '';
|
||||
$fullTableName = $tableName;
|
||||
if (($pos = strrpos($tableName, '.')) !== false) {
|
||||
if (($useSchemaName === null && $this->useSchemaName) || $useSchemaName) {
|
||||
$schemaName = substr($tableName, 0, $pos) . '_';
|
||||
}
|
||||
$tableName = substr($tableName, $pos + 1);
|
||||
}
|
||||
|
||||
$db = $this->getDbConnection();
|
||||
$patterns = [];
|
||||
$patterns[] = "/^{$db->tablePrefix}(.*?)$/";
|
||||
$patterns[] = "/^(.*?){$db->tablePrefix}$/";
|
||||
if (strpos($this->tableName, '*') !== false) {
|
||||
$pattern = $this->tableName;
|
||||
if (($pos = strrpos($pattern, '.')) !== false) {
|
||||
$pattern = substr($pattern, $pos + 1);
|
||||
}
|
||||
$patterns[] = '/^' . str_replace('*', '(\w+)', $pattern) . '$/';
|
||||
}
|
||||
$className = $tableName;
|
||||
foreach ($patterns as $pattern) {
|
||||
if (preg_match($pattern, $tableName, $matches)) {
|
||||
$className = $matches[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->classNames[$fullTableName] = Inflector::id2camel($schemaName.$className, '_');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a query class name from the specified model class name.
|
||||
* @param string $modelClassName model class name
|
||||
* @return string generated class name
|
||||
*/
|
||||
protected function generateQueryClassName($modelClassName)
|
||||
{
|
||||
$queryClassName = $this->queryClass;
|
||||
if (empty($queryClassName) || strpos($this->tableName, '*') !== false) {
|
||||
$queryClassName = $modelClassName . 'Query';
|
||||
}
|
||||
return $queryClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Connection the DB connection as specified by [[db]].
|
||||
*/
|
||||
protected function getDbConnection()
|
||||
{
|
||||
return Yii::$app->get($this->db, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null driver name of db connection.
|
||||
* In case db is not instance of \yii\db\Connection null will be returned.
|
||||
* @since 2.0.6
|
||||
*/
|
||||
protected function getDbDriverName()
|
||||
{
|
||||
/** @var Connection $db */
|
||||
$db = $this->getDbConnection();
|
||||
return $db instanceof \yii\db\Connection ? $db->driverName : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if any of the specified columns is auto incremental.
|
||||
* @param \yii\db\TableSchema $table the table schema
|
||||
* @param array $columns columns to check for autoIncrement property
|
||||
* @return bool whether any of the specified columns is auto incremental.
|
||||
*/
|
||||
protected function isColumnAutoIncremental($table, $columns)
|
||||
{
|
||||
foreach ($columns as $column) {
|
||||
if (isset($table->columns[$column]) && $table->columns[$column]->autoIncrement) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
100
vendor/yiisoft/yii2-gii/src/generators/model/default/model.php
vendored
Normal file
100
vendor/yiisoft/yii2-gii/src/generators/model/default/model.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating the model class of a specified table.
|
||||
*/
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\model\Generator */
|
||||
/* @var $tableName string full table name */
|
||||
/* @var $className string class name */
|
||||
/* @var $queryClassName string query class name */
|
||||
/* @var $tableSchema yii\db\TableSchema */
|
||||
/* @var $properties array list of properties (property => [type, name. comment]) */
|
||||
/* @var $labels string[] list of attribute labels (name => label) */
|
||||
/* @var $rules string[] list of validation rules */
|
||||
/* @var $relations array list of relations (name => relation declaration) */
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
namespace <?= $generator->ns ?>;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* This is the model class for table "<?= $generator->generateTableName($tableName) ?>".
|
||||
*
|
||||
<?php foreach ($properties as $property => $data): ?>
|
||||
* @property <?= "{$data['type']} \${$property}" . ($data['comment'] ? ' ' . strtr($data['comment'], ["\n" => ' ']) : '') . "\n" ?>
|
||||
<?php endforeach; ?>
|
||||
<?php if (!empty($relations)): ?>
|
||||
*
|
||||
<?php foreach ($relations as $name => $relation): ?>
|
||||
* @property <?= $relation[1] . ($relation[2] ? '[]' : '') . ' $' . lcfirst($name) . "\n" ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
*/
|
||||
class <?= $className ?> extends <?= '\\' . ltrim($generator->baseClass, '\\') . "\n" ?>
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function tableName()
|
||||
{
|
||||
return '<?= $generator->generateTableName($tableName) ?>';
|
||||
}
|
||||
<?php if ($generator->db !== 'db'): ?>
|
||||
|
||||
/**
|
||||
* @return \yii\db\Connection the database connection used by this AR class.
|
||||
*/
|
||||
public static function getDb()
|
||||
{
|
||||
return Yii::$app->get('<?= $generator->db ?>');
|
||||
}
|
||||
<?php endif; ?>
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [<?= empty($rules) ? '' : ("\n " . implode(",\n ", $rules) . ",\n ") ?>];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributeLabels()
|
||||
{
|
||||
return [
|
||||
<?php foreach ($labels as $name => $label): ?>
|
||||
<?= "'$name' => " . $generator->generateString($label) . ",\n" ?>
|
||||
<?php endforeach; ?>
|
||||
];
|
||||
}
|
||||
<?php foreach ($relations as $name => $relation): ?>
|
||||
|
||||
/**
|
||||
* @return \yii\db\ActiveQuery
|
||||
*/
|
||||
public function get<?= $name ?>()
|
||||
{
|
||||
<?= $relation[0] . "\n" ?>
|
||||
}
|
||||
<?php endforeach; ?>
|
||||
<?php if ($queryClassName): ?>
|
||||
<?php
|
||||
$queryClassFullName = ($generator->ns === $generator->queryNs) ? $queryClassName : '\\' . $generator->queryNs . '\\' . $queryClassName;
|
||||
echo "\n";
|
||||
?>
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return <?= $queryClassFullName ?> the active query used by this AR class.
|
||||
*/
|
||||
public static function find()
|
||||
{
|
||||
return new <?= $queryClassFullName ?>(get_called_class());
|
||||
}
|
||||
<?php endif; ?>
|
||||
}
|
||||
56
vendor/yiisoft/yii2-gii/src/generators/model/default/query.php
vendored
Normal file
56
vendor/yiisoft/yii2-gii/src/generators/model/default/query.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating the ActiveQuery class.
|
||||
*/
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\model\Generator */
|
||||
/* @var $tableName string full table name */
|
||||
/* @var $className string class name */
|
||||
/* @var $tableSchema yii\db\TableSchema */
|
||||
/* @var $labels string[] list of attribute labels (name => label) */
|
||||
/* @var $rules string[] list of validation rules */
|
||||
/* @var $relations array list of relations (name => relation declaration) */
|
||||
/* @var $className string class name */
|
||||
/* @var $modelClassName string related model class name */
|
||||
|
||||
$modelFullClassName = $modelClassName;
|
||||
if ($generator->ns !== $generator->queryNs) {
|
||||
$modelFullClassName = '\\' . $generator->ns . '\\' . $modelFullClassName;
|
||||
}
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
namespace <?= $generator->queryNs ?>;
|
||||
|
||||
/**
|
||||
* This is the ActiveQuery class for [[<?= $modelFullClassName ?>]].
|
||||
*
|
||||
* @see <?= $modelFullClassName . "\n" ?>
|
||||
*/
|
||||
class <?= $className ?> extends <?= '\\' . ltrim($generator->queryBaseClass, '\\') . "\n" ?>
|
||||
{
|
||||
/*public function active()
|
||||
{
|
||||
return $this->andWhere('[[status]]=1');
|
||||
}*/
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return <?= $modelFullClassName ?>[]|array
|
||||
*/
|
||||
public function all($db = null)
|
||||
{
|
||||
return parent::all($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @return <?= $modelFullClassName ?>|array|null
|
||||
*/
|
||||
public function one($db = null)
|
||||
{
|
||||
return parent::one($db);
|
||||
}
|
||||
}
|
||||
28
vendor/yiisoft/yii2-gii/src/generators/model/form.php
vendored
Normal file
28
vendor/yiisoft/yii2-gii/src/generators/model/form.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use yii\gii\generators\model\Generator;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
/* @var $generator yii\gii\generators\model\Generator */
|
||||
|
||||
echo $form->field($generator, 'tableName')->textInput(['table_prefix' => $generator->getTablePrefix()]);
|
||||
echo $form->field($generator, 'modelClass');
|
||||
echo $form->field($generator, 'ns');
|
||||
echo $form->field($generator, 'baseClass');
|
||||
echo $form->field($generator, 'db');
|
||||
echo $form->field($generator, 'useTablePrefix')->checkbox();
|
||||
echo $form->field($generator, 'generateRelations')->dropDownList([
|
||||
Generator::RELATIONS_NONE => 'No relations',
|
||||
Generator::RELATIONS_ALL => 'All relations',
|
||||
Generator::RELATIONS_ALL_INVERSE => 'All relations with inverse',
|
||||
]);
|
||||
echo $form->field($generator, 'generateRelationsFromCurrentSchema')->checkbox();
|
||||
echo $form->field($generator, 'generateLabelsFromComments')->checkbox();
|
||||
echo $form->field($generator, 'generateQuery')->checkbox();
|
||||
echo $form->field($generator, 'queryNs');
|
||||
echo $form->field($generator, 'queryClass');
|
||||
echo $form->field($generator, 'queryBaseClass');
|
||||
echo $form->field($generator, 'enableI18N')->checkbox();
|
||||
echo $form->field($generator, 'messageCategory');
|
||||
echo $form->field($generator, 'useSchemaName')->checkbox();
|
||||
170
vendor/yiisoft/yii2-gii/src/generators/module/Generator.php
vendored
Normal file
170
vendor/yiisoft/yii2-gii/src/generators/module/Generator.php
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\gii\generators\module;
|
||||
|
||||
use yii\gii\CodeFile;
|
||||
use yii\helpers\Html;
|
||||
use Yii;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/**
|
||||
* This generator will generate the skeleton code needed by a module.
|
||||
*
|
||||
* @property string $controllerNamespace The controller namespace of the module. This property is read-only.
|
||||
* @property bool $modulePath The directory that contains the module class. This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Generator extends \yii\gii\Generator
|
||||
{
|
||||
public $moduleClass;
|
||||
public $moduleID;
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Module Generator';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return 'This generator helps you to generate the skeleton code needed by a Yii module.';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return array_merge(parent::rules(), [
|
||||
[['moduleID', 'moduleClass'], 'filter', 'filter' => 'trim'],
|
||||
[['moduleID', 'moduleClass'], 'required'],
|
||||
[['moduleID'], 'match', 'pattern' => '/^[\w\\-]+$/', 'message' => 'Only word characters and dashes are allowed.'],
|
||||
[['moduleClass'], 'match', 'pattern' => '/^[\w\\\\]*$/', 'message' => 'Only word characters and backslashes are allowed.'],
|
||||
[['moduleClass'], 'validateModuleClass'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributeLabels()
|
||||
{
|
||||
return [
|
||||
'moduleID' => 'Module ID',
|
||||
'moduleClass' => 'Module Class',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hints()
|
||||
{
|
||||
return [
|
||||
'moduleID' => 'This refers to the ID of the module, e.g., <code>admin</code>.',
|
||||
'moduleClass' => 'This is the fully qualified class name of the module, e.g., <code>app\modules\admin\Module</code>.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function successMessage()
|
||||
{
|
||||
if (Yii::$app->hasModule($this->moduleID)) {
|
||||
$link = Html::a('try it now', Yii::$app->getUrlManager()->createUrl($this->moduleID), ['target' => '_blank']);
|
||||
|
||||
return "The module has been generated successfully. You may $link.";
|
||||
}
|
||||
|
||||
$output = <<<EOD
|
||||
<p>The module has been generated successfully.</p>
|
||||
<p>To access the module, you need to add this to your application configuration:</p>
|
||||
EOD;
|
||||
$code = <<<EOD
|
||||
<?php
|
||||
......
|
||||
'modules' => [
|
||||
'{$this->moduleID}' => [
|
||||
'class' => '{$this->moduleClass}',
|
||||
],
|
||||
],
|
||||
......
|
||||
EOD;
|
||||
|
||||
return $output . '<pre>' . highlight_string($code, true) . '</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function requiredTemplates()
|
||||
{
|
||||
return ['module.php', 'controller.php', 'view.php'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate()
|
||||
{
|
||||
$files = [];
|
||||
$modulePath = $this->getModulePath();
|
||||
$files[] = new CodeFile(
|
||||
$modulePath . '/' . StringHelper::basename($this->moduleClass) . '.php',
|
||||
$this->render("module.php")
|
||||
);
|
||||
$files[] = new CodeFile(
|
||||
$modulePath . '/controllers/DefaultController.php',
|
||||
$this->render("controller.php")
|
||||
);
|
||||
$files[] = new CodeFile(
|
||||
$modulePath . '/views/default/index.php',
|
||||
$this->render("view.php")
|
||||
);
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates [[moduleClass]] to make sure it is a fully qualified class name.
|
||||
*/
|
||||
public function validateModuleClass()
|
||||
{
|
||||
if (strpos($this->moduleClass, '\\') === false || Yii::getAlias('@' . str_replace('\\', '/', $this->moduleClass), false) === false) {
|
||||
$this->addError('moduleClass', 'Module class must be properly namespaced.');
|
||||
}
|
||||
if (empty($this->moduleClass) || substr_compare($this->moduleClass, '\\', -1, 1) === 0) {
|
||||
$this->addError('moduleClass', 'Module class name must not be empty. Please enter a fully qualified class name. e.g. "app\\modules\\admin\\Module".');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool the directory that contains the module class
|
||||
*/
|
||||
public function getModulePath()
|
||||
{
|
||||
return Yii::getAlias('@' . str_replace('\\', '/', substr($this->moduleClass, 0, strrpos($this->moduleClass, '\\'))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the controller namespace of the module.
|
||||
*/
|
||||
public function getControllerNamespace()
|
||||
{
|
||||
return substr($this->moduleClass, 0, strrpos($this->moduleClass, '\\')) . '\controllers';
|
||||
}
|
||||
}
|
||||
29
vendor/yiisoft/yii2-gii/src/generators/module/default/controller.php
vendored
Normal file
29
vendor/yiisoft/yii2-gii/src/generators/module/default/controller.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating a controller class within a module.
|
||||
*/
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\module\Generator */
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
namespace <?= $generator->getControllerNamespace() ?>;
|
||||
|
||||
use yii\web\Controller;
|
||||
|
||||
/**
|
||||
* Default controller for the `<?= $generator->moduleID ?>` module
|
||||
*/
|
||||
class DefaultController extends Controller
|
||||
{
|
||||
/**
|
||||
* Renders the index view for the module
|
||||
* @return string
|
||||
*/
|
||||
public function actionIndex()
|
||||
{
|
||||
return $this->render('index');
|
||||
}
|
||||
}
|
||||
38
vendor/yiisoft/yii2-gii/src/generators/module/default/module.php
vendored
Normal file
38
vendor/yiisoft/yii2-gii/src/generators/module/default/module.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* This is the template for generating a module class file.
|
||||
*/
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\module\Generator */
|
||||
|
||||
$className = $generator->moduleClass;
|
||||
$pos = strrpos($className, '\\');
|
||||
$ns = ltrim(substr($className, 0, $pos), '\\');
|
||||
$className = substr($className, $pos + 1);
|
||||
|
||||
echo "<?php\n";
|
||||
?>
|
||||
|
||||
namespace <?= $ns ?>;
|
||||
|
||||
/**
|
||||
* <?= $generator->moduleID ?> module definition class
|
||||
*/
|
||||
class <?= $className ?> extends \yii\base\Module
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public $controllerNamespace = '<?= $generator->getControllerNamespace() ?>';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
// custom initialization code goes here
|
||||
}
|
||||
}
|
||||
16
vendor/yiisoft/yii2-gii/src/generators/module/default/view.php
vendored
Normal file
16
vendor/yiisoft/yii2-gii/src/generators/module/default/view.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\generators\module\Generator */
|
||||
?>
|
||||
<div class="<?= $generator->moduleID . '-default-index' ?>">
|
||||
<h1><?= "<?= " ?>$this->context->action->uniqueId ?></h1>
|
||||
<p>
|
||||
This is the view content for action "<?= "<?= " ?>$this->context->action->id ?>".
|
||||
The action belongs to the controller "<?= "<?= " ?>get_class($this->context) ?>"
|
||||
in the "<?= "<?= " ?>$this->context->module->id ?>" module.
|
||||
</p>
|
||||
<p>
|
||||
You may customize this page by editing the following file:<br>
|
||||
<code><?= "<?= " ?>__FILE__ ?></code>
|
||||
</p>
|
||||
</div>
|
||||
12
vendor/yiisoft/yii2-gii/src/generators/module/form.php
vendored
Normal file
12
vendor/yiisoft/yii2-gii/src/generators/module/form.php
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
/* @var $generator yii\gii\generators\module\Generator */
|
||||
|
||||
?>
|
||||
<div class="module-form">
|
||||
<?php
|
||||
echo $form->field($generator, 'moduleClass');
|
||||
echo $form->field($generator, 'moduleID');
|
||||
?>
|
||||
</div>
|
||||
13
vendor/yiisoft/yii2-gii/src/views/default/diff.php
vendored
Normal file
13
vendor/yiisoft/yii2-gii/src/views/default/diff.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $diff mixed */
|
||||
?>
|
||||
<div class="default-diff">
|
||||
<?php if ($diff === false): ?>
|
||||
<div class="alert alert-danger">Diff is not supported for this file type.</div>
|
||||
<?php elseif (empty($diff)): ?>
|
||||
<div class="alert alert-success">Identical.</div>
|
||||
<?php else: ?>
|
||||
<div class="content"><?= $diff ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
30
vendor/yiisoft/yii2-gii/src/views/default/index.php
vendored
Normal file
30
vendor/yiisoft/yii2-gii/src/views/default/index.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
use yii\helpers\Html;
|
||||
|
||||
/* @var $this \yii\web\View */
|
||||
/* @var $generators \yii\gii\Generator[] */
|
||||
/* @var $content string */
|
||||
|
||||
$generators = Yii::$app->controller->module->generators;
|
||||
$this->title = 'Welcome to Gii';
|
||||
?>
|
||||
<div class="default-index">
|
||||
<div class="page-header">
|
||||
<h1>Welcome to Gii <small>a magical tool that can write code for you</small></h1>
|
||||
</div>
|
||||
|
||||
<p class="lead">Start the fun with the following code generators:</p>
|
||||
|
||||
<div class="row">
|
||||
<?php foreach ($generators as $id => $generator): ?>
|
||||
<div class="generator col-lg-4">
|
||||
<h3><?= Html::encode($generator->getName()) ?></h3>
|
||||
<p><?= $generator->getDescription() ?></p>
|
||||
<p><?= Html::a('Start »', ['default/view', 'id' => $id], ['class' => 'btn btn-default']) ?></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<p><a class="btn btn-success" href="http://www.yiiframework.com/extensions/?tag=gii">Get More Generators</a></p>
|
||||
|
||||
</div>
|
||||
71
vendor/yiisoft/yii2-gii/src/views/default/view.php
vendored
Normal file
71
vendor/yiisoft/yii2-gii/src/views/default/view.php
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
use yii\helpers\Html;
|
||||
use yii\widgets\ActiveForm;
|
||||
use yii\gii\components\ActiveField;
|
||||
use yii\gii\CodeFile;
|
||||
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\Generator */
|
||||
/* @var $id string panel ID */
|
||||
/* @var $form yii\widgets\ActiveForm */
|
||||
/* @var $results string */
|
||||
/* @var $hasError bool */
|
||||
/* @var $files CodeFile[] */
|
||||
/* @var $answers array */
|
||||
|
||||
$this->title = $generator->getName();
|
||||
$templates = [];
|
||||
foreach ($generator->templates as $name => $path) {
|
||||
$templates[$name] = "$name ($path)";
|
||||
}
|
||||
?>
|
||||
<div class="default-view">
|
||||
<h1><?= Html::encode($this->title) ?></h1>
|
||||
|
||||
<p><?= $generator->getDescription() ?></p>
|
||||
|
||||
<?php $form = ActiveForm::begin([
|
||||
'id' => "$id-generator",
|
||||
'successCssClass' => '',
|
||||
'fieldConfig' => ['class' => ActiveField::className()],
|
||||
]); ?>
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-md-10" id="form-fields">
|
||||
<?= $this->renderFile($generator->formView(), [
|
||||
'generator' => $generator,
|
||||
'form' => $form,
|
||||
]) ?>
|
||||
<?= $form->field($generator, 'template')->sticky()
|
||||
->label('Code Template')
|
||||
->dropDownList($templates)->hint('
|
||||
Please select which set of the templates should be used to generated the code.
|
||||
') ?>
|
||||
<div class="form-group">
|
||||
<?= Html::submitButton('Preview', ['name' => 'preview', 'class' => 'btn btn-primary']) ?>
|
||||
|
||||
<?php if (isset($files)): ?>
|
||||
<?= Html::submitButton('Generate', ['name' => 'generate', 'class' => 'btn btn-success']) ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if (isset($results)) {
|
||||
echo $this->render('view/results', [
|
||||
'generator' => $generator,
|
||||
'results' => $results,
|
||||
'hasError' => $hasError,
|
||||
]);
|
||||
} elseif (isset($files)) {
|
||||
echo $this->render('view/files', [
|
||||
'id' => $id,
|
||||
'generator' => $generator,
|
||||
'files' => $files,
|
||||
'answers' => $answers,
|
||||
]);
|
||||
}
|
||||
?>
|
||||
<?php ActiveForm::end(); ?>
|
||||
</div>
|
||||
121
vendor/yiisoft/yii2-gii/src/views/default/view/files.php
vendored
Normal file
121
vendor/yiisoft/yii2-gii/src/views/default/view/files.php
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
use yii\helpers\Html;
|
||||
use yii\gii\CodeFile;
|
||||
|
||||
/* @var $this \yii\web\View */
|
||||
/* @var $generator \yii\gii\Generator */
|
||||
/* @var $files CodeFile[] */
|
||||
/* @var $answers array */
|
||||
/* @var $id string panel ID */
|
||||
|
||||
?>
|
||||
<div class="default-view-files">
|
||||
<p>Click on the above <code>Generate</code> button to generate the files selected below:</p>
|
||||
|
||||
<div class="row form-group">
|
||||
<div class="col-xs-6">
|
||||
<input id="filter-input" class="form-control" placeholder="Type to filter">
|
||||
</div>
|
||||
<div class="col-xs-6 text-right">
|
||||
<div id="action-toggle" class="btn-group btn-group-xs"">
|
||||
<label class="btn btn-success active" title="Filter files that are created">
|
||||
<input type="checkbox" value="<?= CodeFile::OP_CREATE ?>" checked> Create
|
||||
</label>
|
||||
<label class="btn btn-default active" title="Filter files that are unchanged.">
|
||||
<input type="checkbox" value="<?= CodeFile::OP_SKIP ?>" checked> Unchanged
|
||||
</label>
|
||||
<label class="btn btn-warning active" title="Filter files that are overwritten">
|
||||
<input type="checkbox" value="<?= CodeFile::OP_OVERWRITE ?>" checked> Overwrite
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="file">Code File</th>
|
||||
<th class="action">Action</th>
|
||||
<?php
|
||||
$fileChangeExists = false;
|
||||
foreach ($files as $file) {
|
||||
if ($file->operation !== CodeFile::OP_SKIP) {
|
||||
$fileChangeExists = true;
|
||||
echo '<th><input type="checkbox" id="check-all"></th>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="files-body">
|
||||
<?php foreach ($files as $file): ?>
|
||||
<?php
|
||||
if ($file->operation === CodeFile::OP_OVERWRITE) {
|
||||
$trClass = 'warning';
|
||||
} elseif ($file->operation === CodeFile::OP_SKIP) {
|
||||
$trClass = 'active';
|
||||
} elseif ($file->operation === CodeFile::OP_CREATE) {
|
||||
$trClass = 'success';
|
||||
} else {
|
||||
$trClass = '';
|
||||
}
|
||||
?>
|
||||
<tr class="<?= "$file->operation $trClass" ?>">
|
||||
<td class="file">
|
||||
<?= Html::a(Html::encode($file->getRelativePath()), ['preview', 'id' => $id, 'file' => $file->id], ['class' => 'preview-code', 'data-title' => $file->getRelativePath()]) ?>
|
||||
<?php if ($file->operation === CodeFile::OP_OVERWRITE): ?>
|
||||
<?= Html::a('diff', ['diff', 'id' => $id, 'file' => $file->id], ['class' => 'diff-code label label-warning', 'data-title' => $file->getRelativePath()]) ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="action">
|
||||
<?php
|
||||
if ($file->operation === CodeFile::OP_SKIP) {
|
||||
echo 'unchanged';
|
||||
} else {
|
||||
echo $file->operation;
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<?php if ($fileChangeExists): ?>
|
||||
<td class="check">
|
||||
<?php
|
||||
if ($file->operation === CodeFile::OP_SKIP) {
|
||||
echo ' ';
|
||||
} else {
|
||||
echo Html::checkBox("answers[{$file->id}]", isset($answers) ? isset($answers[$file->id]) : ($file->operation === CodeFile::OP_CREATE));
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="modal fade" id="preview-modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<div class="btn-group pull-left">
|
||||
<a class="modal-previous btn btn-xs btn-default" href="#" title="Previous File (Left Arrow)"><span class="glyphicon glyphicon-arrow-left"></span></a>
|
||||
<a class="modal-next btn btn-xs btn-default" href="#" title="Next File (Right Arrow)"><span class="glyphicon glyphicon-arrow-right"></span></a>
|
||||
<a class="modal-refresh btn btn-xs btn-default" href="#" title="Refresh File (R)"><span class="glyphicon glyphicon-refresh"></span></a>
|
||||
<a class="modal-checkbox btn btn-xs btn-default" href="#" title="Check This File (Space)"><span class="glyphicon"></span></a>
|
||||
|
||||
</div>
|
||||
<strong class="modal-title pull-left">Modal title</strong>
|
||||
<span class="modal-copy-hint pull-right"><kbd>CTRL</kbd>+<kbd>C</kbd> to copy</span>
|
||||
<div id="clipboard-container"><textarea id="clipboard"></textarea></div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Please wait ...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
16
vendor/yiisoft/yii2-gii/src/views/default/view/results.php
vendored
Normal file
16
vendor/yiisoft/yii2-gii/src/views/default/view/results.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/* @var $this yii\web\View */
|
||||
/* @var $generator yii\gii\Generator */
|
||||
/* @var $results string */
|
||||
/* @var $hasError bool */
|
||||
?>
|
||||
<div class="default-view-results">
|
||||
<?php
|
||||
if ($hasError) {
|
||||
echo '<div class="alert alert-danger">There was something wrong when generating the code. Please check the following messages.</div>';
|
||||
} else {
|
||||
echo '<div class="alert alert-success">' . $generator->successMessage() . '</div>';
|
||||
}
|
||||
?>
|
||||
<pre><?= nl2br($results) ?></pre>
|
||||
</div>
|
||||
30
vendor/yiisoft/yii2-gii/src/views/layouts/generator.php
vendored
Normal file
30
vendor/yiisoft/yii2-gii/src/views/layouts/generator.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
use yii\helpers\Html;
|
||||
|
||||
/* @var $this \yii\web\View */
|
||||
/* @var $generators \yii\gii\Generator[] */
|
||||
/* @var $activeGenerator \yii\gii\Generator */
|
||||
/* @var $content string */
|
||||
|
||||
$generators = Yii::$app->controller->module->generators;
|
||||
$activeGenerator = Yii::$app->controller->generator;
|
||||
?>
|
||||
<?php $this->beginContent('@yii/gii/views/layouts/main.php'); ?>
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-sm-4">
|
||||
<div class="list-group">
|
||||
<?php
|
||||
foreach ($generators as $id => $generator) {
|
||||
$label = '<i class="glyphicon glyphicon-chevron-right"></i>' . Html::encode($generator->getName());
|
||||
echo Html::a($label, ['default/view', 'id' => $id], [
|
||||
'class' => $generator === $activeGenerator ? 'list-group-item active' : 'list-group-item',
|
||||
]);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9 col-sm-8">
|
||||
<?= $content ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php $this->endContent(); ?>
|
||||
55
vendor/yiisoft/yii2-gii/src/views/layouts/main.php
vendored
Normal file
55
vendor/yiisoft/yii2-gii/src/views/layouts/main.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
use yii\bootstrap\NavBar;
|
||||
use yii\bootstrap\Nav;
|
||||
use yii\helpers\Html;
|
||||
|
||||
/* @var $this \yii\web\View */
|
||||
/* @var $content string */
|
||||
|
||||
$asset = yii\gii\GiiAsset::register($this);
|
||||
?>
|
||||
<?php $this->beginPage() ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="robots" content="none">
|
||||
<?php $this->registerCsrfMetaTags() ?>
|
||||
<title><?= Html::encode($this->title) ?></title>
|
||||
<?php $this->head() ?>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid page-container">
|
||||
<?php $this->beginBody() ?>
|
||||
<?php
|
||||
NavBar::begin([
|
||||
'brandLabel' => Html::img($asset->baseUrl . '/logo.png'),
|
||||
'brandUrl' => ['default/index'],
|
||||
'options' => ['class' => 'navbar-inverse navbar-fixed-top'],
|
||||
]);
|
||||
echo Nav::widget([
|
||||
'options' => ['class' => 'nav navbar-nav navbar-right'],
|
||||
'items' => [
|
||||
['label' => 'Home', 'url' => ['default/index']],
|
||||
['label' => 'Help', 'url' => 'http://www.yiiframework.com/doc-2.0/ext-gii-index.html'],
|
||||
['label' => 'Application', 'url' => Yii::$app->homeUrl],
|
||||
],
|
||||
]);
|
||||
NavBar::end();
|
||||
?>
|
||||
<div class="container content-container">
|
||||
<?= $content ?>
|
||||
</div>
|
||||
<div class="footer-fix"></div>
|
||||
</div>
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<p class="pull-left">A Product of <a href="http://www.yiisoft.com/">Yii Software LLC</a></p>
|
||||
<p class="pull-right"><?= Yii::powered() ?></p>
|
||||
</div>
|
||||
</footer>
|
||||
<?php $this->endBody() ?>
|
||||
</body>
|
||||
</html>
|
||||
<?php $this->endPage() ?>
|
||||
Reference in New Issue
Block a user