├── modules └── v1 │ ├── models │ └── .gitkeep │ ├── Module.php │ ├── swagger │ ├── security.php │ ├── definitions.php │ └── swagger.php │ └── controllers │ └── UserController.php ├── runtime └── .gitignore ├── tests ├── codeception │ ├── unit │ │ ├── fixtures │ │ │ ├── .gitkeep │ │ │ └── data │ │ │ │ └── .gitkeep │ │ ├── templates │ │ │ └── fixtures │ │ │ │ └── .gitkeep │ │ ├── _bootstrap.php │ │ └── models │ │ │ ├── UserTest.php │ │ │ ├── ContactFormTest.php │ │ │ └── LoginFormTest.php │ ├── _output │ │ └── .gitignore │ ├── fixtures │ │ └── .gitignore │ ├── templates │ │ └── .gitignore │ ├── acceptance │ │ ├── _bootstrap.php │ │ ├── AboutCept.php │ │ ├── HomeCept.php │ │ ├── LoginCept.php │ │ └── ContactCept.php │ ├── functional │ │ ├── _bootstrap.php │ │ ├── AboutCept.php │ │ ├── HomeCept.php │ │ ├── LoginCept.php │ │ └── ContactCept.php │ ├── .gitignore │ ├── unit.suite.yml │ ├── config │ │ ├── unit.php │ │ ├── acceptance.php │ │ ├── config.php │ │ └── functional.php │ ├── _pages │ │ ├── AboutPage.php │ │ ├── LoginPage.php │ │ └── ContactPage.php │ ├── bin │ │ ├── _bootstrap.php │ │ ├── yii │ │ └── yii.bat │ ├── functional.suite.yml │ ├── _bootstrap.php │ └── acceptance.suite.yml ├── codeception.yml └── README.md ├── web ├── assets │ └── .gitignore ├── robots.txt ├── favicon.ico ├── .htaccess ├── index.php ├── index-test.php └── css │ └── site.css ├── .bowerrc ├── demo.gif ├── config ├── params.php ├── db.php ├── console.php └── web.php ├── README.md ├── views ├── site │ ├── about.php │ ├── error.php │ ├── login.php │ ├── index.php │ └── contact.php └── layouts │ └── main.php ├── .gitignore ├── yii ├── yii.bat ├── components └── Setup.php ├── assets └── AppAsset.php ├── mail └── layouts │ └── html.php ├── commands └── HelloController.php ├── LICENSE.md ├── models ├── ContactForm.php ├── LoginForm.php └── User.php ├── composer.json ├── controllers └── SiteController.php ├── requirements.php └── composer.lock /modules/v1/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/codeception/unit/fixtures/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /web/assets/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /web/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: -------------------------------------------------------------------------------- /tests/codeception/unit/fixtures/data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/codeception/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/codeception/unit/templates/fixtures/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory" : "vendor/bower" 3 | } 4 | -------------------------------------------------------------------------------- /tests/codeception/fixtures/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/codeception/templates/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lichunqiang/yii2-swagger-demo/HEAD/demo.gif -------------------------------------------------------------------------------- /config/params.php: -------------------------------------------------------------------------------- 1 | 'admin@example.com', 5 | ]; 6 | -------------------------------------------------------------------------------- /web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lichunqiang/yii2-swagger-demo/HEAD/web/favicon.ico -------------------------------------------------------------------------------- /tests/codeception/unit/_bootstrap.php: -------------------------------------------------------------------------------- 1 | 'yii\db\Connection', 5 | 'dsn' => 'mysql:host=localhost;dbname=yii2basic', 6 | 'username' => 'root', 7 | 'password' => '', 8 | 'charset' => 'utf8', 9 | ]; 10 | -------------------------------------------------------------------------------- /tests/codeception/config/unit.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that about works'); 9 | AboutPage::openBy($I); 10 | $I->see('About', 'h1'); 11 | -------------------------------------------------------------------------------- /tests/codeception/functional/AboutCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that about works'); 9 | AboutPage::openBy($I); 10 | $I->see('About', 'h1'); 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Demo 2 | ----- 3 | 4 | Clone 到本地后直接 `composer install`. 5 | 6 | 然后直接启动php内置服务器: 7 | ``` 8 | $ yii serve 9 | ``` 10 | 11 | 然后在浏览器中输入:`http://127.0.0.1:8080` 12 | 13 | ~~对了, 我设置了`api_key` 为 `test`, 所以你要输入这个key才可以正常访问。~~ 14 | 15 | ~~你也可以注释掉这段,在 `SiteController`第58行.~~ 16 | 17 | ![demo](./demo.gif) -------------------------------------------------------------------------------- /tests/codeception/_pages/AboutPage.php: -------------------------------------------------------------------------------- 1 | 3 | Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type" 4 | 5 | # 如果请求的是真实存在的文件或目录,直接访问 6 | RewriteCond %{REQUEST_FILENAME} !-f 7 | RewriteCond %{REQUEST_FILENAME} !-d 8 | # 如果请求的不是真实文件或目录,分发请求至 index.php 9 | RewriteRule . index.php 10 | -------------------------------------------------------------------------------- /modules/v1/Module.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that home page works'); 7 | $I->amOnPage(Yii::$app->homeUrl); 8 | $I->see('My Company'); 9 | $I->seeLink('About'); 10 | $I->click('About'); 11 | $I->see('This is the About page.'); 12 | -------------------------------------------------------------------------------- /tests/codeception/functional/HomeCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that home page works'); 7 | $I->amOnPage(Yii::$app->homeUrl); 8 | $I->see('My Company'); 9 | $I->seeLink('About'); 10 | $I->click('About'); 11 | $I->see('This is the About page.'); 12 | -------------------------------------------------------------------------------- /web/index.php: -------------------------------------------------------------------------------- 1 | run(); 13 | -------------------------------------------------------------------------------- /tests/codeception/unit/models/UserTest.php: -------------------------------------------------------------------------------- 1 | loadFixtures(['user']); 14 | } 15 | 16 | // TODO add test methods here 17 | } 18 | -------------------------------------------------------------------------------- /tests/codeception/bin/_bootstrap.php: -------------------------------------------------------------------------------- 1 | title = 'About'; 8 | $this->params['breadcrumbs'][] = $this->title; 9 | ?> 10 |
11 |

title) ?>

12 | 13 |

14 | This is the About page. You may modify the following file to customize its content: 15 |

16 | 17 | 18 |
19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer vendor dir 16 | /vendor 17 | 18 | # composer itself is not needed 19 | composer.phar 20 | 21 | # Mac DS_Store Files 22 | .DS_Store 23 | 24 | # phpunit itself is not needed 25 | phpunit.phar 26 | # local phpunit config 27 | /phpunit.xml 28 | -------------------------------------------------------------------------------- /tests/codeception/functional.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | 3 | # suite for functional (integration) tests. 4 | # emulate web requests and make application process them. 5 | # (tip: better to use with frameworks). 6 | 7 | # RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. 8 | #basic/web/index.php 9 | class_name: FunctionalTester 10 | modules: 11 | enabled: 12 | - Filesystem 13 | - Yii2 14 | config: 15 | Yii2: 16 | configFile: 'codeception/config/functional.php' 17 | -------------------------------------------------------------------------------- /modules/v1/swagger/security.php: -------------------------------------------------------------------------------- 1 | run(); 20 | exit($exitCode); 21 | -------------------------------------------------------------------------------- /yii.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem ------------------------------------------------------------- 4 | rem Yii command line bootstrap script for Windows. 5 | rem 6 | rem @author Qiang Xue 7 | rem @link http://www.yiiframework.com/ 8 | rem @copyright Copyright (c) 2008 Yii Software LLC 9 | rem @license http://www.yiiframework.com/license/ 10 | rem ------------------------------------------------------------- 11 | 12 | @setlocal 13 | 14 | set YII_PATH=%~dp0 15 | 16 | if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe 17 | 18 | "%PHP_COMMAND%" "%YII_PATH%yii" %* 19 | 20 | @endlocal 21 | -------------------------------------------------------------------------------- /tests/codeception/bin/yii: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(); 20 | exit($exitCode); 21 | -------------------------------------------------------------------------------- /web/index-test.php: -------------------------------------------------------------------------------- 1 | run(); 17 | -------------------------------------------------------------------------------- /components/Setup.php: -------------------------------------------------------------------------------- 1 | getUrlManager()->addRules([ 10 | [ 11 | 'class' => 'yii\web\UrlRule', 12 | 'pattern' => '', 13 | 'route' => 'site/doc', 14 | ], 15 | [ 16 | 'class' => 'yii\web\UrlRule', 17 | 'pattern' => 'site/', 18 | 'route' => 'site/' 19 | ] 20 | ]); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/codeception/bin/yii.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem ------------------------------------------------------------- 4 | rem Yii command line bootstrap script for Windows. 5 | rem 6 | rem @author Qiang Xue 7 | rem @link http://www.yiiframework.com/ 8 | rem @copyright Copyright (c) 2008 Yii Software LLC 9 | rem @license http://www.yiiframework.com/license/ 10 | rem ------------------------------------------------------------- 11 | 12 | @setlocal 13 | 14 | set YII_PATH=%~dp0 15 | 16 | if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe 17 | 18 | "%PHP_COMMAND%" "%YII_PATH%yii" %* 19 | 20 | @endlocal 21 | -------------------------------------------------------------------------------- /views/site/error.php: -------------------------------------------------------------------------------- 1 | title = $name; 11 | ?> 12 |
13 | 14 |

title) ?>

15 | 16 |
17 | 18 |
19 | 20 |

21 | The above error occurred while the Web server was processing your request. 22 |

23 |

24 | Please contact us if you think this is a server error. Thank you. 25 |

26 | 27 |
28 | -------------------------------------------------------------------------------- /assets/AppAsset.php: -------------------------------------------------------------------------------- 1 | 14 | * @since 2.0 15 | */ 16 | class AppAsset extends AssetBundle 17 | { 18 | public $basePath = '@webroot'; 19 | public $baseUrl = '@web'; 20 | public $css = [ 21 | 'css/site.css', 22 | ]; 23 | public $js = [ 24 | ]; 25 | public $depends = [ 26 | 'yii\web\YiiAsset', 27 | 'yii\bootstrap\BootstrapAsset', 28 | ]; 29 | } 30 | -------------------------------------------------------------------------------- /tests/codeception/_pages/LoginPage.php: -------------------------------------------------------------------------------- 1 | actor->fillField('input[name="LoginForm[username]"]', $username); 22 | $this->actor->fillField('input[name="LoginForm[password]"]', $password); 23 | $this->actor->click('login-button'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/codeception/_pages/ContactPage.php: -------------------------------------------------------------------------------- 1 | $value) { 21 | $inputType = $field === 'body' ? 'textarea' : 'input'; 22 | $this->actor->fillField($inputType . '[name="ContactForm[' . $field . ']"]', $value); 23 | } 24 | $this->actor->click('contact-button'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /mail/layouts/html.php: -------------------------------------------------------------------------------- 1 | 8 | beginPage() ?> 9 | 10 | 11 | 12 | 13 | <?= Html::encode($this->title) ?> 14 | head() ?> 15 | 16 | 17 | beginBody() ?> 18 | 19 | endBody() ?> 20 | 21 | 22 | endPage() ?> 23 | -------------------------------------------------------------------------------- /tests/codeception/config/config.php: -------------------------------------------------------------------------------- 1 | 'en-US', 7 | 'controllerMap' => [ 8 | 'fixture' => [ 9 | 'class' => 'yii\faker\FixtureController', 10 | 'fixtureDataPath' => '@tests/codeception/fixtures', 11 | 'templatePath' => '@tests/codeception/templates', 12 | 'namespace' => 'tests\codeception\fixtures', 13 | ], 14 | ], 15 | 'components' => [ 16 | 'db' => [ 17 | 'dsn' => 'mysql:host=localhost;dbname=yii2_basic_tests', 18 | ], 19 | 'mailer' => [ 20 | 'useFileTransport' => true, 21 | ], 22 | 'urlManager' => [ 23 | 'showScriptName' => true, 24 | ], 25 | ], 26 | ]; 27 | -------------------------------------------------------------------------------- /commands/HelloController.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0 19 | */ 20 | class HelloController extends Controller 21 | { 22 | /** 23 | * This command echoes what you have entered as the message. 24 | * @param string $message the message to be echoed. 25 | */ 26 | public function actionIndex($message = 'hello world') 27 | { 28 | echo $message . "\n"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /config/console.php: -------------------------------------------------------------------------------- 1 | 'basic-console', 10 | 'basePath' => dirname(__DIR__), 11 | 'bootstrap' => ['log', 'gii'], 12 | 'controllerNamespace' => 'app\commands', 13 | 'modules' => [ 14 | 'gii' => 'yii\gii\Module', 15 | ], 16 | 'components' => [ 17 | 'cache' => [ 18 | 'class' => 'yii\caching\FileCache', 19 | ], 20 | 'log' => [ 21 | 'targets' => [ 22 | [ 23 | 'class' => 'yii\log\FileTarget', 24 | 'levels' => ['error', 'warning'], 25 | ], 26 | ], 27 | ], 28 | 'db' => $db, 29 | ], 30 | 'params' => $params, 31 | ]; 32 | -------------------------------------------------------------------------------- /tests/codeception/config/functional.php: -------------------------------------------------------------------------------- 1 | [ 13 | 'request' => [ 14 | // it's not recommended to run functional tests with CSRF validation enabled 15 | 'enableCsrfValidation' => false, 16 | // but if you absolutely need it set cookie domain to localhost 17 | /* 18 | 'csrfCookie' => [ 19 | 'domain' => 'localhost', 20 | ], 21 | */ 22 | ], 23 | ], 24 | ] 25 | ); 26 | -------------------------------------------------------------------------------- /tests/codeception/functional/LoginCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that login works'); 9 | 10 | $loginPage = LoginPage::openBy($I); 11 | 12 | $I->see('Login', 'h1'); 13 | 14 | $I->amGoingTo('try to login with empty credentials'); 15 | $loginPage->login('', ''); 16 | $I->expectTo('see validations errors'); 17 | $I->see('Username cannot be blank.'); 18 | $I->see('Password cannot be blank.'); 19 | 20 | $I->amGoingTo('try to login with wrong credentials'); 21 | $loginPage->login('admin', 'wrong'); 22 | $I->expectTo('see validations errors'); 23 | $I->see('Incorrect username or password.'); 24 | 25 | $I->amGoingTo('try to login with correct credentials'); 26 | $loginPage->login('admin', 'admin'); 27 | $I->expectTo('see user info'); 28 | $I->see('Logout (admin)'); 29 | -------------------------------------------------------------------------------- /tests/codeception/_bootstrap.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that login works'); 9 | 10 | $loginPage = LoginPage::openBy($I); 11 | 12 | $I->see('Login', 'h1'); 13 | 14 | $I->amGoingTo('try to login with empty credentials'); 15 | $loginPage->login('', ''); 16 | if (method_exists($I, 'wait')) { 17 | $I->wait(3); // only for selenium 18 | } 19 | $I->expectTo('see validations errors'); 20 | $I->see('Username cannot be blank.'); 21 | $I->see('Password cannot be blank.'); 22 | 23 | $I->amGoingTo('try to login with wrong credentials'); 24 | $loginPage->login('admin', 'wrong'); 25 | if (method_exists($I, 'wait')) { 26 | $I->wait(3); // only for selenium 27 | } 28 | $I->expectTo('see validations errors'); 29 | $I->see('Incorrect username or password.'); 30 | 31 | $I->amGoingTo('try to login with correct credentials'); 32 | $loginPage->login('admin', 'admin'); 33 | if (method_exists($I, 'wait')) { 34 | $I->wait(3); // only for selenium 35 | } 36 | $I->expectTo('see user info'); 37 | $I->see('Logout (admin)'); 38 | -------------------------------------------------------------------------------- /modules/v1/swagger/definitions.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that contact works'); 9 | 10 | $contactPage = ContactPage::openBy($I); 11 | 12 | $I->see('Contact', 'h1'); 13 | 14 | $I->amGoingTo('submit contact form with no data'); 15 | $contactPage->submit([]); 16 | $I->expectTo('see validations errors'); 17 | $I->see('Contact', 'h1'); 18 | $I->see('Name cannot be blank'); 19 | $I->see('Email cannot be blank'); 20 | $I->see('Subject cannot be blank'); 21 | $I->see('Body cannot be blank'); 22 | $I->see('The verification code is incorrect'); 23 | 24 | $I->amGoingTo('submit contact form with not correct email'); 25 | $contactPage->submit([ 26 | 'name' => 'tester', 27 | 'email' => 'tester.email', 28 | 'subject' => 'test subject', 29 | 'body' => 'test content', 30 | 'verifyCode' => 'testme', 31 | ]); 32 | $I->expectTo('see that email adress is wrong'); 33 | $I->dontSee('Name cannot be blank', '.help-inline'); 34 | $I->see('Email is not a valid email address.'); 35 | $I->dontSee('Subject cannot be blank', '.help-inline'); 36 | $I->dontSee('Body cannot be blank', '.help-inline'); 37 | $I->dontSee('The verification code is incorrect', '.help-inline'); 38 | 39 | $I->amGoingTo('submit contact form with correct data'); 40 | $contactPage->submit([ 41 | 'name' => 'tester', 42 | 'email' => 'tester@example.com', 43 | 'subject' => 'test subject', 44 | 'body' => 'test content', 45 | 'verifyCode' => 'testme', 46 | ]); 47 | $I->dontSeeElement('#contact-form'); 48 | $I->see('Thank you for contacting us. We will respond to you as soon as possible.'); 49 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The Yii framework is free software. It is released under the terms of 2 | the following BSD License. 3 | 4 | Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com) 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions 9 | are met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in 15 | the documentation and/or other materials provided with the 16 | distribution. 17 | * Neither the name of Yii Software LLC nor the names of its 18 | contributors may be used to endorse or promote products derived 19 | from this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /models/ContactForm.php: -------------------------------------------------------------------------------- 1 | 'Verification Code', 41 | ]; 42 | } 43 | 44 | /** 45 | * Sends an email to the specified email address using the information collected by this model. 46 | * @param string $email the target email address 47 | * @return boolean whether the model passes validation 48 | */ 49 | public function contact($email) 50 | { 51 | if ($this->validate()) { 52 | Yii::$app->mailer->compose() 53 | ->setTo($email) 54 | ->setFrom([$this->email => $this->name]) 55 | ->setSubject($this->subject) 56 | ->setTextBody($this->body) 57 | ->send(); 58 | 59 | return true; 60 | } 61 | return false; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /views/site/login.php: -------------------------------------------------------------------------------- 1 | title = 'Login'; 11 | $this->params['breadcrumbs'][] = $this->title; 12 | ?> 13 | 48 | -------------------------------------------------------------------------------- /web/css/site.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | } 5 | 6 | .wrap { 7 | min-height: 100%; 8 | height: auto; 9 | margin: 0 auto -60px; 10 | padding: 0 0 60px; 11 | } 12 | 13 | .wrap > .container { 14 | padding: 70px 15px 20px; 15 | } 16 | 17 | .footer { 18 | height: 60px; 19 | background-color: #f5f5f5; 20 | border-top: 1px solid #ddd; 21 | padding-top: 20px; 22 | } 23 | 24 | .jumbotron { 25 | text-align: center; 26 | background-color: transparent; 27 | } 28 | 29 | .jumbotron .btn { 30 | font-size: 21px; 31 | padding: 14px 24px; 32 | } 33 | 34 | .not-set { 35 | color: #c55; 36 | font-style: italic; 37 | } 38 | 39 | /* add sorting icons to gridview sort links */ 40 | a.asc:after, a.desc:after { 41 | position: relative; 42 | top: 1px; 43 | display: inline-block; 44 | font-family: 'Glyphicons Halflings'; 45 | font-style: normal; 46 | font-weight: normal; 47 | line-height: 1; 48 | padding-left: 5px; 49 | } 50 | 51 | a.asc:after { 52 | content: /*"\e113"*/ "\e151"; 53 | } 54 | 55 | a.desc:after { 56 | content: /*"\e114"*/ "\e152"; 57 | } 58 | 59 | .sort-numerical a.asc:after { 60 | content: "\e153"; 61 | } 62 | 63 | .sort-numerical a.desc:after { 64 | content: "\e154"; 65 | } 66 | 67 | .sort-ordinal a.asc:after { 68 | content: "\e155"; 69 | } 70 | 71 | .sort-ordinal a.desc:after { 72 | content: "\e156"; 73 | } 74 | 75 | .grid-view th { 76 | white-space: nowrap; 77 | } 78 | 79 | .hint-block { 80 | display: block; 81 | margin-top: 5px; 82 | color: #999; 83 | } 84 | 85 | .error-summary { 86 | color: #a94442; 87 | background: #fdf7f7; 88 | border-left: 3px solid #eed3d7; 89 | padding: 10px 20px; 90 | margin: 0 0 15px 0; 91 | } 92 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yiisoft/yii2-app-basic", 3 | "description": "Yii 2 Basic Project Template", 4 | "keywords": ["yii2", "framework", "basic", "project template"], 5 | "homepage": "http://www.yiiframework.com/", 6 | "type": "project", 7 | "license": "BSD-3-Clause", 8 | "support": { 9 | "issues": "https://github.com/yiisoft/yii2/issues?state=open", 10 | "forum": "http://www.yiiframework.com/forum/", 11 | "wiki": "http://www.yiiframework.com/wiki/", 12 | "irc": "irc://irc.freenode.net/yii", 13 | "source": "https://github.com/yiisoft/yii2" 14 | }, 15 | "minimum-stability": "stable", 16 | "require": { 17 | "php": ">=5.4.0", 18 | "yiisoft/yii2": ">=2.0.7", 19 | "yiisoft/yii2-bootstrap": "*", 20 | "yiisoft/yii2-swiftmailer": "*" 21 | }, 22 | "require-dev": { 23 | "yiisoft/yii2-debug": "*", 24 | "yiisoft/yii2-gii": "*", 25 | "yiisoft/yii2-faker": "*", 26 | "light/yii2-swagger": "~1.0.4" 27 | }, 28 | "config": { 29 | "process-timeout": 1800 30 | }, 31 | "scripts": { 32 | "post-create-project-cmd": [ 33 | "yii\\composer\\Installer::postCreateProject" 34 | ] 35 | }, 36 | "extra": { 37 | "yii\\composer\\Installer::postCreateProject": { 38 | "setPermission": [ 39 | { 40 | "runtime": "0777", 41 | "web/assets": "0777", 42 | "yii": "0755" 43 | } 44 | ], 45 | "generateCookieValidationKey": [ 46 | "config/web.php" 47 | ] 48 | }, 49 | "asset-installer-paths": { 50 | "npm-asset-library": "vendor/npm", 51 | "bower-asset-library": "vendor/bower" 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/codeception/acceptance/ContactCept.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that contact works'); 9 | 10 | $contactPage = ContactPage::openBy($I); 11 | 12 | $I->see('Contact', 'h1'); 13 | 14 | $I->amGoingTo('submit contact form with no data'); 15 | $contactPage->submit([]); 16 | if (method_exists($I, 'wait')) { 17 | $I->wait(3); // only for selenium 18 | } 19 | $I->expectTo('see validations errors'); 20 | $I->see('Contact', 'h1'); 21 | $I->see('Name cannot be blank'); 22 | $I->see('Email cannot be blank'); 23 | $I->see('Subject cannot be blank'); 24 | $I->see('Body cannot be blank'); 25 | $I->see('The verification code is incorrect'); 26 | 27 | $I->amGoingTo('submit contact form with not correct email'); 28 | $contactPage->submit([ 29 | 'name' => 'tester', 30 | 'email' => 'tester.email', 31 | 'subject' => 'test subject', 32 | 'body' => 'test content', 33 | 'verifyCode' => 'testme', 34 | ]); 35 | if (method_exists($I, 'wait')) { 36 | $I->wait(3); // only for selenium 37 | } 38 | $I->expectTo('see that email adress is wrong'); 39 | $I->dontSee('Name cannot be blank', '.help-inline'); 40 | $I->see('Email is not a valid email address.'); 41 | $I->dontSee('Subject cannot be blank', '.help-inline'); 42 | $I->dontSee('Body cannot be blank', '.help-inline'); 43 | $I->dontSee('The verification code is incorrect', '.help-inline'); 44 | 45 | $I->amGoingTo('submit contact form with correct data'); 46 | $contactPage->submit([ 47 | 'name' => 'tester', 48 | 'email' => 'tester@example.com', 49 | 'subject' => 'test subject', 50 | 'body' => 'test content', 51 | 'verifyCode' => 'testme', 52 | ]); 53 | if (method_exists($I, 'wait')) { 54 | $I->wait(3); // only for selenium 55 | } 56 | $I->dontSeeElement('#contact-form'); 57 | $I->see('Thank you for contacting us. We will respond to you as soon as possible.'); 58 | -------------------------------------------------------------------------------- /tests/codeception/unit/models/ContactFormTest.php: -------------------------------------------------------------------------------- 1 | mailer->fileTransportCallback = function ($mailer, $message) { 17 | return 'testing_message.eml'; 18 | }; 19 | } 20 | 21 | protected function tearDown() 22 | { 23 | unlink($this->getMessageFile()); 24 | parent::tearDown(); 25 | } 26 | 27 | public function testContact() 28 | { 29 | $model = $this->getMock('app\models\ContactForm', ['validate']); 30 | $model->expects($this->once())->method('validate')->will($this->returnValue(true)); 31 | 32 | $model->attributes = [ 33 | 'name' => 'Tester', 34 | 'email' => 'tester@example.com', 35 | 'subject' => 'very important letter subject', 36 | 'body' => 'body of current message', 37 | ]; 38 | 39 | $model->contact('admin@example.com'); 40 | 41 | $this->specify('email should be send', function () { 42 | expect('email file should exist', file_exists($this->getMessageFile()))->true(); 43 | }); 44 | 45 | $this->specify('message should contain correct data', function () use ($model) { 46 | $emailMessage = file_get_contents($this->getMessageFile()); 47 | 48 | expect('email should contain user name', $emailMessage)->contains($model->name); 49 | expect('email should contain sender email', $emailMessage)->contains($model->email); 50 | expect('email should contain subject', $emailMessage)->contains($model->subject); 51 | expect('email should contain body', $emailMessage)->contains($model->body); 52 | }); 53 | } 54 | 55 | private function getMessageFile() 56 | { 57 | return Yii::getAlias(Yii::$app->mailer->fileTransportPath) . '/testing_message.eml'; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /tests/codeception/unit/models/LoginFormTest.php: -------------------------------------------------------------------------------- 1 | user->logout(); 17 | parent::tearDown(); 18 | } 19 | 20 | public function testLoginNoUser() 21 | { 22 | $model = new LoginForm([ 23 | 'username' => 'not_existing_username', 24 | 'password' => 'not_existing_password', 25 | ]); 26 | 27 | $this->specify('user should not be able to login, when there is no identity', function () use ($model) { 28 | expect('model should not login user', $model->login())->false(); 29 | expect('user should not be logged in', Yii::$app->user->isGuest)->true(); 30 | }); 31 | } 32 | 33 | public function testLoginWrongPassword() 34 | { 35 | $model = new LoginForm([ 36 | 'username' => 'demo', 37 | 'password' => 'wrong_password', 38 | ]); 39 | 40 | $this->specify('user should not be able to login with wrong password', function () use ($model) { 41 | expect('model should not login user', $model->login())->false(); 42 | expect('error message should be set', $model->errors)->hasKey('password'); 43 | expect('user should not be logged in', Yii::$app->user->isGuest)->true(); 44 | }); 45 | } 46 | 47 | public function testLoginCorrect() 48 | { 49 | $model = new LoginForm([ 50 | 'username' => 'demo', 51 | 'password' => 'demo', 52 | ]); 53 | 54 | $this->specify('user should be able to login with correct credentials', function () use ($model) { 55 | expect('model should login user', $model->login())->true(); 56 | expect('error message should not be set', $model->errors)->hasntKey('password'); 57 | expect('user should be logged in', Yii::$app->user->isGuest)->false(); 58 | }); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /models/LoginForm.php: -------------------------------------------------------------------------------- 1 | hasErrors()) { 45 | $user = $this->getUser(); 46 | 47 | if (!$user || !$user->validatePassword($this->password)) { 48 | $this->addError($attribute, 'Incorrect username or password.'); 49 | } 50 | } 51 | } 52 | 53 | /** 54 | * Logs in a user using the provided username and password. 55 | * @return boolean whether the user is logged in successfully 56 | */ 57 | public function login() 58 | { 59 | if ($this->validate()) { 60 | return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0); 61 | } 62 | return false; 63 | } 64 | 65 | /** 66 | * Finds user by [[username]] 67 | * 68 | * @return User|null 69 | */ 70 | public function getUser() 71 | { 72 | if ($this->_user === false) { 73 | $this->_user = User::findByUsername($this->username); 74 | } 75 | 76 | return $this->_user; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /views/layouts/main.php: -------------------------------------------------------------------------------- 1 | 14 | beginPage() ?> 15 | 16 | 17 | 18 | 19 | 20 | 21 | <?= Html::encode($this->title) ?> 22 | head() ?> 23 | 24 | 25 | beginBody() ?> 26 | 27 |
28 | 'My Company', 31 | 'brandUrl' => Yii::$app->homeUrl, 32 | 'options' => [ 33 | 'class' => 'navbar-inverse navbar-fixed-top', 34 | ], 35 | ]); 36 | echo Nav::widget([ 37 | 'options' => ['class' => 'navbar-nav navbar-right'], 38 | 'items' => [ 39 | ['label' => 'Home', 'url' => ['/site/index']], 40 | ['label' => 'About', 'url' => ['/site/about']], 41 | ['label' => 'Contact', 'url' => ['/site/contact']], 42 | Yii::$app->user->isGuest ? 43 | ['label' => 'Login', 'url' => ['/site/login']] : 44 | [ 45 | 'label' => 'Logout (' . Yii::$app->user->identity->username . ')', 46 | 'url' => ['/site/logout'], 47 | 'linkOptions' => ['data-method' => 'post'] 48 | ], 49 | ], 50 | ]); 51 | NavBar::end(); 52 | ?> 53 | 54 |
55 | isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], 57 | ]) ?> 58 | 59 |
60 |
61 | 62 |
63 |
64 |

© My Company

65 | 66 |

67 |
68 |
69 | 70 | endBody() ?> 71 | 72 | 73 | endPage() ?> 74 | -------------------------------------------------------------------------------- /views/site/index.php: -------------------------------------------------------------------------------- 1 | title = 'My Yii Application'; 6 | ?> 7 |
8 | 9 |
10 |

Congratulations!

11 | 12 |

You have successfully created your Yii-powered application.

13 | 14 |

Get started with Yii

15 |
16 | 17 |
18 | 19 |
20 |
21 |

Heading

22 | 23 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 24 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 25 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 26 | fugiat nulla pariatur.

27 | 28 |

Yii Documentation »

29 |
30 |
31 |

Heading

32 | 33 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 34 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 35 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 36 | fugiat nulla pariatur.

37 | 38 |

Yii Forum »

39 |
40 |
41 |

Heading

42 | 43 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 44 | dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip 45 | ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 46 | fugiat nulla pariatur.

47 | 48 |

Yii Extensions »

49 |
50 |
51 | 52 |
53 |
54 | -------------------------------------------------------------------------------- /views/site/contact.php: -------------------------------------------------------------------------------- 1 | title = 'Contact'; 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 |
15 |

title) ?>

16 | 17 | session->hasFlash('contactFormSubmitted')): ?> 18 | 19 |
20 | Thank you for contacting us. We will respond to you as soon as possible. 21 |
22 | 23 |

24 | Note that if you turn on the Yii debugger, you should be able 25 | to view the mail message on the mail panel of the debugger. 26 | mailer->useFileTransport): ?> 27 | Because the application is in development mode, the email is not sent but saved as 28 | a file under mailer->fileTransportPath) ?>. 29 | Please configure the useFileTransport property of the mail 30 | application component to be false to enable email sending. 31 | 32 |

33 | 34 | 35 | 36 |

37 | If you have business inquiries or other questions, please fill out the following form to contact us. 38 | Thank you. 39 |

40 | 41 |
42 |
43 | 44 | 'contact-form']); ?> 45 | 46 | field($model, 'name') ?> 47 | 48 | field($model, 'email') ?> 49 | 50 | field($model, 'subject') ?> 51 | 52 | field($model, 'body')->textArea(['rows' => 6]) ?> 53 | 54 | field($model, 'verifyCode')->widget(Captcha::className(), [ 55 | 'template' => '
{image}
{input}
', 56 | ]) ?> 57 | 58 |
59 | 'btn btn-primary', 'name' => 'contact-button']) ?> 60 |
61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 |
69 | -------------------------------------------------------------------------------- /config/web.php: -------------------------------------------------------------------------------- 1 | 'basic', 7 | 'basePath' => dirname(__DIR__), 8 | 'bootstrap' => ['log', 'app\components\Setup'], 9 | 'components' => [ 10 | 'request' => [ 11 | // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 12 | 'cookieValidationKey' => 'SVnVkT24CuHMpvpvZkiANzL6jR8xSNb0', 13 | 'parsers' => [ 14 | 'application/json' => 'yii\web\JsonParser', 15 | ] 16 | ], 17 | 'cache' => [ 18 | 'class' => 'yii\caching\FileCache', 19 | ], 20 | 'user' => [ 21 | 'identityClass' => 'app\models\User', 22 | 'enableAutoLogin' => true, 23 | ], 24 | 'errorHandler' => [ 25 | 'errorAction' => 'site/error', 26 | ], 27 | 'mailer' => [ 28 | 'class' => 'yii\swiftmailer\Mailer', 29 | // send all mails to a file by default. You have to set 30 | // 'useFileTransport' to false and configure a transport 31 | // for the mailer to send real emails. 32 | 'useFileTransport' => true, 33 | ], 34 | 'log' => [ 35 | 'traceLevel' => YII_DEBUG ? 3 : 0, 36 | 'targets' => [ 37 | [ 38 | 'class' => 'yii\log\FileTarget', 39 | 'levels' => ['error', 'warning'], 40 | ], 41 | ], 42 | ], 43 | 'db' => require(__DIR__ . '/db.php'), 44 | 'urlManager' => [ 45 | 'enablePrettyUrl' => true, 46 | 'enableStrictParsing' => true, 47 | 'showScriptName' => false, 48 | 'rules' => [ 49 | [ 50 | 'class' => 'yii\rest\UrlRule', 51 | 'controller' => ['v1/user'], 52 | 'extraPatterns' => [ 53 | 'POST query' => 'query' 54 | ] 55 | ], 56 | ], 57 | ] 58 | ], 59 | 'modules' => [ 60 | 'v1' => [ 61 | 'class' => 'app\modules\v1\Module', 62 | ], 63 | ], 64 | 'params' => $params, 65 | ]; 66 | 67 | if (YII_ENV_DEV) { 68 | // configuration adjustments for 'dev' environment 69 | // $config['bootstrap'][] = 'debug'; 70 | // $config['modules']['debug'] = [ 71 | // 'class' => 'yii\debug\Module', 72 | // ]; 73 | 74 | $config['bootstrap'][] = 'gii'; 75 | $config['modules']['gii'] = [ 76 | 'class' => 'yii\gii\Module', 77 | ]; 78 | } 79 | 80 | return $config; 81 | -------------------------------------------------------------------------------- /models/User.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'id' => '100', 16 | 'username' => 'admin', 17 | 'password' => 'admin', 18 | 'authKey' => 'test100key', 19 | 'accessToken' => '100-token', 20 | ], 21 | '101' => [ 22 | 'id' => '101', 23 | 'username' => 'demo', 24 | 'password' => 'demo', 25 | 'authKey' => 'test101key', 26 | 'accessToken' => '101-token', 27 | ], 28 | ]; 29 | 30 | /** 31 | * @inheritdoc 32 | */ 33 | public static function findIdentity($id) 34 | { 35 | return isset(self::$users[$id]) ? new static(self::$users[$id]) : null; 36 | } 37 | 38 | /** 39 | * @inheritdoc 40 | */ 41 | public static function findIdentityByAccessToken($token, $type = null) 42 | { 43 | foreach (self::$users as $user) { 44 | if ($user['accessToken'] === $token) { 45 | return new static($user); 46 | } 47 | } 48 | 49 | return null; 50 | } 51 | 52 | /** 53 | * Finds user by username 54 | * 55 | * @param string $username 56 | * @return static|null 57 | */ 58 | public static function findByUsername($username) 59 | { 60 | foreach (self::$users as $user) { 61 | if (strcasecmp($user['username'], $username) === 0) { 62 | return new static($user); 63 | } 64 | } 65 | 66 | return null; 67 | } 68 | 69 | /** 70 | * @inheritdoc 71 | */ 72 | public function getId() 73 | { 74 | return $this->id; 75 | } 76 | 77 | /** 78 | * @inheritdoc 79 | */ 80 | public function getAuthKey() 81 | { 82 | return $this->authKey; 83 | } 84 | 85 | /** 86 | * @inheritdoc 87 | */ 88 | public function validateAuthKey($authKey) 89 | { 90 | return $this->authKey === $authKey; 91 | } 92 | 93 | /** 94 | * Validates password 95 | * 96 | * @param string $password password to validate 97 | * @return boolean if password provided is valid for current user 98 | */ 99 | public function validatePassword($password) 100 | { 101 | return $this->password === $password; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /controllers/SiteController.php: -------------------------------------------------------------------------------- 1 | [ 19 | 'class' => AccessControl::className(), 20 | 'only' => ['logout'], 21 | 'rules' => [ 22 | [ 23 | 'actions' => ['logout'], 24 | 'allow' => true, 25 | 'roles' => ['@'], 26 | ], 27 | ], 28 | ], 29 | 'verbs' => [ 30 | 'class' => VerbFilter::className(), 31 | 'actions' => [ 32 | 'logout' => ['post'], 33 | ], 34 | ], 35 | ]; 36 | } 37 | 38 | public function actions() 39 | { 40 | return [ 41 | 'error' => [ 42 | 'class' => 'yii\web\ErrorAction', 43 | ], 44 | 'captcha' => [ 45 | 'class' => 'yii\captcha\CaptchaAction', 46 | 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, 47 | ], 48 | 'doc' => [ 49 | 'class' => 'light\swagger\SwaggerAction', 50 | 'restUrl' => url::to(['/site/api'], true), 51 | ], 52 | 'api' => [ 53 | 'class' => 'light\swagger\SwaggerApiAction', 54 | 'scanDir' => [ 55 | Yii::getAlias('@app/modules/v1/swagger'), 56 | Yii::getAlias('@app/modules/v1/controllers'), 57 | Yii::getAlias('@app/modules/v1/models'), 58 | ], 59 | 'api_key' => 'test' 60 | ], 61 | ]; 62 | } 63 | 64 | public function actionIndex() 65 | { 66 | return $this->render('index'); 67 | } 68 | 69 | public function actionLogin() 70 | { 71 | if (!\Yii::$app->user->isGuest) { 72 | return $this->goHome(); 73 | } 74 | 75 | $model = new LoginForm(); 76 | if ($model->load(Yii::$app->request->post()) && $model->login()) { 77 | return $this->goBack(); 78 | } 79 | return $this->render('login', [ 80 | 'model' => $model, 81 | ]); 82 | } 83 | 84 | public function actionLogout() 85 | { 86 | Yii::$app->user->logout(); 87 | 88 | return $this->goHome(); 89 | } 90 | 91 | public function actionContact() 92 | { 93 | $model = new ContactForm(); 94 | if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) { 95 | Yii::$app->session->setFlash('contactFormSubmitted'); 96 | 97 | return $this->refresh(); 98 | } 99 | return $this->render('contact', [ 100 | 'model' => $model, 101 | ]); 102 | } 103 | 104 | public function actionAbout() 105 | { 106 | return $this->render('about'); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | This directory contains various tests for the basic application. 2 | 3 | Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/). 4 | 5 | After creating the basic application, follow these steps to prepare for the tests: 6 | 7 | 1. Install Codeception if it's not yet installed: 8 | 9 | ``` 10 | composer global require "codeception/codeception=2.0.*" 11 | composer global require "codeception/specify=*" 12 | composer global require "codeception/verify=*" 13 | ``` 14 | 15 | If you've never used Composer for global packages run `composer global status`. It should output: 16 | 17 | ``` 18 | Changed current directory to 19 | ``` 20 | 21 | Then add `/vendor/bin` to you `PATH` environment variable. Now we're able to use `codecept` from command 22 | line globally. 23 | 24 | 2. Install faker extension by running the following from template root directory where `composer.json` is: 25 | 26 | ``` 27 | composer require --dev yiisoft/yii2-faker:* 28 | ``` 29 | 30 | 3. Create `yii2_basic_tests` database and update it by applying migrations (you may skip this step if you do not have created any migrations yet): 31 | 32 | ``` 33 | codeception/bin/yii migrate 34 | ``` 35 | 36 | The command needs to be run in the `tests` directory. 37 | The database configuration can be found at `tests/codeception/config/config.php`. 38 | 39 | 4. Build the test suites: 40 | 41 | ``` 42 | codecept build 43 | ``` 44 | 45 | 5. In order to be able to run acceptance tests you need to start a webserver. The simplest way is to use PHP built in 46 | webserver. In the `web` directory execute the following: 47 | 48 | ``` 49 | php -S localhost:8080 50 | ``` 51 | 52 | 6. Now you can run the tests with the following commands: 53 | 54 | ``` 55 | # run all available tests 56 | codecept run 57 | # run acceptance tests 58 | codecept run acceptance 59 | # run functional tests 60 | codecept run functional 61 | # run unit tests 62 | codecept run unit 63 | ``` 64 | 65 | Code coverage support 66 | --------------------- 67 | 68 | By default, code coverage is disabled in `codeception.yml` configuration file, you should uncomment needed rows to be able 69 | to collect code coverage. You can run your tests and collect coverage with the following command: 70 | 71 | ``` 72 | #collect coverage for all tests 73 | codecept run --coverage-html --coverage-xml 74 | 75 | #collect coverage only for unit tests 76 | codecept run unit --coverage-html --coverage-xml 77 | 78 | #collect coverage for unit and functional tests 79 | codecept run functional,unit --coverage-html --coverage-xml 80 | ``` 81 | 82 | You can see code coverage output under the `tests/_output` directory. 83 | 84 | ###Remote code coverage 85 | 86 | When you run your tests not in the same process where code coverage is collected, then you should uncomment `remote` option and its 87 | related options, to be able to collect code coverage correctly. To setup remote code coverage you should follow [instructions](http://codeception.com/docs/11-Codecoverage) 88 | from codeception site. 89 | 90 | 1. install `Codeception c3` remote support `composer require "codeception/c3:*"`; 91 | 92 | 2. copy `c3.php` file under your `web` directory; 93 | 94 | 3. include `c3.php` file in your `index-test.php` file before application run, so it can catch needed requests. 95 | 96 | 4. edit `c3.php` to update config file path (~ line 55) with `$config_file = realpath(__DIR__ . '/../tests/codeception.yml');` 97 | 98 | Configuration options that are used by remote code coverage: 99 | 100 | - c3_url: url pointing to entry script that includes `c3.php` file, so `Codeception` will be able to produce code coverage; 101 | - remote: whether to enable remote code coverage or not; 102 | - remote_config: path to the `codeception.yml` configuration file, from the directory where `c3.php` file is located. This is needed 103 | so that `Codeception` can create itself instance and collect code coverage correctly. 104 | 105 | By default `c3_url` and `remote_config` setup correctly, you only need to copy and include `c3.php` file in your `index-test.php` 106 | 107 | After that you should be able to collect code coverage from tests that run through `PhpBrowser` or `WebDriver` with same command 108 | as for other tests: 109 | 110 | ``` 111 | #collect coverage from remote 112 | codecept run acceptance --coverage-html --coverage-xml 113 | ``` 114 | 115 | Please refer to [Codeception tutorial](http://codeception.com/docs/01-Introduction) for 116 | more details about writing and running acceptance, functional and unit tests. 117 | -------------------------------------------------------------------------------- /requirements.php: -------------------------------------------------------------------------------- 1 | Error'; 18 | echo '

The path to yii framework seems to be incorrect.

'; 19 | echo '

You need to install Yii framework via composer or adjust the framework path in file ' . basename(__FILE__) . '.

'; 20 | echo '

Please refer to the README on how to install Yii.

'; 21 | } 22 | 23 | require_once($frameworkPath . '/requirements/YiiRequirementChecker.php'); 24 | $requirementsChecker = new YiiRequirementChecker(); 25 | 26 | $gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.'; 27 | $gdOK = $imagickOK = false; 28 | 29 | if (extension_loaded('imagick')) { 30 | $imagick = new Imagick(); 31 | $imagickFormats = $imagick->queryFormats('PNG'); 32 | if (in_array('PNG', $imagickFormats)) { 33 | $imagickOK = true; 34 | } else { 35 | $imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.'; 36 | } 37 | } 38 | 39 | if (extension_loaded('gd')) { 40 | $gdInfo = gd_info(); 41 | if (!empty($gdInfo['FreeType Support'])) { 42 | $gdOK = true; 43 | } else { 44 | $gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.'; 45 | } 46 | } 47 | 48 | /** 49 | * Adjust requirements according to your application specifics. 50 | */ 51 | $requirements = array( 52 | // Database : 53 | array( 54 | 'name' => 'PDO extension', 55 | 'mandatory' => true, 56 | 'condition' => extension_loaded('pdo'), 57 | 'by' => 'All DB-related classes', 58 | ), 59 | array( 60 | 'name' => 'PDO SQLite extension', 61 | 'mandatory' => false, 62 | 'condition' => extension_loaded('pdo_sqlite'), 63 | 'by' => 'All DB-related classes', 64 | 'memo' => 'Required for SQLite database.', 65 | ), 66 | array( 67 | 'name' => 'PDO MySQL extension', 68 | 'mandatory' => false, 69 | 'condition' => extension_loaded('pdo_mysql'), 70 | 'by' => 'All DB-related classes', 71 | 'memo' => 'Required for MySQL database.', 72 | ), 73 | array( 74 | 'name' => 'PDO PostgreSQL extension', 75 | 'mandatory' => false, 76 | 'condition' => extension_loaded('pdo_pgsql'), 77 | 'by' => 'All DB-related classes', 78 | 'memo' => 'Required for PostgreSQL database.', 79 | ), 80 | // Cache : 81 | array( 82 | 'name' => 'Memcache extension', 83 | 'mandatory' => false, 84 | 'condition' => extension_loaded('memcache') || extension_loaded('memcached'), 85 | 'by' => 'MemCache', 86 | 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : '' 87 | ), 88 | array( 89 | 'name' => 'APC extension', 90 | 'mandatory' => false, 91 | 'condition' => extension_loaded('apc'), 92 | 'by' => 'ApcCache', 93 | ), 94 | // CAPTCHA: 95 | array( 96 | 'name' => 'GD PHP extension with FreeType support', 97 | 'mandatory' => false, 98 | 'condition' => $gdOK, 99 | 'by' => 'Captcha', 100 | 'memo' => $gdMemo, 101 | ), 102 | array( 103 | 'name' => 'ImageMagick PHP extension with PNG support', 104 | 'mandatory' => false, 105 | 'condition' => $imagickOK, 106 | 'by' => 'Captcha', 107 | 'memo' => $imagickMemo, 108 | ), 109 | // PHP ini : 110 | 'phpExposePhp' => array( 111 | 'name' => 'Expose PHP', 112 | 'mandatory' => false, 113 | 'condition' => $requirementsChecker->checkPhpIniOff("expose_php"), 114 | 'by' => 'Security reasons', 115 | 'memo' => '"expose_php" should be disabled at php.ini', 116 | ), 117 | 'phpAllowUrlInclude' => array( 118 | 'name' => 'PHP allow url include', 119 | 'mandatory' => false, 120 | 'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"), 121 | 'by' => 'Security reasons', 122 | 'memo' => '"allow_url_include" should be disabled at php.ini', 123 | ), 124 | 'phpSmtp' => array( 125 | 'name' => 'PHP mail SMTP', 126 | 'mandatory' => false, 127 | 'condition' => strlen(ini_get('SMTP'))>0, 128 | 'by' => 'Email sending', 129 | 'memo' => 'PHP mail SMTP server required', 130 | ), 131 | ); 132 | $requirementsChecker->checkYii()->check($requirements)->render(); 133 | -------------------------------------------------------------------------------- /modules/v1/controllers/UserController.php: -------------------------------------------------------------------------------- 1 | $this->action->id, 36 | 'items' => [], 37 | ]; 38 | } 39 | 40 | /** 41 | * @SWG\Post(path="/users", 42 | * tags={"user"}, 43 | * summary="创建用户接口", 44 | * description="测试Param是 *query* 类型, 如果设置成 *formData* 类型的就可以使用post获取数据", 45 | * produces={"application/json"}, 46 | * @SWG\Parameter( 47 | * in = "formData", 48 | * name = "username", 49 | * description = "用户姓名", 50 | * required = true, 51 | * type = "string" 52 | * ), 53 | * @SWG\Parameter( 54 | * in = "formData", 55 | * name = "phone", 56 | * description = "手机号", 57 | * required = true, 58 | * type = "string" 59 | * ), 60 | * @SWG\Parameter( 61 | * in = "formData", 62 | * name = "sex", 63 | * description = "性别 1. 男 2.女 此项为非必填项.展示成select", 64 | * required = false, 65 | * type = "integer", 66 | * enum = {1, 2} 67 | * ), 68 | * 69 | * @SWG\Response( 70 | * response = 200, 71 | * description = " success" 72 | * ), 73 | * @SWG\Response( 74 | * response = 401, 75 | * description = "需要重新登陆", 76 | * @SWG\Schema(ref="#/definitions/Error") 77 | * ) 78 | * ) 79 | * 80 | */ 81 | public function actionCreate() 82 | { 83 | return [ 84 | 'action' => $this->action->id, 85 | 'post_data' => Yii::$app->getRequest()->post(), 86 | ]; 87 | } 88 | 89 | /** 90 | * @SWG\Put(path="/users/{id}", 91 | * tags={"user"}, 92 | * summary="更新用户接口", 93 | * description="*path*类型的参数会放入请求地址地址中", 94 | * produces={"application/json"}, 95 | * @SWG\Parameter( 96 | * in = "path", 97 | * name = "id", 98 | * description = "用户ID", 99 | * required = true, 100 | * type = "integer" 101 | * ), 102 | * @SWG\Parameter( 103 | * in = "formData", 104 | * name = "username", 105 | * description = "用户姓名", 106 | * required = true, 107 | * type = "string" 108 | * ), 109 | * @SWG\Parameter( 110 | * in = "formData", 111 | * name = "phone", 112 | * description = "手机号", 113 | * required = true, 114 | * type = "string" 115 | * ), 116 | * @SWG\Parameter( 117 | * in = "formData", 118 | * name = "sex", 119 | * description = "性别 1. 男 2.女 此项为非必填项.这里指定了一个默认项,那么会默认选中", 120 | * required = false, 121 | * type = "integer", 122 | * default = 1, 123 | * enum = {1, 2} 124 | * ), 125 | * @SWG\Parameter( 126 | * in = "formData", 127 | * name = "job", 128 | * description = "这里可以设置默认值", 129 | * required = false, 130 | * type = "string", 131 | * default = "程序猿" 132 | * ), 133 | * @SWG\Parameter( 134 | * in = "formData", 135 | * name = "avatar", 136 | * description = "类型设置为`file`则可以展示上传按钮,在后端和普通上传一样处理", 137 | * required = false, 138 | * type = "file" 139 | * ), 140 | * 141 | * @SWG\Response( 142 | * response = 200, 143 | * description = " success" 144 | * ), 145 | * @SWG\Response( 146 | * response = 401, 147 | * description = "需要重新登陆", 148 | * @SWG\Schema(ref="#/definitions/Error") 149 | * ) 150 | * ) 151 | * @param integer $id 152 | * 153 | * @return array 154 | */ 155 | public function actionUpdate($id) 156 | { 157 | return [ 158 | 'action' => $this->action->id, 159 | 'user_id' => $id, 160 | 'post_data' => Yii::$app->request->post(), 161 | ]; 162 | } 163 | 164 | /** 165 | * @SWG\Post( 166 | * path = "/users/query", 167 | * tags = {"user"}, 168 | * operationId = "QueryUser", 169 | * summary = "删除用户", 170 | * description = "这里展示一个稍微高端点的用法", 171 | * produces = {"application/json"}, 172 | * consumes = {"application/json"}, 173 | * @SWG\Parameter( 174 | * in = "body", 175 | * name = "body", 176 | * description = "这里要主要配置`request`组件的parsers,来支持接收这个类型的请求", 177 | * required = true, 178 | * type = "string", 179 | * @SWG\Schema(ref = "#/definitions/UserIdList") 180 | * ), 181 | * @SWG\Response(response = 200, description = "success") 182 | *) 183 | */ 184 | public function actionQuery() 185 | { 186 | return [ 187 | 'action' => $this->action->id, 188 | 'data' => Yii::$app->request->post(), 189 | ]; 190 | } 191 | 192 | /** 193 | * @SWG\Options( 194 | * path = "/users", 195 | * tags = {"user"}, 196 | * operationId = "userOptions", 197 | * summary = "options", 198 | * produces = {"application/json"}, 199 | * consumes = {"application/json"}, 200 | * @SWG\Response( 201 | * response = 200, 202 | * description = "success", 203 | * @SWG\Header(header="Allow", type="GET, POST, HEAD, OPTIONS"), 204 | * @SWG\Header(header="Content-Type", type="application/json; charset=UTF-8") 205 | * ) 206 | *) 207 | */ 208 | public function actions() 209 | { 210 | return [ 211 | 'options' => OptionsAction::class, 212 | ]; 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "21d00d1d9e25e0bc0fee6d78a2d7a1b1", 8 | "packages": [ 9 | { 10 | "name": "bower-asset/bootstrap", 11 | "version": "v3.3.7", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/twbs/bootstrap.git", 15 | "reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/twbs/bootstrap/zipball/0b9c4a4007c44201dce9a6cc1a38407005c26c86", 20 | "reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "bower-asset/jquery": ">=1.9.1,<4.0" 25 | }, 26 | "type": "bower-asset-library", 27 | "extra": { 28 | "bower-asset-main": [ 29 | "less/bootstrap.less", 30 | "dist/js/bootstrap.js" 31 | ], 32 | "bower-asset-ignore": [ 33 | "/.*", 34 | "_config.yml", 35 | "CNAME", 36 | "composer.json", 37 | "CONTRIBUTING.md", 38 | "docs", 39 | "js/tests", 40 | "test-infra" 41 | ] 42 | }, 43 | "license": [ 44 | "MIT" 45 | ], 46 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 47 | "keywords": [ 48 | "css", 49 | "framework", 50 | "front-end", 51 | "js", 52 | "less", 53 | "mobile-first", 54 | "responsive", 55 | "web" 56 | ], 57 | "time": "2016-07-25T15:51:55+00:00" 58 | }, 59 | { 60 | "name": "bower-asset/jquery", 61 | "version": "2.2.4", 62 | "source": { 63 | "type": "git", 64 | "url": "https://github.com/jquery/jquery-dist.git", 65 | "reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72" 66 | }, 67 | "dist": { 68 | "type": "zip", 69 | "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/c0185ab7c75aab88762c5aae780b9d83b80eda72", 70 | "reference": "c0185ab7c75aab88762c5aae780b9d83b80eda72", 71 | "shasum": "" 72 | }, 73 | "type": "bower-asset-library", 74 | "extra": { 75 | "bower-asset-main": "dist/jquery.js", 76 | "bower-asset-ignore": [ 77 | "package.json" 78 | ] 79 | }, 80 | "license": [ 81 | "MIT" 82 | ], 83 | "keywords": [ 84 | "browser", 85 | "javascript", 86 | "jquery", 87 | "library" 88 | ], 89 | "time": "2016-05-20T17:24:43+00:00" 90 | }, 91 | { 92 | "name": "bower-asset/jquery.inputmask", 93 | "version": "3.3.9", 94 | "source": { 95 | "type": "git", 96 | "url": "https://github.com/RobinHerbots/Inputmask.git", 97 | "reference": "1fadb54be8a94e879fd1e9693b5222fb36aea04f" 98 | }, 99 | "dist": { 100 | "type": "zip", 101 | "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/1fadb54be8a94e879fd1e9693b5222fb36aea04f", 102 | "reference": "1fadb54be8a94e879fd1e9693b5222fb36aea04f", 103 | "shasum": "" 104 | }, 105 | "require": { 106 | "bower-asset/jquery": ">=1.7" 107 | }, 108 | "type": "bower-asset-library", 109 | "extra": { 110 | "bower-asset-main": [ 111 | "./dist/inputmask/inputmask.js", 112 | "./dist/inputmask/inputmask.extensions.js", 113 | "./dist/inputmask/inputmask.date.extensions.js", 114 | "./dist/inputmask/inputmask.numeric.extensions.js", 115 | "./dist/inputmask/inputmask.phone.extensions.js", 116 | "./dist/inputmask/jquery.inputmask.js", 117 | "./dist/inputmask/global/document.js", 118 | "./dist/inputmask/global/window.js", 119 | "./dist/inputmask/phone-codes/phone.js", 120 | "./dist/inputmask/phone-codes/phone-be.js", 121 | "./dist/inputmask/phone-codes/phone-nl.js", 122 | "./dist/inputmask/phone-codes/phone-ru.js", 123 | "./dist/inputmask/phone-codes/phone-uk.js", 124 | "./dist/inputmask/dependencyLibs/inputmask.dependencyLib.jqlite.js", 125 | "./dist/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.js", 126 | "./dist/inputmask/dependencyLibs/inputmask.dependencyLib.js", 127 | "./dist/inputmask/bindings/inputmask.binding.js" 128 | ], 129 | "bower-asset-ignore": [ 130 | "**/*", 131 | "!dist/*", 132 | "!dist/inputmask/*", 133 | "!dist/min/*", 134 | "!dist/min/inputmask/*" 135 | ] 136 | }, 137 | "license": [ 138 | "http://opensource.org/licenses/mit-license.php" 139 | ], 140 | "description": "Inputmask is a javascript library which creates an input mask. Inputmask can run against vanilla javascript, jQuery and jqlite.", 141 | "keywords": [ 142 | "form", 143 | "input", 144 | "inputmask", 145 | "jquery", 146 | "mask", 147 | "plugins" 148 | ], 149 | "time": "2017-10-10T12:47:01+00:00" 150 | }, 151 | { 152 | "name": "bower-asset/punycode", 153 | "version": "v1.3.2", 154 | "source": { 155 | "type": "git", 156 | "url": "https://github.com/bestiejs/punycode.js.git", 157 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" 158 | }, 159 | "dist": { 160 | "type": "zip", 161 | "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3", 162 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3", 163 | "shasum": "" 164 | }, 165 | "type": "bower-asset-library", 166 | "extra": { 167 | "bower-asset-main": "punycode.js", 168 | "bower-asset-ignore": [ 169 | "coverage", 170 | "tests", 171 | ".*", 172 | "component.json", 173 | "Gruntfile.js", 174 | "node_modules", 175 | "package.json" 176 | ] 177 | }, 178 | "time": "2014-10-22T12:02:42+00:00" 179 | }, 180 | { 181 | "name": "bower-asset/yii2-pjax", 182 | "version": "v2.0.7", 183 | "source": { 184 | "type": "git", 185 | "url": "https://github.com/yiisoft/jquery-pjax.git", 186 | "reference": "885fc8c2d36c93a801b6af0ee8ad55d79df97cb1" 187 | }, 188 | "dist": { 189 | "type": "zip", 190 | "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/885fc8c2d36c93a801b6af0ee8ad55d79df97cb1", 191 | "reference": "885fc8c2d36c93a801b6af0ee8ad55d79df97cb1", 192 | "shasum": "" 193 | }, 194 | "require": { 195 | "bower-asset/jquery": ">=1.8" 196 | }, 197 | "type": "bower-asset-library", 198 | "extra": { 199 | "bower-asset-main": "./jquery.pjax.js", 200 | "bower-asset-ignore": [ 201 | ".travis.yml", 202 | "Gemfile", 203 | "Gemfile.lock", 204 | "CONTRIBUTING.md", 205 | "vendor/", 206 | "script/", 207 | "test/" 208 | ] 209 | }, 210 | "license": [ 211 | "MIT" 212 | ], 213 | "time": "2017-09-27T10:22:38+00:00" 214 | }, 215 | { 216 | "name": "cebe/markdown", 217 | "version": "1.1.2", 218 | "source": { 219 | "type": "git", 220 | "url": "https://github.com/cebe/markdown.git", 221 | "reference": "25b28bae8a6f185b5030673af77b32e1163d5c6e" 222 | }, 223 | "dist": { 224 | "type": "zip", 225 | "url": "https://files.phpcomposer.com/files/cebe/markdown/25b28bae8a6f185b5030673af77b32e1163d5c6e.zip", 226 | "reference": "25b28bae8a6f185b5030673af77b32e1163d5c6e", 227 | "shasum": "" 228 | }, 229 | "require": { 230 | "lib-pcre": "*", 231 | "php": ">=5.4.0" 232 | }, 233 | "require-dev": { 234 | "cebe/indent": "*", 235 | "facebook/xhprof": "*@dev", 236 | "phpunit/phpunit": "4.1.*" 237 | }, 238 | "bin": [ 239 | "bin/markdown" 240 | ], 241 | "type": "library", 242 | "extra": { 243 | "branch-alias": { 244 | "dev-master": "1.1.x-dev" 245 | } 246 | }, 247 | "autoload": { 248 | "psr-4": { 249 | "cebe\\markdown\\": "" 250 | } 251 | }, 252 | "notification-url": "https://packagist.org/downloads/", 253 | "license": [ 254 | "MIT" 255 | ], 256 | "authors": [ 257 | { 258 | "name": "Carsten Brandt", 259 | "email": "mail@cebe.cc", 260 | "homepage": "http://cebe.cc/", 261 | "role": "Creator" 262 | } 263 | ], 264 | "description": "A super fast, highly extensible markdown parser for PHP", 265 | "homepage": "https://github.com/cebe/markdown#readme", 266 | "keywords": [ 267 | "extensible", 268 | "fast", 269 | "gfm", 270 | "markdown", 271 | "markdown-extra" 272 | ], 273 | "time": "2017-07-16T21:13:23+00:00" 274 | }, 275 | { 276 | "name": "doctrine/lexer", 277 | "version": "v1.0.1", 278 | "source": { 279 | "type": "git", 280 | "url": "https://github.com/doctrine/lexer.git", 281 | "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" 282 | }, 283 | "dist": { 284 | "type": "zip", 285 | "url": "https://files.phpcomposer.com/files/doctrine/lexer/83893c552fd2045dd78aef794c31e694c37c0b8c.zip", 286 | "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", 287 | "shasum": "" 288 | }, 289 | "require": { 290 | "php": ">=5.3.2" 291 | }, 292 | "type": "library", 293 | "extra": { 294 | "branch-alias": { 295 | "dev-master": "1.0.x-dev" 296 | } 297 | }, 298 | "autoload": { 299 | "psr-0": { 300 | "Doctrine\\Common\\Lexer\\": "lib/" 301 | } 302 | }, 303 | "notification-url": "https://packagist.org/downloads/", 304 | "license": [ 305 | "MIT" 306 | ], 307 | "authors": [ 308 | { 309 | "name": "Roman Borschel", 310 | "email": "roman@code-factory.org" 311 | }, 312 | { 313 | "name": "Guilherme Blanco", 314 | "email": "guilhermeblanco@gmail.com" 315 | }, 316 | { 317 | "name": "Johannes Schmitt", 318 | "email": "schmittjoh@gmail.com" 319 | } 320 | ], 321 | "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", 322 | "homepage": "http://www.doctrine-project.org", 323 | "keywords": [ 324 | "lexer", 325 | "parser" 326 | ], 327 | "time": "2014-09-09T13:34:57+00:00" 328 | }, 329 | { 330 | "name": "egulias/email-validator", 331 | "version": "2.1.2", 332 | "source": { 333 | "type": "git", 334 | "url": "https://github.com/egulias/EmailValidator.git", 335 | "reference": "bc31baa11ea2883e017f0a10d9722ef9d50eac1c" 336 | }, 337 | "dist": { 338 | "type": "zip", 339 | "url": "https://files.phpcomposer.com/files/egulias/EmailValidator/bc31baa11ea2883e017f0a10d9722ef9d50eac1c.zip", 340 | "reference": "bc31baa11ea2883e017f0a10d9722ef9d50eac1c", 341 | "shasum": "" 342 | }, 343 | "require": { 344 | "doctrine/lexer": "^1.0.1", 345 | "php": ">= 5.5" 346 | }, 347 | "require-dev": { 348 | "dominicsayers/isemail": "dev-master", 349 | "phpunit/phpunit": "^4.8.0", 350 | "satooshi/php-coveralls": "dev-master" 351 | }, 352 | "suggest": { 353 | "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" 354 | }, 355 | "type": "library", 356 | "extra": { 357 | "branch-alias": { 358 | "dev-master": "2.0.x-dev" 359 | } 360 | }, 361 | "autoload": { 362 | "psr-4": { 363 | "Egulias\\EmailValidator\\": "EmailValidator" 364 | } 365 | }, 366 | "notification-url": "https://packagist.org/downloads/", 367 | "license": [ 368 | "MIT" 369 | ], 370 | "authors": [ 371 | { 372 | "name": "Eduardo Gulias Davis" 373 | } 374 | ], 375 | "description": "A library for validating emails against several RFCs", 376 | "homepage": "https://github.com/egulias/EmailValidator", 377 | "keywords": [ 378 | "email", 379 | "emailvalidation", 380 | "emailvalidator", 381 | "validation", 382 | "validator" 383 | ], 384 | "time": "2017-01-30T22:07:36+00:00" 385 | }, 386 | { 387 | "name": "ezyang/htmlpurifier", 388 | "version": "v4.9.3", 389 | "source": { 390 | "type": "git", 391 | "url": "https://github.com/ezyang/htmlpurifier.git", 392 | "reference": "95e1bae3182efc0f3422896a3236e991049dac69" 393 | }, 394 | "dist": { 395 | "type": "zip", 396 | "url": "https://files.phpcomposer.com/files/ezyang/htmlpurifier/95e1bae3182efc0f3422896a3236e991049dac69.zip", 397 | "reference": "95e1bae3182efc0f3422896a3236e991049dac69", 398 | "shasum": "" 399 | }, 400 | "require": { 401 | "php": ">=5.2" 402 | }, 403 | "require-dev": { 404 | "simpletest/simpletest": "^1.1" 405 | }, 406 | "type": "library", 407 | "autoload": { 408 | "psr-0": { 409 | "HTMLPurifier": "library/" 410 | }, 411 | "files": [ 412 | "library/HTMLPurifier.composer.php" 413 | ] 414 | }, 415 | "notification-url": "https://packagist.org/downloads/", 416 | "license": [ 417 | "LGPL" 418 | ], 419 | "authors": [ 420 | { 421 | "name": "Edward Z. Yang", 422 | "email": "admin@htmlpurifier.org", 423 | "homepage": "http://ezyang.com" 424 | } 425 | ], 426 | "description": "Standards compliant HTML filter written in PHP", 427 | "homepage": "http://htmlpurifier.org/", 428 | "keywords": [ 429 | "html" 430 | ], 431 | "time": "2017-06-03T02:28:16+00:00" 432 | }, 433 | { 434 | "name": "swiftmailer/swiftmailer", 435 | "version": "v6.0.2", 436 | "source": { 437 | "type": "git", 438 | "url": "https://github.com/swiftmailer/swiftmailer.git", 439 | "reference": "412333372fb6c8ffb65496a2bbd7321af75733fc" 440 | }, 441 | "dist": { 442 | "type": "zip", 443 | "url": "https://files.phpcomposer.com/files/swiftmailer/swiftmailer/412333372fb6c8ffb65496a2bbd7321af75733fc.zip", 444 | "reference": "412333372fb6c8ffb65496a2bbd7321af75733fc", 445 | "shasum": "" 446 | }, 447 | "require": { 448 | "egulias/email-validator": "~2.0", 449 | "php": ">=7.0.0" 450 | }, 451 | "require-dev": { 452 | "mockery/mockery": "~0.9.1", 453 | "symfony/phpunit-bridge": "~3.3@dev" 454 | }, 455 | "type": "library", 456 | "extra": { 457 | "branch-alias": { 458 | "dev-master": "6.0-dev" 459 | } 460 | }, 461 | "autoload": { 462 | "files": [ 463 | "lib/swift_required.php" 464 | ] 465 | }, 466 | "notification-url": "https://packagist.org/downloads/", 467 | "license": [ 468 | "MIT" 469 | ], 470 | "authors": [ 471 | { 472 | "name": "Chris Corbyn" 473 | }, 474 | { 475 | "name": "Fabien Potencier", 476 | "email": "fabien@symfony.com" 477 | } 478 | ], 479 | "description": "Swiftmailer, free feature-rich PHP mailer", 480 | "homepage": "http://swiftmailer.symfony.com", 481 | "keywords": [ 482 | "email", 483 | "mail", 484 | "mailer" 485 | ], 486 | "time": "2017-09-30T22:39:41+00:00" 487 | }, 488 | { 489 | "name": "yiisoft/yii2", 490 | "version": "2.0.12", 491 | "source": { 492 | "type": "git", 493 | "url": "https://github.com/yiisoft/yii2-framework.git", 494 | "reference": "70acbecc75cb26b6cd66d16be0b06e4b73db190d" 495 | }, 496 | "dist": { 497 | "type": "zip", 498 | "url": "https://files.phpcomposer.com/files/yiisoft/yii2-framework/70acbecc75cb26b6cd66d16be0b06e4b73db190d.zip", 499 | "reference": "70acbecc75cb26b6cd66d16be0b06e4b73db190d", 500 | "shasum": "" 501 | }, 502 | "require": { 503 | "bower-asset/jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", 504 | "bower-asset/jquery.inputmask": "~3.2.2 | ~3.3.5", 505 | "bower-asset/punycode": "1.3.*", 506 | "bower-asset/yii2-pjax": "~2.0.1", 507 | "cebe/markdown": "~1.0.0 | ~1.1.0", 508 | "ext-ctype": "*", 509 | "ext-mbstring": "*", 510 | "ezyang/htmlpurifier": "~4.6", 511 | "lib-pcre": "*", 512 | "php": ">=5.4.0", 513 | "yiisoft/yii2-composer": "~2.0.4" 514 | }, 515 | "bin": [ 516 | "yii" 517 | ], 518 | "type": "library", 519 | "extra": { 520 | "branch-alias": { 521 | "dev-master": "2.0.x-dev" 522 | } 523 | }, 524 | "autoload": { 525 | "psr-4": { 526 | "yii\\": "" 527 | } 528 | }, 529 | "notification-url": "https://packagist.org/downloads/", 530 | "license": [ 531 | "BSD-3-Clause" 532 | ], 533 | "authors": [ 534 | { 535 | "name": "Qiang Xue", 536 | "email": "qiang.xue@gmail.com", 537 | "homepage": "http://www.yiiframework.com/", 538 | "role": "Founder and project lead" 539 | }, 540 | { 541 | "name": "Alexander Makarov", 542 | "email": "sam@rmcreative.ru", 543 | "homepage": "http://rmcreative.ru/", 544 | "role": "Core framework development" 545 | }, 546 | { 547 | "name": "Maurizio Domba", 548 | "homepage": "http://mdomba.info/", 549 | "role": "Core framework development" 550 | }, 551 | { 552 | "name": "Carsten Brandt", 553 | "email": "mail@cebe.cc", 554 | "homepage": "http://cebe.cc/", 555 | "role": "Core framework development" 556 | }, 557 | { 558 | "name": "Timur Ruziev", 559 | "email": "resurtm@gmail.com", 560 | "homepage": "http://resurtm.com/", 561 | "role": "Core framework development" 562 | }, 563 | { 564 | "name": "Paul Klimov", 565 | "email": "klimov.paul@gmail.com", 566 | "role": "Core framework development" 567 | }, 568 | { 569 | "name": "Dmitry Naumenko", 570 | "email": "d.naumenko.a@gmail.com", 571 | "role": "Core framework development" 572 | }, 573 | { 574 | "name": "Boudewijn Vahrmeijer", 575 | "email": "info@dynasource.eu", 576 | "homepage": "http://dynasource.eu", 577 | "role": "Core framework development" 578 | } 579 | ], 580 | "description": "Yii PHP Framework Version 2", 581 | "homepage": "http://www.yiiframework.com/", 582 | "keywords": [ 583 | "framework", 584 | "yii2" 585 | ], 586 | "time": "2017-06-05T14:33:41+00:00" 587 | }, 588 | { 589 | "name": "yiisoft/yii2-bootstrap", 590 | "version": "2.0.7", 591 | "source": { 592 | "type": "git", 593 | "url": "https://github.com/yiisoft/yii2-bootstrap.git", 594 | "reference": "02a54d868343ed11d02f0f0f8cbbecb590e0cb3f" 595 | }, 596 | "dist": { 597 | "type": "zip", 598 | "url": "https://files.phpcomposer.com/files/yiisoft/yii2-bootstrap/02a54d868343ed11d02f0f0f8cbbecb590e0cb3f.zip", 599 | "reference": "02a54d868343ed11d02f0f0f8cbbecb590e0cb3f", 600 | "shasum": "" 601 | }, 602 | "require": { 603 | "bower-asset/bootstrap": "3.3.* | 3.2.* | 3.1.*", 604 | "yiisoft/yii2": "~2.0.6" 605 | }, 606 | "type": "yii2-extension", 607 | "extra": { 608 | "branch-alias": { 609 | "dev-master": "2.0.x-dev" 610 | } 611 | }, 612 | "autoload": { 613 | "psr-4": { 614 | "yii\\bootstrap\\": "" 615 | } 616 | }, 617 | "notification-url": "https://packagist.org/downloads/", 618 | "license": [ 619 | "BSD-3-Clause" 620 | ], 621 | "authors": [ 622 | { 623 | "name": "Qiang Xue", 624 | "email": "qiang.xue@gmail.com" 625 | } 626 | ], 627 | "description": "The Twitter Bootstrap extension for the Yii framework", 628 | "keywords": [ 629 | "bootstrap", 630 | "yii2" 631 | ], 632 | "time": "2017-10-09T19:48:22+00:00" 633 | }, 634 | { 635 | "name": "yiisoft/yii2-composer", 636 | "version": "2.0.5", 637 | "source": { 638 | "type": "git", 639 | "url": "https://github.com/yiisoft/yii2-composer.git", 640 | "reference": "3f4923c2bde6caf3f5b88cc22fdd5770f52f8df2" 641 | }, 642 | "dist": { 643 | "type": "zip", 644 | "url": "https://files.phpcomposer.com/files/yiisoft/yii2-composer/3f4923c2bde6caf3f5b88cc22fdd5770f52f8df2.zip", 645 | "reference": "3f4923c2bde6caf3f5b88cc22fdd5770f52f8df2", 646 | "shasum": "" 647 | }, 648 | "require": { 649 | "composer-plugin-api": "^1.0" 650 | }, 651 | "require-dev": { 652 | "composer/composer": "^1.0" 653 | }, 654 | "type": "composer-plugin", 655 | "extra": { 656 | "class": "yii\\composer\\Plugin", 657 | "branch-alias": { 658 | "dev-master": "2.0.x-dev" 659 | } 660 | }, 661 | "autoload": { 662 | "psr-4": { 663 | "yii\\composer\\": "" 664 | } 665 | }, 666 | "notification-url": "https://packagist.org/downloads/", 667 | "license": [ 668 | "BSD-3-Clause" 669 | ], 670 | "authors": [ 671 | { 672 | "name": "Qiang Xue", 673 | "email": "qiang.xue@gmail.com" 674 | } 675 | ], 676 | "description": "The composer plugin for Yii extension installer", 677 | "keywords": [ 678 | "composer", 679 | "extension installer", 680 | "yii2" 681 | ], 682 | "time": "2016-12-20T13:26:02+00:00" 683 | }, 684 | { 685 | "name": "yiisoft/yii2-swiftmailer", 686 | "version": "2.1.0", 687 | "source": { 688 | "type": "git", 689 | "url": "https://github.com/yiisoft/yii2-swiftmailer.git", 690 | "reference": "563570c9aa19ca47c1b22e3032983229378e9274" 691 | }, 692 | "dist": { 693 | "type": "zip", 694 | "url": "https://files.phpcomposer.com/files/yiisoft/yii2-swiftmailer/563570c9aa19ca47c1b22e3032983229378e9274.zip", 695 | "reference": "563570c9aa19ca47c1b22e3032983229378e9274", 696 | "shasum": "" 697 | }, 698 | "require": { 699 | "swiftmailer/swiftmailer": "~6.0", 700 | "yiisoft/yii2": "~2.0.4" 701 | }, 702 | "type": "yii2-extension", 703 | "extra": { 704 | "branch-alias": { 705 | "dev-master": "2.0.x-dev" 706 | } 707 | }, 708 | "autoload": { 709 | "psr-4": { 710 | "yii\\swiftmailer\\": "" 711 | } 712 | }, 713 | "notification-url": "https://packagist.org/downloads/", 714 | "license": [ 715 | "BSD-3-Clause" 716 | ], 717 | "authors": [ 718 | { 719 | "name": "Paul Klimov", 720 | "email": "klimov.paul@gmail.com" 721 | } 722 | ], 723 | "description": "The SwiftMailer integration for the Yii framework", 724 | "keywords": [ 725 | "email", 726 | "mail", 727 | "mailer", 728 | "swift", 729 | "swiftmailer", 730 | "yii2" 731 | ], 732 | "time": "2017-08-04T10:48:17+00:00" 733 | } 734 | ], 735 | "packages-dev": [ 736 | { 737 | "name": "bower-asset/swagger-ui", 738 | "version": "v2.2.10", 739 | "source": { 740 | "type": "git", 741 | "url": "https://github.com/swagger-api/swagger-ui.git", 742 | "reference": "64dc3060b3700b12e466f8d67b7d7ec3574b015f" 743 | }, 744 | "dist": { 745 | "type": "zip", 746 | "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/64dc3060b3700b12e466f8d67b7d7ec3574b015f", 747 | "reference": "64dc3060b3700b12e466f8d67b7d7ec3574b015f", 748 | "shasum": "" 749 | }, 750 | "type": "bower-asset-library", 751 | "extra": { 752 | "bower-asset-main": "dist/index.html", 753 | "bower-asset-ignore": [ 754 | "**/.*", 755 | "node_modules", 756 | "bower_components", 757 | "test", 758 | "tests" 759 | ], 760 | "bower-asset-private": true 761 | }, 762 | "license": [ 763 | "Apache-2.0", 764 | "Copyright 2016 SmartBear Software", 765 | "./LICENSE" 766 | ], 767 | "description": "Swagger UI", 768 | "keywords": [ 769 | "API", 770 | "Swagger" 771 | ], 772 | "time": "2017-01-05T08:57:09+00:00" 773 | }, 774 | { 775 | "name": "bower-asset/typeahead.js", 776 | "version": "v0.11.1", 777 | "source": { 778 | "type": "git", 779 | "url": "https://github.com/twitter/typeahead.js.git", 780 | "reference": "588440f66559714280628a4f9799f0c4eb880a4a" 781 | }, 782 | "dist": { 783 | "type": "zip", 784 | "url": "https://api.github.com/repos/twitter/typeahead.js/zipball/588440f66559714280628a4f9799f0c4eb880a4a", 785 | "reference": "588440f66559714280628a4f9799f0c4eb880a4a", 786 | "shasum": "" 787 | }, 788 | "require": { 789 | "bower-asset/jquery": ">=1.7" 790 | }, 791 | "require-dev": { 792 | "bower-asset/jasmine-ajax": "~1.3.1", 793 | "bower-asset/jasmine-jquery": "~1.5.2", 794 | "bower-asset/jquery": "~1.7" 795 | }, 796 | "type": "bower-asset-library", 797 | "extra": { 798 | "bower-asset-main": "dist/typeahead.bundle.js" 799 | }, 800 | "time": "2015-04-27T04:02:14+00:00" 801 | }, 802 | { 803 | "name": "doctrine/annotations", 804 | "version": "v1.5.0", 805 | "source": { 806 | "type": "git", 807 | "url": "https://github.com/doctrine/annotations.git", 808 | "reference": "5beebb01b025c94e93686b7a0ed3edae81fe3e7f" 809 | }, 810 | "dist": { 811 | "type": "zip", 812 | "url": "https://files.phpcomposer.com/files/doctrine/annotations/5beebb01b025c94e93686b7a0ed3edae81fe3e7f.zip", 813 | "reference": "5beebb01b025c94e93686b7a0ed3edae81fe3e7f", 814 | "shasum": "" 815 | }, 816 | "require": { 817 | "doctrine/lexer": "1.*", 818 | "php": "^7.1" 819 | }, 820 | "require-dev": { 821 | "doctrine/cache": "1.*", 822 | "phpunit/phpunit": "^5.7" 823 | }, 824 | "type": "library", 825 | "extra": { 826 | "branch-alias": { 827 | "dev-master": "1.5.x-dev" 828 | } 829 | }, 830 | "autoload": { 831 | "psr-4": { 832 | "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" 833 | } 834 | }, 835 | "notification-url": "https://packagist.org/downloads/", 836 | "license": [ 837 | "MIT" 838 | ], 839 | "authors": [ 840 | { 841 | "name": "Roman Borschel", 842 | "email": "roman@code-factory.org" 843 | }, 844 | { 845 | "name": "Benjamin Eberlei", 846 | "email": "kontakt@beberlei.de" 847 | }, 848 | { 849 | "name": "Guilherme Blanco", 850 | "email": "guilhermeblanco@gmail.com" 851 | }, 852 | { 853 | "name": "Jonathan Wage", 854 | "email": "jonwage@gmail.com" 855 | }, 856 | { 857 | "name": "Johannes Schmitt", 858 | "email": "schmittjoh@gmail.com" 859 | } 860 | ], 861 | "description": "Docblock Annotations Parser", 862 | "homepage": "http://www.doctrine-project.org", 863 | "keywords": [ 864 | "annotations", 865 | "docblock", 866 | "parser" 867 | ], 868 | "time": "2017-07-22T10:58:02+00:00" 869 | }, 870 | { 871 | "name": "fzaninotto/faker", 872 | "version": "v1.7.1", 873 | "source": { 874 | "type": "git", 875 | "url": "https://github.com/fzaninotto/Faker.git", 876 | "reference": "d3ed4cc37051c1ca52d22d76b437d14809fc7e0d" 877 | }, 878 | "dist": { 879 | "type": "zip", 880 | "url": "https://files.phpcomposer.com/files/fzaninotto/Faker/d3ed4cc37051c1ca52d22d76b437d14809fc7e0d.zip", 881 | "reference": "d3ed4cc37051c1ca52d22d76b437d14809fc7e0d", 882 | "shasum": "" 883 | }, 884 | "require": { 885 | "php": "^5.3.3 || ^7.0" 886 | }, 887 | "require-dev": { 888 | "ext-intl": "*", 889 | "phpunit/phpunit": "^4.0 || ^5.0", 890 | "squizlabs/php_codesniffer": "^1.5" 891 | }, 892 | "type": "library", 893 | "extra": { 894 | "branch-alias": { 895 | "dev-master": "1.8-dev" 896 | } 897 | }, 898 | "autoload": { 899 | "psr-4": { 900 | "Faker\\": "src/Faker/" 901 | } 902 | }, 903 | "notification-url": "https://packagist.org/downloads/", 904 | "license": [ 905 | "MIT" 906 | ], 907 | "authors": [ 908 | { 909 | "name": "François Zaninotto" 910 | } 911 | ], 912 | "description": "Faker is a PHP library that generates fake data for you.", 913 | "keywords": [ 914 | "data", 915 | "faker", 916 | "fixtures" 917 | ], 918 | "time": "2017-08-15T16:48:10+00:00" 919 | }, 920 | { 921 | "name": "light/yii2-swagger", 922 | "version": "1.0.5", 923 | "source": { 924 | "type": "git", 925 | "url": "https://github.com/lichunqiang/yii2-swagger.git", 926 | "reference": "30837106931730e81300a7cc9d5e2928942f1b88" 927 | }, 928 | "dist": { 929 | "type": "zip", 930 | "url": "https://files.phpcomposer.com/files/lichunqiang/yii2-swagger/30837106931730e81300a7cc9d5e2928942f1b88.zip", 931 | "reference": "30837106931730e81300a7cc9d5e2928942f1b88", 932 | "shasum": "" 933 | }, 934 | "require": { 935 | "bower-asset/swagger-ui": "2.2.10", 936 | "yiisoft/yii2": "^2.0.0", 937 | "zircote/swagger-php": "^2.0" 938 | }, 939 | "type": "library", 940 | "extra": { 941 | "branch-alias": { 942 | "dev-master": "1.0.x-dev" 943 | } 944 | }, 945 | "autoload": { 946 | "psr-4": { 947 | "light\\swagger\\": "src" 948 | } 949 | }, 950 | "notification-url": "https://packagist.org/downloads/", 951 | "license": [ 952 | "MIT" 953 | ], 954 | "authors": [ 955 | { 956 | "name": "lichunqiang", 957 | "email": "light-li@hotmail.com" 958 | } 959 | ], 960 | "description": "swagger intergation with yii2", 961 | "keywords": [ 962 | "document", 963 | "extension", 964 | "restful", 965 | "swagger", 966 | "yii2" 967 | ], 968 | "time": "2017-04-18T05:44:04+00:00" 969 | }, 970 | { 971 | "name": "phpspec/php-diff", 972 | "version": "v1.1.0", 973 | "source": { 974 | "type": "git", 975 | "url": "https://github.com/phpspec/php-diff.git", 976 | "reference": "0464787bfa7cd13576c5a1e318709768798bec6a" 977 | }, 978 | "dist": { 979 | "type": "zip", 980 | "url": "https://files.phpcomposer.com/files/phpspec/php-diff/0464787bfa7cd13576c5a1e318709768798bec6a.zip", 981 | "reference": "0464787bfa7cd13576c5a1e318709768798bec6a", 982 | "shasum": "" 983 | }, 984 | "type": "library", 985 | "extra": { 986 | "branch-alias": { 987 | "dev-master": "1.0.x-dev" 988 | } 989 | }, 990 | "autoload": { 991 | "psr-0": { 992 | "Diff": "lib/" 993 | } 994 | }, 995 | "notification-url": "https://packagist.org/downloads/", 996 | "license": [ 997 | "BSD-3-Clause" 998 | ], 999 | "authors": [ 1000 | { 1001 | "name": "Chris Boulton", 1002 | "homepage": "http://github.com/chrisboulton" 1003 | } 1004 | ], 1005 | "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", 1006 | "time": "2016-04-07T12:29:16+00:00" 1007 | }, 1008 | { 1009 | "name": "symfony/finder", 1010 | "version": "v3.3.10", 1011 | "source": { 1012 | "type": "git", 1013 | "url": "https://github.com/symfony/finder.git", 1014 | "reference": "773e19a491d97926f236942484cb541560ce862d" 1015 | }, 1016 | "dist": { 1017 | "type": "zip", 1018 | "url": "https://files.phpcomposer.com/files/symfony/finder/773e19a491d97926f236942484cb541560ce862d.zip", 1019 | "reference": "773e19a491d97926f236942484cb541560ce862d", 1020 | "shasum": "" 1021 | }, 1022 | "require": { 1023 | "php": "^5.5.9|>=7.0.8" 1024 | }, 1025 | "type": "library", 1026 | "extra": { 1027 | "branch-alias": { 1028 | "dev-master": "3.3-dev" 1029 | } 1030 | }, 1031 | "autoload": { 1032 | "psr-4": { 1033 | "Symfony\\Component\\Finder\\": "" 1034 | }, 1035 | "exclude-from-classmap": [ 1036 | "/Tests/" 1037 | ] 1038 | }, 1039 | "notification-url": "https://packagist.org/downloads/", 1040 | "license": [ 1041 | "MIT" 1042 | ], 1043 | "authors": [ 1044 | { 1045 | "name": "Fabien Potencier", 1046 | "email": "fabien@symfony.com" 1047 | }, 1048 | { 1049 | "name": "Symfony Community", 1050 | "homepage": "https://symfony.com/contributors" 1051 | } 1052 | ], 1053 | "description": "Symfony Finder Component", 1054 | "homepage": "https://symfony.com", 1055 | "time": "2017-10-02T06:42:24+00:00" 1056 | }, 1057 | { 1058 | "name": "yiisoft/yii2-debug", 1059 | "version": "2.0.12", 1060 | "source": { 1061 | "type": "git", 1062 | "url": "https://github.com/yiisoft/yii2-debug.git", 1063 | "reference": "93082f46d3568b4431a26f264e0d16a12c42bd50" 1064 | }, 1065 | "dist": { 1066 | "type": "zip", 1067 | "url": "https://files.phpcomposer.com/files/yiisoft/yii2-debug/93082f46d3568b4431a26f264e0d16a12c42bd50.zip", 1068 | "reference": "93082f46d3568b4431a26f264e0d16a12c42bd50", 1069 | "shasum": "" 1070 | }, 1071 | "require": { 1072 | "yiisoft/yii2": "~2.0.11", 1073 | "yiisoft/yii2-bootstrap": "~2.0.0" 1074 | }, 1075 | "type": "yii2-extension", 1076 | "extra": { 1077 | "branch-alias": { 1078 | "dev-master": "2.0.x-dev" 1079 | } 1080 | }, 1081 | "autoload": { 1082 | "psr-4": { 1083 | "yii\\debug\\": "" 1084 | } 1085 | }, 1086 | "notification-url": "https://packagist.org/downloads/", 1087 | "license": [ 1088 | "BSD-3-Clause" 1089 | ], 1090 | "authors": [ 1091 | { 1092 | "name": "Qiang Xue", 1093 | "email": "qiang.xue@gmail.com" 1094 | } 1095 | ], 1096 | "description": "The debugger extension for the Yii framework", 1097 | "keywords": [ 1098 | "debug", 1099 | "debugger", 1100 | "yii2" 1101 | ], 1102 | "time": "2017-10-09T20:30:01+00:00" 1103 | }, 1104 | { 1105 | "name": "yiisoft/yii2-faker", 1106 | "version": "2.0.3", 1107 | "source": { 1108 | "type": "git", 1109 | "url": "https://github.com/yiisoft/yii2-faker.git", 1110 | "reference": "b88ca69ee226a3610b2c26c026c3203d7ac50f6c" 1111 | }, 1112 | "dist": { 1113 | "type": "zip", 1114 | "url": "https://files.phpcomposer.com/files/yiisoft/yii2-faker/b88ca69ee226a3610b2c26c026c3203d7ac50f6c.zip", 1115 | "reference": "b88ca69ee226a3610b2c26c026c3203d7ac50f6c", 1116 | "shasum": "" 1117 | }, 1118 | "require": { 1119 | "fzaninotto/faker": "*", 1120 | "yiisoft/yii2": "*" 1121 | }, 1122 | "type": "yii2-extension", 1123 | "extra": { 1124 | "branch-alias": { 1125 | "dev-master": "2.0.x-dev" 1126 | } 1127 | }, 1128 | "autoload": { 1129 | "psr-4": { 1130 | "yii\\faker\\": "" 1131 | } 1132 | }, 1133 | "notification-url": "https://packagist.org/downloads/", 1134 | "license": [ 1135 | "BSD-3-Clause" 1136 | ], 1137 | "authors": [ 1138 | { 1139 | "name": "Mark Jebri", 1140 | "email": "mark.github@yandex.ru" 1141 | } 1142 | ], 1143 | "description": "Fixture generator. The Faker integration for the Yii framework.", 1144 | "keywords": [ 1145 | "Fixture", 1146 | "faker", 1147 | "yii2" 1148 | ], 1149 | "time": "2015-03-01T06:22:44+00:00" 1150 | }, 1151 | { 1152 | "name": "yiisoft/yii2-gii", 1153 | "version": "2.0.5", 1154 | "source": { 1155 | "type": "git", 1156 | "url": "https://github.com/yiisoft/yii2-gii.git", 1157 | "reference": "1bd6df6804ca077ec022587905a0d43eb286f507" 1158 | }, 1159 | "dist": { 1160 | "type": "zip", 1161 | "url": "https://files.phpcomposer.com/files/yiisoft/yii2-gii/1bd6df6804ca077ec022587905a0d43eb286f507.zip", 1162 | "reference": "1bd6df6804ca077ec022587905a0d43eb286f507", 1163 | "shasum": "" 1164 | }, 1165 | "require": { 1166 | "bower-asset/typeahead.js": "0.10.* | ~0.11.0", 1167 | "phpspec/php-diff": ">=1.0.2", 1168 | "yiisoft/yii2": ">=2.0.4", 1169 | "yiisoft/yii2-bootstrap": "~2.0" 1170 | }, 1171 | "type": "yii2-extension", 1172 | "extra": { 1173 | "branch-alias": { 1174 | "dev-master": "2.0.x-dev" 1175 | }, 1176 | "asset-installer-paths": { 1177 | "npm-asset-library": "vendor/npm", 1178 | "bower-asset-library": "vendor/bower" 1179 | } 1180 | }, 1181 | "autoload": { 1182 | "psr-4": { 1183 | "yii\\gii\\": "" 1184 | } 1185 | }, 1186 | "notification-url": "https://packagist.org/downloads/", 1187 | "license": [ 1188 | "BSD-3-Clause" 1189 | ], 1190 | "authors": [ 1191 | { 1192 | "name": "Qiang Xue", 1193 | "email": "qiang.xue@gmail.com" 1194 | } 1195 | ], 1196 | "description": "The Gii extension for the Yii framework", 1197 | "keywords": [ 1198 | "code generator", 1199 | "gii", 1200 | "yii2" 1201 | ], 1202 | "time": "2016-03-18T14:09:46+00:00" 1203 | }, 1204 | { 1205 | "name": "zircote/swagger-php", 1206 | "version": "2.0.11", 1207 | "source": { 1208 | "type": "git", 1209 | "url": "https://github.com/zircote/swagger-php.git", 1210 | "reference": "d010ab67536784f8b578cb4ba7d15c906f3e1a45" 1211 | }, 1212 | "dist": { 1213 | "type": "zip", 1214 | "url": "https://files.phpcomposer.com/files/zircote/swagger-php/d010ab67536784f8b578cb4ba7d15c906f3e1a45.zip", 1215 | "reference": "d010ab67536784f8b578cb4ba7d15c906f3e1a45", 1216 | "shasum": "" 1217 | }, 1218 | "require": { 1219 | "doctrine/annotations": "*", 1220 | "php": ">=5.6", 1221 | "symfony/finder": "*" 1222 | }, 1223 | "require-dev": { 1224 | "phpunit/phpunit": ">=4.8 <=5.6", 1225 | "squizlabs/php_codesniffer": ">=2.7", 1226 | "zendframework/zend-form": "<2.8" 1227 | }, 1228 | "bin": [ 1229 | "bin/swagger" 1230 | ], 1231 | "type": "library", 1232 | "autoload": { 1233 | "psr-4": { 1234 | "Swagger\\": "src" 1235 | }, 1236 | "files": [ 1237 | "src/functions.php" 1238 | ] 1239 | }, 1240 | "notification-url": "https://packagist.org/downloads/", 1241 | "license": [ 1242 | "Apache2" 1243 | ], 1244 | "authors": [ 1245 | { 1246 | "name": "Robert Allen", 1247 | "email": "zircote@gmail.com", 1248 | "homepage": "http://www.zircote.com" 1249 | }, 1250 | { 1251 | "name": "Bob Fanger", 1252 | "email": "bfanger@gmail.com", 1253 | "homepage": "http://bfanger.nl" 1254 | } 1255 | ], 1256 | "description": "Swagger-PHP - Generate interactive documentation for your RESTful API using phpdoc annotations", 1257 | "homepage": "https://github.com/zircote/swagger-php/", 1258 | "keywords": [ 1259 | "api", 1260 | "json", 1261 | "rest", 1262 | "service discovery" 1263 | ], 1264 | "time": "2017-08-16T08:32:59+00:00" 1265 | } 1266 | ], 1267 | "aliases": [], 1268 | "minimum-stability": "stable", 1269 | "stability-flags": [], 1270 | "prefer-stable": false, 1271 | "prefer-lowest": false, 1272 | "platform": { 1273 | "php": ">=5.4.0" 1274 | }, 1275 | "platform-dev": [] 1276 | } 1277 | --------------------------------------------------------------------------------