├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── backend ├── assets │ └── AppAsset.php ├── config │ ├── .gitignore │ ├── bootstrap.php │ ├── main.php │ └── params.php ├── controllers │ └── SiteController.php ├── models │ └── .gitkeep ├── runtime │ └── .gitignore ├── views │ ├── layouts │ │ └── main.php │ └── site │ │ ├── error.php │ │ ├── index.php │ │ └── login.php └── web │ ├── .gitignore │ ├── assets │ └── .gitignore │ ├── css │ └── site.css │ ├── favicon.ico │ └── robots.txt ├── common ├── config │ ├── .gitignore │ ├── bootstrap.php │ ├── main.php │ └── params.php └── models │ ├── Comment.php │ ├── ContactForm.php │ ├── LoginForm.php │ ├── Lookup.php │ ├── Post.php │ ├── Tag.php │ └── User.php ├── composer.json ├── composer.lock ├── console ├── config │ ├── .gitignore │ ├── bootstrap.php │ ├── main.php │ └── params.php ├── controllers │ └── .gitkeep ├── migrations │ ├── m140724_112641_init.php │ ├── m140731_074148_post.php │ └── m140922_121411_comments.php ├── models │ └── .gitkeep └── runtime │ └── .gitignore ├── environments ├── dev │ ├── backend │ │ ├── config │ │ │ ├── main-local.php │ │ │ └── params-local.php │ │ └── web │ │ │ ├── index-test.php │ │ │ └── index.php │ ├── common │ │ └── config │ │ │ ├── main-local.php │ │ │ └── params-local.php │ ├── console │ │ └── config │ │ │ ├── main-local.php │ │ │ └── params-local.php │ ├── rest │ │ ├── config │ │ │ ├── main-local.php │ │ │ └── params-local.php │ │ └── web │ │ │ ├── index-test.php │ │ │ └── index.php │ └── yii └── index.php ├── init ├── init.bat ├── requirements.php ├── rest ├── config │ ├── .gitignore │ ├── bootstrap.php │ ├── main.php │ └── params.php ├── runtime │ └── .gitignore ├── versions │ ├── v1 │ │ ├── RestModule.php │ │ └── controllers │ │ │ ├── CommentController.php │ │ │ ├── PostController.php │ │ │ └── UserController.php │ └── v2 │ │ ├── RestModule.php │ │ └── controllers │ │ ├── CommentController.php │ │ ├── PostController.php │ │ └── UserController.php ├── views │ ├── layouts │ │ └── main.php │ └── site │ │ └── error.php └── web │ ├── .gitignore │ └── robots.txt ├── server.md ├── tests ├── README.md ├── codeception.yml └── codeception │ ├── _output │ └── .gitignore │ ├── bin │ ├── _bootstrap.php │ ├── yii │ └── yii.bat │ ├── common │ ├── .gitignore │ ├── _bootstrap.php │ ├── _output │ │ └── .gitignore │ ├── _pages │ │ └── LoginPage.php │ ├── _support │ │ └── FixtureHelper.php │ ├── codeception.yml │ ├── fixtures │ │ ├── PostFixture.php │ │ ├── UserFixture.php │ │ └── data │ │ │ └── init_login.php │ ├── templates │ │ └── fixtures │ │ │ └── user.php │ ├── unit.suite.yml │ └── unit │ │ ├── DbTestCase.php │ │ ├── TestCase.php │ │ ├── _bootstrap.php │ │ ├── fixtures │ │ └── data │ │ │ └── models │ │ │ └── user.php │ │ └── models │ │ └── LoginFormTest.php │ ├── config │ ├── acceptance.php │ ├── common │ │ └── unit.php │ ├── config.php │ ├── console │ │ └── unit.php │ ├── functional.php │ ├── rest │ │ ├── acceptance.php │ │ ├── config.php │ │ ├── functional.php │ │ └── unit.php │ └── unit.php │ ├── console │ ├── .gitignore │ ├── _bootstrap.php │ ├── _output │ │ └── .gitignore │ ├── codeception.yml │ ├── unit.suite.yml │ └── unit │ │ ├── DbTestCase.php │ │ ├── TestCase.php │ │ ├── _bootstrap.php │ │ └── fixtures │ │ └── data │ │ └── .gitkeep │ └── rest │ ├── .gitignore │ ├── _bootstrap.php │ ├── _output │ └── .gitignore │ ├── acceptance.suite.yml │ ├── acceptance │ └── _bootstrap.php │ ├── codeception.yml │ ├── functional.suite.yml │ ├── functional │ ├── PostAPICept.php │ ├── UserApiCept.php │ └── _bootstrap.php │ ├── unit.suite.yml │ └── unit │ ├── DbTestCase.php │ ├── TestCase.php │ ├── _bootstrap.php │ └── fixtures │ └── data │ └── .gitkeep └── yii.bat /.gitignore: -------------------------------------------------------------------------------- 1 | # yii console command 2 | /yii 3 | 4 | # phpstorm project files 5 | .idea 6 | 7 | # netbeans project files 8 | nbproject 9 | 10 | # zend studio for eclipse project files 11 | .buildpath 12 | .project 13 | .settings 14 | 15 | # windows thumbnail cache 16 | Thumbs.db 17 | 18 | # composer vendor dir 19 | /vendor 20 | 21 | # composer itself is not needed 22 | composer.phar 23 | 24 | # Mac DS_Store Files 25 | .DS_Store 26 | 27 | # phpunit itself is not needed 28 | phpunit.phar 29 | # local phpunit config 30 | /phpunit.xml 31 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.6 4 | 5 | # faster builds on new travis setup not using sudo 6 | sudo: false 7 | 8 | # cache vendor dirs 9 | cache: 10 | directories: 11 | - $HOME/.composer/cache 12 | 13 | install: 14 | - travis_retry composer self-update && composer --version 15 | - travis_retry composer update --dev --prefer-dist --no-interaction 16 | # codeception 17 | - travis_retry composer global require "codeception/codeception=2.0.*" "codeception/specify=*" "codeception/verify=*" 18 | # setup application: 19 | - | 20 | php init --env=Development 21 | sed -i s/root/travis/ common/config/main-local.php 22 | sed -i "s/'cookieValidationKey' => ''/'cookieValidationKey' => 'testkey'/" backend/config/main.php 23 | cd tests/codeception/common && codecept build 24 | cd ../console && codecept build 25 | cd ../rest && codecept build 26 | cd ../../../ 27 | 28 | before_script: 29 | - cd tests/codeception/bin && php yii migrate --interactive=0 && cd ../../.. 30 | 31 | script: 32 | - | 33 | php -S localhost:8080 > /dev/null 2>&1 & 34 | cd tests 35 | ./../vendor/bin/codecept run 36 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## TEST REST API APPLICATION ON [Yii2](https://github.com/yiisoft/yii2) 2 | 3 | [![Build Status](https://travis-ci.org/githubjeka/yii2-rest.svg)](https://travis-ci.org/githubjeka/yii2-rest) 4 | 5 | [Demo Server](https://yii2-rest-githubjeka.c9.io/rest/web/) 6 | 7 | ### INSTALLATION 8 | 9 | **Install via Composer** 10 | 11 | If you do not have [Composer](http://getcomposer.org/), you may install it by following the 12 | [instructions at getcomposer.org](https://getcomposer.org/doc/00-intro.md). 13 | 14 | You can then install the application using the following commands: 15 | 16 | ``` 17 | composer global require "fxp/composer-asset-plugin:~1.0.0" 18 | composer create-project --prefer-dist -s dev "githubjeka/rest-yii2" . 19 | ``` 20 | 21 | ### GETTING STARTED 22 | 23 | After you install the application, you have to conduct the following steps to initialize the installed application. 24 | You only need to do these once for all. 25 | 26 | - Run command `php init --env=Development` to initialize the application with a specific environment. 27 | - Create a new database and adjust the `components['db']` configuration in `common/config/main-local.php` accordingly. 28 | - Apply migrations with console command ``php yii migrate``. This will create tables needed for the application to work. 29 | - Set document roots of your Web server: 30 | 31 | for rest `/path/to/yii-application/rest/web/` and using the URL `http://localhost/` 32 | for backend `/path/to/yii-application/backend/web/` and using the URL `http://backend-localhost/` 33 | 34 | Use `demo/demo` to login into the application on [http://localhost/v1/user/login](http://localhost/v1/user/login). See 35 | [`/rest/config/main.php`](/rest/config/main.php) for more info by URL 36 | 37 | ### URL RULE 38 | 39 | See [rest/config/main.php](rest/config/main.php) 40 | 41 | API available: 42 | 43 | ```php 44 | // version 1 45 | OPTIONS /index.php?r=v1/user/login 46 | POST /index.php?r=v1/user/login 47 | 48 | OPTIONS /index.php?r=v1/posts 49 | GET /index.php?r=v1/posts 50 | GET /index.php?r=v1/posts/ID 51 | POST /index.php?r=v1/posts 52 | PUT /index.php?r=v1/posts/ID 53 | DELETE /index.php?r=v1/posts/ID 54 | 55 | OPTIONS /index.php?r=v1/comments 56 | GET /index.php?r=v1/comments 57 | GET /index.php?r=v1/comments/ID 58 | POST /index.php?r=v1/comments 59 | PUT /index.php?r=v1/comments/ID 60 | DELETE /index.php?r=v1/comments/ID 61 | 62 | //version 2 63 | OPTIONS /index.php?r=v2/user/login 64 | POST /index.php?r=v2/user/login 65 | ``` 66 | 67 | You can hide `index.php` from URL. For that see [server.md](server.md) 68 | 69 | ### ADDITIONALLY 70 | 71 | [See client on AngularJS](https://github.com/githubjeka/angular-yii2) 72 | -------------------------------------------------------------------------------- /backend/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 = ['css/site.css']; 21 | public $js = []; 22 | public $depends = [ 23 | 'yii\web\YiiAsset', 24 | 'yii\bootstrap\BootstrapAsset', 25 | ]; 26 | } 27 | -------------------------------------------------------------------------------- /backend/config/.gitignore: -------------------------------------------------------------------------------- 1 | main-local.php 2 | params-local.php -------------------------------------------------------------------------------- /backend/config/bootstrap.php: -------------------------------------------------------------------------------- 1 | 'app-backend', 11 | 'basePath' => dirname(__DIR__), 12 | 'controllerNamespace' => 'backend\controllers', 13 | 'bootstrap' => ['log'], 14 | 'modules' => [], 15 | 'components' => [ 16 | 'user' => [ 17 | 'identityClass' => 'common\models\User', 18 | 'enableAutoLogin' => true, 19 | ], 20 | 'log' => [ 21 | 'traceLevel' => YII_DEBUG ? 3 : 0, 22 | 'targets' => [ 23 | [ 24 | 'class' => 'yii\log\FileTarget', 25 | 'levels' => ['error', 'warning'], 26 | ], 27 | ], 28 | ], 29 | 'errorHandler' => [ 30 | 'errorAction' => 'site/error', 31 | ], 32 | ], 33 | 'params' => $params, 34 | ]; 35 | -------------------------------------------------------------------------------- /backend/config/params.php: -------------------------------------------------------------------------------- 1 | 'admin@example.com', 4 | ]; 5 | -------------------------------------------------------------------------------- /backend/controllers/SiteController.php: -------------------------------------------------------------------------------- 1 | [ 22 | 'class' => AccessControl::className(), 23 | 'rules' => [ 24 | [ 25 | 'actions' => ['login', 'error'], 26 | 'allow' => true, 27 | ], 28 | [ 29 | 'actions' => ['logout', 'index'], 30 | 'allow' => true, 31 | 'roles' => ['@'], 32 | ], 33 | ], 34 | ], 35 | 'verbs' => [ 36 | 'class' => VerbFilter::className(), 37 | 'actions' => [ 38 | 'logout' => ['post'], 39 | ], 40 | ], 41 | ]; 42 | } 43 | 44 | /** 45 | * @inheritdoc 46 | */ 47 | public function actions() 48 | { 49 | return [ 50 | 'error' => [ 51 | 'class' => 'yii\web\ErrorAction', 52 | ], 53 | ]; 54 | } 55 | 56 | public function actionIndex() 57 | { 58 | return $this->render('index'); 59 | } 60 | 61 | public function actionLogin() 62 | { 63 | if (!\Yii::$app->user->isGuest) { 64 | return $this->goHome(); 65 | } 66 | 67 | $model = new LoginForm(); 68 | if ($model->load(Yii::$app->request->post()) && $model->login()) { 69 | return $this->goBack(); 70 | } else { 71 | return $this->render('login', [ 72 | 'model' => $model, 73 | ]); 74 | } 75 | } 76 | 77 | public function actionLogout() 78 | { 79 | Yii::$app->user->logout(); 80 | 81 | return $this->goHome(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /backend/models/.gitkeep: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /backend/runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /backend/views/layouts/main.php: -------------------------------------------------------------------------------- 1 | 13 | beginPage() ?> 14 | 15 | 16 | 17 | 18 | 19 | 20 | <?= Html::encode($this->title) ?> 21 | head() ?> 22 | 23 | 24 | beginBody() ?> 25 |
26 | 'My Company', 29 | 'brandUrl' => Yii::$app->homeUrl, 30 | 'options' => [ 31 | 'class' => 'navbar-inverse navbar-fixed-top', 32 | ], 33 | ]); 34 | $menuItems = [ 35 | ['label' => 'Home', 'url' => ['/site/index']], 36 | ]; 37 | if (Yii::$app->user->isGuest) { 38 | $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']]; 39 | } else { 40 | $menuItems[] = [ 41 | 'label' => 'Logout (' . Yii::$app->user->identity->username . ')', 42 | 'url' => ['/site/logout'], 43 | 'linkOptions' => ['data-method' => 'post'] 44 | ]; 45 | } 46 | echo Nav::widget([ 47 | 'options' => ['class' => 'navbar-nav navbar-right'], 48 | 'items' => $menuItems, 49 | ]); 50 | NavBar::end(); 51 | ?> 52 | 53 |
54 | isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], 56 | ]) ?> 57 | 58 |
59 |
60 | 61 | 67 | 68 | endBody() ?> 69 | 70 | 71 | endPage() ?> 72 | -------------------------------------------------------------------------------- /backend/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 | -------------------------------------------------------------------------------- /backend/views/site/index.php: -------------------------------------------------------------------------------- 1 | title = 'My Yii Application'; 5 | ?> 6 |
7 | 8 |
9 |

Congratulations!

10 | 11 |

You have successfully created your Yii-powered application.

12 | 13 |

Get started with Yii

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

Heading

21 | 22 |

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

26 | 27 |

Yii Documentation »

28 |
29 |
30 |

Heading

31 | 32 |

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

36 | 37 |

Yii Forum »

38 |
39 |
40 |

Heading

41 | 42 |

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

46 | 47 |

Yii Extensions »

48 |
49 |
50 | 51 |
52 |
53 | -------------------------------------------------------------------------------- /backend/views/site/login.php: -------------------------------------------------------------------------------- 1 | title = 'Login'; 8 | $this->params['breadcrumbs'][] = $this->title; 9 | ?> 10 |
11 |

title) ?>

12 | 13 |

Please fill out the following fields to login:

14 | 15 |
16 |
17 | 'login-form']); ?> 18 | field($model, 'username') ?> 19 | field($model, 'password')->passwordInput() ?> 20 | field($model, 'rememberMe')->checkbox() ?> 21 |
22 | 'btn btn-primary', 'name' => 'login-button']) ?> 23 |
24 | 25 |
26 |
27 |
-------------------------------------------------------------------------------- /backend/web/.gitignore: -------------------------------------------------------------------------------- 1 | /index.php 2 | /index-test.php 3 | -------------------------------------------------------------------------------- /backend/web/assets/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /backend/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 | -------------------------------------------------------------------------------- /backend/web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/githubjeka/yii2-rest/e9f18d8a0d3488422abcd2e39303b0c2bb9d6f35/backend/web/favicon.ico -------------------------------------------------------------------------------- /backend/web/robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /common/config/.gitignore: -------------------------------------------------------------------------------- 1 | main-local.php 2 | params-local.php 3 | -------------------------------------------------------------------------------- /common/config/bootstrap.php: -------------------------------------------------------------------------------- 1 | dirname(dirname(__DIR__)) . '/vendor', 4 | 'components' => [ 5 | 'cache' => [ 6 | 'class' => 'yii\caching\FileCache', 7 | ], 8 | ], 9 | ]; 10 | -------------------------------------------------------------------------------- /common/config/params.php: -------------------------------------------------------------------------------- 1 | 'admin@example.com', 4 | 'supportEmail' => 'support@example.com', 5 | 'user.passwordResetTokenExpire' => 3600, 6 | 'maxRateLimit'=>1, 7 | 'perRateLimit'=>30, 8 | 'maxGetRateLimit'=>2, 9 | 'perGetRateLimit'=>1, 10 | 11 | ]; 12 | -------------------------------------------------------------------------------- /common/models/Comment.php: -------------------------------------------------------------------------------- 1 | function ($value) { 46 | return \Yii::$app->formatter->asHtml($value); 47 | } 48 | ], 49 | [['content', 'post_id'], 'required'], 50 | [['content'], 'string', 'max' => 128], 51 | [['post_id'], 'exist', 'targetClass' => Post::className(), 'targetAttribute' => 'id'], 52 | ]; 53 | } 54 | 55 | /** 56 | * @inheritdoc 57 | */ 58 | public function attributeLabels() 59 | { 60 | return [ 61 | 'id' => 'ID', 62 | 'content' => 'Content', 63 | 'post_id' => 'Post ID', 64 | ]; 65 | } 66 | 67 | public function fields() 68 | { 69 | return [ 70 | 'id', 71 | 'content', 72 | 'created_at' => function () { 73 | return date('d-m-y H:i', $this->created_at); 74 | }, 75 | ]; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /common/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->mail->compose() 53 | ->setTo($email) 54 | ->setFrom([$this->email => $this->name]) 55 | ->setSubject($this->subject) 56 | ->setTextBody($this->body) 57 | ->send(); 58 | return true; 59 | } else { 60 | return false; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /common/models/LoginForm.php: -------------------------------------------------------------------------------- 1 | hasErrors()) { 38 | $user = $this->getUser(); 39 | if (!$user || !$user->validatePassword($this->password)) { 40 | $this->addError($attribute, 'Incorrect username or password.'); 41 | } 42 | } 43 | } 44 | /** 45 | * Logs in a user using the provided username and password. 46 | * 47 | * @return boolean whether the user is logged in successfully 48 | */ 49 | public function login() 50 | { 51 | if ($this->validate()) { 52 | return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0); 53 | } else { 54 | return false; 55 | } 56 | } 57 | /** 58 | * Finds user by [[username]] 59 | * 60 | * @return User|null 61 | */ 62 | public function getUser() 63 | { 64 | if ($this->_user === false) { 65 | $this->_user = User::findByUsername($this->username); 66 | } 67 | return $this->_user; 68 | } 69 | } -------------------------------------------------------------------------------- /common/models/Lookup.php: -------------------------------------------------------------------------------- 1 | 128] 33 | ]; 34 | } 35 | 36 | /** 37 | * @inheritdoc 38 | */ 39 | public function attributeLabels() 40 | { 41 | return [ 42 | 'id' => 'ID', 43 | 'name' => 'Name', 44 | 'code' => 'Code', 45 | 'type' => 'Type', 46 | 'position' => 'Position', 47 | ]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /common/models/Post.php: -------------------------------------------------------------------------------- 1 | function ($value) { 53 | return \Yii::$app->formatter->asHtml($value); 54 | } 55 | ], 56 | [['title', 'content', 'status'], 'required'], 57 | [['content', 'tags'], 'string'], 58 | [['status'], 'in', 'range' => [self::STATUS_DRAFT, self::STATUS_PUBLISHED]], 59 | [['title'], 'string', 'max' => 128] 60 | ]; 61 | } 62 | 63 | public function extraFields() 64 | { 65 | return [ 66 | 'comments', 67 | ]; 68 | } 69 | 70 | public function fields() 71 | { 72 | return [ 73 | 'id', 74 | 'title', 75 | 'content', 76 | 'tags', 77 | 'status', 78 | 'author', 79 | 'created_at' => function () { 80 | return date('d-m-y H:i', $this->created_at); 81 | }, 82 | 'updated_at' => function () { 83 | return date('d-m-y H:i', $this->updated_at); 84 | }, 85 | ]; 86 | } 87 | 88 | /** 89 | * @inheritdoc 90 | */ 91 | public function attributeLabels() 92 | { 93 | return [ 94 | 'id' => 'ID', 95 | 'title' => 'Title', 96 | 'content' => 'Content', 97 | 'tags' => 'Tags', 98 | 'status' => 'Status', 99 | 'created_at' => 'created', 100 | 'updated_at' => 'updated', 101 | 'author_id' => 'Author ID', 102 | ]; 103 | } 104 | 105 | public function getAuthor() 106 | { 107 | return $this->hasOne(User::className(), ['id' => 'author_id']); 108 | } 109 | 110 | public function getComments() 111 | { 112 | return $this->hasMany(Comment::className(), ['post_id' => 'id']); 113 | } 114 | 115 | public function beforeSave($insert) 116 | { 117 | if (parent::beforeSave($insert)) { 118 | if ($insert) { 119 | if (empty($this->author_id)) { 120 | $this->author_id = \Yii::$app->user->identity->getId(); 121 | } 122 | } 123 | return true; 124 | } else { 125 | return false; 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /common/models/Tag.php: -------------------------------------------------------------------------------- 1 | 128] 32 | ]; 33 | } 34 | 35 | /** 36 | * @inheritdoc 37 | */ 38 | public function attributeLabels() 39 | { 40 | return [ 41 | 'id' => 'ID', 42 | 'name' => 'Name', 43 | 'frequency' => 'Frequency', 44 | ]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /common/models/User.php: -------------------------------------------------------------------------------- 1 | self::STATUS_ACTIVE], 49 | ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]], 50 | ]; 51 | } 52 | /** 53 | * @inheritdoc 54 | */ 55 | public static function findIdentity($id) 56 | { 57 | return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]); 58 | } 59 | /** 60 | * @inheritdoc 61 | */ 62 | public static function findIdentityByAccessToken($token, $type = null) 63 | { 64 | return static::findOne(['auth_key' => $token]); 65 | } 66 | /** 67 | * Finds user by username 68 | * 69 | * @param string $username 70 | * @return static|null 71 | */ 72 | public static function findByUsername($username) 73 | { 74 | return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); 75 | } 76 | /** 77 | * Finds user by password reset token 78 | * 79 | * @param string $token password reset token 80 | * @return static|null 81 | */ 82 | public static function findByPasswordResetToken($token) 83 | { 84 | if (!static::isPasswordResetTokenValid($token)) { 85 | return null; 86 | } 87 | return static::findOne([ 88 | 'password_reset_token' => $token, 89 | 'status' => self::STATUS_ACTIVE, 90 | ]); 91 | } 92 | /** 93 | * Finds out if password reset token is valid 94 | * 95 | * @param string $token password reset token 96 | * @return boolean 97 | */ 98 | public static function isPasswordResetTokenValid($token) 99 | { 100 | if (empty($token)) { 101 | return false; 102 | } 103 | $expire = Yii::$app->params['user.passwordResetTokenExpire']; 104 | $parts = explode('_', $token); 105 | $timestamp = (int) end($parts); 106 | return $timestamp + $expire >= time(); 107 | } 108 | /** 109 | * @inheritdoc 110 | */ 111 | public function getId() 112 | { 113 | return $this->getPrimaryKey(); 114 | } 115 | /** 116 | * @inheritdoc 117 | */ 118 | public function getAuthKey() 119 | { 120 | return $this->auth_key; 121 | } 122 | /** 123 | * @inheritdoc 124 | */ 125 | public function validateAuthKey($authKey) 126 | { 127 | return $this->getAuthKey() === $authKey; 128 | } 129 | /** 130 | * Validates password 131 | * 132 | * @param string $password password to validate 133 | * @return boolean if password provided is valid for current user 134 | */ 135 | public function validatePassword($password) 136 | { 137 | return Yii::$app->security->validatePassword($password, $this->password_hash); 138 | } 139 | /** 140 | * Generates password hash from password and sets it to the model 141 | * 142 | * @param string $password 143 | */ 144 | public function setPassword($password) 145 | { 146 | $this->password_hash = Yii::$app->security->generatePasswordHash($password); 147 | } 148 | /** 149 | * Generates "remember me" authentication key 150 | */ 151 | public function generateAuthKey() 152 | { 153 | $this->auth_key = Yii::$app->security->generateRandomString(); 154 | } 155 | /** 156 | * Generates new password reset token 157 | */ 158 | public function generatePasswordResetToken() 159 | { 160 | $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); 161 | } 162 | /** 163 | * Removes password reset token 164 | */ 165 | public function removePasswordResetToken() 166 | { 167 | $this->password_reset_token = null; 168 | } 169 | /** 170 | * @inheritdoc 171 | */ 172 | public function getRateLimit($request, $action) 173 | { 174 | if (($request->isPut || $request->isDelete || $request->isPost)) { 175 | return [Yii::$app->params['maxRateLimit'], Yii::$app->params['perRateLimit']]; 176 | } 177 | 178 | return [Yii::$app->params['maxGetRateLimit'], Yii::$app->params['perGetRateLimit']]; 179 | } 180 | /** 181 | * @inheritdoc 182 | */ 183 | public function loadAllowance($request, $action) 184 | { 185 | return [ 186 | \Yii::$app->cache->get($request->getPathInfo() . $request->getMethod() . '_remaining'), 187 | \Yii::$app->cache->get($request->getPathInfo() . $request->getMethod() . '_ts') 188 | ]; 189 | } 190 | /** 191 | * @inheritdoc 192 | */ 193 | public function saveAllowance($request, $action, $allowance, $timestamp) 194 | { 195 | \Yii::$app->cache->set($request->getPathInfo() . $request->getMethod() . '_remaining', $allowance); 196 | \Yii::$app->cache->set($request->getPathInfo() . $request->getMethod() . '_ts', $timestamp); 197 | } 198 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "githubjeka/rest-yii2", 3 | "description": "Yii 2 Rest Api Template", 4 | "keywords": ["yii2", "rest", "application template", "api"], 5 | "homepage": "https://github.com/githubjeka/yii2-rest", 6 | "type": "project", 7 | "license": "BSD-4-Clause", 8 | "authors": [ 9 | { 10 | "name": "Evgeniy Tkachenko", 11 | "email": "et.coder@gmail.com", 12 | "role": "Developer" 13 | } 14 | ], 15 | "support": { 16 | "issues": "https://github.com/githubjeka/yii2-rest/issues", 17 | "source": "https://github.com/githubjeka/yii2-rest" 18 | }, 19 | "minimum-stability": "dev", 20 | "require": { 21 | "php": ">=5.4.0", 22 | "yiisoft/yii2": "~2.0.6", 23 | "yiisoft/yii2-bootstrap": "~2.0.0", 24 | "yiisoft/yii2-swiftmailer": "~2.0.0 || ~2.1.0" 25 | }, 26 | "require-dev": { 27 | "yiisoft/yii2-debug": "~2.0.0", 28 | "yiisoft/yii2-gii": "~2.0.0", 29 | "yiisoft/yii2-faker": "~2.0.0", 30 | "codeception/base": "^2.2.3", 31 | "codeception/verify": "~0.3.1" 32 | }, 33 | "config": { 34 | "process-timeout": 1800, 35 | "fxp-asset": { 36 | "enabled": false 37 | } 38 | }, 39 | "repositories": [ 40 | { 41 | "type": "composer", 42 | "url": "https://asset-packagist.org" 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "e3d1e054cc4edd51ae456652081e91db", 8 | "packages": [ 9 | { 10 | "name": "bower-asset/bootstrap", 11 | "version": "v3.3.4", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/twbs/bootstrap.git", 15 | "reference": "a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/twbs/bootstrap/zipball/a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f", 20 | "reference": "a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "bower-asset/jquery": ">=1.9.1" 25 | }, 26 | "type": "bower-asset-library", 27 | "extra": { 28 | "bower-asset-main": [ 29 | "less/bootstrap.less", 30 | "dist/css/bootstrap.css", 31 | "dist/js/bootstrap.js", 32 | "dist/fonts/glyphicons-halflings-regular.eot", 33 | "dist/fonts/glyphicons-halflings-regular.svg", 34 | "dist/fonts/glyphicons-halflings-regular.ttf", 35 | "dist/fonts/glyphicons-halflings-regular.woff", 36 | "dist/fonts/glyphicons-halflings-regular.woff2" 37 | ], 38 | "bower-asset-ignore": [ 39 | "/.*", 40 | "_config.yml", 41 | "CNAME", 42 | "composer.json", 43 | "CONTRIBUTING.md", 44 | "docs", 45 | "js/tests", 46 | "test-infra" 47 | ] 48 | }, 49 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 50 | "keywords": [ 51 | "css", 52 | "framework", 53 | "front-end", 54 | "js", 55 | "less", 56 | "mobile-first", 57 | "responsive", 58 | "web" 59 | ] 60 | }, 61 | { 62 | "name": "bower-asset/jquery", 63 | "version": "2.1.4", 64 | "source": { 65 | "type": "git", 66 | "url": "https://github.com/jquery/jquery.git", 67 | "reference": "7751e69b615c6eca6f783a81e292a55725af6b85" 68 | }, 69 | "dist": { 70 | "type": "zip", 71 | "url": "https://api.github.com/repos/jquery/jquery/zipball/7751e69b615c6eca6f783a81e292a55725af6b85", 72 | "reference": "7751e69b615c6eca6f783a81e292a55725af6b85", 73 | "shasum": "" 74 | }, 75 | "require-dev": { 76 | "bower-asset/qunit": "1.14.0", 77 | "bower-asset/requirejs": "2.1.10", 78 | "bower-asset/sinon": "1.8.1", 79 | "bower-asset/sizzle": "2.1.1-patch2" 80 | }, 81 | "type": "bower-asset-library", 82 | "extra": { 83 | "bower-asset-main": "dist/jquery.js", 84 | "bower-asset-ignore": [ 85 | "**/.*", 86 | "build", 87 | "dist/cdn", 88 | "speed", 89 | "test", 90 | "*.md", 91 | "AUTHORS.txt", 92 | "Gruntfile.js", 93 | "package.json" 94 | ] 95 | }, 96 | "license": [ 97 | "MIT" 98 | ], 99 | "keywords": [ 100 | "javascript", 101 | "jquery", 102 | "library" 103 | ] 104 | }, 105 | { 106 | "name": "bower-asset/jquery.inputmask", 107 | "version": "3.1.63", 108 | "source": { 109 | "type": "git", 110 | "url": "https://github.com/RobinHerbots/jquery.inputmask.git", 111 | "reference": "c40c7287eadc31e341ebbf0c02352eb55b9cbc48" 112 | }, 113 | "dist": { 114 | "type": "zip", 115 | "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/c40c7287eadc31e341ebbf0c02352eb55b9cbc48", 116 | "reference": "c40c7287eadc31e341ebbf0c02352eb55b9cbc48", 117 | "shasum": "" 118 | }, 119 | "require": { 120 | "bower-asset/jquery": ">=1.7" 121 | }, 122 | "type": "bower-asset-library", 123 | "extra": { 124 | "bower-asset-main": [ 125 | "./dist/inputmask/jquery.inputmask.js", 126 | "./dist/inputmask/jquery.inputmask.extensions.js", 127 | "./dist/inputmask/jquery.inputmask.date.extensions.js", 128 | "./dist/inputmask/jquery.inputmask.numeric.extensions.js", 129 | "./dist/inputmask/jquery.inputmask.phone.extensions.js", 130 | "./dist/inputmask/jquery.inputmask.regex.extensions.js" 131 | ], 132 | "bower-asset-ignore": [ 133 | "**/.*", 134 | "qunit/", 135 | "nuget/", 136 | "tools/", 137 | "js/", 138 | "*.md", 139 | "build.properties", 140 | "build.xml", 141 | "jquery.inputmask.jquery.json" 142 | ] 143 | }, 144 | "license": [ 145 | "http://opensource.org/licenses/mit-license.php" 146 | ], 147 | "description": "jquery.inputmask is a jquery plugin which create an input mask.", 148 | "keywords": [ 149 | "form", 150 | "input", 151 | "inputmask", 152 | "jquery", 153 | "mask", 154 | "plugins" 155 | ] 156 | }, 157 | { 158 | "name": "bower-asset/punycode", 159 | "version": "v1.3.2", 160 | "source": { 161 | "type": "git", 162 | "url": "https://github.com/bestiejs/punycode.js.git", 163 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" 164 | }, 165 | "dist": { 166 | "type": "zip", 167 | "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3", 168 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3", 169 | "shasum": "" 170 | }, 171 | "type": "bower-asset-library", 172 | "extra": { 173 | "bower-asset-main": "punycode.js", 174 | "bower-asset-ignore": [ 175 | "coverage", 176 | "tests", 177 | ".*", 178 | "component.json", 179 | "Gruntfile.js", 180 | "node_modules", 181 | "package.json" 182 | ] 183 | } 184 | }, 185 | { 186 | "name": "bower-asset/yii2-pjax", 187 | "version": "dev-master", 188 | "source": { 189 | "type": "git", 190 | "url": "https://github.com/yiisoft/jquery-pjax.git", 191 | "reference": "3f20897307cca046fca5323b318475ae9dac0ca0" 192 | }, 193 | "dist": { 194 | "type": "zip", 195 | "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/3f20897307cca046fca5323b318475ae9dac0ca0", 196 | "reference": "3f20897307cca046fca5323b318475ae9dac0ca0", 197 | "shasum": "" 198 | }, 199 | "require": { 200 | "bower-asset/jquery": ">=1.8" 201 | }, 202 | "type": "bower-asset-library", 203 | "extra": { 204 | "bower-asset-main": "./jquery.pjax.js", 205 | "bower-asset-ignore": [ 206 | ".travis.yml", 207 | "Gemfile", 208 | "Gemfile.lock", 209 | "vendor/", 210 | "script/", 211 | "test/" 212 | ], 213 | "branch-alias": { 214 | "dev-master": "2.0.3-dev" 215 | } 216 | }, 217 | "license": [ 218 | "MIT" 219 | ], 220 | "time": "2015-03-08 21:03:11" 221 | }, 222 | { 223 | "name": "cebe/markdown", 224 | "version": "dev-master", 225 | "source": { 226 | "type": "git", 227 | "url": "https://github.com/cebe/markdown.git", 228 | "reference": "e14d3da8f84eefa3792fd22b5b5ecba9c98d2e18" 229 | }, 230 | "dist": { 231 | "type": "zip", 232 | "url": "https://api.github.com/repos/cebe/markdown/zipball/e14d3da8f84eefa3792fd22b5b5ecba9c98d2e18", 233 | "reference": "e14d3da8f84eefa3792fd22b5b5ecba9c98d2e18", 234 | "shasum": "" 235 | }, 236 | "require": { 237 | "lib-pcre": "*", 238 | "php": ">=5.4.0" 239 | }, 240 | "require-dev": { 241 | "cebe/indent": "*", 242 | "facebook/xhprof": "*@dev", 243 | "phpunit/phpunit": "4.1.*" 244 | }, 245 | "bin": [ 246 | "bin/markdown" 247 | ], 248 | "type": "library", 249 | "extra": { 250 | "branch-alias": { 251 | "dev-master": "1.1.x-dev" 252 | } 253 | }, 254 | "autoload": { 255 | "psr-4": { 256 | "cebe\\markdown\\": "" 257 | } 258 | }, 259 | "notification-url": "https://packagist.org/downloads/", 260 | "license": [ 261 | "MIT" 262 | ], 263 | "authors": [ 264 | { 265 | "name": "Carsten Brandt", 266 | "email": "mail@cebe.cc", 267 | "homepage": "http://cebe.cc/", 268 | "role": "Creator" 269 | } 270 | ], 271 | "description": "A super fast, highly extensible markdown parser for PHP", 272 | "homepage": "https://github.com/cebe/markdown#readme", 273 | "keywords": [ 274 | "extensible", 275 | "fast", 276 | "gfm", 277 | "markdown", 278 | "markdown-extra" 279 | ], 280 | "time": "2015-03-20 11:07:08" 281 | }, 282 | { 283 | "name": "ezyang/htmlpurifier", 284 | "version": "v4.6.0", 285 | "source": { 286 | "type": "git", 287 | "url": "https://github.com/ezyang/htmlpurifier.git", 288 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd" 289 | }, 290 | "dist": { 291 | "type": "zip", 292 | "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/6f389f0f25b90d0b495308efcfa073981177f0fd", 293 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd", 294 | "shasum": "" 295 | }, 296 | "require": { 297 | "php": ">=5.2" 298 | }, 299 | "type": "library", 300 | "autoload": { 301 | "psr-0": { 302 | "HTMLPurifier": "library/" 303 | }, 304 | "files": [ 305 | "library/HTMLPurifier.composer.php" 306 | ] 307 | }, 308 | "notification-url": "https://packagist.org/downloads/", 309 | "license": [ 310 | "LGPL" 311 | ], 312 | "authors": [ 313 | { 314 | "name": "Edward Z. Yang", 315 | "email": "admin@htmlpurifier.org", 316 | "homepage": "http://ezyang.com" 317 | } 318 | ], 319 | "description": "Standards compliant HTML filter written in PHP", 320 | "homepage": "http://htmlpurifier.org/", 321 | "keywords": [ 322 | "html" 323 | ], 324 | "time": "2013-11-30 08:25:19" 325 | }, 326 | { 327 | "name": "yiisoft/yii2", 328 | "version": "dev-master", 329 | "source": { 330 | "type": "git", 331 | "url": "https://github.com/yiisoft/yii2-framework.git", 332 | "reference": "492aeb766b30eb00747c54096f790d2afd1090c8" 333 | }, 334 | "dist": { 335 | "type": "zip", 336 | "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/492aeb766b30eb00747c54096f790d2afd1090c8", 337 | "reference": "492aeb766b30eb00747c54096f790d2afd1090c8", 338 | "shasum": "" 339 | }, 340 | "require": { 341 | "bower-asset/jquery": "2.1.*@stable | 1.11.*@stable", 342 | "bower-asset/jquery.inputmask": "3.1.*", 343 | "bower-asset/punycode": "1.3.*", 344 | "bower-asset/yii2-pjax": ">=2.0.1", 345 | "cebe/markdown": "~1.0.0 | ~1.1.0", 346 | "ext-mbstring": "*", 347 | "ezyang/htmlpurifier": "4.6.*", 348 | "lib-pcre": "*", 349 | "php": ">=5.4.0", 350 | "yiisoft/yii2-composer": "*" 351 | }, 352 | "bin": [ 353 | "yii" 354 | ], 355 | "type": "library", 356 | "extra": { 357 | "branch-alias": { 358 | "dev-master": "2.0.x-dev" 359 | } 360 | }, 361 | "autoload": { 362 | "psr-4": { 363 | "yii\\": "" 364 | } 365 | }, 366 | "notification-url": "https://packagist.org/downloads/", 367 | "license": [ 368 | "BSD-3-Clause" 369 | ], 370 | "authors": [ 371 | { 372 | "name": "Qiang Xue", 373 | "email": "qiang.xue@gmail.com", 374 | "homepage": "http://www.yiiframework.com/", 375 | "role": "Founder and project lead" 376 | }, 377 | { 378 | "name": "Alexander Makarov", 379 | "email": "sam@rmcreative.ru", 380 | "homepage": "http://rmcreative.ru/", 381 | "role": "Core framework development" 382 | }, 383 | { 384 | "name": "Maurizio Domba", 385 | "homepage": "http://mdomba.info/", 386 | "role": "Core framework development" 387 | }, 388 | { 389 | "name": "Carsten Brandt", 390 | "email": "mail@cebe.cc", 391 | "homepage": "http://cebe.cc/", 392 | "role": "Core framework development" 393 | }, 394 | { 395 | "name": "Timur Ruziev", 396 | "email": "resurtm@gmail.com", 397 | "homepage": "http://resurtm.com/", 398 | "role": "Core framework development" 399 | }, 400 | { 401 | "name": "Paul Klimov", 402 | "email": "klimov.paul@gmail.com", 403 | "role": "Core framework development" 404 | } 405 | ], 406 | "description": "Yii PHP Framework Version 2", 407 | "homepage": "http://www.yiiframework.com/", 408 | "keywords": [ 409 | "framework", 410 | "yii2" 411 | ], 412 | "time": "2015-05-11 09:52:29" 413 | }, 414 | { 415 | "name": "yiisoft/yii2-bootstrap", 416 | "version": "dev-master", 417 | "source": { 418 | "type": "git", 419 | "url": "https://github.com/yiisoft/yii2-bootstrap.git", 420 | "reference": "a02d1356817b988473706f921d7ac56f8797b0bd" 421 | }, 422 | "dist": { 423 | "type": "zip", 424 | "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/a02d1356817b988473706f921d7ac56f8797b0bd", 425 | "reference": "a02d1356817b988473706f921d7ac56f8797b0bd", 426 | "shasum": "" 427 | }, 428 | "require": { 429 | "bower-asset/bootstrap": "3.3.* | 3.2.* | 3.1.*", 430 | "yiisoft/yii2": ">=2.0.4" 431 | }, 432 | "type": "yii2-extension", 433 | "extra": { 434 | "branch-alias": { 435 | "dev-master": "2.0.x-dev" 436 | }, 437 | "asset-installer-paths": { 438 | "npm-asset-library": "vendor/npm", 439 | "bower-asset-library": "vendor/bower" 440 | } 441 | }, 442 | "autoload": { 443 | "psr-4": { 444 | "yii\\bootstrap\\": "" 445 | } 446 | }, 447 | "notification-url": "https://packagist.org/downloads/", 448 | "license": [ 449 | "BSD-3-Clause" 450 | ], 451 | "authors": [ 452 | { 453 | "name": "Qiang Xue", 454 | "email": "qiang.xue@gmail.com" 455 | } 456 | ], 457 | "description": "The Twitter Bootstrap extension for the Yii framework", 458 | "keywords": [ 459 | "bootstrap", 460 | "yii2" 461 | ], 462 | "time": "2015-05-11 22:27:56" 463 | }, 464 | { 465 | "name": "yiisoft/yii2-composer", 466 | "version": "dev-master", 467 | "source": { 468 | "type": "git", 469 | "url": "https://github.com/yiisoft/yii2-composer.git", 470 | "reference": "c7f59a6db76ae12aef4ddd244b0d02ab76b8a0b8" 471 | }, 472 | "dist": { 473 | "type": "zip", 474 | "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/c7f59a6db76ae12aef4ddd244b0d02ab76b8a0b8", 475 | "reference": "c7f59a6db76ae12aef4ddd244b0d02ab76b8a0b8", 476 | "shasum": "" 477 | }, 478 | "require": { 479 | "composer-plugin-api": "1.0.0" 480 | }, 481 | "type": "composer-plugin", 482 | "extra": { 483 | "class": "yii\\composer\\Plugin", 484 | "branch-alias": { 485 | "dev-master": "2.0.x-dev" 486 | } 487 | }, 488 | "autoload": { 489 | "psr-4": { 490 | "yii\\composer\\": "" 491 | } 492 | }, 493 | "notification-url": "https://packagist.org/downloads/", 494 | "license": [ 495 | "BSD-3-Clause" 496 | ], 497 | "authors": [ 498 | { 499 | "name": "Qiang Xue", 500 | "email": "qiang.xue@gmail.com" 501 | } 502 | ], 503 | "description": "The composer plugin for Yii extension installer", 504 | "keywords": [ 505 | "composer", 506 | "extension installer", 507 | "yii2" 508 | ], 509 | "time": "2015-04-29 09:00:02" 510 | } 511 | ], 512 | "packages-dev": [ 513 | { 514 | "name": "bower-asset/typeahead.js", 515 | "version": "v0.10.5", 516 | "source": { 517 | "type": "git", 518 | "url": "https://github.com/twitter/typeahead.js.git", 519 | "reference": "5f198b87d1af845da502ea9df93a5e84801ce742" 520 | }, 521 | "dist": { 522 | "type": "zip", 523 | "url": "https://api.github.com/repos/twitter/typeahead.js/zipball/5f198b87d1af845da502ea9df93a5e84801ce742", 524 | "reference": "5f198b87d1af845da502ea9df93a5e84801ce742", 525 | "shasum": "" 526 | }, 527 | "require": { 528 | "bower-asset/jquery": ">=1.7" 529 | }, 530 | "require-dev": { 531 | "bower-asset/jasmine-ajax": "~1.3.1", 532 | "bower-asset/jasmine-jquery": "~1.5.2", 533 | "bower-asset/jquery": "~1.7" 534 | }, 535 | "type": "bower-asset-library", 536 | "extra": { 537 | "bower-asset-main": "dist/typeahead.bundle.js" 538 | } 539 | }, 540 | { 541 | "name": "fzaninotto/faker", 542 | "version": "dev-master", 543 | "source": { 544 | "type": "git", 545 | "url": "https://github.com/fzaninotto/Faker.git", 546 | "reference": "1dc7404280b32ee661ea65606efcf792be6fc4ca" 547 | }, 548 | "dist": { 549 | "type": "zip", 550 | "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/1dc7404280b32ee661ea65606efcf792be6fc4ca", 551 | "reference": "1dc7404280b32ee661ea65606efcf792be6fc4ca", 552 | "shasum": "" 553 | }, 554 | "require": { 555 | "php": ">=5.3.3" 556 | }, 557 | "require-dev": { 558 | "phpunit/phpunit": "~4.0", 559 | "squizlabs/php_codesniffer": "~1.5" 560 | }, 561 | "suggest": { 562 | "ext-intl": "*" 563 | }, 564 | "type": "library", 565 | "extra": { 566 | "branch-alias": { 567 | "dev-master": "1.5.x-dev" 568 | } 569 | }, 570 | "autoload": { 571 | "psr-4": { 572 | "Faker\\": "src/Faker/" 573 | } 574 | }, 575 | "notification-url": "https://packagist.org/downloads/", 576 | "license": [ 577 | "MIT" 578 | ], 579 | "authors": [ 580 | { 581 | "name": "François Zaninotto" 582 | } 583 | ], 584 | "description": "Faker is a PHP library that generates fake data for you.", 585 | "keywords": [ 586 | "data", 587 | "faker", 588 | "fixtures" 589 | ], 590 | "time": "2015-04-27 20:30:06" 591 | }, 592 | { 593 | "name": "phpspec/php-diff", 594 | "version": "dev-master", 595 | "source": { 596 | "type": "git", 597 | "url": "https://github.com/phpspec/php-diff.git", 598 | "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a" 599 | }, 600 | "dist": { 601 | "type": "zip", 602 | "url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a", 603 | "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a", 604 | "shasum": "" 605 | }, 606 | "type": "library", 607 | "autoload": { 608 | "psr-0": { 609 | "Diff": "lib/" 610 | } 611 | }, 612 | "notification-url": "https://packagist.org/downloads/", 613 | "license": [ 614 | "BSD-3-Clause" 615 | ], 616 | "authors": [ 617 | { 618 | "name": "Chris Boulton", 619 | "homepage": "http://github.com/chrisboulton", 620 | "role": "Original developer" 621 | } 622 | ], 623 | "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", 624 | "time": "2013-11-01 13:02:21" 625 | }, 626 | { 627 | "name": "yiisoft/yii2-codeception", 628 | "version": "dev-master", 629 | "source": { 630 | "type": "git", 631 | "url": "https://github.com/yiisoft/yii2-codeception.git", 632 | "reference": "b3407b0c8614c1d614c5c58287816027ba98418b" 633 | }, 634 | "dist": { 635 | "type": "zip", 636 | "url": "https://api.github.com/repos/yiisoft/yii2-codeception/zipball/b3407b0c8614c1d614c5c58287816027ba98418b", 637 | "reference": "b3407b0c8614c1d614c5c58287816027ba98418b", 638 | "shasum": "" 639 | }, 640 | "require": { 641 | "yiisoft/yii2": ">=2.0.4" 642 | }, 643 | "type": "yii2-extension", 644 | "extra": { 645 | "branch-alias": { 646 | "dev-master": "2.0.x-dev" 647 | } 648 | }, 649 | "autoload": { 650 | "psr-4": { 651 | "yii\\codeception\\": "" 652 | } 653 | }, 654 | "notification-url": "https://packagist.org/downloads/", 655 | "license": [ 656 | "BSD-3-Clause" 657 | ], 658 | "authors": [ 659 | { 660 | "name": "Mark Jebri", 661 | "email": "mark.github@yandex.ru" 662 | } 663 | ], 664 | "description": "The Codeception integration for the Yii framework", 665 | "keywords": [ 666 | "codeception", 667 | "yii2" 668 | ], 669 | "time": "2015-05-10 22:28:02" 670 | }, 671 | { 672 | "name": "yiisoft/yii2-debug", 673 | "version": "dev-master", 674 | "source": { 675 | "type": "git", 676 | "url": "https://github.com/yiisoft/yii2-debug.git", 677 | "reference": "b2448aa67657323409e97b5facbf21b498b848e2" 678 | }, 679 | "dist": { 680 | "type": "zip", 681 | "url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/b2448aa67657323409e97b5facbf21b498b848e2", 682 | "reference": "b2448aa67657323409e97b5facbf21b498b848e2", 683 | "shasum": "" 684 | }, 685 | "require": { 686 | "yiisoft/yii2": ">=2.0.4", 687 | "yiisoft/yii2-bootstrap": "*" 688 | }, 689 | "type": "yii2-extension", 690 | "extra": { 691 | "branch-alias": { 692 | "dev-master": "2.0.x-dev" 693 | } 694 | }, 695 | "autoload": { 696 | "psr-4": { 697 | "yii\\debug\\": "" 698 | } 699 | }, 700 | "notification-url": "https://packagist.org/downloads/", 701 | "license": [ 702 | "BSD-3-Clause" 703 | ], 704 | "authors": [ 705 | { 706 | "name": "Qiang Xue", 707 | "email": "qiang.xue@gmail.com" 708 | } 709 | ], 710 | "description": "The debugger extension for the Yii framework", 711 | "keywords": [ 712 | "debug", 713 | "debugger", 714 | "yii2" 715 | ], 716 | "time": "2015-05-10 22:28:14" 717 | }, 718 | { 719 | "name": "yiisoft/yii2-faker", 720 | "version": "dev-master", 721 | "source": { 722 | "type": "git", 723 | "url": "https://github.com/yiisoft/yii2-faker.git", 724 | "reference": "66432de272e5795435dc7da49381ea7bea2a2a67" 725 | }, 726 | "dist": { 727 | "type": "zip", 728 | "url": "https://api.github.com/repos/yiisoft/yii2-faker/zipball/66432de272e5795435dc7da49381ea7bea2a2a67", 729 | "reference": "66432de272e5795435dc7da49381ea7bea2a2a67", 730 | "shasum": "" 731 | }, 732 | "require": { 733 | "fzaninotto/faker": "~1.4", 734 | "yiisoft/yii2": "*" 735 | }, 736 | "type": "yii2-extension", 737 | "extra": { 738 | "branch-alias": { 739 | "dev-master": "2.0.x-dev" 740 | } 741 | }, 742 | "autoload": { 743 | "psr-4": { 744 | "yii\\faker\\": "" 745 | } 746 | }, 747 | "notification-url": "https://packagist.org/downloads/", 748 | "license": [ 749 | "BSD-3-Clause" 750 | ], 751 | "authors": [ 752 | { 753 | "name": "Mark Jebri", 754 | "email": "mark.github@yandex.ru" 755 | } 756 | ], 757 | "description": "Fixture generator. The Faker integration for the Yii framework.", 758 | "keywords": [ 759 | "Fixture", 760 | "faker", 761 | "yii2" 762 | ], 763 | "time": "2015-05-10 19:14:39" 764 | }, 765 | { 766 | "name": "yiisoft/yii2-gii", 767 | "version": "dev-master", 768 | "source": { 769 | "type": "git", 770 | "url": "https://github.com/yiisoft/yii2-gii.git", 771 | "reference": "dbd9a38f43eb605aa6c433f1ffd3c37c2a3ce9d8" 772 | }, 773 | "dist": { 774 | "type": "zip", 775 | "url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/dbd9a38f43eb605aa6c433f1ffd3c37c2a3ce9d8", 776 | "reference": "dbd9a38f43eb605aa6c433f1ffd3c37c2a3ce9d8", 777 | "shasum": "" 778 | }, 779 | "require": { 780 | "bower-asset/typeahead.js": "0.10.*", 781 | "phpspec/php-diff": ">=1.0.2", 782 | "yiisoft/yii2": ">=2.0.4", 783 | "yiisoft/yii2-bootstrap": "~2.0" 784 | }, 785 | "type": "yii2-extension", 786 | "extra": { 787 | "branch-alias": { 788 | "dev-master": "2.0.x-dev" 789 | }, 790 | "asset-installer-paths": { 791 | "npm-asset-library": "vendor/npm", 792 | "bower-asset-library": "vendor/bower" 793 | } 794 | }, 795 | "autoload": { 796 | "psr-4": { 797 | "yii\\gii\\": "" 798 | } 799 | }, 800 | "notification-url": "https://packagist.org/downloads/", 801 | "license": [ 802 | "BSD-3-Clause" 803 | ], 804 | "authors": [ 805 | { 806 | "name": "Qiang Xue", 807 | "email": "qiang.xue@gmail.com" 808 | } 809 | ], 810 | "description": "The Gii extension for the Yii framework", 811 | "keywords": [ 812 | "code generator", 813 | "gii", 814 | "yii2" 815 | ], 816 | "time": "2015-05-10 22:29:47" 817 | } 818 | ], 819 | "aliases": [], 820 | "minimum-stability": "dev", 821 | "stability-flags": [], 822 | "prefer-stable": false, 823 | "prefer-lowest": false, 824 | "platform": { 825 | "php": ">=5.4.0" 826 | }, 827 | "platform-dev": [] 828 | } 829 | -------------------------------------------------------------------------------- /console/config/.gitignore: -------------------------------------------------------------------------------- 1 | main-local.php 2 | params-local.php -------------------------------------------------------------------------------- /console/config/bootstrap.php: -------------------------------------------------------------------------------- 1 | 'app-console', 10 | 'basePath' => dirname(__DIR__), 11 | 'bootstrap' => ['log', 'gii'], 12 | 'controllerNamespace' => 'console\controllers', 13 | 'modules' => [ 14 | 'gii' => 'yii\gii\Module', 15 | ], 16 | 'components' => [ 17 | 'log' => [ 18 | 'targets' => [ 19 | [ 20 | 'class' => 'yii\log\FileTarget', 21 | 'levels' => ['error', 'warning'], 22 | ], 23 | ], 24 | ], 25 | ], 26 | 'params' => $params, 27 | ]; -------------------------------------------------------------------------------- /console/config/params.php: -------------------------------------------------------------------------------- 1 | 'admin@example.com', 4 | ]; 5 | -------------------------------------------------------------------------------- /console/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/githubjeka/yii2-rest/e9f18d8a0d3488422abcd2e39303b0c2bb9d6f35/console/controllers/.gitkeep -------------------------------------------------------------------------------- /console/migrations/m140724_112641_init.php: -------------------------------------------------------------------------------- 1 | db->driverName === 'mysql') { 12 | $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; 13 | } 14 | 15 | $this->createTable( 16 | '{{%user}}', 17 | [ 18 | 'id' => Schema::TYPE_PK, 19 | 'username' => Schema::TYPE_STRING . ' NOT NULL ', 20 | 'auth_key' => Schema::TYPE_STRING . '(32) NOT NULL', 21 | 'password_hash' => Schema::TYPE_STRING . ' NOT NULL', 22 | 'password_reset_token' => Schema::TYPE_STRING, 23 | 'email' => Schema::TYPE_STRING . ' NOT NULL', 24 | 'status' => Schema::TYPE_SMALLINT . ' NOT NULL DEFAULT 10', 25 | 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', 26 | 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', 27 | ], 28 | $tableOptions 29 | ); 30 | 31 | $user = new \common\models\User(); 32 | $user->username = 'demo'; 33 | $user->email = 'demo@mail.net'; 34 | $user->generateAuthKey(); 35 | $user->setPassword('demo'); 36 | return $user->insert(); 37 | } 38 | 39 | public function down() 40 | { 41 | $this->dropTable('{{%user}}'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /console/migrations/m140731_074148_post.php: -------------------------------------------------------------------------------- 1 | db->driverName === 'mysql') { 12 | $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; 13 | } 14 | 15 | $this->createTable( 16 | '{{%post}}', 17 | [ 18 | 'id' => Schema::TYPE_PK, 19 | 'title' => Schema::TYPE_STRING . '(128) NOT NULL ', 20 | 'content' => Schema::TYPE_TEXT . ' NOT NULL', 21 | 'tags' => Schema::TYPE_TEXT, 22 | 'status' => Schema::TYPE_INTEGER, 23 | 'author_id' => Schema::TYPE_INTEGER . ' NOT NULL', 24 | 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', 25 | 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', 26 | ], 27 | $tableOptions 28 | ); 29 | 30 | $user = \common\models\User::findOne(['id' => 1]); 31 | 32 | if ($user) { 33 | $post = new \common\models\Post(); 34 | 35 | $post->author_id = $user->id; 36 | 37 | $post->title = 'Welcome!'; 38 | $post->content = 'This blog system is developed using Yii. It is meant to demonstrate how to use Yii to 39 | build a complete real-world application. Complete source code may be found in the Yii 40 | releases. Feel free to try this system by writing new posts and posting comments.'; 41 | $post->tags = 'yii2, rest'; 42 | $post->status = 1; 43 | return $post->insert(); 44 | } 45 | 46 | return false; 47 | 48 | } 49 | 50 | public function down() 51 | { 52 | $this->dropTable('{{%post}}'); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /console/migrations/m140922_121411_comments.php: -------------------------------------------------------------------------------- 1 | db->driverName === 'mysql') { 12 | $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB'; 13 | } 14 | 15 | $this->createTable( 16 | '{{%comment}}', 17 | [ 18 | 'id' => Schema::TYPE_PK, 19 | 'content' => Schema::TYPE_STRING . '(128) NOT NULL ', 20 | 'post_id' => Schema::TYPE_INTEGER . ' NOT NULL', 21 | 'created_at' => Schema::TYPE_INTEGER . ' NOT NULL', 22 | 'updated_at' => Schema::TYPE_INTEGER . ' NOT NULL', 23 | ], 24 | $tableOptions 25 | ); 26 | } 27 | 28 | public function down() 29 | { 30 | echo "m140922_121411_comments cannot be reverted.\n"; 31 | 32 | return false; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /console/models/.gitkeep: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /console/runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /environments/dev/backend/config/main-local.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'request' => [ 6 | 'cookieValidationKey' => '', 7 | ], 8 | ], 9 | ]; 10 | 11 | if (!YII_ENV_TEST) { 12 | // configuration adjustments for 'dev' environment 13 | $config['bootstrap'][] = 'debug'; 14 | $config['modules']['debug'] = [ 15 | 'class' => 'yii\debug\Module', 16 | 'allowedIPs' => ['127.0.0.1', '::1'], 17 | ]; 18 | 19 | $config['bootstrap'][] = 'gii'; 20 | $config['modules']['gii'] = [ 21 | 'class' => 'yii\gii\Module', 22 | 'allowedIPs' => ['127.0.0.1', '::1'], 23 | ]; 24 | } 25 | 26 | return $config; 27 | -------------------------------------------------------------------------------- /environments/dev/backend/config/params-local.php: -------------------------------------------------------------------------------- 1 | run(); 20 | -------------------------------------------------------------------------------- /environments/dev/backend/web/index.php: -------------------------------------------------------------------------------- 1 | run(); 19 | -------------------------------------------------------------------------------- /environments/dev/common/config/main-local.php: -------------------------------------------------------------------------------- 1 | 6 | */ 7 | 8 | return [ 9 | 'language' => 'en', 10 | 'components' => [ 11 | 'db' => [ 12 | 'class' => 'yii\db\Connection', 13 | 'dsn' => '', 14 | 'username' => '', 15 | 'password' => '', 16 | 'charset' => 'utf8', 17 | ], 18 | ], 19 | ]; 20 | -------------------------------------------------------------------------------- /environments/dev/common/config/params-local.php: -------------------------------------------------------------------------------- 1 | 6 | */ 7 | 8 | return [ 9 | ]; 10 | -------------------------------------------------------------------------------- /environments/dev/console/config/params-local.php: -------------------------------------------------------------------------------- 1 | 6 | */ 7 | 8 | return [ 9 | 'components' => [ 10 | 'log' => [ 11 | 'traceLevel' => 3, 12 | ], 13 | ], 14 | ]; 15 | -------------------------------------------------------------------------------- /environments/dev/rest/config/params-local.php: -------------------------------------------------------------------------------- 1 | run(); 19 | -------------------------------------------------------------------------------- /environments/dev/rest/web/index.php: -------------------------------------------------------------------------------- 1 | run(); 23 | 24 | -------------------------------------------------------------------------------- /environments/dev/yii: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(); 32 | exit($exitCode); -------------------------------------------------------------------------------- /environments/index.php: -------------------------------------------------------------------------------- 1 | [ 11 | * 'path' => 'directory storing the local files', 12 | * 'setWritable' => [ 13 | * // list of directories that should be set writable 14 | * ], 15 | * 'setExecutable' => [ 16 | * // list of directories that should be set executable 17 | * ], 18 | * 'setCookieValidationKey' => [ 19 | * // list of config files that need to be inserted with automatically generated cookie validation keys 20 | * ], 21 | * ], 22 | * ]; 23 | * ``` 24 | */ 25 | return [ 26 | 'Development' => [ 27 | 'path' => 'dev', 28 | 'setWritable' => [ 29 | 'backend/runtime', 30 | 'backend/web/assets', 31 | 'rest/runtime', 32 | ], 33 | 'setExecutable' => [ 34 | 'yii', 35 | 'tests/codeception/bin/yii', 36 | ], 37 | 'setCookieValidationKey' => [ 38 | 'backend/config/main-local.php', 39 | ], 40 | ], 41 | ]; -------------------------------------------------------------------------------- /init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | 11 | * 12 | * @link http://www.yiiframework.com/ 13 | * @copyright Copyright (c) 2008 Yii Software LLC 14 | * @license http://www.yiiframework.com/license/ 15 | */ 16 | if (!extension_loaded('openssl')) { 17 | die('The OpenSSL PHP extension is required by Yii2.'); 18 | } 19 | $params = getParams(); 20 | $root = str_replace('\\', '/', __DIR__); 21 | $envs = require("$root/environments/index.php"); 22 | $envNames = array_keys($envs); 23 | echo "Yii Application Initialization Tool v1.0\n\n"; 24 | $envName = null; 25 | if (empty($params['env']) || $params['env'] === '1') { 26 | echo "Which environment do you want the application to be initialized in?\n\n"; 27 | foreach ($envNames as $i => $name) { 28 | echo " [$i] $name\n"; 29 | } 30 | echo "\n Your choice [0-" . (count($envs) - 1) . ', or "q" to quit] '; 31 | $answer = trim(fgets(STDIN)); 32 | if (!ctype_digit($answer) || !in_array($answer, range(0, count($envs) - 1))) { 33 | echo "\n Quit initialization.\n"; 34 | exit(0); 35 | } 36 | if (isset($envNames[$answer])) { 37 | $envName = $envNames[$answer]; 38 | } 39 | } else { 40 | $envName = $params['env']; 41 | } 42 | if (!in_array($envName, $envNames)) { 43 | $envsList = implode(', ', $envNames); 44 | echo "\n $envName is not a valid environment. Try one of the following: $envsList. \n"; 45 | exit(2); 46 | } 47 | $env = $envs[$envName]; 48 | if (empty($params['env'])) { 49 | echo "\n Initialize the application under '{$envNames[$answer]}' environment? [yes|no] "; 50 | $answer = trim(fgets(STDIN)); 51 | if (strncasecmp($answer, 'y', 1)) { 52 | echo "\n Quit initialization.\n"; 53 | exit(0); 54 | } 55 | } 56 | echo "\n Start initialization ...\n\n"; 57 | $files = getFileList("$root/environments/{$env['path']}"); 58 | if (isset($env['skipFiles'])) { 59 | $skipFiles = $env['skipFiles']; 60 | array_walk($skipFiles, function(&$value) use($env, $root) { $value = "$root/$value"; }); 61 | $files = array_diff($files, array_intersect_key($env['skipFiles'], array_filter($skipFiles, 'file_exists'))); 62 | } 63 | $all = false; 64 | foreach ($files as $file) { 65 | if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) { 66 | break; 67 | } 68 | } 69 | $callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable', 'createSymlink']; 70 | foreach ($callbacks as $callback) { 71 | if (!empty($env[$callback])) { 72 | $callback($root, $env[$callback]); 73 | } 74 | } 75 | echo "\n ... initialization completed.\n\n"; 76 | function getFileList($root, $basePath = '') 77 | { 78 | $files = []; 79 | $handle = opendir($root); 80 | while (($path = readdir($handle)) !== false) { 81 | if ($path === '.svn' || $path === '.' || $path === '..') { 82 | continue; 83 | } 84 | $fullPath = "$root/$path"; 85 | $relativePath = $basePath === '' ? $path : "$basePath/$path"; 86 | if (is_dir($fullPath)) { 87 | $files = array_merge($files, getFileList($fullPath, $relativePath)); 88 | } else { 89 | $files[] = $relativePath; 90 | } 91 | } 92 | closedir($handle); 93 | return $files; 94 | } 95 | function copyFile($root, $source, $target, &$all, $params) 96 | { 97 | if (!is_file($root . '/' . $source)) { 98 | echo " skip $target ($source not exist)\n"; 99 | return true; 100 | } 101 | if (is_file($root . '/' . $target)) { 102 | if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) { 103 | echo " unchanged $target\n"; 104 | return true; 105 | } 106 | if ($all) { 107 | echo " overwrite $target\n"; 108 | } else { 109 | echo " exist $target\n"; 110 | echo " ...overwrite? [Yes|No|All|Quit] "; 111 | $answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN)); 112 | if (!strncasecmp($answer, 'q', 1)) { 113 | return false; 114 | } else { 115 | if (!strncasecmp($answer, 'y', 1)) { 116 | echo " overwrite $target\n"; 117 | } else { 118 | if (!strncasecmp($answer, 'a', 1)) { 119 | echo " overwrite $target\n"; 120 | $all = true; 121 | } else { 122 | echo " skip $target\n"; 123 | return true; 124 | } 125 | } 126 | } 127 | } 128 | file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); 129 | return true; 130 | } 131 | echo " generate $target\n"; 132 | @mkdir(dirname($root . '/' . $target), 0777, true); 133 | file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); 134 | return true; 135 | } 136 | function getParams() 137 | { 138 | $rawParams = []; 139 | if (isset($_SERVER['argv'])) { 140 | $rawParams = $_SERVER['argv']; 141 | array_shift($rawParams); 142 | } 143 | $params = []; 144 | foreach ($rawParams as $param) { 145 | if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) { 146 | $name = $matches[1]; 147 | $params[$name] = isset($matches[3]) ? $matches[3] : true; 148 | } else { 149 | $params[] = $param; 150 | } 151 | } 152 | return $params; 153 | } 154 | function setWritable($root, $paths) 155 | { 156 | foreach ($paths as $writable) { 157 | echo " chmod 0777 $writable\n"; 158 | @chmod("$root/$writable", 0777); 159 | } 160 | } 161 | function setExecutable($root, $paths) 162 | { 163 | foreach ($paths as $executable) { 164 | echo " chmod 0755 $executable\n"; 165 | @chmod("$root/$executable", 0755); 166 | } 167 | } 168 | function setCookieValidationKey($root, $paths) 169 | { 170 | foreach ($paths as $file) { 171 | echo " generate cookie validation key in $file\n"; 172 | $file = $root . '/' . $file; 173 | $length = 32; 174 | $bytes = openssl_random_pseudo_bytes($length); 175 | $key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.'); 176 | $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file)); 177 | file_put_contents($file, $content); 178 | } 179 | } 180 | function createSymlink($root, $links) { 181 | foreach ($links as $link => $target) { 182 | echo " symlink " . $root . "/" . $target . " " . $root . "/" . $link . "\n"; 183 | //first removing folders to avoid errors if the folder already exists 184 | @rmdir($root . "/" . $link); 185 | @symlink($root . "/" . $target, $root . "/" . $link); 186 | } 187 | } -------------------------------------------------------------------------------- /init.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem ------------------------------------------------------------- 4 | rem Yii command line init 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%init" %* 19 | 20 | @endlocal 21 | -------------------------------------------------------------------------------- /requirements.php: -------------------------------------------------------------------------------- 1 | Error'; 16 | echo '

The path to yii framework seems to be incorrect.

'; 17 | echo '

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

'; 18 | echo '

Please refer to the README on how to install Yii.

'; 19 | } 20 | require_once($frameworkPath . '/requirements/YiiRequirementChecker.php'); 21 | $requirementsChecker = new YiiRequirementChecker(); 22 | $gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.'; 23 | $gdOK = $imagickOK = false; 24 | if (extension_loaded('imagick')) { 25 | $imagick = new Imagick(); 26 | $imagickFormats = $imagick->queryFormats('PNG'); 27 | if (in_array('PNG', $imagickFormats)) { 28 | $imagickOK = true; 29 | } else { 30 | $imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.'; 31 | } 32 | } 33 | if (extension_loaded('gd')) { 34 | $gdInfo = gd_info(); 35 | if (!empty($gdInfo['FreeType Support'])) { 36 | $gdOK = true; 37 | } else { 38 | $gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.'; 39 | } 40 | } 41 | /** 42 | * Adjust requirements according to your application specifics. 43 | */ 44 | $requirements = array( 45 | // Database : 46 | array( 47 | 'name' => 'PDO extension', 48 | 'mandatory' => true, 49 | 'condition' => extension_loaded('pdo'), 50 | 'by' => 'All DB-related classes', 51 | ), 52 | array( 53 | 'name' => 'PDO SQLite extension', 54 | 'mandatory' => false, 55 | 'condition' => extension_loaded('pdo_sqlite'), 56 | 'by' => 'All DB-related classes', 57 | 'memo' => 'Required for SQLite database.', 58 | ), 59 | array( 60 | 'name' => 'PDO MySQL extension', 61 | 'mandatory' => false, 62 | 'condition' => extension_loaded('pdo_mysql'), 63 | 'by' => 'All DB-related classes', 64 | 'memo' => 'Required for MySQL database.', 65 | ), 66 | array( 67 | 'name' => 'PDO PostgreSQL extension', 68 | 'mandatory' => false, 69 | 'condition' => extension_loaded('pdo_pgsql'), 70 | 'by' => 'All DB-related classes', 71 | 'memo' => 'Required for PostgreSQL database.', 72 | ), 73 | // Cache : 74 | array( 75 | 'name' => 'Memcache extension', 76 | 'mandatory' => false, 77 | 'condition' => extension_loaded('memcache') || extension_loaded('memcached'), 78 | 'by' => 'MemCache', 79 | 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : '' 80 | ), 81 | array( 82 | 'name' => 'APC extension', 83 | 'mandatory' => false, 84 | 'condition' => extension_loaded('apc'), 85 | 'by' => 'ApcCache', 86 | ), 87 | // CAPTCHA: 88 | array( 89 | 'name' => 'GD PHP extension with FreeType support', 90 | 'mandatory' => false, 91 | 'condition' => $gdOK, 92 | 'by' => 'Captcha', 93 | 'memo' => $gdMemo, 94 | ), 95 | array( 96 | 'name' => 'ImageMagick PHP extension with PNG support', 97 | 'mandatory' => false, 98 | 'condition' => $imagickOK, 99 | 'by' => 'Captcha', 100 | 'memo' => $imagickMemo, 101 | ), 102 | // PHP ini : 103 | 'phpExposePhp' => array( 104 | 'name' => 'Expose PHP', 105 | 'mandatory' => false, 106 | 'condition' => $requirementsChecker->checkPhpIniOff("expose_php"), 107 | 'by' => 'Security reasons', 108 | 'memo' => '"expose_php" should be disabled at php.ini', 109 | ), 110 | 'phpAllowUrlInclude' => array( 111 | 'name' => 'PHP allow url include', 112 | 'mandatory' => false, 113 | 'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"), 114 | 'by' => 'Security reasons', 115 | 'memo' => '"allow_url_include" should be disabled at php.ini', 116 | ), 117 | 'phpSmtp' => array( 118 | 'name' => 'PHP mail SMTP', 119 | 'mandatory' => false, 120 | 'condition' => strlen(ini_get('SMTP')) > 0, 121 | 'by' => 'Email sending', 122 | 'memo' => 'PHP mail SMTP server required', 123 | ), 124 | ); 125 | $requirementsChecker->checkYii()->check($requirements)->render(); -------------------------------------------------------------------------------- /rest/config/.gitignore: -------------------------------------------------------------------------------- 1 | main-local.php -------------------------------------------------------------------------------- /rest/config/bootstrap.php: -------------------------------------------------------------------------------- 1 | 'rest-api', 12 | 'basePath' => dirname(__DIR__), 13 | 'bootstrap' => ['log'], 14 | 'modules' => [ 15 | 'v1' => [ 16 | 'class' => 'rest\versions\v1\RestModule' 17 | ], 18 | 'v2' => [ 19 | 'class' => 'rest\versions\v2\RestModule' 20 | ], 21 | ], 22 | 'components' => [ 23 | 'user' => [ 24 | 'identityClass' => 'common\models\User', 25 | 'enableSession' => false, 26 | ], 27 | 'response' => [ 28 | 'format' => yii\web\Response::FORMAT_JSON, 29 | 'charset' => 'UTF-8', 30 | ], 31 | 'log' => [ 32 | 'targets' => [ 33 | [ 34 | 'class' => 'yii\log\FileTarget', 35 | 'levels' => ['error', 'warning'], 36 | ], 37 | ], 38 | ], 39 | 'request' => [ 40 | 'class' => '\yii\web\Request', 41 | 'enableCookieValidation' => false, 42 | 'parsers' => [ 43 | 'application/json' => 'yii\web\JsonParser', 44 | ], 45 | ], 46 | 'urlManager' => [ 47 | 'enablePrettyUrl' => true, 48 | 'enableStrictParsing' => true, 49 | 'showScriptName' => false, 50 | 'rules' => [ 51 | ['class' => 'yii\rest\UrlRule', 'controller' => ['v1/post', 'v1/comment', 'v2/post']], 52 | 'OPTIONS v1/user/login' => 'v1/user/login', 53 | 'POST v1/user/login' => 'v1/user/login', 54 | 'POST v2/user/login' => 'v2/user/login', 55 | 'OPTIONS v2/user/login' => 'v2/user/login', 56 | ], 57 | ], 58 | ], 59 | 'params' => $params, 60 | ]; 61 | -------------------------------------------------------------------------------- /rest/config/params.php: -------------------------------------------------------------------------------- 1 | QueryParamAuth::className(), 16 | ]; 17 | return $behaviors; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /rest/versions/v1/controllers/PostController.php: -------------------------------------------------------------------------------- 1 | QueryParamAuth::className(), 18 | ]; 19 | return $behaviors; 20 | } 21 | 22 | public function actions() 23 | { 24 | return array_merge( 25 | parent::actions(), 26 | [ 27 | 'index' => [ 28 | 'class' => 'yii\rest\IndexAction', 29 | 'modelClass' => $this->modelClass, 30 | 'checkAccess' => [$this, 'checkAccess'], 31 | 'prepareDataProvider' => function ($action) { 32 | /* @var $model Post */ 33 | $model = new $this->modelClass; 34 | $query = $model::find(); 35 | $dataProvider = new ActiveDataProvider(['query' => $query]); 36 | 37 | $model->setAttribute('title', @$_GET['title']); 38 | $query->andFilterWhere(['like', 'title', $model->title]); 39 | 40 | return $dataProvider; 41 | } 42 | ] 43 | ] 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /rest/versions/v1/controllers/UserController.php: -------------------------------------------------------------------------------- 1 | load(\Yii::$app->getRequest()->getBodyParams(), '') && $model->login()) { 23 | return \Yii::$app->user->identity->getAuthKey(); 24 | } else { 25 | return $model; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /rest/versions/v2/RestModule.php: -------------------------------------------------------------------------------- 1 | 9 | beginPage() ?> 10 | 11 | 12 | 13 | 14 | 15 | <?= Html::encode($this->title) ?> 16 | head() ?> 17 | 18 | 19 | beginBody() ?> 20 |
21 | 22 |
23 | endBody() ?> 24 | 25 | 26 | endPage() ?> 27 | -------------------------------------------------------------------------------- /rest/views/site/error.php: -------------------------------------------------------------------------------- 1 | title = $name; 13 | ?> 14 |
15 | 16 |

title) ?>

17 | 18 |
19 | 20 |
21 | 22 |

23 | The above error occurred while the Web server was processing your request. 24 |

25 |

26 | Please contact us if you think this is a server error. Thank you. 27 |

28 | 29 |
30 | -------------------------------------------------------------------------------- /rest/web/.gitignore: -------------------------------------------------------------------------------- 1 | /index.php 2 | /index-test.php -------------------------------------------------------------------------------- /rest/web/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: -------------------------------------------------------------------------------- /server.md: -------------------------------------------------------------------------------- 1 | ### Configuration for Apache 2 | 3 | ``` 4 | RewriteEngine on 5 | 6 | RewriteCond %{REQUEST_FILENAME} !-f 7 | RewriteCond %{REQUEST_FILENAME} !-d 8 | RewriteRule (.*) index.php [L] 9 | ``` 10 | 11 | ### Configuration for Nginx 12 | ``` 13 | include common/upstream; 14 | 15 | server { 16 | charset utf-8; 17 | client_max_body_size 128M; 18 | 19 | listen 80; ## listen for ipv4 20 | #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 21 | 22 | server_name localhost; 23 | root /var/www/rest/rest/web; 24 | index index.php; 25 | 26 | #access_log /var/www/log/rest-access.log main; 27 | #error_log /var/www/log/rest-error.log; 28 | 29 | location / { 30 | # Redirect everything that isn't a real file to index.php 31 | try_files $uri $uri/ /index.php?$args; 32 | } 33 | 34 | # uncomment to avoid processing of calls to non-existing static files by Yii 35 | location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { 36 | try_files $uri =404; 37 | } 38 | #error_page 404 /404.html; 39 | 40 | location ~ \.php$ { 41 | include common/php-fpm; 42 | try_files $uri =404; 43 | } 44 | 45 | location ~ /\.(ht|svn|git) { 46 | deny all; 47 | } 48 | } -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | This directory contains various tests for the advanced applications. 2 | 3 | Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/). 4 | 5 | After creating and setting up the advanced 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.*" "codeception/specify=*" "codeception/verify=*" 11 | ``` 12 | 13 | If you've never used Composer for global packages run `composer global status`. It should output: 14 | 15 | ``` 16 | Changed current directory to 17 | ``` 18 | 19 | Then add `/vendor/bin` to you `PATH` environment variable. Now you're able to use `codecept` from command 20 | line globally. 21 | 22 | 2. Install faker extension by running the following from template root directory where `composer.json` is: 23 | 24 | ``` 25 | composer require --dev yiisoft/yii2-faker:* 26 | ``` 27 | 28 | 3. Create `yii2_advanced_tests` database then update it by applying migrations: 29 | 30 | ``` 31 | codeception/bin/yii migrate 32 | ``` 33 | 34 | 4. In order to be able to run acceptance tests you need to start a webserver. The simplest way is to use PHP built in 35 | webserver. In the root directory where `common`, `frontend` etc. are execute the following: 36 | 37 | ``` 38 | php -S localhost:8080 39 | ``` 40 | 41 | 5. Now you can run the tests with the following commands, assuming you are in the `tests/codeception` directory: 42 | 43 | ``` 44 | # frontend tests 45 | cd frontend 46 | codecept build 47 | codecept run 48 | 49 | # backend tests 50 | 51 | cd backend 52 | codecept build 53 | codecept run 54 | 55 | # etc. 56 | ``` 57 | 58 | If you already have run `codecept build` for each application, you can skip that step and run all tests by a single `codecept run`. 59 | -------------------------------------------------------------------------------- /tests/codeception.yml: -------------------------------------------------------------------------------- 1 | include: 2 | - codeception/common 3 | - codeception/console 4 | - codeception/rest 5 | 6 | paths: 7 | log: codeception/_output 8 | 9 | settings: 10 | colors: true 11 | -------------------------------------------------------------------------------- /tests/codeception/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/codeception/bin/_bootstrap.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'fixture' => [ 22 | 'class' => 'yii\faker\FixtureController', 23 | 'fixtureDataPath' => '@tests/codeception/common/fixtures', 24 | 'templatePath' => '@tests/codeception/common/templates', 25 | ], 26 | ], 27 | ] 28 | ); 29 | 30 | $application = new yii\console\Application($config); 31 | $exitCode = $application->run(); 32 | exit($exitCode); 33 | -------------------------------------------------------------------------------- /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_acceptance" %* 19 | 20 | @endlocal 21 | -------------------------------------------------------------------------------- /tests/codeception/common/.gitignore: -------------------------------------------------------------------------------- 1 | # these files are auto generated by codeception build 2 | /unit/UnitTester.php 3 | /functional/FunctionalTester.php 4 | /acceptance/AcceptanceTester.php 5 | -------------------------------------------------------------------------------- /tests/codeception/common/_bootstrap.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/common/_support/FixtureHelper.php: -------------------------------------------------------------------------------- 1 | loadFixtures(); 39 | } 40 | 41 | /** 42 | * Method is called after all suite tests run 43 | */ 44 | public function _afterSuite() 45 | { 46 | $this->unloadFixtures(); 47 | } 48 | 49 | /** 50 | * @inheritdoc 51 | */ 52 | public function fixtures() 53 | { 54 | return [ 55 | 'user' => [ 56 | 'class' => UserFixture::className(), 57 | 'dataFile' => '@tests/codeception/common/fixtures/data/init_login.php', 58 | ], 59 | 'post' => [ 60 | 'class' => PostFixture::className(), 61 | ], 62 | ]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/codeception/common/codeception.yml: -------------------------------------------------------------------------------- 1 | namespace: tests\codeception\common 2 | actor: Tester 3 | paths: 4 | tests: . 5 | log: _output 6 | data: _data 7 | helpers: _support 8 | settings: 9 | bootstrap: _bootstrap.php 10 | suite_class: \PHPUnit_Framework_TestSuite 11 | colors: true 12 | memory_limit: 1024M 13 | log: true 14 | -------------------------------------------------------------------------------- /tests/codeception/common/fixtures/PostFixture.php: -------------------------------------------------------------------------------- 1 | 'erau', 6 | 'auth_key' => 'tUu1qHcde0diwUol3xeI-18MuHkkprQI', 7 | // password_0 8 | 'password_hash' => '$2y$13$nJ1WDlBaGcbCdbNC5.5l4.sgy.OMEKCqtDQOdQ2OWpgiKRWYyzzne', 9 | 'password_reset_token' => 'RkD_Jw0_8HEedzLk7MM-ZKEFfYR7VbMr_1392559490', 10 | 'created_at' => '1392559490', 11 | 'updated_at' => '1392559490', 12 | 'email' => 'sfriesen@jenkins.info', 13 | ], 14 | ]; 15 | -------------------------------------------------------------------------------- /tests/codeception/common/templates/fixtures/user.php: -------------------------------------------------------------------------------- 1 | getSecurity(); 8 | 9 | return [ 10 | 'username' => $faker->userName, 11 | 'email' => $faker->email, 12 | 'auth_key' => $security->generateRandomString(), 13 | 'password_hash' => $security->generatePasswordHash('password_' . $index), 14 | 'password_reset_token' => $security->generateRandomString() . '_' . time(), 15 | 'created_at' => time(), 16 | 'updated_at' => time(), 17 | ]; 18 | -------------------------------------------------------------------------------- /tests/codeception/common/unit.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | 3 | # suite for unit (internal) tests. 4 | # RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. 5 | 6 | class_name: UnitTester 7 | -------------------------------------------------------------------------------- /tests/codeception/common/unit/DbTestCase.php: -------------------------------------------------------------------------------- 1 | 'bayer.hudson', 6 | 'auth_key' => 'HP187Mvq7Mmm3CTU80dLkGmni_FUH_lR', 7 | //password_0 8 | 'password_hash' => '$2y$13$EjaPFBnZOQsHdGuHI.xvhuDp1fHpo8hKRSk6yshqa9c5EG8s3C3lO', 9 | 'password_reset_token' => 'ExzkCOaYc1L8IOBs4wdTGGbgNiG3Wz1I_1402312317', 10 | 'created_at' => '1402312317', 11 | 'updated_at' => '1402312317', 12 | 'email' => 'nicole.paucek@schultz.info', 13 | ], 14 | ]; 15 | -------------------------------------------------------------------------------- /tests/codeception/common/unit/models/LoginFormTest.php: -------------------------------------------------------------------------------- 1 | [ 25 | 'user' => [ 26 | 'class' => 'yii\web\User', 27 | 'identityClass' => 'common\models\User', 28 | ], 29 | ], 30 | ]); 31 | } 32 | 33 | protected function tearDown() 34 | { 35 | Yii::$app->user->logout(); 36 | parent::tearDown(); 37 | } 38 | 39 | public function testLoginNoUser() 40 | { 41 | $model = new LoginForm([ 42 | 'username' => 'not_existing_username', 43 | 'password' => 'not_existing_password', 44 | ]); 45 | 46 | $this->specify('user should not be able to login, when there is no identity', function () use ($model) { 47 | expect('model should not login user', $model->login())->false(); 48 | expect('user should not be logged in', Yii::$app->user->isGuest)->true(); 49 | }); 50 | } 51 | 52 | public function testLoginWrongPassword() 53 | { 54 | $model = new LoginForm([ 55 | 'username' => 'bayer.hudson', 56 | 'password' => 'wrong_password', 57 | ]); 58 | 59 | $this->specify('user should not be able to login with wrong password', function () use ($model) { 60 | expect('model should not login user', $model->login())->false(); 61 | expect('error message should be set', $model->errors)->hasKey('password'); 62 | expect('user should not be logged in', Yii::$app->user->isGuest)->true(); 63 | }); 64 | } 65 | 66 | public function testLoginCorrect() 67 | { 68 | 69 | $model = new LoginForm([ 70 | 'username' => 'bayer.hudson', 71 | 'password' => 'password_0', 72 | ]); 73 | 74 | $this->specify('user should be able to login with correct credentials', function () use ($model) { 75 | expect('model should login user', $model->login())->true(); 76 | expect('error message should not be set', $model->errors)->hasntKey('password'); 77 | expect('user should be logged in', Yii::$app->user->isGuest)->false(); 78 | }); 79 | } 80 | 81 | /** 82 | * @inheritdoc 83 | */ 84 | public function fixtures() 85 | { 86 | return [ 87 | 'user' => [ 88 | 'class' => UserFixture::className(), 89 | 'dataFile' => '@tests/codeception/common/unit/fixtures/data/models/user.php' 90 | ], 91 | ]; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /tests/codeception/config/acceptance.php: -------------------------------------------------------------------------------- 1 | 'app-common', 12 | 'basePath' => dirname(__DIR__), 13 | ] 14 | ); 15 | -------------------------------------------------------------------------------- /tests/codeception/config/config.php: -------------------------------------------------------------------------------- 1 | [ 7 | 'db' => [ 8 | 'dsn' => 'sqlite:' . __DIR__ .'/../../../sqlite-test.db', 9 | ], 10 | 'mailer' => [ 11 | 'useFileTransport' => true, 12 | ], 13 | 'urlManager' => [ 14 | 'showScriptName' => true, 15 | ], 16 | ], 17 | ]; 18 | -------------------------------------------------------------------------------- /tests/codeception/config/console/unit.php: -------------------------------------------------------------------------------- 1 | [ 7 | 8 | ], 9 | ]; -------------------------------------------------------------------------------- /tests/codeception/config/rest/functional.php: -------------------------------------------------------------------------------- 1 | wantTo('ensure that posts access only for auth users'); 7 | 8 | $I->sendGET('/v1/posts'); 9 | $I->seeResponseCodeIs(401); 10 | $I->seeResponseIsJson(); 11 | 12 | $I->wantTo('create post via API'); 13 | $I->haveHttpHeader('Content-Type', 'application/json'); 14 | $I->sendPOST( 15 | '/v1/posts' . $token, 16 | ['title' => 'My first post', 'content' => 'There are many words....', 'status' => 2] 17 | ); 18 | $I->seeResponseCodeIs(201); 19 | $I->seeResponseIsJson(); 20 | $I->seeResponseContainsJson(['title' => 'My first post']); 21 | 22 | $I->wantTo('get my post'); 23 | $I->sendGET('/v1/posts' . $token . '&title=My first post'); 24 | $I->seeResponseCodeIs(200); 25 | $I->seeResponseIsJson(); 26 | $I->seeResponseContainsJson(['title' => 'My first post', 'id' => 1, 'author' => ['username' => 'erau']]); 27 | 28 | $I->wantTo('update my post to draft'); 29 | $I->haveHttpHeader('Content-Type', 'application/json'); 30 | $I->sendPUT('/v1/posts/1' . $token, ['title' => 'My second post']); 31 | $I->seeResponseCodeIs(200); 32 | $I->seeResponseIsJson(); 33 | $I->seeResponseContainsJson(['title' => 'My second post']); -------------------------------------------------------------------------------- /tests/codeception/rest/functional/UserApiCept.php: -------------------------------------------------------------------------------- 1 | wantTo('test to obtain a token'); 6 | 7 | $I->sendPOST('/v1/user/login', ['username' => 'erau', 'password' => 'password_0']); 8 | $I->seeResponseCodeIs(200); 9 | $I->seeResponseIsJson(); 10 | $I->seeResponseContains('tUu1qHcde0diwUol3xeI-18MuHkkprQI'); 11 | 12 | $I->wantTo('test invalid query'); 13 | $I->sendPOST('/v1/user/login', ['username' => 'user', 'password' => 'password']); 14 | $I->seeResponseCodeIs(422); 15 | $I->seeResponseIsJson(); 16 | $I->seeResponseContainsJson(['message' => 'Incorrect username or password.']); -------------------------------------------------------------------------------- /tests/codeception/rest/functional/_bootstrap.php: -------------------------------------------------------------------------------- 1 | 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 | --------------------------------------------------------------------------------