diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b092468..9ee7add 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,7 +1,37 @@ +Contributing to yii2-app-practical-a +================================== +Looking to contribute something to yii2-app-practical-a? **Here's how you can help.** + +We really appreciate clear bug reports that _consistently_ show an issue +_within yii2-app-practical_. + +The ideal bug report follows these guidelines: + +1. **Use the [GitHub issue search][issue-search]** — Check if the issue + has already been reported. +2. **Check if the issue has been fixed** — Try to reproduce the problem + using the code in the `master` branch. + +Please try to be as detailed as possible in your bug report, especially if an +isolated test case cannot be made. Some useful questions to include the answer +to are: + +- What steps can be used to reproduce the issue? +- What is the bug and what is the expected outcome? +- What browser(s) and Operating System have you tested with? +- Does the bug happen consistently across all tested browsers? +- What version of jQuery are you using? And what version of yii2-app-practical-a? +- Are you using yii2-app-practical-a with other plugins? + +All of these questions will help others fix and identify any potential bugs. + Contributing to Yii2 ==================== -- [Report an issue](docs/internals/report-an-issue.md) -- [Translate documentation or messages](docs/internals/translation-workflow.md) +- [Report an issue](https://github.com/yiisoft/yii2/blob/master/docs/internals/report-an-issue.md) +- [Translate documentation or messages](https://github.com/yiisoft/yii2/blob/master/docs/internals/translation-workflow.md) - [Give us feedback or start a design discussion](http://www.yiiframework.com/forum/index.php/forum/42-general-discussions-for-yii-20/) -- [Contribute to the core code or fix bugs](docs/internals/git-workflow.md) +- [Contribute to the core code or fix bugs](https://github.com/yiisoft/yii2/blob/master/docs/internals/git-workflow.md) + +[issue-search]: https://github.com/kartik-v/yii2-app-practical-a/search?q=&type=Issues +[issue-tracker]: https://github.com/kartik-v/yii2-app-practical-a/issues \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index f37c867..52ec869 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,13 +1,14 @@ ### What steps will reproduce the problem? -### What is expected? +### What's expected? ### What do you get instead? + ### Additional info -| Question | Answer -| ---------------- | ---------------- -| Yii version | +| Q | A +| ---------------- | --- +| Yii vesion | | PHP version | | Operating system | diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index bdd0016..968a845 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,5 @@ -| Question | Answer -| ------------- | ------------- +| Q | A +| ------------- | --- | Is bugfix? | yes/no | New feature? | yes/no | Breaks BC? | yes/no diff --git a/.gitignore b/.gitignore index 346d3b2..9ed0894 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,12 @@ composer.phar phpunit.phar # local phpunit config /phpunit.xml + +# backend files +/backend/assets + +# frontend files +/assets +/index.php +/index-test.php +/robots.txt \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index abafb62..f762ebf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,29 +17,19 @@ cache: install: - travis_retry composer self-update && composer --version - - travis_retry composer global require "fxp/composer-asset-plugin:~1.1.0" - - export PATH="$HOME/.composer/vendor/bin:$PATH" - - travis_retry composer install --dev --prefer-dist --no-interaction -# codeception - - travis_retry composer global require "codeception/codeception=2.0.*" "codeception/specify=*" "codeception/verify=*" + - travis_retry composer global require "fxp/composer-asset-plugin:~1.3.1" + - travis_retry composer update --dev --prefer-dist --no-interaction # setup application: - | ./init --env=Development sed -i s/root/travis/ common/config/main-local.php sed -i "s/'cookieValidationKey' => ''/'cookieValidationKey' => 'testkey'/" frontend/config/main.php sed -i "s/'cookieValidationKey' => ''/'cookieValidationKey' => 'testkey'/" backend/config/main.php - cd tests/codeception/backend && codecept build - cd ../common && codecept build - cd ../console && codecept build - cd ../frontend && codecept build - cd ../../../ before_script: - - mysql -e 'CREATE DATABASE yii2_advanced_tests;'; - - cd tests/codeception/bin && php yii migrate --interactive=0 && cd ../../.. + - mysql -e 'CREATE DATABASE yii2practical_test;' + - php yii_test migrate --interactive=0 script: - - | - php -S localhost:8080 > /dev/null 2>&1 & - cd tests - codecept run + - composer validate --strict + - vendor/bin/codecept run diff --git a/CHANGE.md b/CHANGE.md index 232f671..a7e43a6 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -1,17 +1,23 @@ -Change Log: `yii2-app-practical` -================================ +Change Log: `yii2-app-practical-a` +================================== + +## Version 1.5.2 + +**Date:** 2017-06-06 + +- Based on latest yii2-advanced-app until 06-Jun-2017. ## Version 1.5.1 **Date:** 2016-04-08 -- (enh #12): Improve security for .htaccess. -- (bug #13): Set correct writable folders. -- (bug #15): Correct `backend\assets_b\AppAsset` typo. -- (bug #16): Fix `gii` config for backend prod. -- (bug #17): Correct composer.json source for `yii2-app-practical-a`. -- (enh #18): Include index files in `.gitignore`. - (enh #19): Upgrade migrations as per yii 2.0.6 Schema builder. +- (enh #18): Include index files in `.gitignore`. +- (bug #17): Correct composer.json source for `yii2-app-practical-a`. +- (bug #16): Fix `gii` config for backend prod. +- (bug #15): Correct `backend\assets_b\AppAsset` typo. +- (bug #13): Set correct writable folders. +- (enh #12): Improve security for .htaccess. - Update to use yii 2.0.6 archive. - Update sessions configuration for frontend and backend. - Include `urlManagerFE` component in backend config to enable access to frontend routes. @@ -27,38 +33,38 @@ Change Log: `yii2-app-practical` **Date:** 2014-10-25 -- Based on latest yii2-advanced-app until 25-Oct-2014. -- (enh # 9): Included identity cookie settings for backend. -- (enh # 10): Included CSRF token cookie setting for backend. - (enh # 11): Update codeception default settings for tests +- (enh # 10): Included CSRF token cookie setting for backend. +- (enh # 9): Included identity cookie settings for backend. +- Based on latest yii2-advanced-app until 25-Oct-2014. ## Version 1.3.0 **Date:** 2014-08-14 -- Based on latest yii2-advanced-app until 14-Oct-2014. - (enh # 6): Easier AppAsset baseUrl setting +- Based on latest yii2-advanced-app until 14-Oct-2014. ## Version 1.2.0 **Date:** 2014-08-09 -- Based on latest yii2-advanced-app until 09-Oct-2014. - (enh #4): User model findIdentity() does not take into account user status. +- Based on latest yii2-advanced-app until 09-Oct-2014. ## Version 1.1.0 **Date:** 2014-06-30 -- Based on latest yii2-advanced-app until 30-Jun-2014. - Included `.htaccess` for backend. +- Based on latest yii2-advanced-app until 30-Jun-2014. ## Version 1.0.0 **Date:** 2014-06-01 -- Initial release. - Based on latest yii2-advanced-app until 31-May-2014. +- Initial release. diff --git a/README.md b/README.md index 293ba2d..fbac2f6 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ http://domain/app and backend this way ``` -http://domain/backend +http://domain/app/backend ``` All other aspects of the app configuration remain the same as the **yii2-advanced** app. The `common`, and `console` @@ -67,18 +67,20 @@ SOME KEY ADDITIONS 3. The template has isolated cookie settings for backend and frontend so that you can seamlessly access frontend and backend from same client. The config files includes special `identity` and `csrf` cookie parameter settings for backend. Edit it according to your needs if necessary. -Detailed documentation on yii2-app-advanced concepts and usage can be referred at [docs/guide/README.md](docs/guide/README.md). +Detailed documentation can be referred at [docs/guide/README.md](docs/guide/README.md). DIRECTORY STRUCTURE ------------------- + ``` / / contains the frontend entry script, favicon, and robots.txt. - assets/ contains the frontend web runtime assets + assets/ contains frontend application runtime web assets such as JavaScript and CSS common config/ contains shared configurations mail/ contains view files for e-mails models/ contains model classes used in both backend and frontend + tests/ contains tests for common classes console config/ contains console configurations controllers/ contains console controllers (commands) @@ -87,109 +89,24 @@ console runtime/ contains files generated during runtime backend / contains the backend entry script, favicon, and robots.txt. - assets/ contains the backend web runtime assets - assets_b/ contains backend application assets such as JavaScript and CSS + assets/ contains the backend application runtime web assets such as JavaScript and CSS + assets_b/ contains web assets and scripts used by backend application config/ contains backend configurations controllers/ contains Web controller classes models/ contains backend-specific model classes runtime/ contains files generated during runtime + tests/ contains tests for backend application views/ contains view files for the Web application + web/ contains the entry script and Web resources frontend - assets/ contains frontend application assets such as JavaScript and CSS + assets/ contains web assets and scripts used by frontend application config/ contains frontend configurations controllers/ contains Web controller classes models/ contains frontend-specific model classes runtime/ contains files generated during runtime + tests/ contains tests for frontend application views/ contains view files for the Web application widgets/ contains frontend widgets vendor/ contains dependent 3rd-party packages environments/ contains environment-based overrides -tests contains various tests for the "practical" application - codeception/ contains tests developed with Codeception PHP Testing Framework -``` - -REQUIREMENTS ------------- - -The minimum requirement by this application template that your Web server supports PHP 5.4.0. - - -INSTALLATION ------------- - -You can choose to install the application using one of the following methods. - -### Install via Composer - -If you do not have [Composer](http://getcomposer.org/), you may install it by following the instructions -at [getcomposer.org](http://getcomposer.org/doc/00-intro.md#installation-nix). - -You can then install the application using the following command: - -~~~ -php composer.phar global require "fxp/composer-asset-plugin:~1.0.0" -php composer.phar create-project --prefer-dist --stability=dev kartik-v/yii2-app-practical-a practical-a -~~~ - -### Install from an Archive File - -Download the [archive file](https://github.com/kartik-v/yii2-app-practical-a/archive/master.zip) directly to a directory named `practical` that is directly under the Web root. - -> Note: When using a archive file method, the vendor folder is not automatically created. You must download the [latest yii2-advanced archive](https://github.com/yiisoft/yii2/releases/download/2.0.6/yii-advanced-app-2.0.6.tgz) and then extract the vendor folder from here. Then you must copy this folder directly under the app root (i.e. `practical` directory). - -After this is complete, follow the instructions given in "GETTING STARTED". - -GETTING STARTED ---------------- - -After you install the application, you have to conduct the following steps to initialize -the installed application. You only need to do these once for all. - -1. Run command `init` to initialize the application with a specific environment. -2. Create a new database and adjust the `components['db']` configuration in `common/config/main-local.php` accordingly. -3. Apply migrations with console command `yii migrate`. This will create tables needed for the application to work. -4. Set document roots of your Web server: - -- for frontend `/path/to/yii-application/` and using the URL `http://frontend/` -- for backend `/path/to/yii-application/backend/web/` and using the URL `http://backend/` - -To login into the application, you need to first sign up, with any of your email address, username and password. -Then, you can login into the application with same email address and password at any time. - -5. Edit the config files as needed. Especially set the correct paths for the user identity cookie in `backend/config/main-local.php`. - -MORE DOCUMENTATION ------------------- - -You can read the [yii2-advanced application guide](https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md) to understand details on working with the advanced application. - -TESTING -------- - -Follow the [`tests` section README](https://github.com/kartik-v/yii2-app-practical-a/tree/master/tests/README.md) for setting up the tests. For details of testing in Yii 2.0, read the [testing overview and setup](http://www.yiiframework.com/doc-2.0/guide-test-overview.html) within the Yii 2.0 Guide. Setting up the testing environment broadly involves the following steps. - -Install additional composer packages: -* `php composer.phar require --dev "codeception/codeception: 2.0" "codeception/specify: *" "codeception/verify: *"` - -This application boilerplate uses database in testing, so you should create three databases that are used in tests: -* `yii2_practical_unit` - database for unit tests; -* `yii2_practical_functional` - database for functional tests; -* `yii2_practical_acceptance` - database for acceptance tests. - -To make your database up to date, you can run in needed test folder `yii migrate`, for example -if you are starting from `frontend` tests then you should run `yii migrate` in each suite folder `acceptance`, `functional`, `unit` -it will upgrade your database to the last state according migrations. - -To be able to run acceptance tests you need a running webserver. For this you can use the php builtin server and run it in the directory where your main project folder is located. For example if your application is located in `/www/practical` all you need to is: -`cd /www` and then `php -S 127.0.0.1:8080` because the default configuration of acceptance tests expects the url of the application to be `/practical/`. -If you already have a server configured or your application is not located in a folder called `practical`, you may need to adjust the `TEST_ENTRY_URL` in `frontend/tests/_bootstrap.php` and `backend/tests/_bootstrap.php`. - -After that is done you should be able to run your tests, for example to run `frontend` tests do: - -* `cd frontend` -* `../vendor/bin/codecept build` -* `../vendor/bin/codecept run` - -In similar way you can run tests for other application tiers - `backend`, `console`, `common`. - -You can also adjust you application suite configs and `_bootstrap.php` settings to use other urls and files, as it is done in `yii2-basic`. \ No newline at end of file +``` \ No newline at end of file diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000..1ff1b1e --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,72 @@ +require 'yaml' +require 'fileutils' + +domains = { + frontend: 'y2aa-frontend.dev', + backend: 'y2aa-backend.dev' +} + +config = { + local: './vagrant/config/vagrant-local.yml', + example: './vagrant/config/vagrant-local.example.yml' +} + +# copy config from example if local config not exists +FileUtils.cp config[:example], config[:local] unless File.exist?(config[:local]) +# read config +options = YAML.load_file config[:local] + +# check github token +if options['github_token'].nil? || options['github_token'].to_s.length != 40 + puts "You must place REAL GitHub token into configuration:\n/yii2-app-practical/vagrant/config/vagrant-local.yml" + exit +end + +# vagrant configurate +Vagrant.configure(2) do |config| + # select the box + config.vm.box = 'bento/ubuntu-16.04' + + # should we ask about box updates? + config.vm.box_check_update = options['box_check_update'] + + config.vm.provider 'virtualbox' do |vb| + # machine cpus count + vb.cpus = options['cpus'] + # machine memory size + vb.memory = options['memory'] + # machine name (for VirtualBox UI) + vb.name = options['machine_name'] + end + + # machine name (for vagrant console) + config.vm.define options['machine_name'] + + # machine name (for guest machine console) + config.vm.hostname = options['machine_name'] + + # network settings + config.vm.network 'private_network', ip: options['ip'] + + # sync: folder 'yii2-app-practical' (host machine) -> folder '/app' (guest machine) + config.vm.synced_folder './', '/app', owner: 'vagrant', group: 'vagrant' + + # disable folder '/vagrant' (guest machine) + config.vm.synced_folder '.', '/vagrant', disabled: true + + # hosts settings (host machine) + config.vm.provision :hostmanager + config.hostmanager.enabled = true + config.hostmanager.manage_host = true + config.hostmanager.ignore_private_ip = false + config.hostmanager.include_offline = true + config.hostmanager.aliases = domains.values + + # provisioners + config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone']] + config.vm.provision 'shell', path: './vagrant/provision/once-as-vagrant.sh', args: [options['github_token']], privileged: false + config.vm.provision 'shell', path: './vagrant/provision/always-as-root.sh', run: 'always' + + # post-install message (vagrant console) + config.vm.post_up_message = "Frontend URL: http://#{domains[:frontend]}\nBackend URL: http://#{domains[:backend]}" +end diff --git a/backend/.gitignore b/backend/.gitignore index 25c74e6..d94a089 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1,2 +1,3 @@ /index.php /index-test.php +/robots.txt diff --git a/backend/assets_b/css/site.css b/backend/assets_b/css/site.css index 49ee8fb..2f085b3 100644 --- a/backend/assets_b/css/site.css +++ b/backend/assets_b/css/site.css @@ -96,16 +96,25 @@ a.desc:after { } /* align the logout "link" (button in form) of the navbar */ -.nav > li > form { - padding: 8px; +.nav li > form > button.logout { + padding: 15px; + border: none; } -@media(max-width:768px) { - .nav li > form { - padding: 3px; - } +@media(max-width:767px) { + .nav li > form > button.logout { + display:block; + text-align: left; + width: 100%; + padding: 10px 15px; + } } -.nav > li > form > button:hover { +.nav > li > form > button.logout:focus, +.nav > li > form > button.logout:hover { text-decoration: none; } + +.nav > li > form > button.logout:focus { + outline: none; +} diff --git a/backend/codeception.yml b/backend/codeception.yml new file mode 100644 index 0000000..703b518 --- /dev/null +++ b/backend/codeception.yml @@ -0,0 +1,15 @@ +namespace: backend\tests +actor: Tester +paths: + tests: tests + log: tests/_output + data: tests/_data + helpers: tests/_support +settings: + bootstrap: _bootstrap.php + colors: true + memory_limit: 1024M +modules: + config: + Yii2: + configFile: 'config/test-local.php' diff --git a/backend/config/.gitignore b/backend/config/.gitignore index 20da318..42799dd 100644 --- a/backend/config/.gitignore +++ b/backend/config/.gitignore @@ -1,2 +1,3 @@ main-local.php -params-local.php \ No newline at end of file +params-local.php +test-local.php diff --git a/backend/config/main.php b/backend/config/main.php index ea9d342..c804f21 100644 --- a/backend/config/main.php +++ b/backend/config/main.php @@ -7,15 +7,23 @@ ); return [ - 'id' => 'app-practical-a-backend', + 'id' => 'app-backend', 'basePath' => dirname(__DIR__), 'controllerNamespace' => 'backend\controllers', 'bootstrap' => ['log'], 'modules' => [], 'components' => [ + 'request' => [ + 'csrfParam' => '_csrf-backend', + ], 'user' => [ 'identityClass' => 'common\models\User', 'enableAutoLogin' => true, + 'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true], + ], + 'session' => [ + // this is the name of the session cookie used for login on the backend + 'name' => 'practical-a-backend', ], 'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, @@ -29,14 +37,12 @@ 'errorHandler' => [ 'errorAction' => 'site/error', ], - /* 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ ], ], - */ ], 'params' => $params, ]; diff --git a/backend/config/test.php b/backend/config/test.php new file mode 100644 index 0000000..ec2e9a1 --- /dev/null +++ b/backend/config/test.php @@ -0,0 +1,12 @@ + 'app-backend-tests', + 'components' => [ + 'assetManager' => [ + 'basePath' => __DIR__ . '/../web/assets', + ], + 'urlManager' => [ + 'showScriptName' => true, + ], + ], +]; diff --git a/backend/controllers/SiteController.php b/backend/controllers/SiteController.php index 01d9ad8..9624dcc 100644 --- a/backend/controllers/SiteController.php +++ b/backend/controllers/SiteController.php @@ -53,11 +53,21 @@ public function actions() ]; } + /** + * Displays homepage. + * + * @return string + */ public function actionIndex() { return $this->render('index'); } + /** + * Login action. + * + * @return string + */ public function actionLogin() { if (!Yii::$app->user->isGuest) { @@ -74,6 +84,11 @@ public function actionLogin() } } + /** + * Logout action. + * + * @return string + */ public function actionLogout() { Yii::$app->user->logout(); diff --git a/backend/runtime/.gitignore b/backend/runtime/.gitignore index 5d81bf7..ff62a3f 100644 --- a/backend/runtime/.gitignore +++ b/backend/runtime/.gitignore @@ -1,3 +1,4 @@ -* -!.gitignore -!*/ \ No newline at end of file +/* +!/sessions +!/sessions/* +!/.gitignore diff --git a/tests/codeception/common/_bootstrap.php b/backend/tests/_bootstrap.php similarity index 54% rename from tests/codeception/common/_bootstrap.php rename to backend/tests/_bootstrap.php index cea3ee5..83a1f26 100644 --- a/tests/codeception/common/_bootstrap.php +++ b/backend/tests/_bootstrap.php @@ -1,15 +1,9 @@ 'erau', diff --git a/tests/codeception/_output/.gitignore b/backend/tests/_output/.gitignore similarity index 100% rename from tests/codeception/_output/.gitignore rename to backend/tests/_output/.gitignore diff --git a/backend/tests/_support/.gitignore b/backend/tests/_support/.gitignore new file mode 100644 index 0000000..36e264c --- /dev/null +++ b/backend/tests/_support/.gitignore @@ -0,0 +1 @@ +_generated diff --git a/backend/tests/_support/FunctionalTester.php b/backend/tests/_support/FunctionalTester.php new file mode 100644 index 0000000..80a79ed --- /dev/null +++ b/backend/tests/_support/FunctionalTester.php @@ -0,0 +1,25 @@ +haveFixtures([ + 'user' => [ + 'class' => UserFixture::className(), + 'dataFile' => codecept_data_dir() . 'login_data.php' + ] + ]); + } + /** + * @param FunctionalTester $I + */ + public function loginUser(FunctionalTester $I) + { + $I->amOnPage('/site/login'); + $I->fillField('Username', 'erau'); + $I->fillField('Password', 'password_0'); + $I->click('login-button'); + + $I->see('Logout (erau)', 'form button[type=submit]'); + $I->dontSeeLink('Login'); + $I->dontSeeLink('Signup'); + } +} diff --git a/backend/tests/functional/_bootstrap.php b/backend/tests/functional/_bootstrap.php new file mode 100644 index 0000000..30ed54b --- /dev/null +++ b/backend/tests/functional/_bootstrap.php @@ -0,0 +1,16 @@ + 'davert']); + * ``` + * + * In Cests + * + * ```php + * \Codeception\Util\Fixtures::get('user1'); + * ``` + */ \ No newline at end of file diff --git a/backend/tests/unit.suite.yml b/backend/tests/unit.suite.yml new file mode 100644 index 0000000..1ba1eb4 --- /dev/null +++ b/backend/tests/unit.suite.yml @@ -0,0 +1 @@ +class_name: UnitTester diff --git a/backend/tests/unit/_bootstrap.php b/backend/tests/unit/_bootstrap.php new file mode 100644 index 0000000..e432ce5 --- /dev/null +++ b/backend/tests/unit/_bootstrap.php @@ -0,0 +1,16 @@ + 'davert']); + * ``` + * + * In Tests + * + * ```php + * \Codeception\Util\Fixtures::get('user1'); + * ``` + */ diff --git a/backend/views/layouts/main.php b/backend/views/layouts/main.php index 820eb01..96e6e0b 100644 --- a/backend/views/layouts/main.php +++ b/backend/views/layouts/main.php @@ -17,6 +17,7 @@ + <?= Html::encode($this->title) ?> @@ -44,7 +45,7 @@ . Html::beginForm(['/site/logout'], 'post') . Html::submitButton( 'Logout (' . Yii::$app->user->identity->username . ')', - ['class' => 'btn btn-link'] + ['class' => 'btn btn-link logout'] ) . Html::endForm() . ''; diff --git a/codeception.yml b/codeception.yml new file mode 100644 index 0000000..af20104 --- /dev/null +++ b/codeception.yml @@ -0,0 +1,9 @@ +# global codeception file to run tests from all apps +include: + - common + - frontend + - backend +paths: + log: console/runtime/logs +settings: + colors: true \ No newline at end of file diff --git a/common/codeception.yml b/common/codeception.yml new file mode 100644 index 0000000..de5d76a --- /dev/null +++ b/common/codeception.yml @@ -0,0 +1,15 @@ +namespace: common\tests +actor: Tester +paths: + tests: tests + log: tests/_output + data: tests/_data + helpers: tests/_support +settings: + bootstrap: _bootstrap.php + colors: true + memory_limit: 1024M +modules: + config: + Yii2: + configFile: 'config/test-local.php' diff --git a/common/config/.gitignore b/common/config/.gitignore index 97c0f01..42799dd 100644 --- a/common/config/.gitignore +++ b/common/config/.gitignore @@ -1,2 +1,3 @@ main-local.php params-local.php +test-local.php diff --git a/common/config/main.php b/common/config/main.php index 59c65c3..c9071d1 100644 --- a/common/config/main.php +++ b/common/config/main.php @@ -5,9 +5,5 @@ 'cache' => [ 'class' => 'yii\caching\FileCache', ], - 'urlManager' => [ - 'enablePrettyUrl' => true, - 'showScriptName' => false, - ] ], ]; diff --git a/common/config/test.php b/common/config/test.php new file mode 100644 index 0000000..c952c41 --- /dev/null +++ b/common/config/test.php @@ -0,0 +1,11 @@ + 'app-common-tests', + 'basePath' => dirname(__DIR__), + 'components' => [ + 'user' => [ + 'class' => 'yii\web\User', + 'identityClass' => 'common\models\User', + ], + ], +]; diff --git a/tests/codeception/common/fixtures/UserFixture.php b/common/fixtures/UserFixture.php similarity index 63% rename from tests/codeception/common/fixtures/UserFixture.php rename to common/fixtures/UserFixture.php index 7153c8c..034d975 100644 --- a/tests/codeception/common/fixtures/UserFixture.php +++ b/common/fixtures/UserFixture.php @@ -1,13 +1,9 @@ + beginPage() ?> beginBody() ?> diff --git a/common/models/LoginForm.php b/common/models/LoginForm.php index afc1c23..c4869d4 100644 --- a/common/models/LoginForm.php +++ b/common/models/LoginForm.php @@ -51,7 +51,7 @@ public function validatePassword($attribute, $params) /** * Logs in a user using the provided username and password. * - * @return boolean whether the user is logged in successfully + * @return bool whether the user is logged in successfully */ public function login() { diff --git a/common/models/User.php b/common/models/User.php index ce78fcd..2f4508f 100644 --- a/common/models/User.php +++ b/common/models/User.php @@ -26,6 +26,7 @@ class User extends ActiveRecord implements IdentityInterface const STATUS_DELETED = 0; const STATUS_ACTIVE = 10; + /** * @inheritdoc */ @@ -104,7 +105,7 @@ public static function findByPasswordResetToken($token) * Finds out if password reset token is valid * * @param string $token password reset token - * @return boolean + * @return bool */ public static function isPasswordResetTokenValid($token) { @@ -145,7 +146,7 @@ public function validateAuthKey($authKey) * Validates password * * @param string $password password to validate - * @return boolean if password provided is valid for current user + * @return bool if password provided is valid for current user */ public function validatePassword($password) { diff --git a/common/tests/_bootstrap.php b/common/tests/_bootstrap.php new file mode 100644 index 0000000..d5a93de --- /dev/null +++ b/common/tests/_bootstrap.php @@ -0,0 +1,9 @@ +tester->haveFixtures([ + 'user' => [ + 'class' => UserFixture::className(), + 'dataFile' => codecept_data_dir() . 'user.php' + ] + ]); + } + + public function testLoginNoUser() + { + $model = new LoginForm([ + 'username' => 'not_existing_username', + 'password' => 'not_existing_password', + ]); + + expect('model should not login user', $model->login())->false(); + expect('user should not be logged in', Yii::$app->user->isGuest)->true(); + } + + public function testLoginWrongPassword() + { + $model = new LoginForm([ + 'username' => 'bayer.hudson', + 'password' => 'wrong_password', + ]); + + expect('model should not login user', $model->login())->false(); + expect('error message should be set', $model->errors)->hasKey('password'); + expect('user should not be logged in', Yii::$app->user->isGuest)->true(); + } + + public function testLoginCorrect() + { + $model = new LoginForm([ + 'username' => 'bayer.hudson', + 'password' => 'password_0', + ]); + + expect('model should login user', $model->login())->true(); + expect('error message should not be set', $model->errors)->hasntKey('password'); + expect('user should be logged in', Yii::$app->user->isGuest)->false(); + } +} diff --git a/common/widgets/Alert.php b/common/widgets/Alert.php index 8f1e590..69f1c40 100644 --- a/common/widgets/Alert.php +++ b/common/widgets/Alert.php @@ -1,26 +1,22 @@ session->setFlash('error', 'This is the message'); - * \Yii::$app->session->setFlash('success', 'This is the message'); - * \Yii::$app->session->setFlash('info', 'This is the message'); + * Yii::$app->session->setFlash('error', 'This is the message'); + * Yii::$app->session->setFlash('success', 'This is the message'); + * Yii::$app->session->setFlash('info', 'This is the message'); * ``` * * Multiple messages could be set as follows: * * ```php - * \Yii::$app->session->setFlash('error', ['Error 1', 'Error 2']); + * Yii::$app->session->setFlash('error', ['Error 1', 'Error 2']); * ``` * * @author Kartik Visweswaran @@ -41,17 +37,17 @@ class Alert extends \yii\bootstrap\Widget 'info' => 'alert-info', 'warning' => 'alert-warning' ]; - /** * @var array the options for rendering the close button tag. */ public $closeButton = []; + public function init() { parent::init(); - $session = \Yii::$app->session; + $session = Yii::$app->session; $flashes = $session->getAllFlashes(); $appendCss = isset($this->options['class']) ? ' ' . $this->options['class'] : ''; diff --git a/composer.json b/composer.json index 2995f95..c9e6593 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,17 @@ { - "name": "yiisoft/yii2-app-advanced", - "description": "Yii 2 Advanced Project Template", - "keywords": ["yii2", "framework", "advanced", "project template"], - "homepage": "http://www.yiiframework.com/", + "name": "kartik-v/yii2-app-practical", + "description": "Yii 2 Practical Application Template", + "keywords": ["yii2", "framework", "practical", "advanced", "application template"], + "homepage": "http://demos.krajee.com/app-practical", "type": "project", "license": "BSD-3-Clause", + "authors": [ + { + "name": "Kartik Visweswaran", + "email": "kartikv2@gmail.com", + "homepage": "http://www.krajee.com/" + } + ], "support": { "issues": "https://github.com/yiisoft/yii2/issues?state=open", "forum": "http://www.yiiframework.com/forum/", @@ -15,23 +22,25 @@ "minimum-stability": "dev", "require": { "php": ">=5.4.0", - "yiisoft/yii2": ">=2.0.6", - "yiisoft/yii2-bootstrap": "*", - "yiisoft/yii2-swiftmailer": "*" + "yiisoft/yii2": "~2.0.6", + "yiisoft/yii2-bootstrap": "~2.0.0", + "yiisoft/yii2-swiftmailer": "~2.0.0" }, "require-dev": { - "yiisoft/yii2-codeception": "*", - "yiisoft/yii2-debug": "*", - "yiisoft/yii2-gii": "*", - "yiisoft/yii2-faker": "*" + "yiisoft/yii2-debug": "~2.0.0", + "yiisoft/yii2-gii": "~2.0.0", + "yiisoft/yii2-faker": "~2.0.0", + + "codeception/base": "^2.2.3", + "codeception/verify": "~0.3.1" }, "config": { - "process-timeout": 1800 - }, - "extra": { - "asset-installer-paths": { - "npm-asset-library": "vendor/npm", - "bower-asset-library": "vendor/bower" + "process-timeout": 1800, + "fxp-asset":{ + "installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } } } } diff --git a/console/config/main.php b/console/config/main.php index 2c7d7d4..8aaeeff 100644 --- a/console/config/main.php +++ b/console/config/main.php @@ -11,6 +11,12 @@ 'basePath' => dirname(__DIR__), 'bootstrap' => ['log'], 'controllerNamespace' => 'console\controllers', + 'controllerMap' => [ + 'fixture' => [ + 'class' => 'yii\console\controllers\FixtureController', + 'namespace' => 'common\fixtures', + ], + ], 'components' => [ 'log' => [ 'targets' => [ diff --git a/docs/guide-es/start-composer.md b/docs/guide-es/start-composer.md index 48b1bee..4c508ba 100644 --- a/docs/guide-es/start-composer.md +++ b/docs/guide-es/start-composer.md @@ -5,9 +5,9 @@ Después de instalar el proyecto plantilla es una buena idea ajustar el archivo ```json { - "name": "yiisoft/yii2-app-advanced", - "description": "Yii 2 Advanced Project Template", - "keywords": ["yii2", "framework", "advanced", "project template"], + "name": "kartik-v/yii2-app-practical-a", + "description": "Yii 2 Practical-A Project Template", + "keywords": ["yii2", "framework", "practical", "project template"], "homepage": "http://www.yiiframework.com/", "type": "project", "license": "BSD-3-Clause", @@ -21,15 +21,17 @@ Después de instalar el proyecto plantilla es una buena idea ajustar el archivo "minimum-stability": "dev", "require": { "php": ">=5.4.0", - "yiisoft/yii2": "*", - "yiisoft/yii2-bootstrap": "*", - "yiisoft/yii2-swiftmailer": "*" + "yiisoft/yii2": "~2.0.6", + "yiisoft/yii2-bootstrap": "~2.0.0", + "yiisoft/yii2-swiftmailer": "~2.0.0" }, "require-dev": { - "yiisoft/yii2-codeception": "*", - "yiisoft/yii2-debug": "*", - "yiisoft/yii2-gii": "*", - "yiisoft/yii2-faker": "*" + "yiisoft/yii2-debug": "~2.0.0", + "yiisoft/yii2-gii": "~2.0.0", + "yiisoft/yii2-faker": "~2.0.0", + + "codeception/base": "^2.2.3", + "codeception/verify": "~0.3.1" }, "config": { "process-timeout": 1800 diff --git a/docs/guide-es/start-installation.md b/docs/guide-es/start-installation.md index 898f69b..fe85d34 100644 --- a/docs/guide-es/start-installation.md +++ b/docs/guide-es/start-installation.md @@ -11,15 +11,15 @@ Si no tienes [Composer](http://getcomposer.org/), sigue las instrucciones en la Con Composer instalado, puedes entonces instalar la aplicación usando los siguientes comandos: - composer global require "fxp/composer-asset-plugin:~1.1.1" - composer create-project --prefer-dist yiisoft/yii2-app-advanced yii-application + composer global require "fxp/composer-asset-plugin:^1.3.1" + composer create-project --prefer-dist kartik-v/yii2-app-practical-a practical-a -El primer comando instala el [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) el cual permite el manejo de los paquetes de dependencias bower y npm a través de Composer. Sólo necesitas ejecutar este comando la primera vez. El segundo comando instala la aplicación avanzada en un directorio nombrado `yii-application`. +El primer comando instala el [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) el cual permite el manejo de los paquetes de dependencias bower y npm a través de Composer. Sólo necesitas ejecutar este comando la primera vez. El segundo comando instala la aplicación avanzada en un directorio nombrado `practical-a`. Puedes elegir un nombre de directorio diferente si tu quieres. ## Instalación desde un Archivo -Extrae el archivo descargado desde [yiiframework.com](http://www.yiiframework.com/download/) a directorio nombrado `advanced` que está directamente bajo el Web root. +Extrae el archivo descargado desde [yiiframework.com](http://www.yiiframework.com/download/) a directorio nombrado `practical` que está directamente bajo el Web root. A continuación sigue las siguientes instrucciones dadas en la siguiente sub-sección. @@ -31,13 +31,13 @@ Después de instalar la aplicación, tienes que realizar los siguientes pasos pa 1. Ejecuta el comando `init` y selecciona `dev` como entorno. ``` - php /path/to/yii-application/init + php /path/to/practical-a/init ``` Por otra parte, en producción ejecuta `init` con el modo no interactivo. ``` - php /path/to/yii-application/init --env=Production --overwrite=All + php /path/to/practical-a/init --env=Production --overwrite=All ``` 2. Crea una nueva base de datos y ajusta la configuración de `components['db']` en `common/config/main-local.php` como corresponde. @@ -46,17 +46,17 @@ Después de instalar la aplicación, tienes que realizar los siguientes pasos pa 4. Establece los documentos raíces(document-root) de tu servidor web: - - para frontend `/path/to/yii-application/frontend/web/` y usando la URL `http://frontend.dev/` - - para backend `/path/to/yii-application/backend/web/` y usando la URL `http://backend.dev/` + - para frontend `/path/to/practical-a/` y usando la URL `http://frontend.dev/` + - para backend `/path/to/practical-a/backend/web/` y usando la URL `http://backend.dev/` Para Apache podría ser lo siguiente: ```apache ServerName frontend.dev - DocumentRoot "/path/to/yii-application/frontend/web/" + DocumentRoot "/path/to/practical-a/frontend/" - + # use mod_rewrite for pretty URL support RewriteEngine on # If a directory or a file exists, use the request directly @@ -74,9 +74,9 @@ Después de instalar la aplicación, tienes que realizar los siguientes pasos pa ServerName backend.dev - DocumentRoot "/path/to/yii-application/backend/web/" + DocumentRoot "/path/to/practical-a/backend/web/" - + # use mod_rewrite for pretty URL support RewriteEngine on # If a directory or a file exists, use the request directly @@ -104,15 +104,15 @@ Después de instalar la aplicación, tienes que realizar los siguientes pasos pa #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 server_name frontend.dev; - root /path/to/yii-application/frontend/web/; + root /path/to/practical-a/frontend/; index index.php; - access_log /path/to/yii-application/log/frontend-access.log; - error_log /path/to/yii-application/log/frontend-error.log; + access_log /path/to/practical-a/log/frontend-access.log; + error_log /path/to/practical-a/log/frontend-error.log; location / { # Redirect everything that isn't a real file to index.php - try_files $uri $uri/ /index.php?$args; + try_files $uri $uri/ /index.php$is_args$args; } # uncomment to avoid processing of calls to non-existing static files by Yii @@ -123,7 +123,7 @@ Después de instalar la aplicación, tienes que realizar los siguientes pasos pa location ~ \.php$ { include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/php5-fpm.sock; try_files $uri =404; @@ -142,15 +142,15 @@ Después de instalar la aplicación, tienes que realizar los siguientes pasos pa #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 server_name backend.dev; - root /path/to/yii-application/backend/web/; + root /path/to/practical-a/backend/web/; index index.php; - access_log /path/to/yii-application/log/backend-access.log; - error_log /path/to/yii-application/log/backend-error.log; + access_log /path/to/practical-a/log/backend-access.log; + error_log /path/to/practical-a/log/backend-error.log; location / { # Redirect everything that isn't a real file to index.php - try_files $uri $uri/ /index.php?$args; + try_files $uri $uri/ /index.php$is_args$args; } # uncomment to avoid processing of calls to non-existing static files by Yii @@ -161,7 +161,7 @@ Después de instalar la aplicación, tienes que realizar los siguientes pasos pa location ~ \.php$ { include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/php5-fpm.sock; try_files $uri =404; diff --git a/docs/guide-fr/README.md b/docs/guide-fr/README.md new file mode 100644 index 0000000..4f8b47f --- /dev/null +++ b/docs/guide-fr/README.md @@ -0,0 +1,34 @@ +Yii 2 Modèle de projet avancé +=============================== + +Le modèle de projet avancé de Yii 2 est le squelette d'application [Yii 2](http://www.yiiframework.com/) le plus adapté au développement d'applications Web impliquant de multiples parties. + +Ce modèle inclut trois parties : l'interface utilisateur (frontend), l'interface d'administration (backend) et la console, qui constituent chacune une application Yii séparée. + +Ce modèle est conçu pour être utilisé dans un environnement d'équipe de développement. Il prend en charge le déploiement de l'application dans des environnements différents. + +Il va aussi un peu plus loin en ce qui concerne les fonctionnalités et fournit les éléments essentiels que sont la base de données, l'enregistrement et la récupération du mot de passe directement après l'installation initiale. + + +Premiers pas +--------------- + +* [Installation](start-installation.md) +* [Les différences avec le modèle de projet basic](start-comparison.md) +* [Configuration de Composer](start-composer.md) +* [Exécution des Tests](start-testing.md) + +Structure +--------- + +* [Dossiers](structure-directories.md) +* [Alias de chemin prédéfinis](structure-path-aliases.md) +* [Applications](structure-applications.md) +* [Configuration et environnements](structure-environments.md) + +Sujets complémentaires +---------------------- + +* [Création de liens de l'interface d'administration vers l'interface utilisateur](topic-link-backend-frontend.md) +* [Ajout d'applications supplémentaires](topic-adding-more-apps.md) +* [Utiliser le modèle de projet avancé sur un hébergement partagé](topic-shared-hosting.md) diff --git a/docs/guide-fr/images/advanced-app-configs.graphml b/docs/guide-fr/images/advanced-app-configs.graphml new file mode 100644 index 0000000..05a053e --- /dev/null +++ b/docs/guide-fr/images/advanced-app-configs.graphml @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + console + + + + + + + + + + Folder 4 + + + + + + + + + + + + + + + + + + + + backend + + + + + + + + + + Folder 3 + + + + + + + + + + + + + + + + + index + + + + + + + + + + + + + + + + + + + + frontend + + + + + + + + + + Folder 1 + + + + + + + + + + + + + + + + params + + + + + + + + + + + + + + + + + params-local + + + + + + + + + + + + + + + + + main + + + + + + + + + + + + + + + + + main-local + + + + + + + + + + + + + + + + + + + aliases + + + + + + + + + + + + + + + + + + + + common + + + + + + + + + + Folder 2 + + + + + + + + + + + + + + + + params-local + + + + + + + + + + + + + + + + + main-local + + + + + + + + + + + + + + + + + params + + + + + + + + + + + + + + + + + main + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guide-fr/images/advanced-app-configs.png b/docs/guide-fr/images/advanced-app-configs.png new file mode 100644 index 0000000..daa9a6f Binary files /dev/null and b/docs/guide-fr/images/advanced-app-configs.png differ diff --git a/docs/guide-fr/images/tests.png b/docs/guide-fr/images/tests.png new file mode 100644 index 0000000..a537336 Binary files /dev/null and b/docs/guide-fr/images/tests.png differ diff --git a/docs/guide-fr/start-comparison.md b/docs/guide-fr/start-comparison.md new file mode 100644 index 0000000..b0c1767 --- /dev/null +++ b/docs/guide-fr/start-comparison.md @@ -0,0 +1,20 @@ +Comparaison +=========== + +La table ci-dessous présente les différences entre le modèle de projet avancé et le modèle de projet *basic* : + + +| Fonctionnalité | *Basic* | *Advanced* | +|---|:---:|:---:| +| Structure du projet | ✓ | ✓ | +| Contrôleur *site* | ✓ | ✓ | +| Connexion/déconnexion du l'utilisateur | ✓ | ✓ | +| Formulaires | ✓ | ✓ | +| Connexion à la base de données | ✓ | ✓ | +| Commandes en console | ✓ | ✓ | +| Paquets de ressources | ✓ | ✓ | +| Tests Codeception | ✓ | ✓ | +| Twitter Bootstrap | ✓ | ✓ | +| Applications *frontend*/*backend* | | ✓ | +| Modèle utilisateur prêt à l'emploi | | ✓ | +| Enregistrement de l'utilisateur et récupération du mot de passe | | ✓ | diff --git a/docs/guide-fr/start-composer.md b/docs/guide-fr/start-composer.md new file mode 100644 index 0000000..2ead0b4 --- /dev/null +++ b/docs/guide-fr/start-composer.md @@ -0,0 +1,53 @@ +Configuration de Composer +======================== + +Après avoir installé le modèle de projet, il est conseillé d'ajuster le contenu de `composer.json` qui se trouve dans le dossier racine : + +```json +{ + "name": "kartik-v/yii2-app-practical-a", + "description": "Yii 2 Practical-A Project Template", + "keywords": ["yii2", "framework", "practical", "project template"], + "homepage": "http://www.yiiframework.com/", + "type": "project", + "license": "BSD-3-Clause", + "support": { + "issues": "https://github.com/yiisoft/yii2/issues?state=open", + "forum": "http://www.yiiframework.com/forum/", + "wiki": "http://www.yiiframework.com/wiki/", + "irc": "irc://irc.freenode.net/yii", + "source": "https://github.com/yiisoft/yii2" + }, + "minimum-stability": "dev", + "require": { + "php": ">=5.4.0", + "yiisoft/yii2": "~2.0.6", + "yiisoft/yii2-bootstrap": "~2.0.0", + "yiisoft/yii2-swiftmailer": "~2.0.0" + }, + "require-dev": { + "yiisoft/yii2-debug": "~2.0.0", + "yiisoft/yii2-gii": "~2.0.0", + "yiisoft/yii2-faker": "~2.0.0", + + "codeception/base": "^2.2.3", + "codeception/verify": "~0.3.1" + }, + "config": { + "process-timeout": 1800 + }, + "extra": { + "asset-installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } + } +} +``` + +Commencez par mettre les informations de base à jour. Modifiez `name`, `description`, `keywords`, `homepage` et `support` pour qu'ils correspondent à votre projet. + +Maintenant, vient la partie intéressante. Vous pouvez ajouter des paquets nécessaires à votre application dans la section `require`. +Tous ces paquets proviennent de [packagist.org](https://packagist.org/), c'est pourquoi vous ne devez pas hésiter à parcourir le site Web pour trouver du code utile. + +Après avoir modifié votre fichier `composer.json`, vous pouvez exécuter `composer update --prefer-dist`, et attendre tout simplement le téléchargement et l'installation des paquets pour les utiliser. L'auto-chargement des classes est pris en charge automatiquement. diff --git a/docs/guide-fr/start-installation.md b/docs/guide-fr/start-installation.md new file mode 100644 index 0000000..ef7c9d0 --- /dev/null +++ b/docs/guide-fr/start-installation.md @@ -0,0 +1,288 @@ +Installation +============ + +## Exigences + +L'exigence minimum de ce modèle de projet est que votre serveur Web prenne en charge PHP 5.4.0. + +## Installation via Composer + +Si vous n'avez pas [Composer](http://getcomposer.org/), suivez les instructions de la section +[Installation de Yii](https://github.com/yiisoft/yii2/blob/master/docs/guide/start-installation.md#installing-via-composer) du guide complet de Yii pour l'installer. + +Une fois composer installé, vous pouvez l'utiliser pour installer l'application en utilisant les commandes suivantes : + + composer global require "fxp/composer-asset-plugin:^1.3.1" + composer create-project --prefer-dist kartik-v/yii2-app-practical-a practical-a + +La première commande installe le [greffon composer asset](https://github.com/francoispluchino/composer-asset-plugin/) +qui permet de gérer les dépendances de paquets bower et npm via Composer. Vous n'avez besoin d'exécuter cette commande qu'une fois pour toute. La deuxième commande installe l'application avancée dans un dossier nommé `practical-a`. Vous avez le droit de choisir un autre nom de dossier si vous le désirez. + +## Installation à partir d'un fichier archive + +Extrayez l'archive que vous avez téléchargée depuis [yiiframework.com](http://www.yiiframework.com/download/) dans un dossier nommé `practical` placé directement sous la racine Web. + +Ensuite suivez les instructions données dans la sous-section suivante. + + +## Préparation de l'application + +Après que vous avez installé l'application, vous devez accomplir les étapes suivantes pour initialiser l'application installée. Vous n'avez à faire cela qu'une fois pour toute. + +1. Ouvrez un terminal et exécutez la commande `init` et sélectionnez `dev` en tant qu'environnement. + + ``` + /path/to/php-bin/php /path/to/practical-a/init + ``` + + Si vous l'automatisez à l'aide d'un script, vous pouvez exécuter `init` en mode non interactif. + + ``` + /path/to/php-bin/php /path/to/practical-a/init --env=Production --overwrite=All + ``` + +2. Créez une nouvelle base de données et complétez la configuration de `components['db']` dans `common/config/main-local.php` en conséquence. + +3. Ouvrez un terminal, appliquez les migrations avec la commande `/path/to/php-bin/php /path/to/practical-a/yii migrate`. + +4. Définissez la racine du document de votre serveur Web : + + - pour l'interface utilisateur (frontend) `/path/to/practical-a/frontend/`, en utilisant l'URL `http://frontend.dev/` + - pour l'interface d'administration (backend) `/path/to/practical-a/backend/web/`, en utilisant URL `http://backend.dev/` + + Avec le serveur Apache ça pourrait ressembler à ceci : + + ```apache + + ServerName frontend.dev + DocumentRoot "/path/to/practical-a/frontend/" + + + # use mod_rewrite for pretty URL support + RewriteEngine on + # If a directory or a file exists, use the request directly + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + # Otherwise forward the request to index.php + RewriteRule . index.php + + # use index.php as index file + DirectoryIndex index.php + + # ...other settings... + # Apache 2.4 + Require all granted + + ## Apache 2.2 + # Order allow,deny + # Allow from all + + + + + ServerName backend.dev + DocumentRoot "/path/to/practical-a/backend/web/" + + + # use mod_rewrite for pretty URL support + RewriteEngine on + # If a directory or a file exists, use the request directly + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + # Otherwise forward the request to index.php + RewriteRule . index.php + + # use index.php as index file + DirectoryIndex index.php + + # ...other settings... + # Apache 2.4 + Require all granted + + ## Apache 2.2 + # Order allow,deny + # Allow from all + + + ``` + + Avec le serveur nginx: + + ```nginx + server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name frontend.dev; + root /path/to/practical-a/frontend/; + index index.php; + + access_log /path/to/practical-a/log/frontend-access.log; + error_log /path/to/practical-a/log/frontend-error.log; + + location / { + # Redirect everything that isn't a real file to index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # uncomment to avoid processing of calls to non-existing static files by Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + # deny accessing php files for the /assets directory + location ~ ^/assets/.*\.php$ { + deny all; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php5-fpm.sock; + try_files $uri =404; + } + + location ~* /\. { + deny all; + } + } + + server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name backend.dev; + root /path/to/practical-a/backend/web/; + index index.php; + + access_log /path/to/practical-a/log/backend-access.log; + error_log /path/to/practical-a/log/backend-error.log; + + location / { + # Redirect everything that isn't a real file to index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # uncomment to avoid processing of calls to non-existing static files by Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + # deny accessing php files for the /assets directory + location ~ ^/assets/.*\.php$ { + deny all; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php5-fpm.sock; + try_files $uri =404; + } + + location ~* /\. { + deny all; + } + } + ``` + +5. Modifier le fichier hosts pour qu'il pointe sur le domaine ad hoc. + + - Windows: `c:\Windows\System32\Drivers\etc\hosts` + - Linux: `/etc/hosts` + + Ajoutez les lignes suivantes : + + ``` + 127.0.0.1 frontend.dev + 127.0.0.1 backend.dev + ``` + +Pour vous connecter à l'application, vous devez d'abord vous enregistrer avec votre adresse électronique, votre nom d'utilisateur et votre mot de passe. +Ensuite, vous pouvez utiliser cet adresse électronique et ce mot de passe à tout moment. + + + +> Note : si vous voulez utiliser le modèle avancé sur un domaine unique de manière à ce que `/` soit l'interface utilisateur et `/admin` l'interface d'administration, reportez-vous +> à [Utilisation du modèle de projet avancé sur un hébergement partagé](topic-shared-hosting.md). + +## Installation en utilisant Vagrant + +C'est la manière la plus facile mais elle prend du temps (~20 min). + +**Cette façon d'installer ne nécessite pas de logiciel pré-installé (comme un serveur Web, PHP, MySQL, etc.)** - contentez-vous d'accomplir les étapes suivantes ! + +#### Manuel pour les utilisateurs de Linux/Unix + +1. Installez [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. Installez [Vagrant](https://www.vagrantup.com/downloads.html) +3. Créez un [jeton d'API personnel](https://github.com/blog/1509-personal-api-tokens) sur GitHub +3. Préparez le projet: + + ```bash + git clone https://github.com/kartik-v/yii2-app-practical-a.git + cd yii2-app-practical-a/vagrant/config + cp vagrant-local.example.yml vagrant-local.yml + ``` + +4. Placez votre jeton personnel d'API GitHub dans `vagrant-local.yml` +5. Placez-vous (cd) sur la racine du projet : + + ```bash + cd yii2-app-practical-a + ``` + +5. Exécutez les commandes suivantes : + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + +C'est tout. Il ne vous reste plus qu'à attendre la fin de l'exécution ! Après cela, vous pouvez accéder au projet localement par les URL : +* pour l'interface utilisateur : http://y2aa-frontend.dev +* pour l'interface d'administration : http://y2aa-backend.dev + +#### Manuel pour les utilisateurs de Windows + +1. Installez [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. Installez [Vagrant](https://www.vagrantup.com/downloads.html) +3. Redémarrez. +4. Créez un [jeton d'API personnel](https://github.com/blog/1509-personal-api-tokens) sur GitHub +5. Préparez le projet : + * téléchargez le dépôt [yii2-app-practical-a](https://github.com/kartik-v/yii2-app-practical-a/archive/master.zip) + * décompressez-le avec unzip + * placez-vous dans le dossier `yii2-app-practical-a-master/vagrant/config` + * copiez `vagrant-local.example.yml` vers `vagrant-local.yml` + +6. Placez votre jeton personnel d'API GitHub dans `vagrant-local.yml` +7. Ajoutez les lignes suivantes dans le [fichier hosts](https://en.wikipedia.org/wiki/Hosts_(file)): + + ``` + 192.168.83.137 y2aa-frontend.dev + 192.168.83.137 y2aa-backend.dev + ``` + +8. Ouvrez un terminal (`cmd.exe`), **placez-vous à la racine du projet** et exécutez les commandes : + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + + (Vous pouvez apprendre comment changer de dossier dans l'interpréteur de commande en lisant [ceci](http://www.wikihow.com/Change-Directories-in-Command-Prompt)) + +C'est tout. Il ne vous reste qu'à attendre la fin de l'exécution ! Après cela, vous pouvez accéder au projet localement par les URL : +* pour l'interface utilisateur : http://y2aa-frontend.dev +* pour l'interface d'administration : http://y2aa-backend.dev + diff --git a/docs/guide-fr/start-testing.md b/docs/guide-fr/start-testing.md new file mode 100644 index 0000000..01d6b23 --- /dev/null +++ b/docs/guide-fr/start-testing.md @@ -0,0 +1,106 @@ +Tests +=============================== + +L'application avancée de Yii2 utilise Codeception en tant que structure de base de test primaire. Il existe déjà quelques échantillons de tests préparés dans le dossier `tests` des dossiers `frontend`, `backend` et `common`. Pour que la procédure suivante fonctionne, on suppose que l'application a été initialisée en utilisant l'environnement `dev`. Dans le cas où les tests doivent être exécutés dans l'environnement `production`, les fichiers `yii_test` et `yii_test.bat` doivent être copiés manuellement du dossier `environnements/dev` vers le dossier racine du projet. +Les tests nécessitent une **base de données additionnelle**, qui sera vidée entre les tests. Créez une base de données `yii2practical_test` avec mysql (en accord avec la configuration dans `common/config/test.php`) et exécutez : + +``` +./yii_test migrate +``` + +Construisez la suite de tests : + +``` +vendor/bin/codecept build +``` + +Ensuit, tous les échantillons de test peuvent être lancés en exécutant : + +``` +vendor/bin/codecept run +``` + +La sortie devrait ressembler à ceci : + +![](images/tests.png) + +Il est recommandé de maintenir les tests à jour. Si une classe, ou une fonctionnalité, est effacée, les tests correspondant doivent l'être également. +Vous devriez exécuter les tests régulièrement, ou mieux, configurer l'intégration continue au serveur pour eux. + +Reportez-vous à [Étude de cas Yii2 Framework](http://codeception.com/for/yii) pour savoir comment configurer Codeception pour votre application. + +### Common (communs) + +Les tests pour les classes partagées sont situées dans `common/tests`. Dans ce modèle, il s'agit unitquement de tests unitaires (`unit`). +Lancez-les en exécutant : +``` +vendor/bin/codecept run -- -c common +``` + +L'option `-c` permet de définir le chemin vers la configuration `codeception.yml`. + +La suite de tests unitaires (`unit`) (située dans `common/tests/unit`) peut utiliser les fonctionnalités de Yii framework : `Yii::$app`, l'enregistrement actif (*ActiveRecord*), les environnement prédéfinis (*fixtures*), etc. +Cela est effectif parce que le module `Yii2` est activé dans la configuration des tests unitaires : `common/tests/unit.suite.yml`. Vous pouvez le désactiver pour exécuter les tests en isolation totale. + + +### Interface utilisateur (frontend) + +Les tests de l'interface utilisateur contiennent des tests unitaires, fonctionnels et d'acceptation. +Exécutez-les avec : +``` +vendor/bin/codecept run -- -c frontend +``` + +Description des suites de tests : + +* `unit` ⇒ classes relatives à l'application interface utilisateur seulement. +* `functional` ⇒ requêtes/réponses internes de l'application (sans serveur web). +* `acceptance` ⇒ application web, interface utilisateur et interactions javascript dans le navigateur réel. + +Les tests d'acceptation sont désactivés par défaut. Pour les utiliser exécutez ce qui suit. + +#### Exécutiton des tests d'acceptation + +Pour exécuter les tests d'acceptation suivez les étapes ci-dessous : + +1. Renommez `frontend/tests/acceptance.suite.yml.example` en `frontend/tests/acceptance.suite.yml` pour activer la configuration de la suite + +1. Remplacez le paquet `codeception/base` dans `composer.json` par `codeception/codeception` pour installer une version complète de Codeception + +1. Mettez les dépendances à jour avec Composer + + ``` + composer update + ``` + +1. Auto-générez les nouvelles classes pour la prise en charge des tests d'acceptation : + + ``` + vendor/bin/codecept build -- -c frontend + ``` + +1. Téléchargez [Selenium Server](http://www.seleniumhq.org/download/) et lancez-le : + + ``` + java -jar ~/selenium-server-standalone-x.xx.x.jar + ``` + +1. Démarrez le serveur Web : + + ``` + php -S 127.0.0.1:8080 -t frontend + ``` + +1. Maintenant, vous pouvez exécuter tous les tests disponibles : + + ``` + vendor/bin/codecept run acceptance -- -c frontend + ``` + +## Interface d'administration (backend) + +L'application *interface d'administration* contient les suites de tests unitaires et fonctionnels. Exécutez-les avec  : + +``` +vendor/bin/codecept run -- -c backend +``` diff --git a/docs/guide-fr/structure-applications.md b/docs/guide-fr/structure-applications.md new file mode 100644 index 0000000..5621699 --- /dev/null +++ b/docs/guide-fr/structure-applications.md @@ -0,0 +1,10 @@ +Applications +============ + +Il y a trois applications dans le modèle de projet avancé : l'interface utilisateur (*frontend*), l'interface d'administration (*backend*) et la console. L'interface utilisateur est ce qui est présenté à l'utilisateur final, le projet lui-même. L'interface d'administration est un paneau d'administration qui permet l'administration, des analyses et des fonctionnalités de ce genre. La console est typiquement utilisée pour des tâches de cron et la gestion de bas niveau du serveur. C'est pourquoi on l'utilise durant le déploiement de l'application pour la gestion des migrations et des ressources. + +Il existe aussi un dossier `common` (partagé) qui contient les fichiers utilisés par plus d'une application. Par exemple, le modèle `User` (utilisateur). + +L'interface utilisateur et l'interface d'administration sont toutes deux des applications Web et contiennent toutes deux un dossier `web`, qui représente la racine Web vers laquelle vous devez pointer votre serveur Web. + +Chacune des applications possède son propre espace de noms et son propre alias correspondant à son nom. La même chose vaut pour le dossier `common`. diff --git a/docs/guide-fr/structure-directories.md b/docs/guide-fr/structure-directories.md new file mode 100644 index 0000000..0217c14 --- /dev/null +++ b/docs/guide-fr/structure-directories.md @@ -0,0 +1,23 @@ +Dossiers +=========== + +Le dossier racine contient les sous-dossiers suivants : + +- `backend` - [application Web *interface d'administration* (*backend*) ](structure-applications.md). +- `common` - [fichiers partagés entre les applications](structure-applications.md). +- `console` - [application console](structure-applications.md). +- `environments` - [configurations des environnements](structure-environments.md). +- `frontend` - [application Web *interface utilisateur* (*frontend*) ](structure-applications.md). + + +Le dossier racine contient également un jeu de fichiers : + +- `.gitignore` la liste des dossiers ignorés par le système de gestion de versions git. Si vous avez besoin que quelque chose ne remonte jamais dans votre dépôt de code source, ajoutez-le ici. +- `composer.json` - la configuration de Composer décrite dans [Configuration de Composer](start-composer.md). +- `init` - les scripts d'initialisation décrits dans [Configuration et environnements](structure-environments.md). +- `init.bat` - les mêmes pour Windows. +- `LICENSE.md` - les informations de licence. Placez la licence de votre projet ici. En particulier si vous le placez en open source. +- `README.md` - informations de base sur la façon d'installer le modèle de projet. Envisagez de remplacer ces informations par vos propres informations sur votre projet et son installation. +- `requirements.php` - vérificateur des exigences de Yii. +- `yii` - démarrage de l'application console. +- `yii.bat` - la même chose pour Windows. diff --git a/docs/guide-fr/structure-environments.md b/docs/guide-fr/structure-environments.md new file mode 100644 index 0000000..40a6566 --- /dev/null +++ b/docs/guide-fr/structure-environments.md @@ -0,0 +1,36 @@ +Configuration et environnements +============================== + +Dans une approche typique de configuration, on rencontre de multiples problèmes : + +- Chaque membre de l'équipe a ses propres options de configuration. L'engagement (*commit*) de sa propre configuration affecte les autres membres de l'équipe. +- le mot de passe de la base de données de production et les clés d'API ne devraient jamais se retrouver dans le dépôt. +- Il y a plusieurs environnements de serveur : developpement, test, production. Chacun doit avoir sa propre configuration. +- Définir toutes les options de configuration pour chacun des cas est une affaire très répétitive et prend trop de temps à maintenir. + +Pour résoudre ces problèmes, Yii introduit un concept d'environnement simple. Chaque environnement est représenté par un jeu de fichiers dans le dossier `environments`. La commande `init` est utilisée pour initialiser un environnement. Ce que fait exactement cette commande, c'est copier tout ce qui se trouve dans le dossier de l'environnement dans le dossier racine où se trouvent les applications. + +Par défaut, il y a deux environnements : `dev` et `prod`. Le premier sert au développement et les outils de développement et de débogage y sont activés. Le second sert au déploiement sur les serveurs. Les outils de débogage et de développement y sont désactivés. + +Typiquement un environnement contient les fichiers d'amorçage de l'application tels que `index.php` et les fichiers de configuration avec le suffixe `-local.php`. Il s'agit soit de fichiers de configuration personnels de membres de l'équipe qui sont généralement dans l'environnement `dev` ou de configurations de serveurs spécifiques. Par exemple, la connexion à la base de données de production peut être dans une configuration `-local.php` de l'environnement `prod`. +Ces configurations locales sont ajoutées à `.gitignore` et ne sont jamais poussées sur le dépôt de code source. + +Pour éviter que des configurations ne s'écrasent les unes les autres, l'interface utilisateur (*frontend*), par exemple, lit les configurations dans cet ordre : + +- `common/config/main.php` +- `common/config/main-local.php` +- `frontend/config/main.php` +- `frontend/config/main-local.php` + +Les paramètres sont lus dans cet ordre : + +- `common/config/params.php` +- `common/config/params-local.php` +- `frontend/config/params.php` +- `frontend/config/params-local.php` + +Une configuration écrase celles qui la précèdent. + +Voici le schéma complet : + +![Configuration de l'application avancée](images/advanced-app-configs.png) diff --git a/docs/guide-fr/structure-path-aliases.md b/docs/guide-fr/structure-path-aliases.md new file mode 100644 index 0000000..8510d54 --- /dev/null +++ b/docs/guide-fr/structure-path-aliases.md @@ -0,0 +1,18 @@ +Alias de chemin pré-définis +========================== + +- `@yii` - dossier framework . +- `@app` - chemin de base de l'application en exécution. +- `@common` - dossier partagé. +- `@frontend` - dossier de l'application *interface utilisateur* (*frontend*). +- `@backend` - dossier de l'application *interface d'administration* (*backend*). +- `@console` - dossier console. +- `@runtime` - dossier *runtime* de l'application en exécution. +- `@vendor` - dossier Composer des vendeurs. +- `@bower` - dossier des vendeurs qui contient les [paquets bower](http://bower.io/). +- `@npm` - dossier des vendeurs qui contient les [paquets npm](https://www.npmjs.org/). +- `@web` - URL de base de l'application en exécution. +- `@webroot` - dossier racine Web du l'application en cours d'exécution. + +Les alias spécifiques à la structure de dossiers de l'application avancée +(`@common`, `@frontend`, `@backend`, et `@console`) sont définis dans le fichier `common/config/bootstrap.php`. diff --git a/docs/guide-fr/topic-adding-more-apps.md b/docs/guide-fr/topic-adding-more-apps.md new file mode 100644 index 0000000..0d56bbb --- /dev/null +++ b/docs/guide-fr/topic-adding-more-apps.md @@ -0,0 +1,9 @@ +Ajout d'applications supplémentaires +==================================== + +Tandis qu'avoir des interfaces utilisateur et d'administration séparées est une pratique courante, ce n'est parfois pas suffisant. Par exemple, vous pouvez avoir besoin d'une application additionnelle pour, disons, un blog. Pour l'avoir : + +1. Copier le dossier `frontend` sur `blog`, `environments/dev/frontend` sur `environments/dev/blog` et `environments/prod/frontend` +sur `environments/prod/blog`. +2. Adapdez les espaces de noms et les chemins pour démarrer avec `blog` au lieu de `frontend`. +3. Dans `common\config\bootstrap.php` ajoutez `Yii::setAlias('blog', dirname(dirname(__DIR__)) . '/blog');`. diff --git a/docs/guide-fr/topic-link-backend-frontend.md b/docs/guide-fr/topic-link-backend-frontend.md new file mode 100644 index 0000000..31274f7 --- /dev/null +++ b/docs/guide-fr/topic-link-backend-frontend.md @@ -0,0 +1,44 @@ +Création de liens de l'interface d'administration vers l'interface utilisateur +============================================================================== + +Souvent, il est nécessaire de créer des liens depuis l'application interface d'administration vers l'application l'interface utilisateur. Comme l'interface utilisateur peut contenir ses propres règles de gestionnaire d'URL, vous devez les dupliquer pour l'interface d'administration en les nommant différemment : + +```php +return [ + 'components' => [ + 'urlManager' => [ + // ici se trouve votre configuration normale du gestionnaire d'URL de l'interface d'administration + ], + 'urlManagerFrontend' => [ + // ici se trouve votre configuration du gestionnaire d'URL de l'interface utilisateur + ], + + ], +]; +``` + +Après l'avoir fait, vous pouvez obtenir une URL qui pointe sur l'interface utilisateur comme ceci : + +```php +echo Yii::$app->urlManagerFrontend->createAbsoluteUrl(...); +``` + +Afin de ne pas copier-coller les règles de l'interface utilisateur, vous pouvez d'abord les déplacer dans un fichier `urls.php` : + +```php +return [ + // ... + 'components' => [ + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => require 'urls.php', + ], + // ... + + ], + // ... +]; +``` + +Ensuite vous pouvez l'inclure dans les règles `urlManagerFrontend` également. diff --git a/docs/guide-fr/topic-shared-hosting.md b/docs/guide-fr/topic-shared-hosting.md new file mode 100644 index 0000000..890a66a --- /dev/null +++ b/docs/guide-fr/topic-shared-hosting.md @@ -0,0 +1,57 @@ +Utilisation du modèle de projet avancé sur un hébergement partagé +================================================================= + +Le déploiement d'un modèle de projet avancé sur un hébergement partagé est un peu plus délicat que le déploiement du projet *basic* parce qu'il a deux racines Web que les serveurs Web des hébergements partagés ne prennent pas en charge. Il faut adapter la structure des dossiers de manière à ce que l'URL de l'interface utilisateur soit `http://site.local` et celle de l'interface d'administration `http://site.local/admin`. + +### Déplacement des scripts d'entrée dans une racine Web unique + +En premier lieu, il faut un dossier qui serve de racine Web. Créez un nouveau dossier et appelez-le de manière à ce qu'il corresponde à votre nom de racine Web, p. ex. `www` ou `public_html`, ou similaire. Ensuite, créez la structure suivante dans laquelle `www` est la racine Web de l'hébergement que vous venez juste de créer : +``` +www + admin +backend +common +console +environments +frontend +... +``` + +`www` sera notre dossier de l'interface utilisateur, c'est pourquoi il faut déplacer le contenu de `frontend` dedans. Déplacez le contenu de `backend/web` dans `www/admin`. Dans les deux cas, vous devez adapter les chemins dans `index.php` et `index-test.php`. + +### Adaptez les sessions et les témoins de connexion (cookies) + +À l'origine l'interface d'administration et l'interface utilisateur sont prévues pour s'exécuter dans des domaines différents. Lorsqu'on les rassemble dans le même domaine, elles vont partager les mêmes témoins de connexion, ce qui crée une collision. Pour régler cela, adaptez la configuration de l'interface d'administration `backend/config/main.php` comme suit : + +```php +'components' => [ + 'request' => [ + 'csrfParam' => '_csrf-backend', + 'csrfCookie' => [ + 'httpOnly' => true, + 'path' => '/admin', + ], + ], + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + 'identityCookie' => [ + 'name' => '_identity-backend', + 'path' => '/admin', + 'httpOnly' => true, + ], + ], + 'session' => [ + // ceci est le mom du témoin de connexion de session utilisé pour la connexion à l'interface d'administration + 'name' => 'practical-backend', + 'cookieParams' => [ + 'path' => '/admin', + ], + ], +], +``` + +### Installation alternative + +Si la manière d'installer le modèle de projet présentée ci-dessus ne fonctionne pas dans votre cas, essayez +[configurations et documentation d'Oleg Belostotskiy](https://github.com/mickgeek/yii2-practical-one-domain-config). diff --git a/docs/guide-ja/README.md b/docs/guide-ja/README.md index bbb61ce..7770a69 100644 --- a/docs/guide-ja/README.md +++ b/docs/guide-ja/README.md @@ -15,6 +15,7 @@ Yii 2 アドバンストプロジェクトテンプレートは、複数の層 * [インストール](start-installation.md) * [ベーシックプロジェクトテンプレートとの違い](start-comparison.md) * [Composer を構成する](start-composer.md) +* [テストを実行する](start-testing.md) 構造 ---- @@ -29,3 +30,5 @@ Yii 2 アドバンストプロジェクトテンプレートは、複数の層 * [バックエンドからフロントエンドへのリンクを作成する](topic-link-backend-frontend.md) * [アプリケーションをさらに追加する](topic-adding-more-apps.md) +* [共有ホスティング環境でアドバンストプロジェクトテンプレートを使う](topic-shared-hosting.md) + diff --git a/docs/guide-ja/images/tests.png b/docs/guide-ja/images/tests.png new file mode 100644 index 0000000..a537336 Binary files /dev/null and b/docs/guide-ja/images/tests.png differ diff --git a/docs/guide-ja/start-composer.md b/docs/guide-ja/start-composer.md index 48c2b20..fba8cdd 100644 --- a/docs/guide-ja/start-composer.md +++ b/docs/guide-ja/start-composer.md @@ -5,9 +5,9 @@ Composer を構成する ```json { - "name": "yiisoft/yii2-app-advanced", - "description": "Yii 2 Advanced Application Template", - "keywords": ["yii2", "framework", "advanced", "application template"], + "name": "kartik-v/yii2-app-practical-a", + "description": "Yii 2 Practical-A Project Template", + "keywords": ["yii2", "framework", "practical", "project template"], "homepage": "http://www.yiiframework.com/", "type": "project", "license": "BSD-3-Clause", @@ -21,15 +21,17 @@ Composer を構成する "minimum-stability": "dev", "require": { "php": ">=5.4.0", - "yiisoft/yii2": "*", - "yiisoft/yii2-bootstrap": "*", - "yiisoft/yii2-swiftmailer": "*" + "yiisoft/yii2": "~2.0.6", + "yiisoft/yii2-bootstrap": "~2.0.0", + "yiisoft/yii2-swiftmailer": "~2.0.0" }, "require-dev": { - "yiisoft/yii2-codeception": "*", - "yiisoft/yii2-debug": "*", - "yiisoft/yii2-gii": "*", - "yiisoft/yii2-faker": "*" + "yiisoft/yii2-debug": "~2.0.0", + "yiisoft/yii2-gii": "~2.0.0", + "yiisoft/yii2-faker": "~2.0.0", + + "codeception/base": "^2.2.3", + "codeception/verify": "~0.3.1" }, "config": { "process-timeout": 1800 diff --git a/docs/guide-ja/start-installation.md b/docs/guide-ja/start-installation.md index 5b0e868..1cba8d4 100644 --- a/docs/guide-ja/start-installation.md +++ b/docs/guide-ja/start-installation.md @@ -11,19 +11,19 @@ Composer がインストールされていれば、次のコマンドを使ってアプリケーションをインストールすることが出来ます。 - composer global require "fxp/composer-asset-plugin:~1.1.1" - composer create-project --prefer-dist yiisoft/yii2-app-advanced yii-application + composer global require "fxp/composer-asset-plugin:^1.3.1" + composer create-project --prefer-dist kartik-v/yii2-app-practical-a practical-a 最初のコマンドは [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) をインストールします。 これにより、Composer を通じて bower と npm の依存パッケージを管理することが出来るようになります。 このコマンドは全体で一度だけ走らせれば十分です。 -第二のコマンドは `yii-application` という名前のディレクトリにアドバンストアプリケーションをインストールします。 +第二のコマンドは `practical-a` という名前のディレクトリにアドバンストアプリケーションをインストールします。 望むなら別のディレクトリ名を選ぶことも出来ます。 ## アーカイブファイルからインストールする -[yiiframework.com](http://www.yiiframework.com/download/) からダウンロードしたアーカイブファイルをウェブルートの直下、`advanced` と名付けられたディレクトリに解凍します。 +[yiiframework.com](http://www.yiiframework.com/download/) からダウンロードしたアーカイブファイルをウェブルートの直下、`practical` と名付けられたディレクトリに解凍します。 その後は、次の項に記載されている指示に従ってください。 @@ -33,35 +33,35 @@ Composer がインストールされていれば、次のコマンドを使っ アプリケーションをインストールした後に、インストールされたアプリケーションの初期設定をするために、次の各ステップを実行しなければなりません。 これらは全体で一度だけやれば十分です。 -1. `init` コマンドを実行して、環境として `dev` を選択します。 +1. コンソールターミナルを開き、`init` コマンドを実行して環境として `dev` を選択します。 ``` - php /path/to/yii-application/init + /path/to/php-bin/php /path/to/practical-a/init ``` - あるいは、本番サーバで、非対話モードで `init` を実行します。 + あるいは、本番サーバでは、非対話モードで `init` を実行します。 ``` - php /path/to/yii-application/init --env=Production --overwrite=All + /path/to/php-bin/php /path/to/practical-a/init --env=Production --overwrite=All ``` 2. 新しいデータベースを作成し、それに従って `common/config/main-local.php` の `components['db']` の構成情報を修正します。 -3. コンソールコマンド `yii migrate` でマイグレーションを適用します。 +3. コンソールターミナルを開き、`/path/to/php-bin/php /path/to/practical-a/yii migrate` というコマンドでマイグレーションを適用します。 4. ウェブサーバのドキュメントルートを設定します。 - - フロントエンドのパスは `/path/to/yii-application/frontend/web/`、URL は `http://frontend/` を使用 - - バックエンドのパスは `/path/to/yii-application/backend/web/`、URL は `http://backend/` を使用 + - フロントエンドのパスは `/path/to/practical-a/`、URL は `http://frontend/` を使用 + - バックエンドのパスは `/path/to/practical-a/backend/web/`、URL は `http://backend/` を使用 Apache の場合は、次のように設定することが出来ます。 ```apache ServerName frontend.dev - DocumentRoot "/path/to/yii-application/frontend/web/" + DocumentRoot "/path/to/practical-a/frontend/" - + # 綺麗な URL をサポートするために mod_rewrite を使用 RewriteEngine on # ディレクトリまたはファイルがある場合は、リクエストを直接使用 @@ -74,14 +74,20 @@ Composer がインストールされていれば、次のコマンドを使っ DirectoryIndex index.php # ... その他の設定 ... + # Apache 2.4 + Require all granted + + ## Apache 2.2 + # Order allow,deny + # Allow from all ServerName backend.dev - DocumentRoot "/path/to/yii-application/backend/web/" + DocumentRoot "/path/to/practical-a/backend/web/" - + # 綺麗な URL をサポートするために mod_rewrite を使用 RewriteEngine on # ディレクトリまたはファイルがある場合は、リクエストを直接使用 @@ -94,6 +100,12 @@ Composer がインストールされていれば、次のコマンドを使っ DirectoryIndex index.php # ... その他の設定 ... + # Apache 2.4 + Require all granted + + ## Apache 2.2 + # Order allow,deny + # Allow from all ``` @@ -104,20 +116,20 @@ Composer がインストールされていれば、次のコマンドを使っ server { charset utf-8; client_max_body_size 128M; - + listen 80; ## listen for ipv4 #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 - + server_name frontend.dev; - root /path/to/yii-application/frontend/web/; + root /path/to/practical-a/frontend/; index index.php; - - access_log /path/to/yii-application/log/frontend-access.log; - error_log /path/to/yii-application/log/frontend-error.log; - + + access_log /path/to/practical-a/log/frontend-access.log; + error_log /path/to/practical-a/log/frontend-error.log; + location / { # 本当のファイルでないものは全て index.php にリダイレクト - try_files $uri $uri/ /index.php?$args; + try_files $uri $uri/ /index.php$is_args$args; } # 存在しない静的なファイルの呼び出しを Yii が処理するのを防ぐためには、コメントをはずす @@ -125,54 +137,64 @@ Composer がインストールされていれば、次のコマンドを使っ # try_files $uri =404; #} #error_page 404 /404.html; - + + # /assets ディレクトリの php ファイルへのアクセスを拒否する + location ~ ^/assets/.*\.php$ { + deny all; + } + location ~ \.php$ { include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; - fastcgi_pass 127.0.0.1:9000; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/php5-fpm.sock; try_files $uri =404; } - - location ~ /\.(ht|svn|git) { + + location ~* /\. { deny all; } } - + server { charset utf-8; client_max_body_size 128M; - + listen 80; ## listen for ipv4 #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 - + server_name backend.dev; - root /path/to/yii-application/backend/web/; + root /path/to/practical-a/backend/web/; index index.php; - - access_log /path/to/yii-application/log/backend-access.log; - error_log /path/to/yii-application/log/backend-error.log; - + + access_log /path/to/practical-a/log/backend-access.log; + error_log /path/to/practical-a/log/backend-error.log; + location / { # 本当のファイルでないものは全て index.php にリダイレクト - try_files $uri $uri/ /index.php?$args; + try_files $uri $uri/ /index.php$is_args$args; } - + # 存在しない静的なファイルの呼び出しを Yii が処理するのを防ぐためには、コメントをはずす #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { # try_files $uri =404; #} #error_page 404 /404.html; - + + # /assets ディレクトリの php ファイルへのアクセスを拒否する + location ~ ^/assets/.*\.php$ { + deny all; + } + location ~ \.php$ { include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/php5-fpm.sock; try_files $uri =404; } - - location ~ /\.(ht|svn|git) { + + location ~* /\. { deny all; } } @@ -194,3 +216,81 @@ Composer がインストールされていれば、次のコマンドを使っ アプリケーションにログインするためには、最初にユーザ登録をする必要があります。 あなたの任意のメールアドレス、ユーザ名、パスワードを指定してください。 そうすれば、同じメールアドレスとパスワードを使って何時でもアプリケーションにログインすることが出来ます。 + + +> Note: `/` をフロントエンド、`/admin` をバックエンドにして、アドバンストテンプレートを単一のドメインで走らせたい場合は、 +> [共有ホスティング環境でアドバンストプロジェクトテンプレートを使う](topic-shared-hosting.md) を参照して下さい。 + + +## Vagrant を使ってインストールする + +この方法が最も簡単ですが、時間はかかります (~20分)。 + +**このインストール方法では、(ウェブサーバ、PHP、MySQL 等々の) ソフトウェアを事前にインストールする必要はありません。** - 単に以下のステップを実行するだけです。 steps! + +#### Linux/Unix ユーザ用マニュアル + +1. [VirtualBox](https://www.virtualbox.org/wiki/Downloads) をインストールする +2. [Vagrant](https://www.vagrantup.com/downloads.html) をインストールする +3. GitHub [personal API token](https://github.com/blog/1509-personal-api-tokens) を作成する +3. プロジェクトを準備する + + ```bash + git clone https://github.com/kartik-v/yii2-app-practical-a.git + cd yii2-app-practical-a/vagrant/config + cp vagrant-local.example.yml vagrant-local.yml + ``` + +4. 作成した GitHub personal API token を `vagrant-local.yml` に置く +5. プロジェクトのルートディレクトリに移動する + + ```bash + cd yii2-app-practical-a + ``` + +5. 下記のコマンドを実行する + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + +これで全部です。後はただ完了するのを待つだけです。 +完了後には、次の URL でローカルのプロジェクトにアクセスすることが出来ます。 +* フロントエンド: http://y2aa-frontend.dev +* バックエンド: http://y2aa-backend.dev + +#### Windows ユーザ用マニュアル + +1. [VirtualBox](https://www.virtualbox.org/wiki/Downloads) をインストールする +2. [Vagrant](https://www.vagrantup.com/downloads.html) をインストールする +3. 再起動する +4. GitHub [personal API token](https://github.com/blog/1509-personal-api-tokens) を作成する +5. プロジェクトを準備する + * [yii2-app-practical-a](https://github.com/kartik-v/yii2-app-practical-a/archive/master.zip) レポジトリをダウンロードする + * 解凍する + * `yii2-app-practical-a-master/vagrant/config` ディレクトリに入る + * vagrant-local.example.yml` を `vagrant-local.yml` にコピーする + +6. 作成した GitHub personal API token を `vagrant-local.yml` に置く +7. 次の2行を [hosts file](https://en.wikipedia.org/wiki/Hosts_(file)) に追加する + + ``` + 192.168.83.137 y2aa-frontend.dev + 192.168.83.137 y2aa-backend.dev + ``` + +8. ターミナル (`cmd.exe`) を開き、 **プロジェクトのルートディレクトリに移動して** 次のコマンドを実行する + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + + (コマンドプロンプトでディレクトリを移動する方法については、[ここ](http://www.wikihow.com/Change-Directories-in-Command-Prompt) を読んでください) + +これで全部です。後はただ完了するのを待つだけです。 +完了後には、次の URL でローカルのプロジェクトにアクセスすることが出来ます。 +* フロントエンド: http://y2aa-frontend.dev +* バックエンド: http://y2aa-backend.dev + diff --git a/docs/guide-ja/start-testing.md b/docs/guide-ja/start-testing.md new file mode 100644 index 0000000..8dfa0cc --- /dev/null +++ b/docs/guide-ja/start-testing.md @@ -0,0 +1,107 @@ +テスト +====== + +Yii2 アドバンストアプリケーションは Codeception を主たるテストフレームワークとして使用します。 +`frontend`、`backend` および `common` の `tests` ディレクトリに、既にいくつかのサンプルテストが用意されています。 +テストには、テストを実行するたびに事前にクリーンアップされる **追加のデータベース** が必要になります。 +(`common/config/test.php` の構成に従って) mysql に `yii2practical_test` というデータベースを作成し、下記を実行して下さい。 + +``` +./yii_test migrate +``` + +次に、テストスイートをビルドします。 + +``` +vendor/bin/codecept build +``` + +これで、次のコマンドを実行すれば、全てのサンプルテストを開始することが出来ます。 + +``` +vendor/bin/codecept run +``` + +次の図と同じような出力が得られる筈です。 + +![](images/tests.png) + +あなたのテストを最新の状態に保つことが推奨されます。 +クラスまたは機能が削除されたときには、対応するテストも削除されるべきです。 +テストは定期的に実行すべきです。あるいは、もっと良い方法として、継続インテグレーションサーバをテストのためにセットアップしましょう。 + +Codeception をあなたのアプリケーションのために構成する方法を学ぶために [Yii2 Framework Case Study](http://codeception.com/for/yii) を参照して下さい。 + +### Common + +共通クラスのためのテストは `common/tests` にあります。このテンプレートでは、単体テスト (`unit` テスト) しか有りません。 +下記を実行してテストを実行します。 + +``` +vendor/bin/codecept run -- -c common +``` + +`-c` オプションが `codeception.yml` 構成ファイルへのパスをセットすることを可能にしています。 + +単体テスト (`unit` テスト) スイート (`common/tests/unit` にあります) では、Yii フレームワークの機能、例えば、`Yii::$app`、アクティブレコード、フィクスチャなどを使用することが出来ます。 +このことが可能なのは、テストの構成 `common/tests/unit.suite.yml` において `Yii2` モジュールが有効になっているからです。 +これを無効すると、テストを完全に独立した状態で走らせることが出来ます。 + + +### Frontend + +フロントエンドのテストは、単体テスト、機能テスト、受入テストを含んでいます。 +下記を実行してテストを実行します。 + +``` +vendor/bin/codecept run -- -c frontend +``` + +テストスイートの説明 + +* 単体 (`unit`) ⇒ フロントエンドアプリケーションだけに関係する諸クラスのテスト +* 機能 (`functional`) ⇒ アプリケーションの内部的なリクエストとレスポンスのテスト (ウェブサーバ抜きで) +* 受入 (`acceptance`) ⇒ 実際のブラウザにおけるWebアプリケーション、ユーザインタフェイス、javascript 相互作用のテスト + +デフォルトでは、受入テストは無効になっています。受入テストを実行するためには、次のようにします。 + +#### 受入テストを実行する + +受入テストを実行するためには、次のようにします。 + +1. `frontend/tests/acceptance.suite.yml.example` を `frontend/tests/acceptance.suite.yml` にリネームして、スイートの構成を有効にする + +2. `composer.json` の `codeception/base` パッケージを `codeception/codeception` に置き換えて、全ての機能をもつ Codeception のバージョンをインストールする + +3. Composer で依存を更新する + + ``` + composer update + ``` + +4. [Selenium Server](http://www.seleniumhq.org/download/) をダウンロードして起動する + + ``` + java -jar ~/selenium-server-standalone-x.xx.x.jar + ``` + +5. ウェブサーバを開始する + + ``` + php -S 127.0.0.1:8080 -t frontend + ``` + +6. これで全てのテストを実行することが出来る + + ``` + vendor/bin/codecept run acceptance -- -c frontend + ``` + +## Backend + +バックエンドアプリケーションは、単体テストと機能テストのスイートを含んでいます。 +下記によって、テストスイートを実行します。 + +``` +vendor/bin/codecept run -- -c backend +``` \ No newline at end of file diff --git a/docs/guide-ja/structure-applications.md b/docs/guide-ja/structure-applications.md index fe2e479..a915736 100644 --- a/docs/guide-ja/structure-applications.md +++ b/docs/guide-ja/structure-applications.md @@ -8,8 +8,7 @@ コンソールは典型的にはクロンジョブや低レベルのサーバ管理に使用されます。 コンソールは、また、アプリケーションの配備の際にも使われ、マイグレーションやアセットを処理します。 -さらに、二つ以上のアプリケーションから使われるファイルを含む `common` ディレクトリがあります。 -例えば、`User` モデルがそうです。 +さらに、二つ以上のアプリケーションから使われるファイル、例えば `User` モデルを含む `common` ディレクトリがあります。 フロントエンドとバックエンドは両方ともウェブアプリケーションであり、ともに `web` ディレクトリを含んでいます。 これがウェブサーバのウェブルートとすべきディレクトリです。 diff --git a/docs/guide-ja/structure-directories.md b/docs/guide-ja/structure-directories.md index 60a716f..361fca2 100644 --- a/docs/guide-ja/structure-directories.md +++ b/docs/guide-ja/structure-directories.md @@ -3,11 +3,11 @@ ルートディレクトリは次のサブディレクトリを含みます。 -- `backend` - バックエンドのウェブアプリケーション -- `common` - 全てのアプリケーションに共通なファイル -- `console` - コンソールアプリケーション -- `environments` - 環境設定 -- `frontend` - フロントエンドのウェブアプリケーション +- `backend` - [バックエンドのウェブアプリケーション](structure-applications.md) +- `common` - [全てのアプリケーションに共通なファイル](structure-applications.md) +- `console` - [コンソールアプリケーション](structure-applications.md) +- `environments` - [環境設定](structure-applications.md) +- `frontend` - [フロントエンドのウェブアプリケーション](structure-applications.md) ルートディレクトリは次の一群のファイルを含みます。 diff --git a/docs/guide-ja/structure-environments.md b/docs/guide-ja/structure-environments.md index b3276a0..114381c 100644 --- a/docs/guide-ja/structure-environments.md +++ b/docs/guide-ja/structure-environments.md @@ -11,7 +11,7 @@ これらの問題を解決するために、Yii は単純な環境の概念を導入しました。 それぞれの環境は `environments` ディレクトリ配下の一群のファイルとして表現されます。 -`init` コマンドがこれらの環境を切り替えるのに使用されます。 +`init` コマンドが環境を初期設定するのに使用されます。 `init` コマンドが実際にやっていることは、環境ディレクトリから、全てのアプリケーションがあるルートディレクトリへと、すべてをごっそりとコピーすることです。 デフォルトでは二つの環境があります。すなわち、`dev` と `prod` です。 diff --git a/docs/guide-ja/topic-link-backend-frontend.md b/docs/guide-ja/topic-link-backend-frontend.md index 043ed42..58e2261 100644 --- a/docs/guide-ja/topic-link-backend-frontend.md +++ b/docs/guide-ja/topic-link-backend-frontend.md @@ -21,5 +21,25 @@ return [ このようにすると、フロントエンドを指す URL を次のようにして取得することが出来ます。 ```php -echo Yii::$app->urlManagerFrontend->createUrl(...); +echo Yii::$app->urlManagerFrontend->createAbsoluteUrl(...); ``` + +フロントエンドの規則をコピペしなくても済むように、最初にそれらの規則を独立した `urlsphp` ファイルに移しておくことが出来ます。 + +```php +return [ + // ... + 'components' => [ + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => require 'urls.php', + ], + // ... + + ], + // ... +]; +``` + +そして、後でこれを `urlManagerFrontend` の規則としても読み込めば良いわけです。 diff --git a/docs/guide-ja/topic-shared-hosting.md b/docs/guide-ja/topic-shared-hosting.md new file mode 100644 index 0000000..70fedf8 --- /dev/null +++ b/docs/guide-ja/topic-shared-hosting.md @@ -0,0 +1,68 @@ +共有ホスティング環境でアドバンストプロジェクトテンプレートを使う +================================================================ + +アドバンストプロジェクトテンプレートを共有ホストに配備するのは、ベーシックプロジェクトテンプレートを配備するのに比べると、少しトリッキーになります。 +なぜなら、アドバンストアプリケーションは、共有ホストがサポートしていない二つのウェブルートを持っているからです。 +ディレクトリ構造を修正して、フロントエンドの URL が `http://site.local` となり、 +バックエンドの URL が `http://site.local/admin` となるようにしなければなりません。 + +### エントリスクリプトを単一のウェブルートに移動する + +まずは、ウェブルートディレクトリが必要です。 +新しいディレクトリを作成して、あなたのホストのウェブルートの名前に合った名前を付けて下さい。 +例えば、`www` や `public_html` や、そのような名前です。 +そして、次のようなディレクトリ構成にします。ここで `www` は、たった今作成したホストのウェブルートディレクトリを指します。 + +``` +www + admin +backend +common +console +environments +frontend +... +``` + +`www` が私たちのフロントエンドのディレクトリになりますので、`frontend` のコンテンツをこの中に移動します。 +`backend/web` のコンテンツは `www/admin` に移動します。 + どちらの場合も、index.php および index-test.php の中のパスを修正する必要があります。 + +### セッションとクッキーを修正する + +元来は、バックエンドとフロントエンドは異なるドメインで走ることを意図されています。 +両方を同じドメインに移動すると、フロントエンドとバックエンドが同じクッキーを共有して、衝突することになります。 +この障害を修正するために、バックエンドのアプリケーション構成 backend/config/main.php を以下のように修正します。 + +```php +'components' => [ + 'request' => [ + 'csrfParam' => '_csrf-backend', + 'csrfCookie' => [ + 'httpOnly' => true, + 'path' => '/admin', + ], + ], + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + 'identityCookie' => [ + 'name' => '_identity-backend', + 'path' => '/admin', + 'httpOnly' => true, + ], + ], + 'session' => [ + // これがバックエンドへのログインに使用されるセッションクッキーの名前 + 'name' => 'practical-backend', + 'cookieParams' => [ + 'path' => '/admin', + ], + ], +], +``` + +### 別のセットアップ + +テンプレートをセットアップする上記の方法があなたにとってはうまく行かない場合は、 +[Oleg Belostotskiy による構成とドキュメント](https://github.com/mickgeek/yii2-practical-one-domain-config) を試してみて下さい。 diff --git a/docs/guide-pl/README.md b/docs/guide-pl/README.md new file mode 100644 index 0000000..8fb0f4f --- /dev/null +++ b/docs/guide-pl/README.md @@ -0,0 +1,36 @@ +Zaawansowany Szablon Projektu Yii 2 +=================================== + +Zaawansowany Szablon Projektu Yii 2 jest szkieletem aplikacji [Yii 2](http://www.yiiframework.com/), idealnym do +stworzenia złożonych wielopoziomowych serwisów Web. + +Szablon zawiera trzy warstwy: front-end (zwaną też stroną interfejsową, kliencką), back-end (zwaną również stroną +administracyjną, zarządzającą) i konsolę - każda z tych warstw jest oddzielną aplikacją Yii. + +Szablon został zaprojektowany do pracy w grupie deweloperów i wspiera proces wydawniczy aplikacji na różnych środowiskach. + +Aby ułatwić pracę programistów, szablon posiada szereg zaimplementowanych funkcjonalności, m.in. obsługę bazy danych, +rejestrację użytkowników i mechanizm przywracania haseł. + +Od czego zacząć? +---------------- + +* [Instalacja](start-installation.md) +* [Różnice pomiędzy zaawansowanym a podstawowym szablonem projektu](start-comparison.md) +* [Konfiguracja Composera](start-composer.md) +* [Uruchamianie testów](start-testing.md) + +Struktura +--------- + +* [Foldery](structure-directories.md) +* [Predefiniowane aliasy](structure-path-aliases.md) +* [Aplikacje](structure-applications.md) +* [Konfiguracja i środowiska](structure-environments.md) + +Dodatkowe tematy +---------------- + +* [Tworzenie linków pomiędzy back-endem i front-endem](topic-link-backend-frontend.md) +* [Dodawanie kolejnych aplikacji](topic-adding-more-apps.md) +* [Korzystanie z zaawansowanego szablonu projektu w środowisku współdzielonym](topic-shared-hosting.md) diff --git a/docs/guide-pl/images/advanced-app-configs.graphml b/docs/guide-pl/images/advanced-app-configs.graphml new file mode 100644 index 0000000..05a053e --- /dev/null +++ b/docs/guide-pl/images/advanced-app-configs.graphml @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + console + + + + + + + + + + Folder 4 + + + + + + + + + + + + + + + + + + + + backend + + + + + + + + + + Folder 3 + + + + + + + + + + + + + + + + + index + + + + + + + + + + + + + + + + + + + + frontend + + + + + + + + + + Folder 1 + + + + + + + + + + + + + + + + params + + + + + + + + + + + + + + + + + params-local + + + + + + + + + + + + + + + + + main + + + + + + + + + + + + + + + + + main-local + + + + + + + + + + + + + + + + + + + aliases + + + + + + + + + + + + + + + + + + + + common + + + + + + + + + + Folder 2 + + + + + + + + + + + + + + + + params-local + + + + + + + + + + + + + + + + + main-local + + + + + + + + + + + + + + + + + params + + + + + + + + + + + + + + + + + main + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guide-pl/images/advanced-app-configs.png b/docs/guide-pl/images/advanced-app-configs.png new file mode 100644 index 0000000..daa9a6f Binary files /dev/null and b/docs/guide-pl/images/advanced-app-configs.png differ diff --git a/docs/guide-pl/images/tests.png b/docs/guide-pl/images/tests.png new file mode 100644 index 0000000..a537336 Binary files /dev/null and b/docs/guide-pl/images/tests.png differ diff --git a/docs/guide-pl/start-comparison.md b/docs/guide-pl/start-comparison.md new file mode 100644 index 0000000..9d1f671 --- /dev/null +++ b/docs/guide-pl/start-comparison.md @@ -0,0 +1,20 @@ +Różnice pomiędzy szablonami +=========================== + +Poniższa tabela pokazuje, które funkcjonalności dostępne są w podstawowym i zaawansowanym szablonem projektu: + + +| Funkcjonalność | Podstawowy | Zaawansowany | +|---|:---:|:---:| +| Struktura projektu | ✓ | ✓ | +| Główny kontroler strony | ✓ | ✓ | +| Logowanie użytkownika | ✓ | ✓ | +| Formularze | ✓ | ✓ | +| Połączenie z bazą danych | ✓ | ✓ | +| Polecenia konsoli | ✓ | ✓ | +| Pakiety assetów | ✓ | ✓ | +| Testy Codeception | ✓ | ✓ | +| Twitter Bootstrap | ✓ | ✓ | +| Aplikacja front i back-endowa | | ✓ | +| Gotowy model użytkownika | | ✓ | +| Rejestracja i przywracanie hasła użytkownika | | ✓ | diff --git a/docs/guide-pl/start-composer.md b/docs/guide-pl/start-composer.md new file mode 100644 index 0000000..ca76d56 --- /dev/null +++ b/docs/guide-pl/start-composer.md @@ -0,0 +1,57 @@ +Konfiguracja Composera +====================== + +Po zainstalowaniu szablonu projektu dobrze jest zmodyfikować domyślny plik `composer.json`, znajdujący się w głównym +folderze: + +```json +{ + "name": "kartik-v/yii2-app-practical-a", + "description": "Yii 2 Practical-A Project Template", + "keywords": ["yii2", "framework", "practical", "project template"], + "homepage": "http://www.yiiframework.com/", + "type": "project", + "license": "BSD-3-Clause", + "support": { + "issues": "https://github.com/yiisoft/yii2/issues?state=open", + "forum": "http://www.yiiframework.com/forum/", + "wiki": "http://www.yiiframework.com/wiki/", + "irc": "irc://irc.freenode.net/yii", + "source": "https://github.com/yiisoft/yii2" + }, + "minimum-stability": "dev", + "require": { + "php": ">=5.4.0", + "yiisoft/yii2": "~2.0.6", + "yiisoft/yii2-bootstrap": "~2.0.0", + "yiisoft/yii2-swiftmailer": "~2.0.0" + }, + "require-dev": { + "yiisoft/yii2-debug": "~2.0.0", + "yiisoft/yii2-gii": "~2.0.0", + "yiisoft/yii2-faker": "~2.0.0", + + "codeception/base": "^2.2.3", + "codeception/verify": "~0.3.1" + }, + "config": { + "process-timeout": 1800 + }, + "extra": { + "asset-installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } + } +} +``` + +Zacznijmy od podstawowych informacji. Zmień `name` (nazwę), `description` (opis), `keywords` (słowa kluczowe), +`homepage` (stronę domową) i `support` (adresy serwisów wsparcia projektu) na odpowiednie dla Twojego projektu. + +Teraz czas na interesującą część - w sekcji `require` możesz dodać więcej pakietów zależności, których wymaga Twoja +aplikacja. Pakiety te są pobierane poprzez serwis [packagist.org](https://packagist.org/) - zerknij na jego zasoby +w poszukiwaniu przydatnego kodu. + +Po aktualizacji pliku `composer.json` możesz uruchomić komendę `composer update --prefer-dist` - nowe pakiety zostaną +pobrane i zainstalowane i będą od razu gotowe do użycia. Autoładowanie klas jest obsługiwane automatycznie. diff --git a/docs/guide-pl/start-installation.md b/docs/guide-pl/start-installation.md new file mode 100644 index 0000000..0415e93 --- /dev/null +++ b/docs/guide-pl/start-installation.md @@ -0,0 +1,295 @@ +Instalacja +========== + +## Wymagania + +Minimalne wymagania tego szablonu projektu dla serwera to obsługa PHP 5.4.0. + +## Instalacja za pomocą Composera + +Jeśli nie posiadasz zainstalowanego [Composera](http://getcomposer.org/), zapoznaj się najpierw z rozdziałem Przewodnika +[Instalacja Yii](https://github.com/yiisoft/yii2/blob/master/docs/guide-pl/start-installation.md#installing-via-composer). + +Po zainstalowaniu Composera możesz zainstalować aplikację korzystając z poniższych komend: + + composer global require "fxp/composer-asset-plugin:^1.3.1" + composer create-project --prefer-dist kartik-v/yii2-app-practical-a practical-a + +Pierwsza z nich instaluje [plugin assetowy Composera](https://github.com/francoispluchino/composer-asset-plugin/), +pozwalający na zarządzanie pakietami zależności Bowera i NPM z poziomu Composera. Tę komendę trzeba uruchomić tylko raz +przed pierwszą instalacją Yii w systemie. +Druga komenda instaluje zaawansowaną aplikację w folderze o nazwie `practical-a`. Możesz, rzecz jasna, wybrać +dowolną inną nazwę. + +## Instalacja z pliku archiwum + +Wypakuj plik archiwum pobrany ze strony [yiiframework.com](http://www.yiiframework.com/download/) do folderu `practical`, +znajdującego się bezpośrednio w głównym folderze serwera Web. + +Następnie przejdź do instrukcji w sekcji poniżej. + + +## Przygotowanie aplikacji + +Po zainstalowaniu aplikacji konieczne jest wykonanie poniższych kroków, aby ją poprawnie zainicjalizować. Należy to +zrobić raz na każdym nowym środowisku. + +1. Otwórz terminal konsoli, uruchom komendę `init` i wybierz `dev` dla środowiska deweloperskiego (lub `prod` dla produkcyjnego). + + ``` + /path/to/php-bin/php /path/to/practical-a/init + ``` + + W przypadku zautomatyzowanego procesu z użyciem skryptu, możesz uruchomić `init` w trybie nieinteraktywnym. + + ``` + /path/to/php-bin/php /path/to/practical-a/init --env=Production --overwrite=All + ``` + +2. Stwórz nową bazę danych i zmodyfikuj odpowiednio jej dane w kluczu `components['db']` w pliku `common/config/main-local.php`. + +3. Uruchom migrację w terminalu konsoli za pomocą komendy `/path/to/php-bin/php /path/to/practical-a/yii migrate`. + +4. Ustaw docelowe foldery serwera Web: + + - dla front-endu `/path/to/practical-a/` z użyciem adresu URL `http://frontend.dev/` + - dla back-endu `/path/to/practical-a/backend/web/` z użyciem adresu URL `http://backend.dev/` + + W przypadku serwera Apache konfiguracja może wyglądać następująco: + + ```apache + + ServerName frontend.dev + DocumentRoot "/path/to/practical-a/frontend/" + + + # uruchom mod_rewrite dla obslugi 'ladnych' adresow URL + RewriteEngine on + # jesli folder lub plik istnieje, po prostu wywolaj go + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + # w pozostalych przypadkach przekieruj na index.php + RewriteRule . index.php + + # ustaw index.php jako plik indeksowy + DirectoryIndex index.php + + # ...pozostale ustawienia... + # Apache 2.4 + Require all granted + + ## Apache 2.2 + # Order allow,deny + # Allow from all + + + + + ServerName backend.dev + DocumentRoot "/path/to/practical-a/backend/web/" + + + # uruchom mod_rewrite dla obslugi 'ladnych' adresow URL + RewriteEngine on + # jesli folder lub plik istnieje, po prostu wywolaj go + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + # w pozostalych przypadkach przekieruj na index.php + RewriteRule . index.php + + # ustaw index.php jako plik indeksowy + DirectoryIndex index.php + + # ...pozostale ustawienia... + # Apache 2.4 + Require all granted + + ## Apache 2.2 + # Order allow,deny + # Allow from all + + + ``` + + W przypadku serwera nginx: + + ```nginx + server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## nasluchuj dla ipv4 + #listen [::]:80 default_server ipv6only=on; ## nasluchuj dla ipv6 + + server_name frontend.dev; + root /path/to/practical-a/frontend/; + index index.php; + + access_log /path/to/practical-a/log/frontend-access.log; + error_log /path/to/practical-a/log/frontend-error.log; + + location / { + # przekieruj wszystko, co nie jest rzeczywistym plikiem, na index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # odkomentuj ponizsze, aby uniknac przetwarzania wywolan nieistniejacych statycznych plikow przez Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + # zablokuj wywolywanie plikow php w folderze /assets + location ~ ^/assets/.*\.php$ { + deny all; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php5-fpm.sock; + try_files $uri =404; + } + + location ~* /\. { + deny all; + } + } + + server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## nasluchuj dla ipv4 + #listen [::]:80 default_server ipv6only=on; ## nasluchuj dla ipv6 + + server_name backend.dev; + root /path/to/practical-a/backend/web/; + index index.php; + + access_log /path/to/practical-a/log/backend-access.log; + error_log /path/to/practical-a/log/backend-error.log; + + location / { + # przekieruj wszystko, co nie jest rzeczywistym plikiem, na index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # odkomentuj ponizsze, aby uniknac przetwarzania wywolan nieistniejacych statycznych plikow przez Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + # zablokuj wywolywanie plikow php w folderze /assets + location ~ ^/assets/.*\.php$ { + deny all; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php5-fpm.sock; + try_files $uri =404; + } + + location ~* /\. { + deny all; + } + } + ``` + +5. Zmodyfikuj plik hostów, aby wskazać domenę na serwerze. + + - Windows: `c:\Windows\System32\Drivers\etc\hosts` + - Linux: `/etc/hosts` + + Dodaj poniżesz linie: + + ``` + 127.0.0.1 frontend.dev + 127.0.0.1 backend.dev + ``` + +Aby zalogować się do aplikacji, najpierw musisz się zarejestrować używając dowolnego adresu email, nazwy użytkwnika +i hasła. Po udanej rejestracji możesz się zalogować używając podanych danych. + + +> Note: jeśli chcesz używać zaawansowanego szablonu w pojedynczej domenie (gdzie `/` wskazuje na front-end, a `/admin` +> na back-end), zapoznaj się z rozdziałem +> [Korzystanie z zaawansowanego szablonu projektu w środowisku współdzielonym](topic-shared-hosting.md). + +## Instalacja przy użyciu Vagrant + +Poniższy sposób jest najłatwiejszy, ale za to długi (ok. 20 minut). + +**Ten sposób nie wymaga instalowania odpowiedniego oprogramowania (tj. serwera Web, PHP, MySQL itp.)** - po prostu +wykonuj kolejne kroki! + +#### Instrukcje dla użytkowników Linux/Unix + +1. Zainstaluj [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. Zainstaluj [Vagrant](https://www.vagrantup.com/downloads.html) +3. Utwórz [osobisty token API](https://github.com/blog/1509-personal-api-tokens) w serwisie GitHub +4. Przygotuj projekt: + + ```bash + git clone https://github.com/kartik-v/yii2-app-practical-a.git + cd yii2-app-practical-a/vagrant/config + cp vagrant-local.example.yml vagrant-local.yml + ``` + +5. Umieść swój osobisty token API GitHub w `vagrant-local.yml` +6. Zmień folder na główny folder projektu: + + ```bash + cd yii2-app-practical-a + ``` + +7. Uruchom komendy: + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + +To wszystko. Teraz tylko musisz poczekać na zakończenie procesu! Po wszystkim możesz przejść do lokalnego projektu za +pomocą adresów URL: +* front-end: http://y2aa-frontend.dev +* back-end: http://y2aa-backend.dev + +#### Instrukcje dla użytkowników Windows + +1. Zainstaluj [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. Zainstaluj [Vagrant](https://www.vagrantup.com/downloads.html) +3. Zrestartuj system +4. Utwórz [osobisty token API](https://github.com/blog/1509-personal-api-tokens) w serwisie GitHub +5. Przygotuj projekt: + * pobierz repozytorium [yii2-app-practical-a](https://github.com/kartik-v/yii2-app-practical-a/archive/master.zip) + * rozpakuj je + * przejdź do folderu `yii2-app-practical-a-master/vagrant/config` + * skopiuj zawartość pliku `vagrant-local.example.yml` do `vagrant-local.yml` + +6. Umieść swój osobisty token API GitHub w `vagrant-local.yml` +7. Dodaj poniższe linie do [pliku hostów](https://en.wikipedia.org/wiki/Hosts_(file)): + + ``` + 192.168.83.137 y2aa-frontend.dev + 192.168.83.137 y2aa-backend.dev + ``` + +8. Otwórz terminal (`cmd.exe`), **zmień folder na folder główny projektu** i uruchom komendy: + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + + (Przeczytaj [tutaj](http://www.wikihow.com/Change-Directories-in-Command-Prompt), w jaki sposób zmienić foldery w terminalu konsoli) + +To wszystko. Teraz tylko musisz poczekać na zakończenie procesu! Po wszystkim możesz przejść do lokalnego projektu za +pomocą adresów URL: +* front-end: http://y2aa-frontend.dev +* back-end: http://y2aa-backend.dev diff --git a/docs/guide-pl/start-testing.md b/docs/guide-pl/start-testing.md new file mode 100644 index 0000000..fd0d04f --- /dev/null +++ b/docs/guide-pl/start-testing.md @@ -0,0 +1,117 @@ +Uruchamianie testów +=================== + +Zaawansowana aplikacji Yii 2 korzysta z Codeception jako głównego frameworka testowego. +Kilka przygotowanych przykładowych testów można znaleźć w folderze `tests` w `frontend`, `backend` i `common`. +Poniżej opisana procedura zakłada, że aplikacja została zainicjowana dla środowiska `dev`. W przypadku testowania +środowiska `Production` należy ręcznie skopiować pliki `yii_test` i `yii_test.bat` z folderu `environments/dev` do +głównego folderu projektu. +Proces testowania wymaga **dodatkowej bazy danych**, która będzie czyszczona pomiędzy poszczególnymi testami. +Stwórz bazę danych MySQL o nazwie `yii2practical_test` (zgodnie z konfigurację pliku `common/config/test.php`) i uruchom: + +``` +./yii_test migrate +``` + +Zbuduj pakiet testowy: + +``` +vendor/bin/codecept build +``` + +Teraz wszystkie przykładowe testy można uruchomić za pomocą: + +``` +vendor/bin/codecept run +``` + +Rezultat będzie podobny do poniższego: + +![](images/tests.png) + +Zalecane jest ciągłe aktualizowanie swoich testów. W przypadku, gdy klasa lub funkcjonalność jest usuwana, odpowiadające +jej testy również powinny być skasowane. +Testy powinno się przeprowadzać regularnie, a najlepiej jest przygotować do tego celu serwer Ciągłej Integracji. + +Przeczytaj artykuł [Yii 2 Framework Case Study](http://codeception.com/for/yii), aby zapoznać się z konfiguracją +Codeception dla swojej aplikacji. + +### Część Common + +Testy dla klas folderu common umieszczone są w `common/tests`. W tym szablonie przygotowane zostały jedynie testy +`jednostkowe`. +Uruchomisz je za pomocą: + +``` +vendor/bin/codecept run -- -c common +``` + +Opcja `-c` pozwala na ustawienie ścieżki do pliku konfiguracyjnego `codeception.yml`. + +Testy `jednostkowe` pakietu (umieszczone w `common/tests/unit`) mogą korzystać z funkcjonalności frameworka Yii: +`Yii::$app`, Active Record, fixtures, itp. Jest to możliwe dzięki modułowi `Yii2` dodanemu w konfiguracji +`common/tests/unit.suite.yml` (moduł można wyłączyć, aby przeprowadzać testy w izolacji od głównego frameworka). + + +### Część Frontend + +Pakiet testowy części Frontend składa się z testów jednostkowych, funkcjonalnych i akceptacyjnych. +Uruchomisz je za pomocą: + +``` +vendor/bin/codecept run -- -c frontend +``` + +Opis poszczególnych pakietów: + +* `unit` ⇒ klasy związane jedynie z aplikacją front-end. +* `functional` ⇒ wewnętrzne żądania i odpowiedzi aplikacji (bez serwera web). +* `acceptance` ⇒ aplikacja web, interfejs użytkownika i interakcje z użyciem JavaScript w prawdziwej przeglądarce. + +Domyślnie testy akceptacyjne są wyłączone. Poniżej znajdziesz instrukcję ich uruchamiania: + +#### Uruchamianie testów akceptacyjnych + +Aby przeprowadzić testy akceptacyjne, wykonaj następujące kroki: + +1. Zmień nazwę pliku `frontend/tests/acceptance.suite.yml.example` na `frontend/tests/acceptance.suite.yml`, aby włączyć konfigurację pakietu + +2. Zamień pakiet `codeception/base` w pliku `composer.json` na `codeception/codeception`, aby zainstalować pełną wersję Codeception + +3. Zaktualizuj zależności używając Composera + + ``` + composer update + ``` + +4. Wygeneruj automatycznie nowe pomocnicze klasy dla testów akceptacyjnych: + + ``` + vendor/bin/codecept build -- -c frontend + ``` + +5. Pobierz [Serwer Selenium](http://www.seleniumhq.org/download/) i uruchom go: + + ``` + java -jar ~/selenium-server-standalone-x.xx.x.jar + ``` + +6. Uruchom serwer web: + + ``` + php -S 127.0.0.1:8080 -t frontend + ``` + +7. Teraz już możesz uruchomić wszystkie dostępne testy + + ``` + vendor/bin/codecept run acceptance -- -c frontend + ``` + +## Część Backend + +Aplikacja back-end zawiera testy jednostkowe i funkcjonalne. Uruchomisz je za pomocą: + +``` +vendor/bin/codecept run -- -c backend +``` diff --git a/docs/guide-pl/structure-applications.md b/docs/guide-pl/structure-applications.md new file mode 100644 index 0000000..3a2f413 --- /dev/null +++ b/docs/guide-pl/structure-applications.md @@ -0,0 +1,15 @@ +Aplikacje +========= + +W zaawansowanym szablonie znajdują się trzy aplikacje: front-end, back-end i konsola. Front-end to część, którą +zwyczajowo prezentuje się użytkownikowi końcowemu, właściwy projekt. Back-end to panel administracyjny, statystyki, +analiza i podobne funkcjonalności. Konsola jest zwykle używana do obsługi zadań Crona i niskopoziomowego zarządzania +serwerem. Dodatkowo wykorzystywana jest w trakcie inicjalizowania aplikacji oraz obsługi migracji i assetów. + +W szablonie znajduje się również folder `common`, zawierający pliki używane przez więcej niż jedną z aplikacji. +Przykładowo model `User`. + +Zarówno front-end jak i back-end to aplikacje web i dlatego obie zawierają folder `web`. Jest to folder docelowy, na +który powinna wskazywać domena serwera web. + +Każda z aplikacji ma własną przestrzeń nazw i alias odpowiadający swojej nazwie. To samo dotyczy folderu common. diff --git a/docs/guide-pl/structure-directories.md b/docs/guide-pl/structure-directories.md new file mode 100644 index 0000000..752bcf6 --- /dev/null +++ b/docs/guide-pl/structure-directories.md @@ -0,0 +1,24 @@ +Foldery +======= + +Główny folder zawiera następujące podfoldery: + +- `backend` - [aplikacja web back-end](structure-applications.md). +- `common` - [pliki wspólne dla wszystkich aplikacji](structure-applications.md). +- `console` - [aplikacja konsoli](structure-applications.md). +- `environments` - [konfiguracje środowisk](structure-environments.md). +- `frontend` - [aplikacja web front-end](structure-applications.md). + +Folder główny zawiera zestaw plików. + +- `.gitignore` zawiera listę folderów ignorowanych przez system wersjonowania git. Jeśli chcesz, aby coś nie zostało + zapisane w plikach źródłowych repozytorium, dodaj to w tym miejscu. +- `composer.json` - plik konfiguracyjny Composera opisany w rozdziale [Konfiguracja Composera](start-composer.md). +- `init` - skrypt inicjalizujący opisany w rozdziale [Konfiguracja i środowiska](structure-environments.md). +- `init.bat` - ten sam skrypt dla systemu Windows. +- `LICENSE.md` - informacje o licencji. Umieść tutaj licencję odpowiednią dla swojego projektu (zwłaszcza w przypadku projektu typu open-source). +- `README.md` - podstawowe informacje na temat instalowania szablonu. Pomyśl o zamienieniu ich na informacje dotyczące + swojego projektu i jego instalacji. +- `requirements.php` - test spełnienia wymagań Yii. +- `yii` - plik wejściowy aplikacji konsoli. +- `yii.bat` - ten sam plik dla systemu Windows. diff --git a/docs/guide-pl/structure-environments.md b/docs/guide-pl/structure-environments.md new file mode 100644 index 0000000..8d3f71a --- /dev/null +++ b/docs/guide-pl/structure-environments.md @@ -0,0 +1,44 @@ +Konfiguracja i środowiska +========================= + +Typowe podejście do konfigurowania projektu stawia przed deweloperami wiele problemów: + +- Każdy programista w grupie ustala swoje własne opcje konfiguracyjne. Zapisywanie takiej konfiguracji może wpływać na resztę grupy. +- Hasła baz produkcyjnych i klucze API nie powinny znajdować się w repozytorium. +- Projekt wydawany jest zwykle na wielu środowiskach serwerowych: deweloperskim, testowym, produkcyjnym. Każde z nich powinno mieć oddzielną konfigurację. +- Ustalanie wszystkich opcji konfiguracyjnych dla każdego przypadku z osobna jest procesem żmudnym i wysoce powtarzalnym i zajmuje zbyt wiele czasu. + +Yii, dzięki prostej koncepcji środowisk, zapewnia rozwiązanie powyższych problemów. Każde środowisko jest reprezentowane +przez zestaw plików w folderze `environments`. Środowisko jest inicjalizowane za pomocą komendy `init`, która kopiuje +wszystko z folderu środowiskowego do głównego folderu, w którym znajdują się aplikacje. + +Domyślnie zdefiniowane są dwa środowiska: `dev` i `prod`. Pierwsze jest środowiskiem rozwojowym, skonfigurowanym +z wszystkim narzędziami deweloperskimi i włączonym modułem debugowania. Drugie przeznaczone jest do wydania projektu +na serwerze i powyższe opcje są tam wyłączone. + +Zwykle środowisko zawiera pliki skryptów wejściowych aplikacji jak np. `index.php` oraz pliki konfiguracyjne +z przyrostkiem `-local.php`, które przechowują osobiste ustawienia programistów (zazwyczaj dla środowiska `dev`) lub też +konkretne ustawienia serwerowe. Dla przykładu, połączenie do produkcyjnej bazy danych mogłoby znajdować się w pliku +konfiguracyjnym `-local.php` środowiska `prod`. +Takie lokalne konfiguracje są dodawane do pliku `.gitignore` i nie umieszczane nigdy w źródłowym repozytorium kodu. + +Aby uniknąć duplikowania ustawień, pliki konfiguracyjne nadpisują się. Przykładowo, front-end odczytuje konfiguracje +w następującej kolejności: + +- `common/config/main.php` +- `common/config/main-local.php` +- `frontend/config/main.php` +- `frontend/config/main-local.php` + +Parametry są odczytywane w takiej kolejności: + +- `common/config/params.php` +- `common/config/params-local.php` +- `frontend/config/params.php` +- `frontend/config/params-local.php` + +Kolejny plik konfiguracyjny nadpisuje poprzednika. + +Poniżej przedstawiony jest pełny schemat: + +![Advanced application configs](images/advanced-app-configs.png) diff --git a/docs/guide-pl/structure-path-aliases.md b/docs/guide-pl/structure-path-aliases.md new file mode 100644 index 0000000..d08db4f --- /dev/null +++ b/docs/guide-pl/structure-path-aliases.md @@ -0,0 +1,18 @@ +Predefiniowane aliasy +===================== + +- `@yii` - folder frameworka. +- `@app` - bazowa ścieżka aktualnie uruchomionej aplikacji. +- `@common` - folder common. +- `@frontend` - folder aplikacji web front-end. +- `@backend` - folder aplikacji web back-end. +- `@console` - folder konsoli. +- `@runtime` - folder runtime (roboczy) aktualnie uruchomionej aplikacji. +- `@vendor` - folder vendor (dostawców) Composera. +- `@bower` - folder vendor (dostawców) zawierający [pakiety bower](http://bower.io/). +- `@npm` - folder vendor (dostawców) zawierający [pakiety npm](https://www.npmjs.org/). +- `@web` - bazowy adres URL aktualnie uruchomionej aplikacji. +- `@webroot` - główny folder web aktualnie uruchomionej aplikacji. + +Aliasy odpowiadające strukturze folderów zaawansowanej aplikacji (`@common`, `@frontend`, `@backend` i `@console`) są +zdefiniowane w pliku `common/config/bootstrap.php`. diff --git a/docs/guide-pl/topic-adding-more-apps.md b/docs/guide-pl/topic-adding-more-apps.md new file mode 100644 index 0000000..0990e3a --- /dev/null +++ b/docs/guide-pl/topic-adding-more-apps.md @@ -0,0 +1,55 @@ +Dodawanie kolejnych aplikacji +============================= + +Powszechnie spotykane rozdzielenie części front-endowej od back-endowej czasem nie jest wystarczające. Dla przykładu, +być może wymagane jest wydzielenie jeszcze jednej aplikacji, dla, powiedzmy, bloga. Aby to uzyskać: + +1. Skopiuj folder `frontend` do folderu `blog`, `environments/dev/frontend` do `environments/dev/blog` + i `environments/prod/frontend` do `environments/prod/blog`. +2. Popraw przestrzenie nazw i ścieżki tak, aby zaczynały się od `blog` zamiast `frontend`. +3. W pliku `common\config\bootstrap.php` dodaj `Yii::setAlias('blog', dirname(dirname(__DIR__)) . '/blog');`. +4. Zmodyfikuj zawartość pliku `environments/index.php` (dodane linie zostały oznaczone `+`): + +```php +return [ + 'Development' => [ + 'path' => 'dev', + 'setWritable' => [ + 'backend/runtime', + 'backend/web/assets', + 'frontend/runtime', + 'frontend/assets', ++ 'blog/runtime', ++ 'blog/web/assets', + ], + 'setExecutable' => [ + 'yii', + 'yii_test', + ], + 'setCookieValidationKey' => [ + 'backend/config/main-local.php', + 'frontend/config/main-local.php', ++ 'blog/config/main-local.php', + ], + ], + 'Production' => [ + 'path' => 'prod', + 'setWritable' => [ + 'backend/runtime', + 'backend/web/assets', + 'frontend/runtime', + 'frontend/assets', ++ 'blog/runtime', ++ 'blog/web/assets', + ], + 'setExecutable' => [ + 'yii', + ], + 'setCookieValidationKey' => [ + 'backend/config/main-local.php', + 'frontend/config/main-local.php', ++ 'blog/config/main-local.php', + ], + ], +]; +``` diff --git a/docs/guide-pl/topic-link-backend-frontend.md b/docs/guide-pl/topic-link-backend-frontend.md new file mode 100644 index 0000000..6f7a761 --- /dev/null +++ b/docs/guide-pl/topic-link-backend-frontend.md @@ -0,0 +1,45 @@ +Tworzenie linków pomiędzy back-endem i front-endem +================================================== + +Często spotykanym wymaganiem jest utworzenie linków pomiędzy aplikacją back-endową a front-endową. Ponieważ front-end +może posiadać oddzielny komponent menadżera adresów URL, musisz skopiować jego ustawienia (pod inną nazwą): + +```php +return [ + 'components' => [ + 'urlManager' => [ + // w tym miejscu podaj konfigurację menadżera URL dla aplikacji back-end + ], + 'urlManagerFrontend' => [ + // a tutaj konfigurację menadżera URL dla front-end + ], + + ], +]; +``` + +Od tej pory możesz podać adres URL wskazujący na front-end w poniższy sposób: + +```php +echo Yii::$app->urlManagerFrontend->createAbsoluteUrl(...); +``` + +Aby nie podawać podwójnie front-endowych zasad menadżera, możesz umieścić je w osobnym pliku `urls.php`: + +```php +return [ + // ... + 'components' => [ + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => require 'urls.php', + ], + // ... + + ], + // ... +]; +``` + +Dzięki temu wystarczy, że dołączysz go również w konfiguracji `urlManagerFrontend`. diff --git a/docs/guide-pl/topic-shared-hosting.md b/docs/guide-pl/topic-shared-hosting.md new file mode 100644 index 0000000..3469b25 --- /dev/null +++ b/docs/guide-pl/topic-shared-hosting.md @@ -0,0 +1,67 @@ +Korzystanie z zaawansowanego szablonu projektu w środowisku współdzielonym +========================================================================== + +Wdrożenie zaawansowanego szablonu projektu w środowisku współdzielonym jest nieco bardziej skomplikowane niż w przypadku +podstawowego szablonu, ponieważ zawiera on dwa foldery web (foldery, na które wskazuje adres serwisu), co nie jest +wspierane przez serwery takich środowisk. Konieczna jest modyfikacja struktury folderów tak, aby adresem URL front-endu +stał się `http://site.local`, a back-endu `http://site.local/admin`. + +### Przenieś skrypty wejściowe do jednego folderu web + +Przede wszystkim konieczny jest jeden folder web. Stwórz nowy folder i nazwij go tak, jak wymaga tego Twój hosting, +np. `www` lub też `public_html`, czy coś podobnego. Następnie stwórz poniższą strukturę folderów, gdzie `www` jest +nazwą hostingowego folderu web, dodanego przed chwilą (zmień ją, jeśli Twój hosting wymaga innej): + +``` +www + admin +backend +common +console +environments +frontend +... +``` + +`www` będzie naszym nowym folderem front-endowym, zatem przenieś do niego zawartość `frontend`. Zawartość folderu +`backend/web` przenieś za to do `www/admin`. W obu przypadkach będziesz musiał poprawić ścieżki podane w `index.php` +i `index-test.php`. + +### Dopasuj ustawienia sesji i ciasteczek + +Standardowo back-end i front-end stworzone zostały do pracy na różnych domenach. Po przeniesieniu ich do tej samej +domeny, aplikacje będą współdzielić ciasteczka, co doprowadzi do konfliktu. Aby temu przeciwdziałać, zmodyfikuj konfigurację +aplikacji back-end w pliku `backend/config/main.php` następująco: + +```php +'components' => [ + 'request' => [ + 'csrfParam' => '_csrf-backend', + 'csrfCookie' => [ + 'httpOnly' => true, + 'path' => '/admin', + ], + ], + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + 'identityCookie' => [ + 'name' => '_identity-backend', + 'path' => '/admin', + 'httpOnly' => true, + ], + ], + 'session' => [ + // to jest nazwa ciasteczka sesji używanego do logowania się na back-endzie + 'name' => 'practical-backend', + 'cookieParams' => [ + 'path' => '/admin', + ], + ], +], +``` + +### Alternatywne ustawienia + +Jeśli podany tutaj sposób nie działa na Twoim serwerze, wypróbuj +[instrukcję, którą stworzył Oleg Belostotskiy](https://github.com/mickgeek/yii2-practical-one-domain-config). diff --git a/docs/guide-pt-BR/README.md b/docs/guide-pt-BR/README.md new file mode 100644 index 0000000..d5746b1 --- /dev/null +++ b/docs/guide-pt-BR/README.md @@ -0,0 +1,34 @@ +Template Avançado de Projetos Yii 2 +=================================== + +O template Avançado de Projetos Yii 2 é uma estrutura de aplicação [Yii 2](http://www.yiiframework.com/) mais adequada +para desenvolvimento de projetos Web complexos com múltiplas camadas. + +O template inclui três camadas: frontend, backend, e console, sendo cada uma delas uma aplicação Yii diferente. + +O template é projetado para funcionar em um ambiente de desenvolvimento em equipe e suporta +deploy da aplicação em diferentes ambientes. + +Ele também vai um pouco além em relação a funcionalidades e provê banco de dados necessário, +registro de usuários e recuperação de senha sem necessidade de configuração adicional. + +Introdução +---------- + +* [Instalação](start-installation.md) +* [Diferença do template de projetos básico para o avançado](start-comparison.md) +* [Configurando o Composer](start-composer.md) + +Estrutura +--------- + +* [Diretórios](structure-directories.md) +* [Aliases predefinidos](structure-path-aliases.md) +* [Aplicações](structure-applications.md) +* [Configurações e ambientes](structure-environments.md) + +Tópicos adicionais +------------------ + +* [Criando links do backend para o frontend](topic-link-backend-frontend.md) +* [Adicionando mais aplicações](topic-adding-more-apps.md) \ No newline at end of file diff --git a/docs/guide-pt-BR/images/advanced-app-configs.graphml b/docs/guide-pt-BR/images/advanced-app-configs.graphml new file mode 100644 index 0000000..05a053e --- /dev/null +++ b/docs/guide-pt-BR/images/advanced-app-configs.graphml @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + console + + + + + + + + + + Folder 4 + + + + + + + + + + + + + + + + + + + + backend + + + + + + + + + + Folder 3 + + + + + + + + + + + + + + + + + index + + + + + + + + + + + + + + + + + + + + frontend + + + + + + + + + + Folder 1 + + + + + + + + + + + + + + + + params + + + + + + + + + + + + + + + + + params-local + + + + + + + + + + + + + + + + + main + + + + + + + + + + + + + + + + + main-local + + + + + + + + + + + + + + + + + + + aliases + + + + + + + + + + + + + + + + + + + + common + + + + + + + + + + Folder 2 + + + + + + + + + + + + + + + + params-local + + + + + + + + + + + + + + + + + main-local + + + + + + + + + + + + + + + + + params + + + + + + + + + + + + + + + + + main + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guide-pt-BR/images/advanced-app-configs.png b/docs/guide-pt-BR/images/advanced-app-configs.png new file mode 100644 index 0000000..daa9a6f Binary files /dev/null and b/docs/guide-pt-BR/images/advanced-app-configs.png differ diff --git a/docs/guide-pt-BR/start-comparison.md b/docs/guide-pt-BR/start-comparison.md new file mode 100644 index 0000000..f26a32a --- /dev/null +++ b/docs/guide-pt-BR/start-comparison.md @@ -0,0 +1,19 @@ +Comparativo +=========== + +A tabela a seguir faz um comparativo entre o template de projetos básico e avançado: + +| Funcionalidade | Básico | Avançado | +|---|:---:|:---:| +| Estrutura do projeto | ✓ | ✓ | +| Controller do site | ✓ | ✓ | +| Login/logout de usuários | ✓ | ✓ | +| Formulários | ✓ | ✓ | +| Conexão com BD | ✓ | ✓ | +| Comando de console | ✓ | ✓ | +| Asset bundle | ✓ | ✓ | +| Testes com Codeception | ✓ | ✓ | +| Twitter Bootstrap | ✓ | ✓ | +| Aplicações front e back-end | | ✓ | +| Model de usuário pronto para uso | | ✓ | +| Registro de usuários e recuperação de senha | | ✓ | \ No newline at end of file diff --git a/docs/guide-pt-BR/start-composer.md b/docs/guide-pt-BR/start-composer.md new file mode 100644 index 0000000..9257fe6 --- /dev/null +++ b/docs/guide-pt-BR/start-composer.md @@ -0,0 +1,58 @@ +Configurando o Composer +======================= + +Após a instalação do template de projetos, é uma boa ideia ajustar o `composer.json` padrão, que pode ser encontrado +no diretório raiz: + + +```json +{ + "name": "kartik-v/yii2-app-practical-a", + "description": "Yii 2 Practical-A Project Template", + "keywords": ["yii2", "framework", "practical", "project template"], + "homepage": "http://www.yiiframework.com/", + "type": "project", + "license": "BSD-3-Clause", + "support": { + "issues": "https://github.com/yiisoft/yii2/issues?state=open", + "forum": "http://www.yiiframework.com/forum/", + "wiki": "http://www.yiiframework.com/wiki/", + "irc": "irc://irc.freenode.net/yii", + "source": "https://github.com/yiisoft/yii2" + }, + "minimum-stability": "dev", + "require": { + "php": ">=5.4.0", + "yiisoft/yii2": "~2.0.6", + "yiisoft/yii2-bootstrap": "~2.0.0", + "yiisoft/yii2-swiftmailer": "~2.0.0" + }, + "require-dev": { + "yiisoft/yii2-debug": "~2.0.0", + "yiisoft/yii2-gii": "~2.0.0", + "yiisoft/yii2-faker": "~2.0.0", + + "codeception/base": "^2.2.3", + "codeception/verify": "~0.3.1" + }, + "config": { + "process-timeout": 1800 + }, + "extra": { + "asset-installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } + } +} +``` + +Primeiro vamos alterar as informações básicas. Modifique `name`, `description`, `keywords`, `homepage` e `support` +para corresponder as informações do seu projeto. + +Agora a parte interessante. Você pode adicionar mais pacotes que a sua aplicação necessita, na seção `require`. +Todos os pacotes são provindos do [packagist.org](https://packagist.org/) então, sinta-se a vontade para procurar +pacotes úteis no website. + +Após alterar seu `composer.json` você pode executar o comando `composer update --prefer-dist`, aguardar o download e +instalação dos pacotes e depois utilizá-los. Todas as classes são carregadas automaticamente através de autoloading. \ No newline at end of file diff --git a/docs/guide-pt-BR/start-installation.md b/docs/guide-pt-BR/start-installation.md new file mode 100644 index 0000000..9503b93 --- /dev/null +++ b/docs/guide-pt-BR/start-installation.md @@ -0,0 +1,269 @@ +Instalação +========== + +## Pré-Requisitos + +O requisito mínimo deste template de projetos é que seu servidor Web suporte PHP 5.4.0. + +## Instalação utilizando Composer + +Caso você não tenha o [Composer](http://getcomposer.org/) instalado, siga as instruções na seção [Instalando o Yii](https://github.com/yiisoft/yii2/blob/master/docs/guide-pt-BR/start-installation.md#instalando-via-composer-) +do guia definitivo para Yii 2.0 para instala-lo. + +Com o Composer instalado, você pode então instalar o template de projetos usando os seguintes comandos: + + composer global require "fxp/composer-asset-plugin:^1.3.1" + composer create-project --prefer-dist kartik-v/yii2-app-practical-a practical-a + +O primeiro comando instala o [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) que permite +o gerenciamento de dependências de pacotes bower e npm através do Composer. Este comando só precisa ser executado uma vez, no momento da instalação. +O segundo comando instala o template avançado de projetos no diretório `practical-a`. +Você pode escolher um diretório diferente se desejar. + +## Instalação a partir de um arquivo + +Descompacte o arquivo baixado de [yiiframework.com](http://www.yiiframework.com/download/) para +um diretório com nome de `practical` no diretório raiz do servidor Web. + +Então siga as instruções presentes na próxima subseção. + + +## Preparando a aplicação + +Após instalar o template avançado de projetos, você deve seguir os seguintes passos +para inicializar a aplicação, sendo necessário realizá-los apenas uma vez no momento da instalação. + +1. Abra um terminal de console, execute comando `init` e selecione a opção `dev`. + + ``` + /caminho/para/binario-php/php /caminho/para/aplicacao-yii/init + ``` + + Caso queria realizar a automação do processo por meio de um script, você pode executar o comando `init` em modo não interativo. + + ``` + /caminho/para/binario-php/php /caminho/para/aplicacao-yii/init --env=Production --overwrite=All + ``` + +2. Crie um novo banco de dados e ajuste a configuração `components['db']` em `common/config/main-local.php` adequadamente. + +3. Abra um terminal de console e aplique as migrações de dados utilizando o comando `/caminho/para/binario-php/php /caminho/para/aplicacao-yii/yii migrate`. + +4. Configure a raiz dos documentos do seu servidor Web: + + - para o frontend `/caminho/para/aplicacao-yii/frontend/` usando URL `http://frontend.dev/` + - para o backend `/caminho/para/aplicacao-yii/backend/web/` usando URL `http://backend.dev/` + + + Exemplo de configuração para servidores Apache + + ```apache + + ServerName frontend.dev + DocumentRoot "/caminho/para/aplicacao-yii/frontend/" + + + # Utilize o mod_rewrite para suporte a URL amigável + RewriteEngine on + # Se um diretório ou arquivo existe, usa a requisição diretamente + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + # Caso contrário, encaminha a requisição para index.php + RewriteRule . index.php + + # usar index.php com arquivo index + DirectoryIndex index.php + + # ...outras configurações... + + + + + ServerName backend.dev + DocumentRoot "/caminho/para/aplicacao-yii/backend/web/" + + + # Utilize o mod_rewrite para suporte a URL amigável + RewriteEngine on + # Se um diretório ou arquivo existe, usa a requisição diretamente + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + # Caso contrário, encaminha a requisição para index.php + RewriteRule . index.php + + # usar index.php com arquivo index + DirectoryIndex index.php + + # ...outras configurações... + + + ``` + + Exemplo de configuração para servidores nginx: + + ```nginx + server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name frontend.dev; + root /caminho/para/aplicacao-yii/frontend/; + index index.php; + + access_log /caminho/para/aplicacao-yii/log/frontend-access.log; + error_log /caminho/para/aplicacao-yii/log/frontend-error.log; + + location / { + # Redireciona tudo que não é um arquivo real para index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # descomente para evitar o processamento de chamadas a arquivos estáticos não existentes pelo Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php5-fpm.sock; + try_files $uri =404; + } + + location ~ /\.(ht|svn|git) { + deny all; + } + } + + server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name backend.dev; + root /caminho/para/aplicacao-yii/backend/web/; + index index.php; + + access_log /caminho/para/aplicacao-yii/log/backend-access.log; + error_log /caminho/para/aplicacao-yii/log/backend-error.log; + + location / { + # Redireciona tudo que não é um arquivo real para index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # descomente para evitar o processamento de chamadas a arquivos estáticos não existentes pelo Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php5-fpm.sock; + try_files $uri =404; + } + + location ~ /\.(ht|svn|git) { + deny all; + } + } + ``` + +5. Altere o arquivo de hosts para apontar o domínio do seu servidor. + + - Windows: `c:\Windows\System32\Drivers\etc\hosts` + - Linux: `/etc/hosts` + + Adicione as seguintes linhas: + + ``` + 127.0.0.1 frontend.dev + 127.0.0.1 backend.dev + ``` + +Para se autenticar na aplicação é necessário que primeiro, você se registre com qualquer um dos seus endereços de e-mail, usuário e senha. +Então, você pode se autenticar na aplicação com o mesmo endereço de e-mail e senha a qualquer momento. + +> PS: caso queira que o template avançado de projetos utilize um único domínio, sendo `/` o frontend e `/admin` o backend, +> consulte as [configurações e documentações por Oleg Belostotskiy](https://github.com/mickgeek/yii2-practical-one-domain-config) (apenas inglês). + +## Instalação utilizando Vagrant + +Esta é a forma mais simples porém, mais demorada (~20 min). + +**Esta forma de instalação não necessita de nenhum software pré-instalado (web-server, PHP, MySQL, etc.)** - basta apenas seguir as etapas! + +#### Manual para usuários Linux/Unix + +1. Instale o [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. Instale o [Vagrant](https://www.vagrantup.com/downloads.html) +3. Crie um [token de API pessoal](https://github.com/blog/1509-personal-api-tokens) do GitHub +4. Prepare o projeto: + + ```bash + git clone https://github.com/kartik-v/yii2-app-practical-a.git + cd yii2-app-practical-a/vagrant/config + cp vagrant-local.example.yml vagrant-local.yml + ``` + +4. Introduza seu token de API pessoal no arquivo `vagrant-local.yml` +5. Entre no diretório raiz do projeto: + + ```bash + cd yii2-app-practical-a + ``` + +5. Execute os comandos: + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + +Isso é tudo. Basta aguardar a conclusão! Após isso você pode acessar o projeto localmente pelas URLs: +* frontend: http://y2aa-frontend.dev +* backend: http://y2aa-backend.dev + +#### Manual para usuários Windows + +1. Instale o [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. Instale o [Vagrant](https://www.vagrantup.com/downloads.html) +3. Reinicie +4. Crie um [token de API pessoal](https://github.com/blog/1509-personal-api-tokens) do GitHub +5. Prepare o projeto: + * faça do download do repositório [yii2-app-practical-a](https://github.com/kartik-v/yii2-app-practical-a/archive/master.zip) + * descompacte o arquivo + * entre no diretório `yii2-app-practical-a-master/vagrant/config` + * copie o arquivo `vagrant-local.example.yml` para `vagrant-local.yml` + +6. Introduza seu token de API pessoal no arquivo `vagrant-local.yml` +7. Adicione as seguintes linhas no [arquivo de hosts](https://pt.wikipedia.org/wiki/Hosts_(arquivo)): + + ``` + 192.168.83.137 y2aa-frontend.dev + 192.168.83.137 y2aa-backend.dev + ``` + +8. Abra o terminal (`cmd.exe`), **entre no diretório raiz do projeto** e execute os comandos: + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + + (Você pode ler [aqui](http://pt.wikihow.com/Alterar-Diret%C3%B3rios-no-Prompt-de-Comandos) como alterar diretórios no prompt de comando) + +Isso é tudo. Basta aguardar a conclusão! Após isso você pode acessar o projeto localmente pelas URLs: +* frontend: http://y2aa-frontend.dev +* backend: http://y2aa-backend.dev + diff --git a/docs/guide-pt-BR/structure-applications.md b/docs/guide-pt-BR/structure-applications.md new file mode 100644 index 0000000..13c19c1 --- /dev/null +++ b/docs/guide-pt-BR/structure-applications.md @@ -0,0 +1,15 @@ +Aplicações +========== + +O template avançado de projetos possui três aplicações: frontend, backend e console. Frontend é, geralmente, o que é +apresentado ao usuário final. Backend é o painel administrativo, e contém dados de análise da aplicação e outras funcionalidades do tipo. +Console é geralmente utilizado para execução de tarefas cron e gerenciamento do servidor. É também utilizado +durante o deploy da aplicação para gerenciar migrações de dados e assets. + +Há também um diretório `common` que contém arquivos não exclusivos e que são utilizados por mais de uma aplicação. +Por exemplo, o model `User`. + +Ambos frontend e backend são aplicações web e contem o diretório `web`. Esta é a raíz dos diretórios acessíveis pela web, o +qual seu servidor deve apontar. + +Cada aplicação possui seu próprio namespace e um alias correspondendo ao seu nome. O mesmo se aplica para o diretório "common". \ No newline at end of file diff --git a/docs/guide-pt-BR/structure-directories.md b/docs/guide-pt-BR/structure-directories.md new file mode 100644 index 0000000..a71060b --- /dev/null +++ b/docs/guide-pt-BR/structure-directories.md @@ -0,0 +1,24 @@ +Diretórios +========== + +O diretório raiz contém os seguintes subdiretórios: + +- `backend` - [aplicação web backend](structure-applications.md). +- `common` - [arquivos comuns para todas as aplicações](structure-applications.md). +- `console` - [aplicação de console](structure-applications.md). +- `environments` - [configurações de ambiente](structure-environments.md). +- `frontend` - [aplicação web frontend](structure-applications.md). + +O diretório raiz contém uma série de arquivos. + +- `.gitignore` contém uma lista de diretórios que deve ser ignorado pelo sistema de versionamento git. Caso você precise que +algo não seja enviado ao repositório, basta adicioná-lo aqui. +- `composer.json` - Configuração do Composer descrito em [Configurando o Composer](start-composer.md). +- `init` - script de inicialização descrito em [Configurações e ambientes](structure-environments.md). +- `init.bat` - script de inicialização para Windows. +- `LICENSE.md` - informações de licença. Adicione os termos de licença aqui. Especialmente se o projeto for de código aberto. +- `README.md` - informações básicas de como instalar o template. Considere substituí-lo com informações sobre seu projeto +e sua instalação. +- `requirements.php` - verificador de requisitos Yii. +- `yii` - inicializador da aplicação de console. +- `yii.bat` - inicializador da aplicação de console para Windows. \ No newline at end of file diff --git a/docs/guide-pt-BR/structure-environments.md b/docs/guide-pt-BR/structure-environments.md new file mode 100644 index 0000000..6a83b21 --- /dev/null +++ b/docs/guide-pt-BR/structure-environments.md @@ -0,0 +1,44 @@ +Configurações e ambientes +========================= + +Existem diversos problemas com a abordagem típica para a configuração: + +- Cada membro da equipe possui suas próprias opções de configurações. Commitar essas configurações irá afetar a configuração de outros membros da equipe. +- Senhas do banco de dados de produção e chaves de API não devem estar presentes no repositório. +- Existem diversos ambientes: desenvolvimento, homologação, produção. Cada um deve possuir sua própria configuração. +- Definir todas as configurações para cada caso é muito repetitivo e é muito custoso para se manter. + +Para resolver estes problemas Yii introduz conceito simples de ambientes. Cada ambiente é representado por uma série +de arquivos presentes no diretório `environments`. O comando `init` é usado para inicializar um ambiente. O papel deste comando +é copiar todo o conteúdo presente no diretório do ambiente para a raíz do projeto onde todas as aplicações residem. + +Por padrão existem dois ambientes: `dev` e `prod`. O primeiro é utilizado para desenvolvimento. Ele possui todas as ferramentas +de desenvolvimento e depuração habilitadas. O segundo é utilizado para deploy de produção. Todas as ferramentas de +desenvolvimento e depuração estão desabilitadas. + +Tipicamente, diretórios de ambiente contém arquivos de inicialização como o `index.php` e arquivos de configuração +com o sufixo de `-local.php`. Estes são ou arquivos de configuração pessoal de membros da equipe que geralmente +estão localizados no diretório `dev` ou configurações específicas de servidor. Por exemplo: configurações de conexão +do banco de dados de produção estaria no arquivo de configuração `-local.php` dentro do diretório de ambiente `prod`. +Os arquivos de configuração local são adicionados ao `.gitignore` e nunca são enviados para o repositório de versionamento de código. + +Para evitar a duplicação de configurações, as mesmas se sobrescrevem. Por exemplo, a aplicação frontend lê as configurações +na seguinte ordem: + +- `common/config/main.php` +- `common/config/main-local.php` +- `frontend/config/main.php` +- `frontend/config/main-local.php` + +Parâmetros são lidos na seguinte ordem: + +- `common/config/params.php` +- `common/config/params-local.php` +- `frontend/config/params.php` +- `frontend/config/params-local.php` + +O arquivo de configuração posterior sobrescreve o anterior. + +Aqui está o esquema completo: + +![Configurações da aplicação avançada](images/advanced-app-configs.png) \ No newline at end of file diff --git a/docs/guide-pt-BR/structure-path-aliases.md b/docs/guide-pt-BR/structure-path-aliases.md new file mode 100644 index 0000000..96d72a8 --- /dev/null +++ b/docs/guide-pt-BR/structure-path-aliases.md @@ -0,0 +1,15 @@ +Aliases de caminho predefinidos +=============================== + +- `@yii` - diretório do framework. +- `@app` - caminho base da aplicação sendo executada. +- `@common` - diretório "common". +- `@frontend` - diretório da aplicação web frontend. +- `@backend` - diretório da aplicação web backend. +- `@console` - diretório "console". +- `@runtime` - diretório "runtime" da aplicação sendo executada. +- `@vendor` - diretório vendor do Composer. +- `@bower` - diretório vendor contendo [pacotes bower](http://bower.io/). +- `@npm` - diretório vendor contendo [pacotes npm](https://www.npmjs.org/). +- `@web` - URL base da aplicação sendo executada. +- `@webroot` - raíz do diretório web da aplicação sendo executada. \ No newline at end of file diff --git a/docs/guide-pt-BR/topic-adding-more-apps.md b/docs/guide-pt-BR/topic-adding-more-apps.md new file mode 100644 index 0000000..2582c31 --- /dev/null +++ b/docs/guide-pt-BR/topic-adding-more-apps.md @@ -0,0 +1,10 @@ +Adicionando mais aplicações +=========================== + +Enquanto a separação entre frontend e backend é comum, a mesma pode não ser o suficiente dependendo da situação. +Você pode necessitar de uma aplicação adicional, por exemplo, um blog. A fim de obtê-lo: + +1. Copie `frontend` para `blog`, `environments/dev/frontend` para `environments/dev/blog` e `environments/prod/frontend` +para `environments/prod/blog`. +2. Ajuste os namespaces e caminhos para iniciarem com `blog` ao invés de `frontend`. +3. Em `common\config\bootstrap.php` adicione `Yii::setAlias('blog', dirname(dirname(__DIR__)) . '/blog');`. \ No newline at end of file diff --git a/docs/guide-pt-BR/topic-link-backend-frontend.md b/docs/guide-pt-BR/topic-link-backend-frontend.md new file mode 100644 index 0000000..ea26132 --- /dev/null +++ b/docs/guide-pt-BR/topic-link-backend-frontend.md @@ -0,0 +1,46 @@ +Criando links do backend para o frontend +======================================== + +Frequentemente é necessário a criação de links da aplicação de backend para a aplicação de frontend. Uma vez que a +aplicação de frontend pode conter suas próprias regras do gerenciador de URL, você deve replicá-las para a aplicação +de backend e criar um componente de gerenciador de URL com um nome diferente: + +```php +return [ + 'components' => [ + 'urlManager' => [ + // configurações normais do gerenciador de URL do backend + ], + 'urlManagerFrontend' => [ + // regras do gerenciador de URL provindas do frontend + ], + + ], +]; +``` + +Tendo configurado o novo componente, você pode criar uma URL apontando para o frontend da seguinte forma: + +```php +echo Yii::$app->urlManagerFrontend->createUrl(...); +``` + +Para evitar copiar e colar as regras do seu frontend, você pode primeiro movê-las para um arquivo `urls.php` separado: + +```php +return [ + // ... + 'components' => [ + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => require 'urls.php', + ], + // ... + + ], + // ... +]; +``` + +E depois incluí-las no componente `urlManagerFrontend` do backend também. \ No newline at end of file diff --git a/docs/guide-zh-CN/README.md b/docs/guide-zh-CN/README.md new file mode 100644 index 0000000..a83e8fc --- /dev/null +++ b/docs/guide-zh-CN/README.md @@ -0,0 +1,33 @@ +Yii 2高级项目模板 +=============== + +Yii 2高级项目模板是一个最基本的 [Yii 2](http://www.yiiframework.com/) 应用程序,用于开发具有多层的复杂Web应用程序。 + +模板包括三个层:前端,后端和控制台,每个都是单独的Yii应用程序。 + +该模板设计用于在团队开发环境中工作。 它支持在不同环境中部署应用程序。 + +它还有一些其他功能,并提供了必要的开箱即用的数据库操作,注册和重置密码等功能。 + +起步 +---- + +* [安装](start-installation.md) +* [与基本项目模板的区别](start-comparison.md) +* [配置Composer](start-composer.md) +* [运行测试](start-testing.md) + +框架结构 +------- + +* [目录](structure-directories.md) +* [预定义路径别名](structure-path-aliases.md) +* [应用程序](structure-applications.md) +* [配置和环境](structure-environments.md) + +其他 +---- + +* [创建从后端到前端的链接](topic-link-backend-frontend.md) +* [添加更多应用程序](topic-adding-more-apps.md) +* [在共享主机上使用高级项目模板](topic-shared-hosting.md) \ No newline at end of file diff --git a/docs/guide-zh-CN/images/advanced-app-configs.graphml b/docs/guide-zh-CN/images/advanced-app-configs.graphml new file mode 100644 index 0000000..05a053e --- /dev/null +++ b/docs/guide-zh-CN/images/advanced-app-configs.graphml @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + console + + + + + + + + + + Folder 4 + + + + + + + + + + + + + + + + + + + + backend + + + + + + + + + + Folder 3 + + + + + + + + + + + + + + + + + index + + + + + + + + + + + + + + + + + + + + frontend + + + + + + + + + + Folder 1 + + + + + + + + + + + + + + + + params + + + + + + + + + + + + + + + + + params-local + + + + + + + + + + + + + + + + + main + + + + + + + + + + + + + + + + + main-local + + + + + + + + + + + + + + + + + + + aliases + + + + + + + + + + + + + + + + + + + + common + + + + + + + + + + Folder 2 + + + + + + + + + + + + + + + + params-local + + + + + + + + + + + + + + + + + main-local + + + + + + + + + + + + + + + + + params + + + + + + + + + + + + + + + + + main + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/guide-zh-CN/images/advanced-app-configs.png b/docs/guide-zh-CN/images/advanced-app-configs.png new file mode 100644 index 0000000..daa9a6f Binary files /dev/null and b/docs/guide-zh-CN/images/advanced-app-configs.png differ diff --git a/docs/guide-zh-CN/images/tests.png b/docs/guide-zh-CN/images/tests.png new file mode 100644 index 0000000..a537336 Binary files /dev/null and b/docs/guide-zh-CN/images/tests.png differ diff --git a/docs/guide-zh-CN/start-comparison.md b/docs/guide-zh-CN/start-comparison.md new file mode 100644 index 0000000..3f8f841 --- /dev/null +++ b/docs/guide-zh-CN/start-comparison.md @@ -0,0 +1,20 @@ +比较 +==== + +下表比较了高级项目模板和基本项目模板之间的区别: + + +| 特性 | 基本项目模版 | 高级项目模版 | +|---|:---:|:---:| +| 项目结构 | ✓ | ✓ | +| Site controller | ✓ | ✓ | +| 用户 登录/退出 | ✓ | ✓ | +| 表单 | ✓ | ✓ | +| 数据库链接 | ✓ | ✓ | +| 命令行操作 | ✓ | ✓ | +| 资源包 | ✓ | ✓ | +| 代码测试 | ✓ | ✓ | +| Bootstrap | ✓ | ✓ | +| 前端 以及 后端 应用 | | ✓ | +| 准备使用用户模型 | | ✓ | +| 用户注册以及密码重置 | | ✓ | \ No newline at end of file diff --git a/docs/guide-zh-CN/start-composer.md b/docs/guide-zh-CN/start-composer.md new file mode 100644 index 0000000..be4c1dd --- /dev/null +++ b/docs/guide-zh-CN/start-composer.md @@ -0,0 +1,53 @@ +配置 Composer +============= + +安装项目模板后,最好调整默认的 `composer.json` ,它可以在根目录下找到: + +```json +{ + "name": "kartik-v/yii2-app-practical-a", + "description": "Yii 2 Practical-A Project Template", + "keywords": ["yii2", "framework", "practical", "project template"], + "homepage": "http://www.yiiframework.com/", + "type": "project", + "license": "BSD-3-Clause", + "support": { + "issues": "https://github.com/yiisoft/yii2/issues?state=open", + "forum": "http://www.yiiframework.com/forum/", + "wiki": "http://www.yiiframework.com/wiki/", + "irc": "irc://irc.freenode.net/yii", + "source": "https://github.com/yiisoft/yii2" + }, + "minimum-stability": "dev", + "require": { + "php": ">=5.4.0", + "yiisoft/yii2": "~2.0.6", + "yiisoft/yii2-bootstrap": "~2.0.0", + "yiisoft/yii2-swiftmailer": "~2.0.0" + }, + "require-dev": { + "yiisoft/yii2-debug": "~2.0.0", + "yiisoft/yii2-gii": "~2.0.0", + "yiisoft/yii2-faker": "~2.0.0", + + "codeception/base": "^2.2.3", + "codeception/verify": "~0.3.1" + }, + "config": { + "process-timeout": 1800 + }, + "extra": { + "asset-installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } + } +} +``` + +首先,我们要更新基本信息。 更改 `name` ,`description` ,`keywords` ,`homepage` 和 `support` 来匹配您的项目。 + +接下来是见证奇迹的时刻. 您可以将您的应用程序需要的更多包添加到 `require` 部分。 +所有这些包都来自 [packagist.org](https://packagist.org/) 浏览这里你可以找到更多的实用的免费代码。 + +在你的 `composer.json` 改变之后,你可以运行 `composer update --prefer-dist` ,等待程序包下载完成,安装后,就可以使用它们了。 包里面所有的类都会自动加载。 \ No newline at end of file diff --git a/docs/guide-zh-CN/start-installation.md b/docs/guide-zh-CN/start-installation.md new file mode 100644 index 0000000..a149cf9 --- /dev/null +++ b/docs/guide-zh-CN/start-installation.md @@ -0,0 +1,276 @@ +安装 +=== + +## 要求 + +此项目模板的最低要求是您的Web服务器支持PHP 5.4.0。 + +## 使用Composer安装 + +如果您没有 [Composer](http://getcomposer.org/),请按照最终指南的 +[安装Yii](https://github.com/yiisoft/yii2/blob/master/docs/guide/start-installation.md#installing-via-composer) 部分中的说明进行安装。 + +安装Composer后,您可以使用以下命令安装应用程序: + + composer global require "fxp/composer-asset-plugin:^1.3.1" + composer create-project --prefer-dist kartik-v/yii2-app-practical-a practical-a + +第一个命令安装 [composer asset插件](https://github.com/francoispluchino/composer-asset-plugin/) +第一个命令安装composer asset插件,它允许通过Composer管理bower和npm包依赖。 您只需要为所有运行此命令一次。 第二个命令将高级应用程序安装在名为 `practical-a` 的目录中。 如果需要,您可以选择不同的目录名称。 + +## 从归档文件安装 + +将从 [yiiframework.com](http://www.yiiframework.com/download/) 下载的归档文件解压缩到直接位于Web根目录下的名为practical的目录。 + +然后按照下一小节中给出的说明进行操作。 + + +## 准备应用程序 + +安装应用程序后,必须执行以下步骤来初始化已安装的应用程序。 这些操作仅需执行一次即可。 + +1. 打开控制台终端,执行 `init` 命令并选择 `dev` 作为环境。 + + ``` + /path/to/php-bin/php /path/to/practical-a/init + ``` + + 如果使用脚本自动化,可以在非交互模式下执行 `init` 。 + + ``` + /path/to/php-bin/php /path/to/practical-a/init --env=Production --overwrite=All + ``` + +2. 创建一个新的数据库,并相应地调整 `common/config/main-local.php` 中的 `components['db']` 配置。 + +3. 打开控制台终端,执行迁移命令 `/path/to/php-bin/php /path/to/practical-a/yii migrate`. + +4. 设置Web服务器的文档根目录: + + - 对于前端 `/path/to/practical-a/` 并且使用URL `http://frontend.dev/` + - 对于后端 `/path/to/practical-a/backend/web/` 并且使用URL `http://backend.dev/` + + 对于Apache,使用如下配置: + + ```apache + + ServerName frontend.dev + DocumentRoot "/path/to/practical-a/frontend/" + + + # use mod_rewrite for pretty URL support + RewriteEngine on + # If a directory or a file exists, use the request directly + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + # Otherwise forward the request to index.php + RewriteRule . index.php + + # use index.php as index file + DirectoryIndex index.php + + # ...other settings... + + + + + ServerName backend.dev + DocumentRoot "/path/to/practical-a/backend/web/" + + + # use mod_rewrite for pretty URL support + RewriteEngine on + # If a directory or a file exists, use the request directly + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + # Otherwise forward the request to index.php + RewriteRule . index.php + + # use index.php as index file + DirectoryIndex index.php + + # ...other settings... + + + ``` + + nginx使用如下配置: + + ```nginx + server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name frontend.dev; + root /path/to/practical-a/frontend/; + index index.php; + + access_log /path/to/practical-a/log/frontend-access.log; + error_log /path/to/practical-a/log/frontend-error.log; + + location / { + # Redirect everything that isn't a real file to index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # uncomment to avoid processing of calls to non-existing static files by Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + # deny accessing php files for the /assets directory + location ~ ^/assets/.*\.php$ { + deny all; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php5-fpm.sock; + try_files $uri =404; + } + + location ~* /\. { + deny all; + } + } + + server { + charset utf-8; + client_max_body_size 128M; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name backend.dev; + root /path/to/practical-a/backend/web/; + index index.php; + + access_log /path/to/practical-a/log/backend-access.log; + error_log /path/to/practical-a/log/backend-error.log; + + location / { + # Redirect everything that isn't a real file to index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # uncomment to avoid processing of calls to non-existing static files by Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + # deny accessing php files for the /assets directory + location ~ ^/assets/.*\.php$ { + deny all; + } + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; + #fastcgi_pass unix:/var/run/php5-fpm.sock; + try_files $uri =404; + } + + location ~* /\. { + deny all; + } + } + ``` + +5. 更改主机文件以将域指向您的服务器。 + + - Windows: `c:\Windows\System32\Drivers\etc\hosts` + - Linux: `/etc/hosts` + + 添加以下行: + + ``` + 127.0.0.1 frontend.dev + 127.0.0.1 backend.dev + ``` + +要登录应用程序,您需要先注册您的电子邮件地址,用户名和密码。 +然后,您可以随时使用相同的电子邮件地址和密码登录应用程序。 + + +> 注意:如果要在单个域上运行高级模板,则 `/` 是前端,而 `/admin` 是后端,请参阅[在共享主机上使用高级项目模板](topic-shared-hosting.md)。 + +## 使用Vagrant安装 + +这是最简单的安装方式,但是耗时较长(约20分钟)。 + +**这种安装方式不需要预先安装的软件(如Web服务器,PHP,MySQL等)** - 只是做下一步! + +#### Linux/Unix 用户手册 + +1. 安装 [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. 安装 [Vagrant](https://www.vagrantup.com/downloads.html) +3. 创建 GitHub [personal API token](https://github.com/blog/1509-personal-api-tokens) +3. 准备项目: + + ```bash + git clone https://github.com/kartik-v/yii2-app-practical-a.git + cd yii2-app-practical-a/vagrant/config + cp vagrant-local.example.yml vagrant-local.yml + ``` + +4. 将您的GitHub个人API令牌放置到 `vagrant-local.yml` +5. 将目录更改为项目根目录: + + ```bash + cd yii2-app-practical-a + ``` + +5. 执行如下命令: + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + +等待完成后,在浏览器中访问如下URL即可 + +* frontend: http://y2aa-frontend.dev +* backend: http://y2aa-backend.dev + +#### Windows 用户手册 + +1. 安装 [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. 安装 [Vagrant](https://www.vagrantup.com/downloads.html) +3. 重启电脑 +4. 创建 GitHub [personal API token](https://github.com/blog/1509-personal-api-tokens) +5. 准备项目: + * 下载 [yii2-app-practical-a](https://github.com/kartik-v/yii2-app-practical-a/archive/master.zip) + * 解压 + * 进入 `yii2-app-practical-a-master/vagrant/config` 文件夹 + * 重命名 `vagrant-local.example.yml` 为 `vagrant-local.yml` + +6. 将您的GitHub个人API令牌放置到 `vagrant-local.yml` +7. 添加如下代码到 [hosts 文件](https://en.wikipedia.org/wiki/Hosts_(file)): + + ``` + 192.168.83.137 y2aa-frontend.dev + 192.168.83.137 y2aa-backend.dev + ``` + +8. 打开终端 (`cmd.exe`), **切换路径至项目根目录** 并且执行如下命令: + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + + (猛击 [这里](http://www.wikihow.com/Change-Directories-in-Command-Prompt) 查看如何在命令提示符中更改目录) + +等待完成后,在浏览器中访问如下URL即可 + +* frontend: http://y2aa-frontend.dev +* backend: http://y2aa-backend.dev + diff --git a/docs/guide-zh-CN/start-testing.md b/docs/guide-zh-CN/start-testing.md new file mode 100644 index 0000000..e0bc013 --- /dev/null +++ b/docs/guide-zh-CN/start-testing.md @@ -0,0 +1,110 @@ +测试 +=============================== + +Yii2高级应用程序使用Codeception作为其主要测试框架。 +已经在 `frontend` , `backend` 和 `common` 的 `tests` 目录中准备了一些样本测试。 +为了使以下过程工作,假定应用程序已使用初始化 `dev` 环境。 如果测试需要在 `Production` 环境中执行, `yii_test` 和 `yii_test.bat` 必须从 `environments/dev` 文件夹手动复制到项目根目录。 +测试需要一个 **额外的数据库** ,这将在测试之间清除。 +在mysql中创建数据库 `yii2practical_test` (根据 `common/config/test.php` 中的配置)并执行: + +``` +./yii_test migrate +``` + +构建测试套件: + +``` +vendor/bin/codecept build +``` + +然后所有的样例测试可以通过运行如下代码: + +``` +vendor/bin/codecept run +``` + +您将看到类似于以下的输出: + +![](images/tests.png) + +建议保持测试最新。 如果一个类或功能被删除,相应的测试也应该被删除。 +您应定期运行测试,或更好地为它们设置持续集成服务器。 + +请参考 [Yii2 Framework Case Study](http://codeception.com/for/yii) ,了解如何为应用程序配置代码。 +### Common + +common部分的测试位于 `common/tests`. 在这个模板中只有 `unit` (单元)测试。 +运行如下代码: + +``` +vendor/bin/codecept run -- -c common +``` + +`-c` 选项允许设置 `codeception.yml` 配置的路径。 + +在 `unit` 测试套件(位于 `common/tests/unit` )中的测试可以使用Yii框架特性:`Yii::$app`,Active Record,fixtures等。 +这是因为 `Yii2` 模块在单元测试config:`common/tests/unit.suite.yml` 中被启用。 您可以禁用它以完全隔离的方式运行测试。 + + +### Frontend + +前端测试包含单元测试,功能测试和验收测试。 +通过运行: + +``` +vendor/bin/codecept run -- -c frontend +``` + +测试套件描述: + +* `unit` ⇒ 仅与前端应用程序相关的类。 +* `functional` ⇒ 应用程序内部请求/响应(无Web服务器)。 +* `acceptance` ⇒ web应用程序,用户界面和javascript交互。 + +默认情况下,验收测试被禁用,运行它们使用: + +#### 运行验收测试 + +要执行验收测试,请执行以下操作: + +1. 重命名 `frontend/tests/acceptance.suite.yml.example` 为 `frontend/tests/acceptance.suite.yml` 以启用套件配置 + +1. 在 `composer.json` 中替换 `codeception/base` 包为 `codeception/codeception` 以安装Codeception的全部功能 + +1. 使用Composer更新依赖关系 + + ``` + composer update + ``` + +1. 为验收测试自动生成新的支持类: + + ``` + vendor/bin/codecept build -- -c frontend + ``` + +1. 下载 [Selenium Server](http://www.seleniumhq.org/download/) 并启动: + + ``` + java -jar ~/selenium-server-standalone-x.xx.x.jar + ``` + +1. 启动web服务器: + + ``` + php -S 127.0.0.1:8080 -t frontend + ``` + +1. 现在可以运行所有可用的测试 + + ``` + vendor/bin/codecept run acceptance -- -c frontend + ``` + +## Backend + +后端应用程序包含单元和功能测试套件。 通过运行: + +``` +vendor/bin/codecept run -- -c backend +``` diff --git a/docs/guide-zh-CN/structure-applications.md b/docs/guide-zh-CN/structure-applications.md new file mode 100644 index 0000000..c6fe939 --- /dev/null +++ b/docs/guide-zh-CN/structure-applications.md @@ -0,0 +1,10 @@ +应用 +============ + +高级模板中有三个应用程序:前端,后端和控制台。 前端通常是呈现项目本身到最终用户。 后端是管理面板,分析和其他诸如此类的功能。 控制台通常用于cron作业和低级服务器管理。 它也在应用程序部署期间使用,并处理数据迁移和资源包。 + +还有一个 `common` 目录,其中包含多个应用程序使用的文件。 例如,`User` Model。 + +前端和后端都是Web应用程序,并且都包含 `web` 目录。 这个目录就是web服务器要映射域名的目录。 + +每个应用程序都有自己的命名空间和别名对应其名称。 这同样适用于公共目录。 diff --git a/docs/guide-zh-CN/structure-directories.md b/docs/guide-zh-CN/structure-directories.md new file mode 100644 index 0000000..6c7df16 --- /dev/null +++ b/docs/guide-zh-CN/structure-directories.md @@ -0,0 +1,22 @@ +目录 +=========== + +根目录包含以下子目录: + +- `backend` - [backend (后端应用)](structure-applications.md). +- `common` - [common (所有应用程序共有的文件)](structure-applications.md). +- `console` - [console (命令行应用)](structure-applications.md). +- `environments` - [environment (环境配置)](structure-environments.md). +- `frontend` - [frontend (前端应用)](structure-applications.md). + +根目录包含一组文件。 + +- `.gitignore` 包含由git版本系统忽略的目录列表。 如果你需要的东西从来没有到你的源代码存储库,添加它。 +- `composer.json` - Composer配置文件 [Configuring Composer](start-composer.md). +- `init` - 初始化脚本描述文件 [Configuration and environments](structure-environments.md). +- `init.bat` - Windows下的初始化脚本描述文件. +- `LICENSE.md` - 许可信息。 把你的项目许可证放到这里。 特别是开源醒目。 +- `README.md` - 安装模板的基本信息。 请考虑将其替换为有关您的项目及其安装的信息。 +- `requirements.php` - 安装使用 Yii 需求检查器。 +- `yii` - 控制台应用程序引导。 +- `yii.bat` - Windows下的控制台应用程序引导. diff --git a/docs/guide-zh-CN/structure-environments.md b/docs/guide-zh-CN/structure-environments.md new file mode 100644 index 0000000..b9a3b62 --- /dev/null +++ b/docs/guide-zh-CN/structure-environments.md @@ -0,0 +1,35 @@ +配置和环境 +============================== + +典型的配置方法有多个问题: + +- 每个团队成员都有自己的配置选项。 提交此配置将影响其他团队成员。 +- 生产数据库密码和API密钥不应该存储在存代码库中。 +- 有多个服务器环境:开发,测试,生产。 每个应该有自己的配置。 +- 为每种情况定义所有配置选项非常重复,需要花费太多时间来维护。 + +为了解决这些问题,Yii介绍了一个简单的环境概念。 每个环境由 `environments` 目录下的一组文件表示。 `init` 命令用于初始化一个环境。 它真正做的是将所有内容从环境目录复制到所有应用程序所在的根目录。 + +默认情况下有两个环境: `dev` 和 `prod` 。 第一个是开发环境。 默认打开所有开发调试工具。 第二个是生产环境。 默认关闭调试和开发工具。 + +通常环境包含应用程序引导文件,如 `index.php` 和配置文件后缀 `-local.php` 。 这些是通常在 `dev` 环境中的团队成员的个人配置或特定服务器的配置。 例如,生产数据库连接可以在 `prod` 环境 `-local.php` 配置中。 这些本地配置被添加到 `.gitignore` ,从不推送到源代码仓库。 + +为了避免重复配置彼此覆盖。 例如,前端读取配置以如下顺序: + +- `common/config/main.php` +- `common/config/main-local.php` +- `frontend/config/main.php` +- `frontend/config/main-local.php` + +参数按以下顺序读取: + +- `common/config/params.php` +- `common/config/params-local.php` +- `frontend/config/params.php` +- `frontend/config/params-local.php` + +后面的配置文件覆盖前者。 + +这里是完整的流程: + +![Advanced application configs](images/advanced-app-configs.png) diff --git a/docs/guide-zh-CN/structure-path-aliases.md b/docs/guide-zh-CN/structure-path-aliases.md new file mode 100644 index 0000000..988250f --- /dev/null +++ b/docs/guide-zh-CN/structure-path-aliases.md @@ -0,0 +1,18 @@ +预定义路径别名 +======================= + +- `@yii` - 框架目录。 +- `@app` - 当前运行的应用程序的基本路径。 +- `@common` - 公共目录。 +- `@frontend` - 前端Web应用程序目录。 +- `@backend` - 后端Web应用程序目录。 +- `@console` - 控制台目录。 +- `@runtime` - 当前正在运行的Web应用程序的runtime目录。 +- `@vendor` - Composer vendor 目录. +- `@bower` - vendor 目录下的 [bower packages](http://bower.io/). +- `@npm` - vendor 目录下的 [npm packages](https://www.npmjs.org/). +- `@web` - 当前运行的Web应用程序的 base URL。 +- `@webroot` - 当前运行的Web应用程序的web根目录。 + +特定于高级应用程序的目录结构的别名 +(`@common`, `@frontend`, `@backend`, 以及 `@console`) 在 `common/config/bootstrap.php` 文件中定义. \ No newline at end of file diff --git a/docs/guide-zh-CN/topic-adding-more-apps.md b/docs/guide-zh-CN/topic-adding-more-apps.md new file mode 100644 index 0000000..ede0555 --- /dev/null +++ b/docs/guide-zh-CN/topic-adding-more-apps.md @@ -0,0 +1,9 @@ +添加更多应用程序 +======================== + +虽然有单独的前端和后端是常见的,有时它是不够的。 例如,您可能需要额外的应用程序,例如博客。 使用如下方式创建: + +1. 复制 `frontend` 至 `blog`, `environments/dev/frontend` 至 `environments/dev/blog` 以及 `environments/prod/frontend` +至 `environments/prod/blog`. +2. 调整命名空间和路径以 `blog` 开头(替换 `frontend`). +3. 在 `common\config\bootstrap.php` 中添加 `Yii::setAlias('blog', dirname(dirname(__DIR__)) . '/blog');`. diff --git a/docs/guide-zh-CN/topic-link-backend-frontend.md b/docs/guide-zh-CN/topic-link-backend-frontend.md new file mode 100644 index 0000000..7db7247 --- /dev/null +++ b/docs/guide-zh-CN/topic-link-backend-frontend.md @@ -0,0 +1,44 @@ +创建从后端到前端的链接 +======================================= + +通常需要创建从后端应用程序到前端应用程序的链接。 由于前端应用程序可能包含自己的URL管理器规则,因此您需要通过将后端应用程序命名为不同的方式来复制后端应用程序: + +```php +return [ + 'components' => [ + 'urlManager' => [ + // here is your normal backend url manager config + ], + 'urlManagerFrontend' => [ + // here is your frontend URL manager config + ], + + ], +]; +``` + +完成后,您可以获取指向前端的URL,如下所示: + +```php +echo Yii::$app->urlManagerFrontend->createAbsoluteUrl(...); +``` + +为了不复制粘贴前端规则,你可以先将它们移动到单独的 `urls.php` 文件中: + +```php +return [ + // ... + 'components' => [ + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => require 'urls.php', + ], + // ... + + ], + // ... +]; +``` + +之后,你可以将它包含在 `urlManagerFrontend` 规则中。 diff --git a/docs/guide-zh-CN/topic-shared-hosting.md b/docs/guide-zh-CN/topic-shared-hosting.md new file mode 100644 index 0000000..75434dd --- /dev/null +++ b/docs/guide-zh-CN/topic-shared-hosting.md @@ -0,0 +1,58 @@ +在虚拟主机上使用高级项目模板 +================================== + +将高级项目模板部署到虚拟主机,相比基本项目模版来说有点棘手,因为它有两个webroots,共享托管网络服务器不支持。 我们需要调整目录结构,然后前端的 URL 是 `http://site.local` 而后端的 URL 是 `http://site.local/admin` . + +### 将入口文件移动到单个webroot + +首先我们需要一个webroot目录。 创建一个新目录并将其命名为与托管webroot名称匹配,例如 `www` 或 `public_html` 等. 然后创建以下结构,其中 `www` 是您刚刚创建的托管webroot目录: + +``` +www + admin +backend +common +console +environments +frontend +... +``` + +`www` 将是我们的前端目录,所以将 `frontend` 的内容移动到其中。 将 `backend/web` 的内容移动到 `www/admin`。 在每种情况下,您都需要调整 “index.php” 和 “index-test.php” 中的路径。 + +### 调整 sessions 和 cookies 的配置 + +最初,后端和前端旨在运行在不同的域。 当我们将其全部移动到同一个域时,前端和后端将共享相同的Cookie,从而产生冲突。 为了解决它,请调整后端应用程序配置 `backend/config/main.php` 如下: + +```php +'components' => [ + 'request' => [ + 'csrfParam' => '_csrf-backend', + 'csrfCookie' => [ + 'httpOnly' => true, + 'path' => '/admin', + ], + ], + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + 'identityCookie' => [ + 'name' => '_identity-backend', + 'path' => '/admin', + 'httpOnly' => true, + ], + ], + 'session' => [ + // this is the name of the session cookie used for login on the backend + 'name' => 'practical-backend', + 'cookieParams' => [ + 'path' => '/admin', + ], + ], +], +``` + +### 自行配置 + +如果上面提供的设置模板的方式不适合你,请尝试 +[configs and docs by Oleg Belostotskiy](https://github.com/mickgeek/yii2-practical-one-domain-config). diff --git a/docs/guide/README.md b/docs/guide/README.md index 54e36ac..b15c4c7 100644 --- a/docs/guide/README.md +++ b/docs/guide/README.md @@ -1,7 +1,7 @@ -Yii 2 Advanced Project Template -=============================== +Yii 2 Practical-A Project Template +================================== -Yii 2 Advanced Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for +Yii 2 Practical-A Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for developing complex Web applications with multiple tiers. The template includes three tiers: front end, back end, and console, each of which @@ -19,6 +19,7 @@ Getting Started * [Installation](start-installation.md) * [Difference from basic project template](start-comparison.md) * [Configuring Composer](start-composer.md) +* [Running Tests](start-testing.md) Structure --------- @@ -33,3 +34,4 @@ Additional Topics * [Creating links from backend to frontend](topic-link-backend-frontend.md) * [Adding more applications](topic-adding-more-apps.md) +* [Using practical project template at shared hosting](topic-shared-hosting.md) diff --git a/docs/guide/images/tests.png b/docs/guide/images/tests.png new file mode 100644 index 0000000..a537336 Binary files /dev/null and b/docs/guide/images/tests.png differ diff --git a/docs/guide/start-comparison.md b/docs/guide/start-comparison.md index bfa2154..9beaa0b 100644 --- a/docs/guide/start-comparison.md +++ b/docs/guide/start-comparison.md @@ -1,10 +1,10 @@ Comparison ========== -The following table compares the difference between the advanced and the basic project templates: +The following table compares the difference between the practical and the basic project templates: -| Feature | Basic | Advanced | +| Feature | Basic | Practical-A | |---|:---:|:---:| | Project structure | ✓ | ✓ | | Site controller | ✓ | ✓ | diff --git a/docs/guide/start-composer.md b/docs/guide/start-composer.md index 63e60d1..680d940 100644 --- a/docs/guide/start-composer.md +++ b/docs/guide/start-composer.md @@ -6,9 +6,9 @@ directory: ```json { - "name": "yiisoft/yii2-app-advanced", - "description": "Yii 2 Advanced Project Template", - "keywords": ["yii2", "framework", "advanced", "project template"], + "name": "kartik-v/yii2-app-practical-a", + "description": "Yii 2 Practical-A Project Template", + "keywords": ["yii2", "framework", "practical", "project template"], "homepage": "http://www.yiiframework.com/", "type": "project", "license": "BSD-3-Clause", @@ -22,15 +22,17 @@ directory: "minimum-stability": "dev", "require": { "php": ">=5.4.0", - "yiisoft/yii2": "*", - "yiisoft/yii2-bootstrap": "*", - "yiisoft/yii2-swiftmailer": "*" + "yiisoft/yii2": "~2.0.6", + "yiisoft/yii2-bootstrap": "~2.0.0", + "yiisoft/yii2-swiftmailer": "~2.0.0" }, "require-dev": { - "yiisoft/yii2-codeception": "*", - "yiisoft/yii2-debug": "*", - "yiisoft/yii2-gii": "*", - "yiisoft/yii2-faker": "*" + "yiisoft/yii2-debug": "~2.0.0", + "yiisoft/yii2-gii": "~2.0.0", + "yiisoft/yii2-faker": "~2.0.0", + + "codeception/base": "^2.2.3", + "codeception/verify": "~0.3.1" }, "config": { "process-timeout": 1800 diff --git a/docs/guide/start-installation.md b/docs/guide/start-installation.md index 32d29fa..278013e 100644 --- a/docs/guide/start-installation.md +++ b/docs/guide/start-installation.md @@ -12,18 +12,18 @@ If you do not have [Composer](http://getcomposer.org/), follow the instructions With Composer installed, you can then install the application using the following commands: - composer global require "fxp/composer-asset-plugin:~1.1.1" - composer create-project --prefer-dist yiisoft/yii2-app-advanced yii-application + composer global require "fxp/composer-asset-plugin:^1.3.1" + composer create-project --prefer-dist kartik-v/yii2-app-practical-a practical-a The first command installs the [composer asset plugin](https://github.com/francoispluchino/composer-asset-plugin/) which allows managing bower and npm package dependencies through Composer. You only need to run this command -once for all. The second command installs the advanced application in a directory named `yii-application`. +once for all. The second command installs the practical-a application in a directory named `practical-a`. You can choose a different directory name if you want. ## Install from an Archive File Extract the archive file downloaded from [yiiframework.com](http://www.yiiframework.com/download/) to -a directory named `advanced` that is directly under the Web root. +a directory named `practical` that is directly under the Web root. Then follow the instructions given in the next subsection. @@ -36,32 +36,32 @@ the installed application. You only need to do these once for all. 1. Open a console terminal, execute the `init` command and select `dev` as environment. ``` - /path/to/php-bin/php /path/to/yii-application/init + /path/to/php-bin/php /path/to/practical-a/init ``` - Otherwise, in production execute `init` in non-interactive mode. + If you automate it with a script you can execute `init` in non-interactive mode. ``` - /path/to/php-bin/php /path/to/yii-application/init --env=Production --overwrite=All + /path/to/php-bin/php /path/to/practical-a/init --env=Production --overwrite=All ``` 2. Create a new database and adjust the `components['db']` configuration in `common/config/main-local.php` accordingly. -3. Open a console terminal, apply migrations with command `/path/to/php-bin/php /path/to/yii-application/yii migrate`. +3. Open a console terminal, apply migrations with command `/path/to/php-bin/php /path/to/practical-a/yii migrate`. 4. Set document roots of your web server: - - for frontend `/path/to/yii-application/frontend/web/` and using the URL `http://frontend.dev/` - - for backend `/path/to/yii-application/backend/web/` and using the URL `http://backend.dev/` + - for frontend `/path/to/practical-a/` and using the URL `http://frontend.dev/` + - for backend `/path/to/practical-a/backend/web/` and using the URL `http://backend.dev/` For Apache it could be the following: ```apache ServerName frontend.dev - DocumentRoot "/path/to/yii-application/frontend/web/" + DocumentRoot "/path/to/practical-a/frontend/" - + # use mod_rewrite for pretty URL support RewriteEngine on # If a directory or a file exists, use the request directly @@ -74,14 +74,20 @@ the installed application. You only need to do these once for all. DirectoryIndex index.php # ...other settings... + # Apache 2.4 + Require all granted + + ## Apache 2.2 + # Order allow,deny + # Allow from all ServerName backend.dev - DocumentRoot "/path/to/yii-application/backend/web/" + DocumentRoot "/path/to/practical-a/backend/web/" - + # use mod_rewrite for pretty URL support RewriteEngine on # If a directory or a file exists, use the request directly @@ -94,6 +100,12 @@ the installed application. You only need to do these once for all. DirectoryIndex index.php # ...other settings... + # Apache 2.4 + Require all granted + + ## Apache 2.2 + # Order allow,deny + # Allow from all ``` @@ -104,37 +116,42 @@ the installed application. You only need to do these once for all. server { charset utf-8; client_max_body_size 128M; - + listen 80; ## listen for ipv4 #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 - + server_name frontend.dev; - root /path/to/yii-application/frontend/web/; + root /path/to/practical-a/frontend/; index index.php; - - access_log /path/to/yii-application/log/frontend-access.log; - error_log /path/to/yii-application/log/frontend-error.log; - + + access_log /path/to/practical-a/log/frontend-access.log; + error_log /path/to/practical-a/log/frontend-error.log; + location / { # Redirect everything that isn't a real file to index.php - try_files $uri $uri/ /index.php?$args; + try_files $uri $uri/ /index.php$is_args$args; } - + # uncomment to avoid processing of calls to non-existing static files by Yii #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { # try_files $uri =404; #} #error_page 404 /404.html; - + + # deny accessing php files for the /assets directory + location ~ ^/assets/.*\.php$ { + deny all; + } + location ~ \.php$ { include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; - fastcgi_pass 127.0.0.1:9000; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/php5-fpm.sock; try_files $uri =404; } - location ~ /\.(ht|svn|git) { + location ~* /\. { deny all; } } @@ -147,15 +164,15 @@ the installed application. You only need to do these once for all. #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 server_name backend.dev; - root /path/to/yii-application/backend/web/; + root /path/to/practical-a/backend/web/; index index.php; - access_log /path/to/yii-application/log/backend-access.log; - error_log /path/to/yii-application/log/backend-error.log; + access_log /path/to/practical-a/log/backend-access.log; + error_log /path/to/practical-a/log/backend-error.log; location / { # Redirect everything that isn't a real file to index.php - try_files $uri $uri/ /index.php?$args; + try_files $uri $uri/ /index.php$is_args$args; } # uncomment to avoid processing of calls to non-existing static files by Yii @@ -163,16 +180,21 @@ the installed application. You only need to do these once for all. # try_files $uri =404; #} #error_page 404 /404.html; - + + # deny accessing php files for the /assets directory + location ~ ^/assets/.*\.php$ { + deny all; + } + location ~ \.php$ { include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; - fastcgi_pass 127.0.0.1:9000; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_pass 127.0.0.1:9000; #fastcgi_pass unix:/var/run/php5-fpm.sock; try_files $uri =404; } - location ~ /\.(ht|svn|git) { + location ~* /\. { deny all; } } @@ -192,3 +214,78 @@ the installed application. You only need to do these once for all. To login into the application, you need to first sign up, with any of your email address, username and password. Then, you can login into the application with same email address and password at any time. + + +> Note: if you want to run practical template on a single domain so `/` is frontend and `/admin` is backend, refer +> to [Using practical project template at shared hosting](topic-shared-hosting.md). + +## Installing using Vagrant + +This way is the easiest but long (~20 min). + +**This installation way doesn't require pre-installed software (such as web-server, PHP, MySQL etc.)** - just do next steps! + +#### Manual for Linux/Unix users + +1. Install [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. Install [Vagrant](https://www.vagrantup.com/downloads.html) +3. Create GitHub [personal API token](https://github.com/blog/1509-personal-api-tokens) +3. Prepare project: + + ```bash + git clone https://github.com/kartik-v/yii2-app-practical-a.git + cd yii2-app-practical-a/vagrant/config + cp vagrant-local.example.yml vagrant-local.yml + ``` + +4. Place your GitHub personal API token to `vagrant-local.yml` +5. Change directory to project root: + + ```bash + cd yii2-app-practical-a + ``` + +5. Run commands: + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + +That's all. You just need to wait for completion! After that you can access project locally by URLs: +* frontend: http://y2aa-frontend.dev +* backend: http://y2aa-backend.dev + +#### Manual for Windows users + +1. Install [VirtualBox](https://www.virtualbox.org/wiki/Downloads) +2. Install [Vagrant](https://www.vagrantup.com/downloads.html) +3. Reboot +4. Create GitHub [personal API token](https://github.com/blog/1509-personal-api-tokens) +5. Prepare project: + * download repo [yii2-app-practical-a](https://github.com/kartik-v/yii2-app-practical-a/archive/master.zip) + * unzip it + * go into directory `yii2-app-practical-a-master/vagrant/config` + * copy `vagrant-local.example.yml` to `vagrant-local.yml` + +6. Place your GitHub personal API token to `vagrant-local.yml` +7. Add the following lines to [hosts file](https://en.wikipedia.org/wiki/Hosts_(file)): + + ``` + 192.168.83.137 y2aa-frontend.dev + 192.168.83.137 y2aa-backend.dev + ``` + +8. Open terminal (`cmd.exe`), **change directory to project root** and run commands: + + ```bash + vagrant plugin install vagrant-hostmanager + vagrant up + ``` + + (You can read [here](http://www.wikihow.com/Change-Directories-in-Command-Prompt) how to change directories in command prompt) + +That's all. You just need to wait for completion! After that you can access project locally by URLs: +* frontend: http://y2aa-frontend.dev +* backend: http://y2aa-backend.dev + diff --git a/docs/guide/start-testing.md b/docs/guide/start-testing.md new file mode 100644 index 0000000..105b8cf --- /dev/null +++ b/docs/guide/start-testing.md @@ -0,0 +1,114 @@ +Testing +================================== + +Yii2 Advanced Application uses Codeception as its primary test framework. +There are already some sample tests prepared in `tests` directory of `frontend`, `backend`, and `common`. +In order for the following procedure to work, it is assumed that the application has been initialized using +the `dev` environment. In case tests need to be executed within a `Production` environment, `yii_test` and +`yii_test.bat` must be manually copied from the `environments/dev` folder into the project root directory. +Tests require an **additional database**, which will be cleaned up between tests. +Create database `yii2practical_test` in mysql (according to config in `common/config/test.php`) and execute: + +``` +./yii_test migrate +``` + +Build the test suite: + +``` +vendor/bin/codecept build +``` + +Then all sample tests can be started by running: + +``` +vendor/bin/codecept run +``` + +You will see output similar to this: + +![](images/tests.png) + +It is recommended to keep your tests up to date. If a class, or functionality is deleted, corresponding tests should be deleted as well. +You should run tests regularly, or better to set up Continuous Integration server for them. + +Please refer to [Yii2 Framework Case Study](http://codeception.com/for/yii) to learn how to configure Codeception for your application. + +### Common + +Tests for common classes are located in `common/tests`. In this template there are only `unit` tests. +Execute them by running: + +``` +vendor/bin/codecept run -- -c common +``` + +`-c` option allows to set path to `codeception.yml` config. + +Tests in `unit` test suite (located in `common/tests/unit`) can use Yii framework features: `Yii::$app`, Active Record, fixtures, etc. +This is done because `Yii2` module is enabled in unit tests config: `common/tests/unit.suite.yml`. You can disable it to run tests in complete isolation. + + +### Frontend + +Frontend tests contain unit tests, functional tests, and acceptance tests. +Execute them by running: + +``` +vendor/bin/codecept run -- -c frontend +``` + +Description of test suites: + +* `unit` ⇒ classes related to frontend application only. +* `functional` ⇒ application internal requests/responses (without a web server). +* `acceptance` ⇒ web application, user interface and javascript interactions in real browser. + +By default acceptance tests are disabled, to run them use: + +#### Running Acceptance Tests + +To execute acceptance tests do the following: + +1. Rename `frontend/tests/acceptance.suite.yml.example` to `frontend/tests/acceptance.suite.yml` to enable suite configuration + +1. Replace `codeception/base` package in `composer.json` with `codeception/codeception` to install full featured + version of Codeception + +1. Update dependencies with Composer + + ``` + composer update + ``` + +1. Auto-generate new support classes for acceptance tests: + + ``` + vendor/bin/codecept build -- -c frontend + ``` + +1. Download [Selenium Server](http://www.seleniumhq.org/download/) and launch it: + + ``` + java -jar ~/selenium-server-standalone-x.xx.x.jar + ``` + +1. Start web server: + + ``` + php -S 127.0.0.1:8080 -t frontend + ``` + +1. Now you can run all available tests + + ``` + vendor/bin/codecept run acceptance -- -c frontend + ``` + +## Backend + +Backend application contain unit and functional test suites. Execute them by running: + +``` +vendor/bin/codecept run -- -c backend +``` diff --git a/docs/guide/structure-applications.md b/docs/guide/structure-applications.md index 836d0ed..43af378 100644 --- a/docs/guide/structure-applications.md +++ b/docs/guide/structure-applications.md @@ -1,13 +1,13 @@ Applications ============ -There are three applications in advanced template: frontend, backend and console. Frontend is typically what is presented +There are three applications in practical template: frontend, backend and console. Frontend is typically what is presented to end user, the project itself. Backend is admin panel, analytics and such functionality. Console is typically used for cron jobs and low-level server management. Also it's used during application deployment and handles migrations and assets. There's also a `common` directory that contains files used by more than one application. For example, `User` model. -frontend and backend are both web applications and both contain the `web` directory. That's the webroot you should point your +Frontend and backend are both web applications and both contain the `web` directory. That's the webroot you should point your web server to. -Each application has its own namespace and alias corresponding to its name. Same applies to common directory. +Each application has its own namespace and alias corresponding to its name. Same applies to the common directory. diff --git a/docs/guide/structure-directories.md b/docs/guide/structure-directories.md index 710fe18..daa50c4 100644 --- a/docs/guide/structure-directories.md +++ b/docs/guide/structure-directories.md @@ -3,11 +3,11 @@ Directories The root directory contains the following subdirectories: -- `backend` - backend web application. -- `common` - files common to all applications. -- `console` - console application. -- `environments` - environment configs. -- `frontend` - frontend web application. +- `backend` - [backend web application](structure-applications.md). +- `common` - [files common to all applications](structure-applications.md). +- `console` - [console application](structure-applications.md). +- `environments` - [environment configs](structure-environments.md). +- `frontend` - [frontend web application](structure-applications.md). Root directory contains a set of files. diff --git a/docs/guide/structure-environments.md b/docs/guide/structure-environments.md index 17636c6..9bd4ef7 100644 --- a/docs/guide/structure-environments.md +++ b/docs/guide/structure-environments.md @@ -9,7 +9,7 @@ There are multiple problems with a typical approach to configuration: - Defining all configuration options for each case is very repetitive and takes too much time to maintain. In order to solve these issues Yii introduces a simple environments concept. Each environment is represented -by a set of files under the `environments` directory. The `init` command is used to switch between these. What it really does is +by a set of files under the `environments` directory. The `init` command is used to initialize an environment. What it really does is copy everything from the environment directory over to the root directory where all applications are. By default there are two environments: `dev` and `prod`. First is for development. It has all the developer tools diff --git a/docs/guide/structure-path-aliases.md b/docs/guide/structure-path-aliases.md index 3f29921..9057835 100644 --- a/docs/guide/structure-path-aliases.md +++ b/docs/guide/structure-path-aliases.md @@ -14,5 +14,5 @@ Predefined path aliases - `@web` - base URL of currently running web application. - `@webroot` - web root directory of currently running web application. -The aliases specific to the directory structure of the advanced application +The aliases specific to the directory structure of the practical application (`@common`, `@frontend`, `@backend`, and `@console`) are defined in `common/config/bootstrap.php`. diff --git a/docs/guide/topic-adding-more-apps.md b/docs/guide/topic-adding-more-apps.md index 4551488..f24449a 100644 --- a/docs/guide/topic-adding-more-apps.md +++ b/docs/guide/topic-adding-more-apps.md @@ -8,3 +8,48 @@ application for, say, a blog. In order to get it: to `environments/prod/blog`. 2. Adjust namespaces and paths to start with `blog` instead of `frontend`. 3. In `common\config\bootstrap.php` add `Yii::setAlias('blog', dirname(dirname(__DIR__)) . '/blog');`. +4. Make adjustments to `environments/index.php` (marked with `+`): + +```php +return [ + 'Development' => [ + 'path' => 'dev', + 'setWritable' => [ + 'backend/runtime', + 'backend/web/assets', + 'frontend/runtime', + 'frontend/assets', ++ 'blog/runtime', ++ 'blog/web/assets', + ], + 'setExecutable' => [ + 'yii', + 'yii_test', + ], + 'setCookieValidationKey' => [ + 'backend/config/main-local.php', + 'frontend/config/main-local.php', ++ 'blog/config/main-local.php', + ], + ], + 'Production' => [ + 'path' => 'prod', + 'setWritable' => [ + 'backend/runtime', + 'backend/web/assets', + 'frontend/runtime', + 'frontend/assets', ++ 'blog/runtime', ++ 'blog/web/assets', + ], + 'setExecutable' => [ + 'yii', + ], + 'setCookieValidationKey' => [ + 'backend/config/main-local.php', + 'frontend/config/main-local.php', ++ 'blog/config/main-local.php', + ], + ], +]; +``` diff --git a/docs/guide/topic-link-backend-frontend.md b/docs/guide/topic-link-backend-frontend.md index dd6d586..fbd8aea 100644 --- a/docs/guide/topic-link-backend-frontend.md +++ b/docs/guide/topic-link-backend-frontend.md @@ -1,5 +1,5 @@ Creating links from backend to frontend -======================================= +======================================== Often it's required to create links from the backend application to the frontend application. Since the frontend application may contain its own URL manager rules you need to duplicate that for the backend application by naming it differently: @@ -21,5 +21,25 @@ return [ After it is done, you can get an URL pointing to frontend like the following: ```php -echo Yii::$app->urlManagerFrontend->createUrl(...); +echo Yii::$app->urlManagerFrontend->createAbsoluteUrl(...); ``` + +In order not to copy-paste frontend rules you may first move these into separate `urls.php` file: + +```php +return [ + // ... + 'components' => [ + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => require 'urls.php', + ], + // ... + + ], + // ... +]; +``` + +After then you may include it in `urlManagerFrontend` rules as well. diff --git a/docs/guide/topic-shared-hosting.md b/docs/guide/topic-shared-hosting.md new file mode 100644 index 0000000..403f284 --- /dev/null +++ b/docs/guide/topic-shared-hosting.md @@ -0,0 +1,65 @@ +Using practical project template at shared hosting +================================================== + +Deploying an practical project template to shared hosting is a bit trickier than a basic one because it has two webroots, +which shared hosting webservers don't support. We will need to adjust the directory structure so frontend URL will be +`http://site.local` and backend URL will be `http://site.local/admin`. + +### Move entry scripts into single webroot + +First of all we need a webroot directory. Create a new directory and name it to match your hosting webroot name, +e.g., `www` or `public_html` or the like. Then create the +following structure where `www` is the hosting webroot directory you just created: + +``` +www + admin +backend +common +console +environments +frontend +... +``` + +`www` will be our frontend directory so move the contents of `frontend` into it. Move the contents of `backend/web` +into `www/admin`. In each case you will need to adjust the paths in `index.php` and `index-test.php`. + +### Adjust sessions and cookies + +Originally the backend and frontend are intended to run at different domains. When we’re moving it all to the same domain +the frontend and backend will be sharing the same cookies, creating a clash. In order to fix it, adjust backend application config +`backend/config/main.php` as follows: + +```php +'components' => [ + 'request' => [ + 'csrfParam' => '_csrf-backend', + 'csrfCookie' => [ + 'httpOnly' => true, + 'path' => '/admin', + ], + ], + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + 'identityCookie' => [ + 'name' => '_identity-backend', + 'path' => '/admin', + 'httpOnly' => true, + ], + ], + 'session' => [ + // this is the name of the session cookie used for login on the backend + 'name' => 'practical-backend', + 'cookieParams' => [ + 'path' => '/admin', + ], + ], +], +``` + +### Alternative setup + +If the way to set up template provided above doesn't work for you, try +[configs and docs by Oleg Belostotskiy](https://github.com/mickgeek/yii2-practical-one-domain-config). diff --git a/environments/dev/backend/config/main-local.php b/environments/dev/backend/config/main-local.php index 2ebd0ea..b988c2d 100644 --- a/environments/dev/backend/config/main-local.php +++ b/environments/dev/backend/config/main-local.php @@ -5,17 +5,17 @@ 'request' => [ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => '', - // unique CSRF cookie parameter for backend (set by kartik-v/yii2-app-practical) + // unique CSRF cookie parameter for backend (set by kartik-v/yii2-app-practical-a) 'csrfParam' => '_backendCsrf', ], - // unique identity cookie configuration for backend (set by kartik-v/yii2-app-practical) + // unique identity cookie configuration for backend (set by kartik-v/yii2-app-practical-a) 'user' => [ 'identityCookie' => [ 'name' => '_backendUser', // unique for backend 'path' => '/backend' // set it to correct path for backend app. ] ], - // unique session configuration for backend (set by kartik-v/yii2-app-practical) + // unique session configuration for backend (set by kartik-v/yii2-app-practical-a) 'session' => [ 'name' => '_backendSessionId', // unique for backend 'savePath' => __DIR__ . '/../runtime/sessions' // set it to correct path for backend app. @@ -23,7 +23,7 @@ // url manager to access frontend 'urlManagerFE' => [ 'class' => 'yii\web\urlManager', - 'baseUrl' => '/practical', // change to your app base folder name + 'baseUrl' => '/practical-a', // change to your app base folder name 'enablePrettyUrl' => true, 'showScriptName' => false, ] diff --git a/environments/dev/backend/config/test-local.php b/environments/dev/backend/config/test-local.php new file mode 100644 index 0000000..4513a34 --- /dev/null +++ b/environments/dev/backend/config/test-local.php @@ -0,0 +1,9 @@ +run(); \ No newline at end of file +(new yii\web\Application($config))->run(); diff --git a/backend/robots.txt b/environments/dev/backend/robots.txt similarity index 53% rename from backend/robots.txt rename to environments/dev/backend/robots.txt index 1f53798..77470cb 100644 --- a/backend/robots.txt +++ b/environments/dev/backend/robots.txt @@ -1,2 +1,2 @@ User-agent: * -Disallow: / +Disallow: / \ No newline at end of file diff --git a/environments/dev/common/config/main-local.php b/environments/dev/common/config/main-local.php index 43db30e..47ea80f 100644 --- a/environments/dev/common/config/main-local.php +++ b/environments/dev/common/config/main-local.php @@ -3,7 +3,7 @@ 'components' => [ 'db' => [ 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=yii2advanced', + 'dsn' => 'mysql:host=localhost;dbname=yii2practical', 'username' => 'root', 'password' => '', 'charset' => 'utf8', diff --git a/environments/dev/common/config/test-local.php b/environments/dev/common/config/test-local.php new file mode 100644 index 0000000..784b2ac --- /dev/null +++ b/environments/dev/common/config/test-local.php @@ -0,0 +1,13 @@ + [ + 'db' => [ + 'dsn' => 'mysql:host=localhost;dbname=yii2practical_test', + ] + ], + ] +); diff --git a/environments/dev/frontend/config/main-local.php b/environments/dev/frontend/config/main-local.php index 295ee4f..d54b657 100644 --- a/environments/dev/frontend/config/main-local.php +++ b/environments/dev/frontend/config/main-local.php @@ -5,17 +5,17 @@ 'request' => [ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => '', - // unique CSRF cookie parameter for frontend (set by kartik-v/yii2-app-practical) + // unique CSRF cookie parameter for frontend (set by kartik-v/yii2-app-practical-a) 'csrfParam' => '_frontendCsrf', ], - // unique identity cookie configuration for frontend (set by kartik-v/yii2-app-practical) + // unique identity cookie configuration for frontend (set by kartik-v/yii2-app-practical-a) 'user' => [ 'identityCookie' => [ 'name' => '_frontendUser', // unique for frontend 'path' => '/' // set it to correct path for frontend app. ] ], - // unique session configuration for frontend (set by kartik-v/yii2-app-practical) + // unique session configuration for frontend (set by kartik-v/yii2-app-practical-a) 'session' => [ 'name' => '_frontendSessionId', // unique for frontend 'savePath' => __DIR__ . '/../runtime/sessions' // set it to correct path for frontend app. @@ -29,6 +29,7 @@ $config['modules']['debug'] = [ 'class' => 'yii\debug\Module', ]; + $config['bootstrap'][] = 'gii'; $config['modules']['gii'] = [ 'class' => 'yii\gii\Module', diff --git a/environments/dev/frontend/config/test-local.php b/environments/dev/frontend/config/test-local.php new file mode 100644 index 0000000..4513a34 --- /dev/null +++ b/environments/dev/frontend/config/test-local.php @@ -0,0 +1,9 @@ +run(); diff --git a/environments/dev/index.php b/environments/dev/index.php index f130d22..3aea8a0 100644 --- a/environments/dev/index.php +++ b/environments/dev/index.php @@ -15,4 +15,4 @@ ); $application = new yii\web\Application($config); -$application->run(); +$application->run(); \ No newline at end of file diff --git a/environments/dev/robots.txt b/environments/dev/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/environments/dev/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/environments/dev/tests/codeception/config/config-local.php b/environments/dev/tests/codeception/config/config-local.php deleted file mode 100644 index c2a6a04..0000000 --- a/environments/dev/tests/codeception/config/config-local.php +++ /dev/null @@ -1,11 +0,0 @@ - [ - 'db' => [ - 'dsn' => 'mysql:host=localhost;dbname=yii2_advanced_tests', - 'username' => 'root', - 'password' => '', - 'charset' => 'utf8', - ], - ], -]; diff --git a/environments/dev/yii_test b/environments/dev/yii_test new file mode 100644 index 0000000..880050e --- /dev/null +++ b/environments/dev/yii_test @@ -0,0 +1,27 @@ +#!/usr/bin/env php +run(); +exit($exitCode); diff --git a/tests/codeception/bin/yii.bat b/environments/dev/yii_test.bat similarity index 92% rename from tests/codeception/bin/yii.bat rename to environments/dev/yii_test.bat index d516b3a..854e08b 100644 --- a/tests/codeception/bin/yii.bat +++ b/environments/dev/yii_test.bat @@ -15,6 +15,6 @@ set YII_PATH=%~dp0 if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe -"%PHP_COMMAND%" "%YII_PATH%yii" %* +"%PHP_COMMAND%" "%YII_PATH%yii_test" %* @endlocal diff --git a/environments/index.php b/environments/index.php index 19c989d..e0eb457 100644 --- a/environments/index.php +++ b/environments/index.php @@ -35,11 +35,11 @@ 'backend/runtime', 'backend/web/assets', 'frontend/runtime', - 'frontend/web/assets', + 'frontend/assets', ], 'setExecutable' => [ 'yii', - 'tests/codeception/bin/yii', + 'yii_test', ], 'setCookieValidationKey' => [ 'backend/config/main-local.php', @@ -52,7 +52,7 @@ 'backend/runtime', 'backend/web/assets', 'frontend/runtime', - 'frontend/web/assets', + 'frontend/assets', ], 'setExecutable' => [ 'yii', diff --git a/environments/prod/backend/config/main-local.php b/environments/prod/backend/config/main-local.php index 40d8717..f089bbc 100644 --- a/environments/prod/backend/config/main-local.php +++ b/environments/prod/backend/config/main-local.php @@ -4,17 +4,17 @@ 'request' => [ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => '', - // unique CSRF cookie parameter for backend (set by kartik-v/yii2-app-practical) + // unique CSRF cookie parameter for backend (set by kartik-v/yii2-app-practical-a) 'csrfParam' => '_backendCsrf', ], - // unique identity cookie configuration for backend (set by kartik-v/yii2-app-practical) + // unique identity cookie configuration for backend (set by kartik-v/yii2-app-practical-a) 'user' => [ 'identityCookie' => [ 'name' => '_backendUser', // unique for backend 'path' => '/backend/web' // set it to correct path for backend app. ] ], - // unique session configuration for backend (set by kartik-v/yii2-app-practical) + // unique session configuration for backend (set by kartik-v/yii2-app-practical-a) 'session' => [ 'name' => '_backendSessionId', // unique for backend 'savePath' => __DIR__ . '/../runtime/sessions' // set it to correct path for backend app. diff --git a/environments/prod/backend/index.php b/environments/prod/backend/index.php index 7cca436..2af48dd 100644 --- a/environments/prod/backend/index.php +++ b/environments/prod/backend/index.php @@ -2,17 +2,16 @@ defined('YII_DEBUG') or define('YII_DEBUG', false); defined('YII_ENV') or define('YII_ENV', 'prod'); -require(__DIR__ . '/../vendor/autoload.php'); -require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php'); -require(__DIR__ . '/../common/config/bootstrap.php'); -require(__DIR__ . '/config/bootstrap.php'); +require(__DIR__ . '/../../vendor/autoload.php'); +require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php'); +require(__DIR__ . '/../../common/config/bootstrap.php'); +require(__DIR__ . '/../config/bootstrap.php'); $config = yii\helpers\ArrayHelper::merge( - require(__DIR__ . '/../common/config/main.php'), - require(__DIR__ . '/../common/config/main-local.php'), - require(__DIR__ . '/config/main.php'), - require(__DIR__ . '/config/main-local.php') + require(__DIR__ . '/../../common/config/main.php'), + require(__DIR__ . '/../../common/config/main-local.php'), + require(__DIR__ . '/../config/main.php'), + require(__DIR__ . '/../config/main-local.php') ); -$application = new yii\web\Application($config); -$application->run(); \ No newline at end of file +(new yii\web\Application($config))->run(); diff --git a/environments/prod/backend/robots.txt b/environments/prod/backend/robots.txt new file mode 100644 index 0000000..77470cb --- /dev/null +++ b/environments/prod/backend/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/environments/prod/common/config/main-local.php b/environments/prod/common/config/main-local.php index 84c4d9f..54eed57 100644 --- a/environments/prod/common/config/main-local.php +++ b/environments/prod/common/config/main-local.php @@ -3,7 +3,7 @@ 'components' => [ 'db' => [ 'class' => 'yii\db\Connection', - 'dsn' => 'mysql:host=localhost;dbname=yii2advanced', + 'dsn' => 'mysql:host=localhost;dbname=yii2practical', 'username' => 'root', 'password' => '', 'charset' => 'utf8', diff --git a/environments/prod/frontend/config/main-local.php b/environments/prod/frontend/config/main-local.php index 60e1b78..0f9143d 100644 --- a/environments/prod/frontend/config/main-local.php +++ b/environments/prod/frontend/config/main-local.php @@ -4,17 +4,17 @@ 'request' => [ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => '', - // unique CSRF cookie parameter for frontend (set by kartik-v/yii2-app-practical) + // unique CSRF cookie parameter for frontend (set by kartik-v/yii2-app-practical-a) 'csrfParam' => '_frontendCsrf', ], - // unique identity cookie configuration for frontend (set by kartik-v/yii2-app-practical) + // unique identity cookie configuration for frontend (set by kartik-v/yii2-app-practical-a) 'user' => [ 'identityCookie' => [ 'name' => '_frontendUser', // unique for frontend 'path' => '/' // set it to correct path for frontend app. ] ], - // unique session configuration for frontend (set by kartik-v/yii2-app-practical) + // unique session configuration for frontend (set by kartik-v/yii2-app-practical-a) 'session' => [ 'name' => '_frontendSessionId', // unique for frontend 'savePath' => __DIR__ . '/../runtime/sessions' // set it to correct path for frontend app. diff --git a/robots.txt b/environments/prod/robots.txt similarity index 60% rename from robots.txt rename to environments/prod/robots.txt index 6f27bb6..14267e9 100644 --- a/robots.txt +++ b/environments/prod/robots.txt @@ -1,2 +1,2 @@ User-agent: * -Disallow: \ No newline at end of file +Allow: / \ No newline at end of file diff --git a/environments/prod/tests/codeception/config/config-local.php b/environments/prod/tests/codeception/config/config-local.php deleted file mode 100644 index c2a6a04..0000000 --- a/environments/prod/tests/codeception/config/config-local.php +++ /dev/null @@ -1,11 +0,0 @@ - [ - 'db' => [ - 'dsn' => 'mysql:host=localhost;dbname=yii2_advanced_tests', - 'username' => 'root', - 'password' => '', - 'charset' => 'utf8', - ], - ], -]; diff --git a/frontend/assets/css/site.css b/frontend/assets/css/site.css index 490c34f..5f1e6b9 100644 --- a/frontend/assets/css/site.css +++ b/frontend/assets/css/site.css @@ -96,16 +96,25 @@ a.desc:after { } /* align the logout "link" (button in form) of the navbar */ -.nav > li > form { - padding: 8px; +.nav li > form > button.logout { + padding: 15px; + border: none; } -@media(max-width:768px) { - .nav li > form { - padding: 3px; - } +@media(max-width:767px) { + .nav li > form > button.logout { + display:block; + text-align: left; + width: 100%; + padding: 10px 15px; + } } -.nav > li > form > button:hover { +.nav > li > form > button.logout:focus, +.nav > li > form > button.logout:hover { text-decoration: none; } + +.nav > li > form > button.logout:focus { + outline: none; +} diff --git a/frontend/codeception.yml b/frontend/codeception.yml new file mode 100644 index 0000000..1203f39 --- /dev/null +++ b/frontend/codeception.yml @@ -0,0 +1,15 @@ +namespace: frontend\tests +actor: Tester +paths: + tests: tests + log: tests/_output + data: tests/_data + helpers: tests/_support +settings: + bootstrap: _bootstrap.php + colors: true + memory_limit: 1024M +modules: + config: + Yii2: + configFile: 'config/test-local.php' diff --git a/frontend/config/.gitignore b/frontend/config/.gitignore index 20da318..42799dd 100644 --- a/frontend/config/.gitignore +++ b/frontend/config/.gitignore @@ -1,2 +1,3 @@ main-local.php -params-local.php \ No newline at end of file +params-local.php +test-local.php diff --git a/frontend/config/main.php b/frontend/config/main.php index e84be29..988fef4 100644 --- a/frontend/config/main.php +++ b/frontend/config/main.php @@ -7,14 +7,22 @@ ); return [ - 'id' => 'app-practical-a-frontend', + 'id' => 'app-frontend', 'basePath' => dirname(__DIR__), 'bootstrap' => ['log'], 'controllerNamespace' => 'frontend\controllers', 'components' => [ + 'request' => [ + 'csrfParam' => '_csrf-frontend', + ], 'user' => [ 'identityClass' => 'common\models\User', 'enableAutoLogin' => true, + 'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true], + ], + 'session' => [ + // this is the name of the session cookie used for login on the frontend + 'name' => 'practical-a-frontend', ], 'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, @@ -27,7 +35,13 @@ ], 'errorHandler' => [ 'errorAction' => 'site/error', - ] + ], + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => [ + ], + ], ], 'params' => $params, ]; diff --git a/frontend/config/test.php b/frontend/config/test.php new file mode 100644 index 0000000..50882c4 --- /dev/null +++ b/frontend/config/test.php @@ -0,0 +1,12 @@ + 'app-frontend-tests', + 'components' => [ + 'assetManager' => [ + 'basePath' => __DIR__ . '/../assets', + ], + 'urlManager' => [ + 'showScriptName' => true, + ], + ], +]; diff --git a/frontend/controllers/SiteController.php b/frontend/controllers/SiteController.php index 67b5aa0..519d575 100644 --- a/frontend/controllers/SiteController.php +++ b/frontend/controllers/SiteController.php @@ -120,7 +120,7 @@ public function actionContact() if ($model->sendEmail(Yii::$app->params['adminEmail'])) { Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.'); } else { - Yii::$app->session->setFlash('error', 'There was an error sending email.'); + Yii::$app->session->setFlash('error', 'There was an error sending your message.'); } return $this->refresh(); @@ -176,7 +176,7 @@ public function actionRequestPasswordReset() return $this->goHome(); } else { - Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for email provided.'); + Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for the provided email address.'); } } @@ -201,7 +201,7 @@ public function actionResetPassword($token) } if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) { - Yii::$app->session->setFlash('success', 'New password was saved.'); + Yii::$app->session->setFlash('success', 'New password saved.'); return $this->goHome(); } diff --git a/frontend/models/ContactForm.php b/frontend/models/ContactForm.php index 613abb5..d0cc9cb 100644 --- a/frontend/models/ContactForm.php +++ b/frontend/models/ContactForm.php @@ -16,6 +16,7 @@ class ContactForm extends Model public $body; public $verifyCode; + /** * @inheritdoc */ @@ -44,8 +45,8 @@ public function attributeLabels() /** * Sends an email to the specified email address using the information collected by this model. * - * @param string $email the target email address - * @return boolean whether the email was sent + * @param string $email the target email address + * @return bool whether the email was sent */ public function sendEmail($email) { diff --git a/frontend/models/PasswordResetRequestForm.php b/frontend/models/PasswordResetRequestForm.php index 57d42b5..c11aeec 100644 --- a/frontend/models/PasswordResetRequestForm.php +++ b/frontend/models/PasswordResetRequestForm.php @@ -12,19 +12,20 @@ class PasswordResetRequestForm extends Model { public $email; + /** * @inheritdoc */ public function rules() { return [ - ['email', 'filter', 'filter' => 'trim'], + ['email', 'trim'], ['email', 'required'], ['email', 'email'], ['email', 'exist', 'targetClass' => '\common\models\User', 'filter' => ['status' => User::STATUS_ACTIVE], - 'message' => 'There is no user with such email.' + 'message' => 'There is no user with this email address.' ], ]; } @@ -32,7 +33,7 @@ public function rules() /** * Sends an email with a link, for resetting the password. * - * @return boolean whether the email was send + * @return bool whether the email was send */ public function sendEmail() { @@ -48,10 +49,9 @@ public function sendEmail() if (!User::isPasswordResetTokenValid($user->password_reset_token)) { $user->generatePasswordResetToken(); - } - - if (!$user->save()) { - return false; + if (!$user->save()) { + return false; + } } return Yii::$app diff --git a/frontend/models/ResetPasswordForm.php b/frontend/models/ResetPasswordForm.php index 164fde7..fb36dd0 100644 --- a/frontend/models/ResetPasswordForm.php +++ b/frontend/models/ResetPasswordForm.php @@ -21,8 +21,8 @@ class ResetPasswordForm extends Model /** * Creates a form model given a token. * - * @param string $token - * @param array $config name-value pairs that will be used to initialize the object properties + * @param string $token + * @param array $config name-value pairs that will be used to initialize the object properties * @throws \yii\base\InvalidParamException if token is empty or not valid */ public function __construct($token, $config = []) @@ -51,7 +51,7 @@ public function rules() /** * Resets password. * - * @return boolean if password was reset. + * @return bool if password was reset. */ public function resetPassword() { diff --git a/frontend/models/SignupForm.php b/frontend/models/SignupForm.php index bde9118..57a51d8 100644 --- a/frontend/models/SignupForm.php +++ b/frontend/models/SignupForm.php @@ -13,18 +13,19 @@ class SignupForm extends Model public $email; public $password; + /** * @inheritdoc */ public function rules() { return [ - ['username', 'filter', 'filter' => 'trim'], + ['username', 'trim'], ['username', 'required'], ['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'], ['username', 'string', 'min' => 2, 'max' => 255], - ['email', 'filter', 'filter' => 'trim'], + ['email', 'trim'], ['email', 'required'], ['email', 'email'], ['email', 'string', 'max' => 255], diff --git a/frontend/runtime/.gitignore b/frontend/runtime/.gitignore index 5d81bf7..1372325 100644 --- a/frontend/runtime/.gitignore +++ b/frontend/runtime/.gitignore @@ -1,3 +1,4 @@ -* -!.gitignore -!*/ \ No newline at end of file +/* +!/sessions +!/sessions/* +!/.gitignore \ No newline at end of file diff --git a/frontend/tests/_bootstrap.php b/frontend/tests/_bootstrap.php new file mode 100644 index 0000000..83a1f26 --- /dev/null +++ b/frontend/tests/_bootstrap.php @@ -0,0 +1,9 @@ + 'erau', + 'auth_key' => 'tUu1qHcde0diwUol3xeI-18MuHkkprQI', + // password_0 + 'password_hash' => '$2y$13$nJ1WDlBaGcbCdbNC5.5l4.sgy.OMEKCqtDQOdQ2OWpgiKRWYyzzne', + 'password_reset_token' => 'RkD_Jw0_8HEedzLk7MM-ZKEFfYR7VbMr_1392559490', + 'created_at' => '1392559490', + 'updated_at' => '1392559490', + 'email' => 'sfriesen@jenkins.info', + ], +]; diff --git a/tests/codeception/frontend/unit/fixtures/data/models/user.php b/frontend/tests/_data/user.php similarity index 100% rename from tests/codeception/frontend/unit/fixtures/data/models/user.php rename to frontend/tests/_data/user.php diff --git a/tests/codeception/common/_output/.gitignore b/frontend/tests/_output/.gitignore similarity index 100% rename from tests/codeception/common/_output/.gitignore rename to frontend/tests/_output/.gitignore diff --git a/frontend/tests/_support/.gitignore b/frontend/tests/_support/.gitignore new file mode 100644 index 0000000..36e264c --- /dev/null +++ b/frontend/tests/_support/.gitignore @@ -0,0 +1 @@ +_generated diff --git a/frontend/tests/_support/FunctionalTester.php b/frontend/tests/_support/FunctionalTester.php new file mode 100644 index 0000000..7475d8a --- /dev/null +++ b/frontend/tests/_support/FunctionalTester.php @@ -0,0 +1,33 @@ +see($message, '.help-block'); + } + + public function dontSeeValidationError($message) + { + $this->dontSee($message, '.help-block'); + } +} diff --git a/frontend/tests/_support/UnitTester.php b/frontend/tests/_support/UnitTester.php new file mode 100644 index 0000000..8c708e7 --- /dev/null +++ b/frontend/tests/_support/UnitTester.php @@ -0,0 +1,25 @@ +amOnPage(Url::toRoute('/site/index')); + $I->see('My Company'); + + $I->seeLink('About'); + $I->click('About'); + $I->wait(2); // wait for page to be opened + + $I->see('This is the About page.'); + } +} diff --git a/frontend/tests/acceptance/_bootstrap.php b/frontend/tests/acceptance/_bootstrap.php new file mode 100644 index 0000000..47716f0 --- /dev/null +++ b/frontend/tests/acceptance/_bootstrap.php @@ -0,0 +1,16 @@ + 'davert']); + * ``` + * + * In Cept + * + * ```php + * \Codeception\Util\Fixtures::get('user1'); + * ``` + */ \ No newline at end of file diff --git a/frontend/tests/functional.suite.yml b/frontend/tests/functional.suite.yml new file mode 100644 index 0000000..3f851d1 --- /dev/null +++ b/frontend/tests/functional.suite.yml @@ -0,0 +1,5 @@ +class_name: FunctionalTester +modules: + enabled: + - Filesystem + - Yii2 diff --git a/frontend/tests/functional/AboutCest.php b/frontend/tests/functional/AboutCest.php new file mode 100644 index 0000000..6c3cb9e --- /dev/null +++ b/frontend/tests/functional/AboutCest.php @@ -0,0 +1,13 @@ +amOnRoute('site/about'); + $I->see('About', 'h1'); + } +} diff --git a/frontend/tests/functional/ContactCest.php b/frontend/tests/functional/ContactCest.php new file mode 100644 index 0000000..bdda991 --- /dev/null +++ b/frontend/tests/functional/ContactCest.php @@ -0,0 +1,59 @@ +amOnPage(['site/contact']); + } + + public function checkContact(FunctionalTester $I) + { + $I->see('Contact', 'h1'); + } + + public function checkContactSubmitNoData(FunctionalTester $I) + { + $I->submitForm('#contact-form', []); + $I->see('Contact', 'h1'); + $I->seeValidationError('Name cannot be blank'); + $I->seeValidationError('Email cannot be blank'); + $I->seeValidationError('Subject cannot be blank'); + $I->seeValidationError('Body cannot be blank'); + $I->seeValidationError('The verification code is incorrect'); + } + + public function checkContactSubmitNotCorrectEmail(FunctionalTester $I) + { + $I->submitForm('#contact-form', [ + 'ContactForm[name]' => 'tester', + 'ContactForm[email]' => 'tester.email', + 'ContactForm[subject]' => 'test subject', + 'ContactForm[body]' => 'test content', + 'ContactForm[verifyCode]' => 'testme', + ]); + $I->seeValidationError('Email is not a valid email address.'); + $I->dontSeeValidationError('Name cannot be blank'); + $I->dontSeeValidationError('Subject cannot be blank'); + $I->dontSeeValidationError('Body cannot be blank'); + $I->dontSeeValidationError('The verification code is incorrect'); + } + + public function checkContactSubmitCorrectData(FunctionalTester $I) + { + $I->submitForm('#contact-form', [ + 'ContactForm[name]' => 'tester', + 'ContactForm[email]' => 'tester@example.com', + 'ContactForm[subject]' => 'test subject', + 'ContactForm[body]' => 'test content', + 'ContactForm[verifyCode]' => 'testme', + ]); + $I->seeEmailIsSent(); + $I->see('Thank you for contacting us. We will respond to you as soon as possible.'); + } +} diff --git a/frontend/tests/functional/HomeCest.php b/frontend/tests/functional/HomeCest.php new file mode 100644 index 0000000..8f99b48 --- /dev/null +++ b/frontend/tests/functional/HomeCest.php @@ -0,0 +1,17 @@ +amOnPage(\Yii::$app->homeUrl); + $I->see('My Company'); + $I->seeLink('About'); + $I->click('About'); + $I->see('This is the About page.'); + } +} \ No newline at end of file diff --git a/frontend/tests/functional/LoginCest.php b/frontend/tests/functional/LoginCest.php new file mode 100644 index 0000000..b496d7a --- /dev/null +++ b/frontend/tests/functional/LoginCest.php @@ -0,0 +1,49 @@ +haveFixtures([ + 'user' => [ + 'class' => UserFixture::className(), + 'dataFile' => codecept_data_dir() . 'login_data.php' + ] + ]); + $I->amOnRoute('site/login'); + } + + protected function formParams($login, $password) + { + return [ + 'LoginForm[username]' => $login, + 'LoginForm[password]' => $password, + ]; + } + + public function checkEmpty(FunctionalTester $I) + { + $I->submitForm('#login-form', $this->formParams('', '')); + $I->seeValidationError('Username cannot be blank.'); + $I->seeValidationError('Password cannot be blank.'); + } + + public function checkWrongPassword(FunctionalTester $I) + { + $I->submitForm('#login-form', $this->formParams('admin', 'wrong')); + $I->seeValidationError('Incorrect username or password.'); + } + + public function checkValidLogin(FunctionalTester $I) + { + $I->submitForm('#login-form', $this->formParams('erau', 'password_0')); + $I->see('Logout (erau)', 'form button[type=submit]'); + $I->dontSeeLink('Login'); + $I->dontSeeLink('Signup'); + } +} diff --git a/frontend/tests/functional/SignupCest.php b/frontend/tests/functional/SignupCest.php new file mode 100644 index 0000000..8cfde9a --- /dev/null +++ b/frontend/tests/functional/SignupCest.php @@ -0,0 +1,57 @@ +amOnRoute('site/signup'); + } + + public function signupWithEmptyFields(FunctionalTester $I) + { + $I->see('Signup', 'h1'); + $I->see('Please fill out the following fields to signup:'); + $I->submitForm($this->formId, []); + $I->seeValidationError('Username cannot be blank.'); + $I->seeValidationError('Email cannot be blank.'); + $I->seeValidationError('Password cannot be blank.'); + + } + + public function signupWithWrongEmail(FunctionalTester $I) + { + $I->submitForm( + $this->formId, [ + 'SignupForm[username]' => 'tester', + 'SignupForm[email]' => 'ttttt', + 'SignupForm[password]' => 'tester_password', + ] + ); + $I->dontSee('Username cannot be blank.', '.help-block'); + $I->dontSee('Password cannot be blank.', '.help-block'); + $I->see('Email is not a valid email address.', '.help-block'); + } + + public function signupSuccessfully(FunctionalTester $I) + { + $I->submitForm($this->formId, [ + 'SignupForm[username]' => 'tester', + 'SignupForm[email]' => 'tester.email@example.com', + 'SignupForm[password]' => 'tester_password', + ]); + + $I->seeRecord('common\models\User', [ + 'username' => 'tester', + 'email' => 'tester.email@example.com', + ]); + + $I->see('Logout (tester)', 'form button[type=submit]'); + } +} diff --git a/frontend/tests/functional/_bootstrap.php b/frontend/tests/functional/_bootstrap.php new file mode 100644 index 0000000..30ed54b --- /dev/null +++ b/frontend/tests/functional/_bootstrap.php @@ -0,0 +1,16 @@ + 'davert']); + * ``` + * + * In Cests + * + * ```php + * \Codeception\Util\Fixtures::get('user1'); + * ``` + */ \ No newline at end of file diff --git a/frontend/tests/unit.suite.yml b/frontend/tests/unit.suite.yml new file mode 100644 index 0000000..27f2907 --- /dev/null +++ b/frontend/tests/unit.suite.yml @@ -0,0 +1,6 @@ +class_name: UnitTester +modules: + enabled: + - Yii2: + part: [orm, email, fixtures] + - Asserts diff --git a/frontend/tests/unit/_bootstrap.php b/frontend/tests/unit/_bootstrap.php new file mode 100644 index 0000000..e432ce5 --- /dev/null +++ b/frontend/tests/unit/_bootstrap.php @@ -0,0 +1,16 @@ + 'davert']); + * ``` + * + * In Tests + * + * ```php + * \Codeception\Util\Fixtures::get('user1'); + * ``` + */ diff --git a/frontend/tests/unit/models/ContactFormTest.php b/frontend/tests/unit/models/ContactFormTest.php new file mode 100644 index 0000000..acdf9db --- /dev/null +++ b/frontend/tests/unit/models/ContactFormTest.php @@ -0,0 +1,32 @@ +attributes = [ + 'name' => 'Tester', + 'email' => 'tester@example.com', + 'subject' => 'very important letter subject', + 'body' => 'body of current message', + ]; + + expect_that($model->sendEmail('admin@example.com')); + + // using Yii2 module actions to check email was sent + $this->tester->seeEmailIsSent(); + + $emailMessage = $this->tester->grabLastSentEmail(); + expect('valid email is sent', $emailMessage)->isInstanceOf('yii\mail\MessageInterface'); + expect($emailMessage->getTo())->hasKey('admin@example.com'); + expect($emailMessage->getFrom())->hasKey('tester@example.com'); + expect($emailMessage->getSubject())->equals('very important letter subject'); + expect($emailMessage->toString())->contains('body of current message'); + } +} diff --git a/frontend/tests/unit/models/PasswordResetRequestFormTest.php b/frontend/tests/unit/models/PasswordResetRequestFormTest.php new file mode 100644 index 0000000..6f4a8e7 --- /dev/null +++ b/frontend/tests/unit/models/PasswordResetRequestFormTest.php @@ -0,0 +1,59 @@ +tester->haveFixtures([ + 'user' => [ + 'class' => UserFixture::className(), + 'dataFile' => codecept_data_dir() . 'user.php' + ] + ]); + } + + public function testSendMessageWithWrongEmailAddress() + { + $model = new PasswordResetRequestForm(); + $model->email = 'not-existing-email@example.com'; + expect_not($model->sendEmail()); + } + + public function testNotSendEmailsToInactiveUser() + { + $user = $this->tester->grabFixture('user', 1); + $model = new PasswordResetRequestForm(); + $model->email = $user['email']; + expect_not($model->sendEmail()); + } + + public function testSendEmailSuccessfully() + { + $userFixture = $this->tester->grabFixture('user', 0); + + $model = new PasswordResetRequestForm(); + $model->email = $userFixture['email']; + $user = User::findOne(['password_reset_token' => $userFixture['password_reset_token']]); + + expect_that($model->sendEmail()); + expect_that($user->password_reset_token); + + $emailMessage = $this->tester->grabLastSentEmail(); + expect('valid email is sent', $emailMessage)->isInstanceOf('yii\mail\MessageInterface'); + expect($emailMessage->getTo())->hasKey($model->email); + expect($emailMessage->getFrom())->hasKey(Yii::$app->params['supportEmail']); + } +} diff --git a/frontend/tests/unit/models/ResetPasswordFormTest.php b/frontend/tests/unit/models/ResetPasswordFormTest.php new file mode 100644 index 0000000..f506368 --- /dev/null +++ b/frontend/tests/unit/models/ResetPasswordFormTest.php @@ -0,0 +1,44 @@ +tester->haveFixtures([ + 'user' => [ + 'class' => UserFixture::className(), + 'dataFile' => codecept_data_dir() . 'user.php' + ], + ]); + } + + public function testResetWrongToken() + { + $this->tester->expectException('yii\base\InvalidParamException', function() { + new ResetPasswordForm(''); + }); + + $this->tester->expectException('yii\base\InvalidParamException', function() { + new ResetPasswordForm('notexistingtoken_1391882543'); + }); + } + + public function testResetCorrectToken() + { + $user = $this->tester->grabFixture('user', 0); + $form = new ResetPasswordForm($user['password_reset_token']); + expect_that($form->resetPassword()); + } + +} diff --git a/frontend/tests/unit/models/SignupFormTest.php b/frontend/tests/unit/models/SignupFormTest.php new file mode 100644 index 0000000..eb9b61c --- /dev/null +++ b/frontend/tests/unit/models/SignupFormTest.php @@ -0,0 +1,59 @@ +tester->haveFixtures([ + 'user' => [ + 'class' => UserFixture::className(), + 'dataFile' => codecept_data_dir() . 'user.php' + ] + ]); + } + + public function testCorrectSignup() + { + $model = new SignupForm([ + 'username' => 'some_username', + 'email' => 'some_email@example.com', + 'password' => 'some_password', + ]); + + $user = $model->signup(); + + expect($user)->isInstanceOf('common\models\User'); + + expect($user->username)->equals('some_username'); + expect($user->email)->equals('some_email@example.com'); + expect($user->validatePassword('some_password'))->true(); + } + + public function testNotCorrectSignup() + { + $model = new SignupForm([ + 'username' => 'troy.becker', + 'email' => 'nicolas.dianna@hotmail.com', + 'password' => 'some_password', + ]); + + expect_not($model->signup()); + expect_that($model->getErrors('username')); + expect_that($model->getErrors('email')); + + expect($model->getFirstError('username')) + ->equals('This username has already been taken.'); + expect($model->getFirstError('email')) + ->equals('This email address has already been taken.'); + } +} diff --git a/frontend/views/layouts/main.php b/frontend/views/layouts/main.php index c86aa9b..a55833b 100644 --- a/frontend/views/layouts/main.php +++ b/frontend/views/layouts/main.php @@ -17,6 +17,7 @@ + <?= Html::encode($this->title) ?> @@ -47,7 +48,7 @@ . Html::beginForm(['/site/logout'], 'post') . Html::submitButton( 'Logout (' . Yii::$app->user->identity->username . ')', - ['class' => 'btn btn-link'] + ['class' => 'btn btn-link logout'] ) . Html::endForm() . ''; diff --git a/frontend/views/site/contact.php b/frontend/views/site/contact.php index dcad18f..dc48410 100644 --- a/frontend/views/site/contact.php +++ b/frontend/views/site/contact.php @@ -28,7 +28,7 @@ field($model, 'subject') ?> - field($model, 'body')->textArea(['rows' => 6]) ?> + field($model, 'body')->textarea(['rows' => 6]) ?> field($model, 'verifyCode')->widget(Captcha::className(), [ 'template' => '
{image}
{input}
', diff --git a/frontend/web/.gitignore b/frontend/web/.gitignore deleted file mode 100644 index 25c74e6..0000000 --- a/frontend/web/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/index.php -/index-test.php diff --git a/init b/init index 50d51eb..7aaf086 100644 --- a/init +++ b/init @@ -174,10 +174,13 @@ function setWritable($root, $paths) { foreach ($paths as $writable) { if (is_dir("$root/$writable")) { - echo " chmod 0777 $writable\n"; - @chmod("$root/$writable", 0777); + if (@chmod("$root/$writable", 0777)) { + echo " chmod 0777 $writable\n"; + } else { + printError("Operation chmod not permitted for directory $writable."); + } } else { - echo "\n Error. Directory $writable does not exist. \n"; + printError("Directory $writable does not exist."); } } } @@ -185,8 +188,15 @@ function setWritable($root, $paths) function setExecutable($root, $paths) { foreach ($paths as $executable) { - echo " chmod 0755 $executable\n"; - @chmod("$root/$executable", 0755); + if (file_exists("$root/$executable")) { + if (@chmod("$root/$executable", 0755)) { + echo " chmod 0755 $executable\n"; + } else { + printError("Operation chmod not permitted for $executable."); + } + } else { + printError("$executable does not exist."); + } } } @@ -203,15 +213,87 @@ function setCookieValidationKey($root, $paths) } } -function createSymlink($root, $links) { +function createSymlink($root, $links) +{ foreach ($links as $link => $target) { - echo " symlink " . $root . "/" . $target . " " . $root . "/" . $link . "\n"; //first removing folders to avoid errors if the folder already exists @rmdir($root . "/" . $link); //next removing existing symlink in order to update the target if (is_link($root . "/" . $link)) { @unlink($root . "/" . $link); } - @symlink($root . "/" . $target, $root . "/" . $link); + if (@symlink($root . "/" . $target, $root . "/" . $link)) { + echo " symlink $root/$target $root/$link\n"; + } else { + printError("Cannot create symlink $root/$target $root/$link."); + } } } + +/** + * Prints error message. + * @param string $message message + */ +function printError($message) +{ + echo "\n " . formatMessage("Error. $message", ['fg-red']) . " \n"; +} + +/** + * Returns true if the stream supports colorization. ANSI colors are disabled if not supported by the stream. + * + * - windows without ansicon + * - not tty consoles + * + * @return boolean true if the stream supports ANSI colors, otherwise false. + */ +function ansiColorsSupported() +{ + return DIRECTORY_SEPARATOR === '\\' + ? getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON' + : function_exists('posix_isatty') && @posix_isatty(STDOUT); +} + +/** + * Get ANSI code of style. + * @param string $name style name + * @return integer ANSI code of style. + */ +function getStyleCode($name) +{ + $styles = [ + 'bold' => 1, + 'fg-black' => 30, + 'fg-red' => 31, + 'fg-green' => 32, + 'fg-yellow' => 33, + 'fg-blue' => 34, + 'fg-magenta' => 35, + 'fg-cyan' => 36, + 'fg-white' => 37, + 'bg-black' => 40, + 'bg-red' => 41, + 'bg-green' => 42, + 'bg-yellow' => 43, + 'bg-blue' => 44, + 'bg-magenta' => 45, + 'bg-cyan' => 46, + 'bg-white' => 47, + ]; + return $styles[$name]; +} + +/** + * Formats message using styles if STDOUT supports it. + * @param string $message message + * @param string[] $styles styles + * @return string formatted message. + */ +function formatMessage($message, $styles) +{ + if (empty($styles) || !ansiColorsSupported()) { + return $message; + } + + return sprintf("\x1b[%sm", implode(';', array_map('getStyleCode', $styles))) . $message . "\x1b[0m"; +} diff --git a/requirements.php b/requirements.php index fd84f47..62c731b 100644 --- a/requirements.php +++ b/requirements.php @@ -7,7 +7,7 @@ * * In order to run this script from the web, you should copy it to the web root. * If you are using Linux you can create a hard link instead, using the following command: - * ln requirements.php ../requirements.php + * ln ../requirements.php requirements.php */ // you may need to adjust this path to the correct Yii framework path diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 112090f..0000000 --- a/tests/README.md +++ /dev/null @@ -1,59 +0,0 @@ -This directory contains various tests for the advanced applications. - -Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/). - -After creating and setting up the advanced application, follow these steps to prepare for the tests: - -1. Install Codeception if it's not yet installed: - - ``` - composer global require "codeception/codeception=2.1.*" "codeception/specify=*" "codeception/verify=*" - ``` - - If you've never used Composer for global packages run `composer global status`. It should output: - - ``` - Changed current directory to - ``` - - Then add `/vendor/bin` to you `PATH` environment variable. Now you're able to use `codecept` from command - line globally. - -2. Install faker extension by running the following from template root directory where `composer.json` is: - - ``` - composer require --dev yiisoft/yii2-faker:* - ``` - -3. Create a database for tests, adjust the `components['db']` configuration in `tests/codeception/config/config-local.php`, - then update it by applying migrations: - - ``` - codeception/bin/yii migrate - ``` - -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 - webserver. In the root directory where `common`, `frontend` etc. are execute the following: - - ``` - php -S localhost:8080 - ``` - -5. Now you can run the tests with the following commands, assuming you are in the `tests/codeception` directory: - - ``` - # frontend tests - cd frontend - codecept build - codecept run - - # backend tests - - cd backend - codecept build - codecept run - - # etc. - ``` - - If you already have run `codecept build` for each application, you can skip that step and run all tests by a single `codecept run`. diff --git a/tests/codeception.yml b/tests/codeception.yml deleted file mode 100644 index 1a793ed..0000000 --- a/tests/codeception.yml +++ /dev/null @@ -1,11 +0,0 @@ -include: - - codeception/common - - codeception/console - - codeception/backend - - codeception/frontend - -paths: - log: codeception/_output - -settings: - colors: true diff --git a/tests/codeception/backend/.gitignore b/tests/codeception/backend/.gitignore deleted file mode 100644 index 985dbb4..0000000 --- a/tests/codeception/backend/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# these files are auto generated by codeception build -/unit/UnitTester.php -/functional/FunctionalTester.php -/acceptance/AcceptanceTester.php diff --git a/tests/codeception/backend/_bootstrap.php b/tests/codeception/backend/_bootstrap.php deleted file mode 100644 index 335271f..0000000 --- a/tests/codeception/backend/_bootstrap.php +++ /dev/null @@ -1,23 +0,0 @@ -wantTo('ensure login page works'); - -$loginPage = LoginPage::openBy($I); - -$I->amGoingTo('submit login form with no data'); -$loginPage->login('', ''); -if (method_exists($I, 'wait')) { - $I->wait(3); // only for selenium -} -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.', '.help-block'); -$I->see('Password cannot be blank.', '.help-block'); - -$I->amGoingTo('try to login with wrong credentials'); -$I->expectTo('see validations errors'); -$loginPage->login('admin', 'wrong'); -if (method_exists($I, 'wait')) { - $I->wait(3); // only for selenium -} -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.', '.help-block'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('erau', 'password_0'); -if (method_exists($I, 'wait')) { - $I->wait(3); // only for selenium -} -$I->expectTo('see that user is logged'); -$I->see('Logout (erau)', 'form button[type=submit]'); -$I->dontSeeLink('Login'); -$I->dontSeeLink('Signup'); -/** Uncomment if using WebDriver - * $I->click('Logout (erau)'); - * $I->dontSeeLink('Logout (erau)'); - * $I->seeLink('Login'); - */ diff --git a/tests/codeception/backend/acceptance/_bootstrap.php b/tests/codeception/backend/acceptance/_bootstrap.php deleted file mode 100644 index 411855e..0000000 --- a/tests/codeception/backend/acceptance/_bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ -wantTo('ensure login page works'); - -$loginPage = LoginPage::openBy($I); - -$I->amGoingTo('submit login form with no data'); -$loginPage->login('', ''); -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.', '.help-block'); -$I->see('Password cannot be blank.', '.help-block'); - -$I->amGoingTo('try to login with wrong credentials'); -$I->expectTo('see validations errors'); -$loginPage->login('admin', 'wrong'); -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.', '.help-block'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('erau', 'password_0'); -$I->expectTo('see that user is logged'); -$I->see('Logout (erau)', 'form button[type=submit]'); -$I->dontSeeLink('Login'); -$I->dontSeeLink('Signup'); diff --git a/tests/codeception/backend/functional/_bootstrap.php b/tests/codeception/backend/functional/_bootstrap.php deleted file mode 100644 index 94f3fbd..0000000 --- a/tests/codeception/backend/functional/_bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ -run(); -exit($exitCode); diff --git a/tests/codeception/common/.gitignore b/tests/codeception/common/.gitignore deleted file mode 100644 index 985dbb4..0000000 --- a/tests/codeception/common/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# these files are auto generated by codeception build -/unit/UnitTester.php -/functional/FunctionalTester.php -/acceptance/AcceptanceTester.php diff --git a/tests/codeception/common/_pages/LoginPage.php b/tests/codeception/common/_pages/LoginPage.php deleted file mode 100644 index 6a1dc84..0000000 --- a/tests/codeception/common/_pages/LoginPage.php +++ /dev/null @@ -1,25 +0,0 @@ -actor->fillField('input[name="LoginForm[username]"]', $username); - $this->actor->fillField('input[name="LoginForm[password]"]', $password); - $this->actor->click('login-button'); - } -} diff --git a/tests/codeception/common/_support/FixtureHelper.php b/tests/codeception/common/_support/FixtureHelper.php deleted file mode 100644 index 63739ef..0000000 --- a/tests/codeception/common/_support/FixtureHelper.php +++ /dev/null @@ -1,73 +0,0 @@ -loadFixtures(); - } - - /** - * Method is called after all suite tests run - */ - public function _afterSuite() - { - $this->unloadFixtures(); - } - - /** - * @inheritdoc - */ - public function globalFixtures() - { - return [ - InitDbFixture::className(), - ]; - } - - /** - * @inheritdoc - */ - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/common/fixtures/data/init_login.php', - ], - ]; - } -} diff --git a/tests/codeception/common/codeception.yml b/tests/codeception/common/codeception.yml deleted file mode 100644 index e8a3407..0000000 --- a/tests/codeception/common/codeception.yml +++ /dev/null @@ -1,13 +0,0 @@ -namespace: tests\codeception\common -actor: Tester -paths: - tests: . - log: _output - data: _data - helpers: _support -settings: - bootstrap: _bootstrap.php - suite_class: \PHPUnit_Framework_TestSuite - colors: true - memory_limit: 1024M - log: true diff --git a/tests/codeception/common/templates/fixtures/user.php b/tests/codeception/common/templates/fixtures/user.php deleted file mode 100644 index d3f83b5..0000000 --- a/tests/codeception/common/templates/fixtures/user.php +++ /dev/null @@ -1,17 +0,0 @@ -getSecurity(); - -return [ - 'username' => $faker->userName, - 'email' => $faker->email, - 'auth_key' => $security->generateRandomString(), - 'password_hash' => $security->generatePasswordHash('password_' . $index), - 'password_reset_token' => $security->generateRandomString() . '_' . time(), - 'created_at' => time(), - 'updated_at' => time(), -]; diff --git a/tests/codeception/common/unit.suite.yml b/tests/codeception/common/unit.suite.yml deleted file mode 100644 index a0582a5..0000000 --- a/tests/codeception/common/unit.suite.yml +++ /dev/null @@ -1,6 +0,0 @@ -# Codeception Test Suite Configuration - -# suite for unit (internal) tests. -# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. - -class_name: UnitTester diff --git a/tests/codeception/common/unit/DbTestCase.php b/tests/codeception/common/unit/DbTestCase.php deleted file mode 100644 index 2159a69..0000000 --- a/tests/codeception/common/unit/DbTestCase.php +++ /dev/null @@ -1,11 +0,0 @@ - [ - 'user' => [ - 'class' => 'yii\web\User', - 'identityClass' => 'common\models\User', - ], - ], - ]); - } - - protected function tearDown() - { - Yii::$app->user->logout(); - parent::tearDown(); - } - - public function testLoginNoUser() - { - $model = new LoginForm([ - 'username' => 'not_existing_username', - 'password' => 'not_existing_password', - ]); - - $this->specify('user should not be able to login, when there is no identity', function () use ($model) { - expect('model should not login user', $model->login())->false(); - expect('user should not be logged in', Yii::$app->user->isGuest)->true(); - }); - } - - public function testLoginWrongPassword() - { - $model = new LoginForm([ - 'username' => 'bayer.hudson', - 'password' => 'wrong_password', - ]); - - $this->specify('user should not be able to login with wrong password', function () use ($model) { - expect('model should not login user', $model->login())->false(); - expect('error message should be set', $model->errors)->hasKey('password'); - expect('user should not be logged in', Yii::$app->user->isGuest)->true(); - }); - } - - public function testLoginCorrect() - { - - $model = new LoginForm([ - 'username' => 'bayer.hudson', - 'password' => 'password_0', - ]); - - $this->specify('user should be able to login with correct credentials', function () use ($model) { - expect('model should login user', $model->login())->true(); - expect('error message should not be set', $model->errors)->hasntKey('password'); - expect('user should be logged in', Yii::$app->user->isGuest)->false(); - }); - } - - /** - * @inheritdoc - */ - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/common/unit/fixtures/data/models/user.php' - ], - ]; - } -} diff --git a/tests/codeception/config/.gitignore b/tests/codeception/config/.gitignore deleted file mode 100644 index 059a02c..0000000 --- a/tests/codeception/config/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config-local.php diff --git a/tests/codeception/config/acceptance.php b/tests/codeception/config/acceptance.php deleted file mode 100644 index 9318da5..0000000 --- a/tests/codeception/config/acceptance.php +++ /dev/null @@ -1,7 +0,0 @@ - 'app-common', - 'basePath' => dirname(__DIR__), - ] -); diff --git a/tests/codeception/config/config.php b/tests/codeception/config/config.php deleted file mode 100644 index b478679..0000000 --- a/tests/codeception/config/config.php +++ /dev/null @@ -1,26 +0,0 @@ - 'en-US', - 'controllerMap' => [ - 'fixture' => [ - 'class' => 'yii\faker\FixtureController', - 'fixtureDataPath' => '@tests/codeception/common/fixtures/data', - 'templatePath' => '@tests/codeception/common/templates/fixtures', - 'namespace' => 'tests\codeception\common\fixtures', - ], - ], - 'components' => [ - 'db' => [ - 'dsn' => 'mysql:host=localhost;dbname=yii2_advanced_tests', - ], - 'mailer' => [ - 'useFileTransport' => true, - ], - 'urlManager' => [ - 'showScriptName' => true, - ], - ], -]; diff --git a/tests/codeception/config/console/unit.php b/tests/codeception/config/console/unit.php deleted file mode 100644 index 3c24df0..0000000 --- a/tests/codeception/config/console/unit.php +++ /dev/null @@ -1,15 +0,0 @@ - [ - 'request' => [ - // it's not recommended to run functional tests with CSRF validation enabled - 'enableCsrfValidation' => false, - // but if you absolutely need it set cookie domain to localhost - /* - 'csrfCookie' => [ - 'domain' => 'localhost', - ], - */ - ], - ], -]; \ No newline at end of file diff --git a/tests/codeception/config/unit.php b/tests/codeception/config/unit.php deleted file mode 100644 index 6bd08d3..0000000 --- a/tests/codeception/config/unit.php +++ /dev/null @@ -1,7 +0,0 @@ - $value) { - $inputType = $field === 'body' ? 'textarea' : 'input'; - $this->actor->fillField($inputType . '[name="ContactForm[' . $field . ']"]', $value); - } - $this->actor->click('contact-button'); - } -} diff --git a/tests/codeception/frontend/_pages/SignupPage.php b/tests/codeception/frontend/_pages/SignupPage.php deleted file mode 100644 index 0e1cefa..0000000 --- a/tests/codeception/frontend/_pages/SignupPage.php +++ /dev/null @@ -1,27 +0,0 @@ - $value) { - $inputType = $field === 'body' ? 'textarea' : 'input'; - $this->actor->fillField($inputType . '[name="SignupForm[' . $field . ']"]', $value); - } - $this->actor->click('signup-button'); - } -} diff --git a/tests/codeception/frontend/acceptance.suite.yml b/tests/codeception/frontend/acceptance.suite.yml deleted file mode 100644 index 1828a04..0000000 --- a/tests/codeception/frontend/acceptance.suite.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Codeception Test Suite Configuration - -# suite for acceptance tests. -# perform tests in browser using the Selenium-like tools. -# powered by Mink (http://mink.behat.org). -# (tip: that's what your customer will see). -# (tip: test your ajax and javascript by one of Mink drivers). - -# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. - -class_name: AcceptanceTester -modules: - enabled: - - PhpBrowser - - tests\codeception\common\_support\FixtureHelper -# you can use WebDriver instead of PhpBrowser to test javascript and ajax. -# This will require you to install selenium. See http://codeception.com/docs/04-AcceptanceTests#Selenium -# "restart" option is used by the WebDriver to start each time per test-file new session and cookies, -# it is useful if you want to login in your app in each test. -# - WebDriver - config: - PhpBrowser: -# PLEASE ADJUST IT TO THE ACTUAL ENTRY POINT WITHOUT PATH INFO - url: http://localhost:8080 -# WebDriver: -# url: http://localhost:8080 -# browser: firefox -# restart: true diff --git a/tests/codeception/frontend/acceptance/AboutCept.php b/tests/codeception/frontend/acceptance/AboutCept.php deleted file mode 100644 index 50bf9ba..0000000 --- a/tests/codeception/frontend/acceptance/AboutCept.php +++ /dev/null @@ -1,10 +0,0 @@ -wantTo('ensure that about works'); -AboutPage::openBy($I); -$I->see('About', 'h1'); diff --git a/tests/codeception/frontend/acceptance/ContactCept.php b/tests/codeception/frontend/acceptance/ContactCept.php deleted file mode 100644 index 5e989a5..0000000 --- a/tests/codeception/frontend/acceptance/ContactCept.php +++ /dev/null @@ -1,56 +0,0 @@ -wantTo('ensure that contact works'); - -$contactPage = ContactPage::openBy($I); - -$I->see('Contact', 'h1'); - -$I->amGoingTo('submit contact form with no data'); -$contactPage->submit([]); -if (method_exists($I, 'wait')) { - $I->wait(3); // only for selenium -} -$I->expectTo('see validations errors'); -$I->see('Contact', 'h1'); -$I->see('Name cannot be blank', '.help-block'); -$I->see('Email cannot be blank', '.help-block'); -$I->see('Subject cannot be blank', '.help-block'); -$I->see('Body cannot be blank', '.help-block'); -$I->see('The verification code is incorrect', '.help-block'); - -$I->amGoingTo('submit contact form with not correct email'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester.email', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -if (method_exists($I, 'wait')) { - $I->wait(3); // only for selenium -} -$I->expectTo('see that email address is wrong'); -$I->dontSee('Name cannot be blank', '.help-block'); -$I->see('Email is not a valid email address.', '.help-block'); -$I->dontSee('Subject cannot be blank', '.help-block'); -$I->dontSee('Body cannot be blank', '.help-block'); -$I->dontSee('The verification code is incorrect', '.help-block'); - -$I->amGoingTo('submit contact form with correct data'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester@example.com', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -if (method_exists($I, 'wait')) { - $I->wait(3); // only for selenium -} -$I->see('Thank you for contacting us. We will respond to you as soon as possible.'); diff --git a/tests/codeception/frontend/acceptance/HomeCept.php b/tests/codeception/frontend/acceptance/HomeCept.php deleted file mode 100644 index 9566a2e..0000000 --- a/tests/codeception/frontend/acceptance/HomeCept.php +++ /dev/null @@ -1,12 +0,0 @@ -wantTo('ensure that home page works'); -$I->amOnPage(Yii::$app->homeUrl); -$I->see('My Company'); -$I->seeLink('About'); -$I->click('About'); -$I->see('This is the About page.'); diff --git a/tests/codeception/frontend/acceptance/LoginCept.php b/tests/codeception/frontend/acceptance/LoginCept.php deleted file mode 100644 index 7c433af..0000000 --- a/tests/codeception/frontend/acceptance/LoginCept.php +++ /dev/null @@ -1,34 +0,0 @@ -wantTo('ensure login page works'); - -$loginPage = LoginPage::openBy($I); - -$I->amGoingTo('submit login form with no data'); -$loginPage->login('', ''); -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.', '.help-block'); -$I->see('Password cannot be blank.', '.help-block'); - -$I->amGoingTo('try to login with wrong credentials'); -$I->expectTo('see validations errors'); -$loginPage->login('admin', 'wrong'); -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.', '.help-block'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('erau', 'password_0'); -$I->expectTo('see that user is logged'); -$I->see('Logout (erau)', 'form button[type=submit]'); -$I->dontSeeLink('Login'); -$I->dontSeeLink('Signup'); -/** Uncomment if using WebDriver - * $I->click('Logout (erau)'); - * $I->dontSeeLink('Logout (erau)'); - * $I->seeLink('Login'); - */ diff --git a/tests/codeception/frontend/acceptance/SignupCest.php b/tests/codeception/frontend/acceptance/SignupCest.php deleted file mode 100644 index e8431e5..0000000 --- a/tests/codeception/frontend/acceptance/SignupCest.php +++ /dev/null @@ -1,82 +0,0 @@ - 'tester.email@example.com', - 'username' => 'tester', - ]); - } - - /** - * This method is called when test fails. - * @param \Codeception\Event\FailEvent $event - */ - public function _fail($event) - { - } - - /** - * @param \codeception_frontend\AcceptanceTester $I - * @param \Codeception\Scenario $scenario - */ - public function testUserSignup($I, $scenario) - { - $I->wantTo('ensure that signup works'); - - $signupPage = SignupPage::openBy($I); - $I->see('Signup', 'h1'); - $I->see('Please fill out the following fields to signup:'); - - $I->amGoingTo('submit signup form with no data'); - - $signupPage->submit([]); - - $I->expectTo('see validation errors'); - $I->see('Username cannot be blank.', '.help-block'); - $I->see('Email cannot be blank.', '.help-block'); - $I->see('Password cannot be blank.', '.help-block'); - - $I->amGoingTo('submit signup form with not correct email'); - $signupPage->submit([ - 'username' => 'tester', - 'email' => 'tester.email', - 'password' => 'tester_password', - ]); - - $I->expectTo('see that email address is wrong'); - $I->dontSee('Username cannot be blank.', '.help-block'); - $I->dontSee('Password cannot be blank.', '.help-block'); - $I->see('Email is not a valid email address.', '.help-block'); - - $I->amGoingTo('submit signup form with correct email'); - $signupPage->submit([ - 'username' => 'tester', - 'email' => 'tester.email@example.com', - 'password' => 'tester_password', - ]); - - $I->expectTo('see that user logged in'); - $I->see('Logout (tester)', 'form button[type=submit]'); - } -} diff --git a/tests/codeception/frontend/acceptance/_bootstrap.php b/tests/codeception/frontend/acceptance/_bootstrap.php deleted file mode 100644 index b0a40ef..0000000 --- a/tests/codeception/frontend/acceptance/_bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ -wantTo('ensure that about works'); -AboutPage::openBy($I); -$I->see('About', 'h1'); diff --git a/tests/codeception/frontend/functional/ContactCept.php b/tests/codeception/frontend/functional/ContactCept.php deleted file mode 100644 index a93d7e4..0000000 --- a/tests/codeception/frontend/functional/ContactCept.php +++ /dev/null @@ -1,47 +0,0 @@ -wantTo('ensure that contact works'); - -$contactPage = ContactPage::openBy($I); - -$I->see('Contact', 'h1'); - -$I->amGoingTo('submit contact form with no data'); -$contactPage->submit([]); -$I->expectTo('see validations errors'); -$I->see('Contact', 'h1'); -$I->see('Name cannot be blank', '.help-block'); -$I->see('Email cannot be blank', '.help-block'); -$I->see('Subject cannot be blank', '.help-block'); -$I->see('Body cannot be blank', '.help-block'); -$I->see('The verification code is incorrect', '.help-block'); - -$I->amGoingTo('submit contact form with not correct email'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester.email', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -$I->expectTo('see that email address is wrong'); -$I->dontSee('Name cannot be blank', '.help-block'); -$I->see('Email is not a valid email address.', '.help-block'); -$I->dontSee('Subject cannot be blank', '.help-block'); -$I->dontSee('Body cannot be blank', '.help-block'); -$I->dontSee('The verification code is incorrect', '.help-block'); - -$I->amGoingTo('submit contact form with correct data'); -$contactPage->submit([ - 'name' => 'tester', - 'email' => 'tester@example.com', - 'subject' => 'test subject', - 'body' => 'test content', - 'verifyCode' => 'testme', -]); -$I->see('Thank you for contacting us. We will respond to you as soon as possible.'); diff --git a/tests/codeception/frontend/functional/HomeCept.php b/tests/codeception/frontend/functional/HomeCept.php deleted file mode 100644 index f340061..0000000 --- a/tests/codeception/frontend/functional/HomeCept.php +++ /dev/null @@ -1,12 +0,0 @@ -wantTo('ensure that home page works'); -$I->amOnPage(Yii::$app->homeUrl); -$I->see('My Company'); -$I->seeLink('About'); -$I->click('About'); -$I->see('This is the About page.'); diff --git a/tests/codeception/frontend/functional/LoginCept.php b/tests/codeception/frontend/functional/LoginCept.php deleted file mode 100644 index e1d2f9b..0000000 --- a/tests/codeception/frontend/functional/LoginCept.php +++ /dev/null @@ -1,29 +0,0 @@ -wantTo('ensure login page works'); - -$loginPage = LoginPage::openBy($I); - -$I->amGoingTo('submit login form with no data'); -$loginPage->login('', ''); -$I->expectTo('see validations errors'); -$I->see('Username cannot be blank.', '.help-block'); -$I->see('Password cannot be blank.', '.help-block'); - -$I->amGoingTo('try to login with wrong credentials'); -$I->expectTo('see validations errors'); -$loginPage->login('admin', 'wrong'); -$I->expectTo('see validations errors'); -$I->see('Incorrect username or password.', '.help-block'); - -$I->amGoingTo('try to login with correct credentials'); -$loginPage->login('erau', 'password_0'); -$I->expectTo('see that user is logged'); -$I->see('Logout (erau)', 'form button[type=submit]'); -$I->dontSeeLink('Login'); -$I->dontSeeLink('Signup'); diff --git a/tests/codeception/frontend/functional/SignupCest.php b/tests/codeception/frontend/functional/SignupCest.php deleted file mode 100644 index 16410de..0000000 --- a/tests/codeception/frontend/functional/SignupCest.php +++ /dev/null @@ -1,88 +0,0 @@ -loadFixtures(); - } - - /** - * This method is called when test fails. - * @param \codeception_frontend\FunctionalTester $I - */ - public function _failed($I) - { - - } - - /** - * - * @param \codeception_frontend\FunctionalTester $I - * @param \Codeception\Scenario $scenario - */ - public function testUserSignup($I, $scenario) - { - $I->wantTo('ensure that signup works'); - - $signupPage = SignupPage::openBy($I); - $I->see('Signup', 'h1'); - $I->see('Please fill out the following fields to signup:'); - - $I->amGoingTo('submit signup form with no data'); - - $signupPage->submit([]); - - $I->expectTo('see validation errors'); - $I->see('Username cannot be blank.', '.help-block'); - $I->see('Email cannot be blank.', '.help-block'); - $I->see('Password cannot be blank.', '.help-block'); - - $I->amGoingTo('submit signup form with not correct email'); - $signupPage->submit([ - 'username' => 'tester', - 'email' => 'tester.email', - 'password' => 'tester_password', - ]); - - $I->expectTo('see that email address is wrong'); - $I->dontSee('Username cannot be blank.', '.help-block'); - $I->dontSee('Password cannot be blank.', '.help-block'); - $I->see('Email is not a valid email address.', '.help-block'); - - $I->amGoingTo('submit signup form with correct email'); - $signupPage->submit([ - 'username' => 'tester', - 'email' => 'tester.email@example.com', - 'password' => 'tester_password', - ]); - - $I->expectTo('see that user is created'); - $I->seeRecord('common\models\User', [ - 'username' => 'tester', - 'email' => 'tester.email@example.com', - ]); - - $I->expectTo('see that user logged in'); - $I->see('Logout (tester)', 'form button[type=submit]'); - } -} diff --git a/tests/codeception/frontend/functional/_bootstrap.php b/tests/codeception/frontend/functional/_bootstrap.php deleted file mode 100644 index 1abc491..0000000 --- a/tests/codeception/frontend/functional/_bootstrap.php +++ /dev/null @@ -1,3 +0,0 @@ -mailer->fileTransportCallback = function ($mailer, $message) { - return 'testing_message.eml'; - }; - } - - protected function tearDown() - { - unlink($this->getMessageFile()); - parent::tearDown(); - } - - public function testContact() - { - $model = new ContactForm(); - - $model->attributes = [ - 'name' => 'Tester', - 'email' => 'tester@example.com', - 'subject' => 'very important letter subject', - 'body' => 'body of current message', - ]; - - $model->sendEmail('admin@example.com'); - - $this->specify('email should be send', function () { - expect('email file should exist', file_exists($this->getMessageFile()))->true(); - }); - - $this->specify('message should contain correct data', function () use ($model) { - $emailMessage = file_get_contents($this->getMessageFile()); - - expect('email should contain user name', $emailMessage)->contains($model->name); - expect('email should contain sender email', $emailMessage)->contains($model->email); - expect('email should contain subject', $emailMessage)->contains($model->subject); - expect('email should contain body', $emailMessage)->contains($model->body); - }); - } - - private function getMessageFile() - { - return Yii::getAlias(Yii::$app->mailer->fileTransportPath) . '/testing_message.eml'; - } -} diff --git a/tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php b/tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php deleted file mode 100644 index ced8cce..0000000 --- a/tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php +++ /dev/null @@ -1,87 +0,0 @@ -mailer->fileTransportCallback = function ($mailer, $message) { - return 'testing_message.eml'; - }; - } - - protected function tearDown() - { - @unlink($this->getMessageFile()); - - parent::tearDown(); - } - - public function testSendEmailWrongUser() - { - $this->specify('no user with such email, message should not be sent', function () { - - $model = new PasswordResetRequestForm(); - $model->email = 'not-existing-email@example.com'; - - expect('email not sent', $model->sendEmail())->false(); - - }); - - $this->specify('user is not active, message should not be sent', function () { - - $model = new PasswordResetRequestForm(); - $model->email = $this->user[1]['email']; - - expect('email not sent', $model->sendEmail())->false(); - - }); - } - - public function testSendEmailCorrectUser() - { - $model = new PasswordResetRequestForm(); - $model->email = $this->user[0]['email']; - $user = User::findOne(['password_reset_token' => $this->user[0]['password_reset_token']]); - - expect('email sent', $model->sendEmail())->true(); - expect('user has valid token', $user->password_reset_token)->notNull(); - - $this->specify('message has correct format', function () use ($model) { - - expect('message file exists', file_exists($this->getMessageFile()))->true(); - - $message = file_get_contents($this->getMessageFile()); - expect('message "from" is correct', $message)->contains(Yii::$app->params['supportEmail']); - expect('message "to" is correct', $message)->contains($model->email); - - }); - } - - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/frontend/unit/fixtures/data/models/user.php' - ], - ]; - } - - private function getMessageFile() - { - return Yii::getAlias(Yii::$app->mailer->fileTransportPath) . '/testing_message.eml'; - } -} diff --git a/tests/codeception/frontend/unit/models/ResetPasswordFormTest.php b/tests/codeception/frontend/unit/models/ResetPasswordFormTest.php deleted file mode 100644 index a4dd021..0000000 --- a/tests/codeception/frontend/unit/models/ResetPasswordFormTest.php +++ /dev/null @@ -1,43 +0,0 @@ -user[0]['password_reset_token']); - expect('password should be resetted', $form->resetPassword())->true(); - } - - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/frontend/unit/fixtures/data/models/user.php' - ], - ]; - } -} diff --git a/tests/codeception/frontend/unit/models/SignupFormTest.php b/tests/codeception/frontend/unit/models/SignupFormTest.php deleted file mode 100644 index 4d08e8c..0000000 --- a/tests/codeception/frontend/unit/models/SignupFormTest.php +++ /dev/null @@ -1,52 +0,0 @@ - 'some_username', - 'email' => 'some_email@example.com', - 'password' => 'some_password', - ]); - - $user = $model->signup(); - - $this->assertInstanceOf('common\models\User', $user, 'user should be valid'); - - expect('username should be correct', $user->username)->equals('some_username'); - expect('email should be correct', $user->email)->equals('some_email@example.com'); - expect('password should be correct', $user->validatePassword('some_password'))->true(); - } - - public function testNotCorrectSignup() - { - $model = new SignupForm([ - 'username' => 'troy.becker', - 'email' => 'nicolas.dianna@hotmail.com', - 'password' => 'some_password', - ]); - - expect('username and email are in use, user should not be created', $model->signup())->null(); - } - - public function fixtures() - { - return [ - 'user' => [ - 'class' => UserFixture::className(), - 'dataFile' => '@tests/codeception/frontend/unit/fixtures/data/models/user.php', - ], - ]; - } -} diff --git a/vagrant/config/.gitignore b/vagrant/config/.gitignore new file mode 100644 index 0000000..0685a56 --- /dev/null +++ b/vagrant/config/.gitignore @@ -0,0 +1,2 @@ +# local configuration +vagrant-local.yml \ No newline at end of file diff --git a/vagrant/config/vagrant-local.example.yml b/vagrant/config/vagrant-local.example.yml new file mode 100644 index 0000000..32dd3ab --- /dev/null +++ b/vagrant/config/vagrant-local.example.yml @@ -0,0 +1,22 @@ +# Your personal GitHub token +github_token: +# Read more: https://github.com/blog/1509-personal-api-tokens +# You can generate it here: https://github.com/settings/tokens + +# Guest OS timezone +timezone: Europe/London + +# Are we need check box updates for every 'vagrant up'? +box_check_update: false + +# Virtual machine name +machine_name: y2aa + +# Virtual machine IP +ip: 192.168.83.137 + +# Virtual machine CPU cores number +cpus: 1 + +# Virtual machine RAM +memory: 512 diff --git a/vagrant/nginx/app.conf b/vagrant/nginx/app.conf new file mode 100644 index 0000000..eab6e58 --- /dev/null +++ b/vagrant/nginx/app.conf @@ -0,0 +1,77 @@ +server { + charset utf-8; + client_max_body_size 128M; + sendfile off; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name y2aa-frontend.dev; + root /app/frontend/; + index index.php; + + access_log /app/vagrant/nginx/log/frontend-access.log; + error_log /app/vagrant/nginx/log/frontend-error.log; + + location / { + # Redirect everything that isn't a real file to index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # uncomment to avoid processing of calls to non-existing static files by Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + #fastcgi_pass 127.0.0.1:9000; + fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; + try_files $uri =404; + } + + location ~ /\.(ht|svn|git) { + deny all; + } +} + +server { + charset utf-8; + client_max_body_size 128M; + sendfile off; + + listen 80; ## listen for ipv4 + #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 + + server_name y2aa-backend.dev; + root /app/backend/web/; + index index.php; + + access_log /app/vagrant/nginx/log/backend-access.log; + error_log /app/vagrant/nginx/log/backend-error.log; + + location / { + # Redirect everything that isn't a real file to index.php + try_files $uri $uri/ /index.php$is_args$args; + } + + # uncomment to avoid processing of calls to non-existing static files by Yii + #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { + # try_files $uri =404; + #} + #error_page 404 /404.html; + + location ~ \.php$ { + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + #fastcgi_pass 127.0.0.1:9000; + fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; + try_files $uri =404; + } + + location ~ /\.(ht|svn|git) { + deny all; + } +} diff --git a/vagrant/nginx/log/.gitignore b/vagrant/nginx/log/.gitignore new file mode 100644 index 0000000..c15cedd --- /dev/null +++ b/vagrant/nginx/log/.gitignore @@ -0,0 +1,5 @@ +# nginx logs +backend-access.log +backend-error.log +frontend-access.log +frontend-error.log \ No newline at end of file diff --git a/vagrant/provision/always-as-root.sh b/vagrant/provision/always-as-root.sh new file mode 100644 index 0000000..e5d8e33 --- /dev/null +++ b/vagrant/provision/always-as-root.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +#== Bash helpers == + +function info { + echo " " + echo "--> $1" + echo " " +} + +#== Provision script == + +info "Provision-script user: `whoami`" + +info "Restart web-stack" +service php7.0-fpm restart +service nginx restart +service mysql restart \ No newline at end of file diff --git a/vagrant/provision/once-as-root.sh b/vagrant/provision/once-as-root.sh new file mode 100644 index 0000000..6e77bc3 --- /dev/null +++ b/vagrant/provision/once-as-root.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +#== Import script args == + +timezone=$(echo "$1") + +#== Bash helpers == + +function info { + echo " " + echo "--> $1" + echo " " +} + +#== Provision script == + +info "Provision-script user: `whoami`" + +export DEBIAN_FRONTEND=noninteractive + +info "Configure timezone" +timedatectl set-timezone ${timezone} --no-ask-password + +info "Prepare root password for MySQL" +debconf-set-selections <<< "mysql-community-server mysql-community-server/root-pass password \"''\"" +debconf-set-selections <<< "mysql-community-server mysql-community-server/re-root-pass password \"''\"" +echo "Done!" + +info "Update OS software" +apt-get update +apt-get upgrade -y + +info "Install additional software" +apt-get install -y php7.0-curl php7.0-cli php7.0-intl php7.0-mysqlnd php7.0-gd php7.0-fpm php7.0-mbstring php7.0-xml unzip nginx mysql-server-5.7 + +info "Configure MySQL" +sed -i "s/.*bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/mysql.conf.d/mysqld.cnf +mysql -uroot <<< "CREATE USER 'root'@'%' IDENTIFIED BY ''" +mysql -uroot <<< "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'" +mysql -uroot <<< "DROP USER 'root'@'localhost'" +mysql -uroot <<< "FLUSH PRIVILEGES" +echo "Done!" + +info "Configure PHP-FPM" +sed -i 's/user = www-data/user = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf +sed -i 's/group = www-data/group = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf +sed -i 's/owner = www-data/owner = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf +echo "Done!" + +info "Configure NGINX" +sed -i 's/user www-data/user vagrant/g' /etc/nginx/nginx.conf +echo "Done!" + +info "Enabling site configuration" +ln -s /app/vagrant/nginx/app.conf /etc/nginx/sites-enabled/app.conf +echo "Done!" + +info "Initailize databases for MySQL" +mysql -uroot <<< "CREATE DATABASE yii2practical" +mysql -uroot <<< "CREATE DATABASE yii2practical_test" +echo "Done!" + +info "Install composer" +curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \ No newline at end of file diff --git a/vagrant/provision/once-as-vagrant.sh b/vagrant/provision/once-as-vagrant.sh new file mode 100644 index 0000000..51aee73 --- /dev/null +++ b/vagrant/provision/once-as-vagrant.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +#== Import script args == + +github_token=$(echo "$1") + +#== Bash helpers == + +function info { + echo " " + echo "--> $1" + echo " " +} + +#== Provision script == + +info "Provision-script user: `whoami`" + +info "Configure composer" +composer config --global github-oauth.github.com ${github_token} +echo "Done!" + +info "Install plugins for composer" +composer global require "fxp/composer-asset-plugin:^1.3.1" --no-progress + +info "Install project dependencies" +cd /app +composer --no-progress --prefer-dist install + +info "Init project" +./init --env=Development --overwrite=y + +info "Apply migrations" +./yii migrate --interactive=0 +./yii_test migrate --interactive=0 + +info "Create bash-alias 'app' for vagrant user" +echo 'alias app="cd /app"' | tee /home/vagrant/.bash_aliases + +info "Enabling colorized prompt for guest console" +sed -i "s/#force_color_prompt=yes/force_color_prompt=yes/" /home/vagrant/.bashrc