From 58743b317cc5184757020b71d2cd239b19aa54b4 Mon Sep 17 00:00:00 2001 From: Mihail Date: Wed, 26 Aug 2015 09:23:26 +0300 Subject: [PATCH] init commit - base on yii2 advanced, clear main layout and and add simple upload form and add htaccess --- .bowerrc | 3 +++ .gitignore | 2 ++ .htaccess | 18 ++++++++++++++++++ LICENSE.md | 32 ++++++++++++++++++++++++++++++++ README.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/assets/AppAsset.php | 29 +++++++++++++++++++++++++++++ backend/config/.gitignore | 2 ++ backend/config/bootstrap.php | 1 + backend/config/main.php | 34 ++++++++++++++++++++++++++++++++++ backend/config/params.php | 4 ++++ backend/controllers/ParserController.php | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/controllers/SiteController.php | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/models/.gitkeep | 1 + backend/models/UploadForm.php | 26 ++++++++++++++++++++++++++ backend/runtime/.gitignore | 2 ++ backend/views/layouts/main.php | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/views/parser/parser.php | 11 +++++++++++ backend/views/site/error.php | 27 +++++++++++++++++++++++++++ backend/views/site/index.php | 16 ++++++++++++++++ backend/views/site/login.php | 35 +++++++++++++++++++++++++++++++++++ backend/web/.gitignore | 3 +++ backend/web/.htaccess | 8 ++++++++ backend/web/assets/.gitignore | 2 ++ backend/web/css/site.css | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ backend/web/favicon.ico | Bin 0 -> 318 bytes backend/web/robots.txt | 2 ++ common/config/.gitignore | 2 ++ common/config/bootstrap.php | 5 +++++ common/config/main.php | 9 +++++++++ common/config/params.php | 6 ++++++ common/mail/layouts/html.php | 22 ++++++++++++++++++++++ common/mail/layouts/text.php | 12 ++++++++++++ common/mail/passwordResetToken-html.php | 15 +++++++++++++++ common/mail/passwordResetToken-text.php | 12 ++++++++++++ common/models/LoginForm.php | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/models/User.php | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/widgets/Alert.php | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ composer.json | 37 +++++++++++++++++++++++++++++++++++++ composer.lock | 924 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ console/config/.gitignore | 2 ++ console/config/bootstrap.php | 1 + console/config/main.php | 25 +++++++++++++++++++++++++ console/config/params.php | 4 ++++ console/controllers/.gitkeep | 0 console/migrations/m130524_201442_init.php | 34 ++++++++++++++++++++++++++++++++++ console/models/.gitkeep | 1 + console/runtime/.gitignore | 2 ++ environments/dev/backend/config/main-local.php | 25 +++++++++++++++++++++++++ environments/dev/backend/config/params-local.php | 3 +++ environments/dev/backend/web/index-test.php | 19 +++++++++++++++++++ environments/dev/backend/web/index.php | 18 ++++++++++++++++++ environments/dev/common/config/main-local.php | 20 ++++++++++++++++++++ environments/dev/common/config/params-local.php | 3 +++ environments/dev/console/config/main-local.php | 7 +++++++ environments/dev/console/config/params-local.php | 3 +++ environments/dev/frontend/config/main-local.php | 21 +++++++++++++++++++++ environments/dev/frontend/config/params-local.php | 3 +++ environments/dev/frontend/web/index-test.php | 18 ++++++++++++++++++ environments/dev/frontend/web/index.php | 18 ++++++++++++++++++ environments/dev/yii | 28 ++++++++++++++++++++++++++++ environments/index.php | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ environments/prod/backend/config/main-local.php | 9 +++++++++ environments/prod/backend/config/params-local.php | 3 +++ environments/prod/backend/web/index.php | 18 ++++++++++++++++++ environments/prod/common/config/main-local.php | 16 ++++++++++++++++ environments/prod/common/config/params-local.php | 3 +++ environments/prod/console/config/main-local.php | 3 +++ environments/prod/console/config/params-local.php | 3 +++ environments/prod/frontend/config/main-local.php | 9 +++++++++ environments/prod/frontend/config/params-local.php | 3 +++ environments/prod/frontend/web/index.php | 18 ++++++++++++++++++ environments/prod/yii | 28 ++++++++++++++++++++++++++++ frontend/assets/AppAsset.php | 29 +++++++++++++++++++++++++++++ frontend/config/.gitignore | 2 ++ frontend/config/bootstrap.php | 1 + frontend/config/main.php | 33 +++++++++++++++++++++++++++++++++ frontend/config/params.php | 4 ++++ frontend/controllers/SiteController.php | 213 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/models/ContactForm.php | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/models/PasswordResetRequestForm.php | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/models/ResetPasswordForm.php | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/models/SignupForm.php | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/runtime/.gitignore | 2 ++ frontend/views/layouts/main.php | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/views/site/about.php | 16 ++++++++++++++++ frontend/views/site/contact.php | 45 +++++++++++++++++++++++++++++++++++++++++++++ frontend/views/site/error.php | 27 +++++++++++++++++++++++++++ frontend/views/site/index.php | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/views/site/login.php | 39 +++++++++++++++++++++++++++++++++++++++ frontend/views/site/requestPasswordResetToken.php | 31 +++++++++++++++++++++++++++++++ frontend/views/site/resetPassword.php | 31 +++++++++++++++++++++++++++++++ frontend/views/site/signup.php | 35 +++++++++++++++++++++++++++++++++++ frontend/web/.gitignore | 2 ++ frontend/web/.htaccess | 8 ++++++++ frontend/web/assets/.gitignore | 2 ++ frontend/web/css/site.css | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/web/favicon.ico | Bin 0 -> 318 bytes frontend/web/robots.txt | 2 ++ init | 209 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ init.bat | 20 ++++++++++++++++++++ requirements.php | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/codeception.yml | 11 +++++++++++ tests/codeception/_output/.gitignore | 2 ++ tests/codeception/backend/.gitignore | 4 ++++ tests/codeception/backend/_bootstrap.php | 23 +++++++++++++++++++++++ tests/codeception/backend/_output/.gitignore | 2 ++ tests/codeception/backend/acceptance.suite.yml | 28 ++++++++++++++++++++++++++++ tests/codeception/backend/acceptance/LoginCept.php | 44 ++++++++++++++++++++++++++++++++++++++++++++ tests/codeception/backend/acceptance/_bootstrap.php | 2 ++ tests/codeception/backend/codeception.yml | 17 +++++++++++++++++ tests/codeception/backend/functional.suite.yml | 17 +++++++++++++++++ tests/codeception/backend/functional/LoginCept.php | 30 ++++++++++++++++++++++++++++++ tests/codeception/backend/functional/_bootstrap.php | 2 ++ tests/codeception/backend/unit.suite.yml | 6 ++++++ tests/codeception/backend/unit/DbTestCase.php | 8 ++++++++ tests/codeception/backend/unit/TestCase.php | 8 ++++++++ tests/codeception/backend/unit/_bootstrap.php | 2 ++ tests/codeception/backend/unit/fixtures/data/.gitkeep | 0 tests/codeception/bin/_bootstrap.php | 19 +++++++++++++++++++ tests/codeception/bin/yii | 23 +++++++++++++++++++++++ tests/codeception/bin/yii.bat | 20 ++++++++++++++++++++ tests/codeception/common/.gitignore | 4 ++++ tests/codeception/common/_bootstrap.php | 15 +++++++++++++++ tests/codeception/common/_output/.gitignore | 2 ++ tests/codeception/common/_pages/LoginPage.php | 25 +++++++++++++++++++++++++ tests/codeception/common/_support/FixtureHelper.php | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/codeception/common/codeception.yml | 13 +++++++++++++ tests/codeception/common/fixtures/UserFixture.php | 13 +++++++++++++ tests/codeception/common/fixtures/data/init_login.php | 14 ++++++++++++++ tests/codeception/common/templates/fixtures/user.php | 17 +++++++++++++++++ tests/codeception/common/unit.suite.yml | 6 ++++++ tests/codeception/common/unit/DbTestCase.php | 11 +++++++++++ tests/codeception/common/unit/TestCase.php | 11 +++++++++++ tests/codeception/common/unit/_bootstrap.php | 2 ++ tests/codeception/common/unit/fixtures/data/models/user.php | 14 ++++++++++++++ tests/codeception/common/unit/models/LoginFormTest.php | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/codeception/config/acceptance.php | 7 +++++++ tests/codeception/config/backend/acceptance.php | 17 +++++++++++++++++ tests/codeception/config/backend/config.php | 5 +++++ tests/codeception/config/backend/functional.php | 18 ++++++++++++++++++ tests/codeception/config/backend/unit.php | 16 ++++++++++++++++ tests/codeception/config/common/unit.php | 14 ++++++++++++++ tests/codeception/config/config.php | 26 ++++++++++++++++++++++++++ tests/codeception/config/console/unit.php | 14 ++++++++++++++ tests/codeception/config/frontend/acceptance.php | 17 +++++++++++++++++ tests/codeception/config/frontend/config.php | 5 +++++ tests/codeception/config/frontend/functional.php | 18 ++++++++++++++++++ tests/codeception/config/frontend/unit.php | 16 ++++++++++++++++ tests/codeception/config/functional.php | 18 ++++++++++++++++++ tests/codeception/config/unit.php | 7 +++++++ tests/codeception/console/.gitignore | 2 ++ tests/codeception/console/_bootstrap.php | 16 ++++++++++++++++ tests/codeception/console/_output/.gitignore | 2 ++ tests/codeception/console/codeception.yml | 13 +++++++++++++ tests/codeception/console/unit.suite.yml | 6 ++++++ tests/codeception/console/unit/DbTestCase.php | 11 +++++++++++ tests/codeception/console/unit/TestCase.php | 11 +++++++++++ tests/codeception/console/unit/_bootstrap.php | 2 ++ tests/codeception/console/unit/fixtures/data/.gitkeep | 0 tests/codeception/frontend/.gitignore | 4 ++++ tests/codeception/frontend/_bootstrap.php | 23 +++++++++++++++++++++++ tests/codeception/frontend/_output/.gitignore | 2 ++ tests/codeception/frontend/_pages/AboutPage.php | 14 ++++++++++++++ tests/codeception/frontend/_pages/ContactPage.php | 26 ++++++++++++++++++++++++++ tests/codeception/frontend/_pages/SignupPage.php | 27 +++++++++++++++++++++++++++ tests/codeception/frontend/acceptance.suite.yml | 28 ++++++++++++++++++++++++++++ tests/codeception/frontend/acceptance/AboutCept.php | 10 ++++++++++ tests/codeception/frontend/acceptance/ContactCept.php | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/codeception/frontend/acceptance/HomeCept.php | 12 ++++++++++++ tests/codeception/frontend/acceptance/LoginCept.php | 34 ++++++++++++++++++++++++++++++++++ tests/codeception/frontend/acceptance/SignupCest.php | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/codeception/frontend/acceptance/_bootstrap.php | 2 ++ tests/codeception/frontend/codeception.yml | 17 +++++++++++++++++ tests/codeception/frontend/functional.suite.yml | 17 +++++++++++++++++ tests/codeception/frontend/functional/AboutCept.php | 10 ++++++++++ tests/codeception/frontend/functional/ContactCept.php | 47 +++++++++++++++++++++++++++++++++++++++++++++++ tests/codeception/frontend/functional/HomeCept.php | 12 ++++++++++++ tests/codeception/frontend/functional/LoginCept.php | 29 +++++++++++++++++++++++++++++ tests/codeception/frontend/functional/SignupCest.php | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/codeception/frontend/functional/_bootstrap.php | 3 +++ tests/codeception/frontend/unit.suite.yml | 6 ++++++ tests/codeception/frontend/unit/DbTestCase.php | 11 +++++++++++ tests/codeception/frontend/unit/TestCase.php | 11 +++++++++++ tests/codeception/frontend/unit/_bootstrap.php | 2 ++ tests/codeception/frontend/unit/fixtures/data/models/user.php | 23 +++++++++++++++++++++++ tests/codeception/frontend/unit/models/ContactFormTest.php | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/codeception/frontend/unit/models/ResetPasswordFormTest.php | 43 +++++++++++++++++++++++++++++++++++++++++++ tests/codeception/frontend/unit/models/SignupFormTest.php | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ yii | 28 ++++++++++++++++++++++++++++ yii.bat | 20 ++++++++++++++++++++ 192 files changed, 5627 insertions(+), 0 deletions(-) create mode 100644 .bowerrc create mode 100644 .gitignore create mode 100644 .htaccess create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 backend/assets/AppAsset.php create mode 100644 backend/config/.gitignore create mode 100644 backend/config/bootstrap.php create mode 100644 backend/config/main.php create mode 100644 backend/config/params.php create mode 100644 backend/controllers/ParserController.php create mode 100644 backend/controllers/SiteController.php create mode 100644 backend/models/.gitkeep create mode 100644 backend/models/UploadForm.php create mode 100644 backend/runtime/.gitignore create mode 100644 backend/views/layouts/main.php create mode 100644 backend/views/parser/parser.php create mode 100644 backend/views/site/error.php create mode 100644 backend/views/site/index.php create mode 100644 backend/views/site/login.php create mode 100644 backend/web/.gitignore create mode 100644 backend/web/.htaccess create mode 100644 backend/web/assets/.gitignore create mode 100644 backend/web/css/site.css create mode 100644 backend/web/favicon.ico create mode 100644 backend/web/robots.txt create mode 100644 common/config/.gitignore create mode 100644 common/config/bootstrap.php create mode 100644 common/config/main.php create mode 100644 common/config/params.php create mode 100644 common/mail/layouts/html.php create mode 100644 common/mail/layouts/text.php create mode 100644 common/mail/passwordResetToken-html.php create mode 100644 common/mail/passwordResetToken-text.php create mode 100644 common/models/LoginForm.php create mode 100644 common/models/User.php create mode 100644 common/widgets/Alert.php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 console/config/.gitignore create mode 100644 console/config/bootstrap.php create mode 100644 console/config/main.php create mode 100644 console/config/params.php create mode 100644 console/controllers/.gitkeep create mode 100644 console/migrations/m130524_201442_init.php create mode 100644 console/models/.gitkeep create mode 100644 console/runtime/.gitignore create mode 100644 environments/dev/backend/config/main-local.php create mode 100644 environments/dev/backend/config/params-local.php create mode 100644 environments/dev/backend/web/index-test.php create mode 100644 environments/dev/backend/web/index.php create mode 100644 environments/dev/common/config/main-local.php create mode 100644 environments/dev/common/config/params-local.php create mode 100644 environments/dev/console/config/main-local.php create mode 100644 environments/dev/console/config/params-local.php create mode 100644 environments/dev/frontend/config/main-local.php create mode 100644 environments/dev/frontend/config/params-local.php create mode 100644 environments/dev/frontend/web/index-test.php create mode 100644 environments/dev/frontend/web/index.php create mode 100644 environments/dev/yii create mode 100644 environments/index.php create mode 100644 environments/prod/backend/config/main-local.php create mode 100644 environments/prod/backend/config/params-local.php create mode 100644 environments/prod/backend/web/index.php create mode 100644 environments/prod/common/config/main-local.php create mode 100644 environments/prod/common/config/params-local.php create mode 100644 environments/prod/console/config/main-local.php create mode 100644 environments/prod/console/config/params-local.php create mode 100644 environments/prod/frontend/config/main-local.php create mode 100644 environments/prod/frontend/config/params-local.php create mode 100644 environments/prod/frontend/web/index.php create mode 100644 environments/prod/yii create mode 100644 frontend/assets/AppAsset.php create mode 100644 frontend/config/.gitignore create mode 100644 frontend/config/bootstrap.php create mode 100644 frontend/config/main.php create mode 100644 frontend/config/params.php create mode 100644 frontend/controllers/SiteController.php create mode 100644 frontend/models/ContactForm.php create mode 100644 frontend/models/PasswordResetRequestForm.php create mode 100644 frontend/models/ResetPasswordForm.php create mode 100644 frontend/models/SignupForm.php create mode 100644 frontend/runtime/.gitignore create mode 100644 frontend/views/layouts/main.php create mode 100644 frontend/views/site/about.php create mode 100644 frontend/views/site/contact.php create mode 100644 frontend/views/site/error.php create mode 100644 frontend/views/site/index.php create mode 100644 frontend/views/site/login.php create mode 100644 frontend/views/site/requestPasswordResetToken.php create mode 100644 frontend/views/site/resetPassword.php create mode 100644 frontend/views/site/signup.php create mode 100644 frontend/web/.gitignore create mode 100644 frontend/web/.htaccess create mode 100644 frontend/web/assets/.gitignore create mode 100644 frontend/web/css/site.css create mode 100644 frontend/web/favicon.ico create mode 100644 frontend/web/robots.txt create mode 100644 init create mode 100644 init.bat create mode 100644 requirements.php create mode 100644 tests/README.md create mode 100644 tests/codeception.yml create mode 100644 tests/codeception/_output/.gitignore create mode 100644 tests/codeception/backend/.gitignore create mode 100644 tests/codeception/backend/_bootstrap.php create mode 100644 tests/codeception/backend/_output/.gitignore create mode 100644 tests/codeception/backend/acceptance.suite.yml create mode 100644 tests/codeception/backend/acceptance/LoginCept.php create mode 100644 tests/codeception/backend/acceptance/_bootstrap.php create mode 100644 tests/codeception/backend/codeception.yml create mode 100644 tests/codeception/backend/functional.suite.yml create mode 100644 tests/codeception/backend/functional/LoginCept.php create mode 100644 tests/codeception/backend/functional/_bootstrap.php create mode 100644 tests/codeception/backend/unit.suite.yml create mode 100644 tests/codeception/backend/unit/DbTestCase.php create mode 100644 tests/codeception/backend/unit/TestCase.php create mode 100644 tests/codeception/backend/unit/_bootstrap.php create mode 100644 tests/codeception/backend/unit/fixtures/data/.gitkeep create mode 100644 tests/codeception/bin/_bootstrap.php create mode 100644 tests/codeception/bin/yii create mode 100644 tests/codeception/bin/yii.bat create mode 100644 tests/codeception/common/.gitignore create mode 100644 tests/codeception/common/_bootstrap.php create mode 100644 tests/codeception/common/_output/.gitignore create mode 100644 tests/codeception/common/_pages/LoginPage.php create mode 100644 tests/codeception/common/_support/FixtureHelper.php create mode 100644 tests/codeception/common/codeception.yml create mode 100644 tests/codeception/common/fixtures/UserFixture.php create mode 100644 tests/codeception/common/fixtures/data/init_login.php create mode 100644 tests/codeception/common/templates/fixtures/user.php create mode 100644 tests/codeception/common/unit.suite.yml create mode 100644 tests/codeception/common/unit/DbTestCase.php create mode 100644 tests/codeception/common/unit/TestCase.php create mode 100644 tests/codeception/common/unit/_bootstrap.php create mode 100644 tests/codeception/common/unit/fixtures/data/models/user.php create mode 100644 tests/codeception/common/unit/models/LoginFormTest.php create mode 100644 tests/codeception/config/acceptance.php create mode 100644 tests/codeception/config/backend/acceptance.php create mode 100644 tests/codeception/config/backend/config.php create mode 100644 tests/codeception/config/backend/functional.php create mode 100644 tests/codeception/config/backend/unit.php create mode 100644 tests/codeception/config/common/unit.php create mode 100644 tests/codeception/config/config.php create mode 100644 tests/codeception/config/console/unit.php create mode 100644 tests/codeception/config/frontend/acceptance.php create mode 100644 tests/codeception/config/frontend/config.php create mode 100644 tests/codeception/config/frontend/functional.php create mode 100644 tests/codeception/config/frontend/unit.php create mode 100644 tests/codeception/config/functional.php create mode 100644 tests/codeception/config/unit.php create mode 100644 tests/codeception/console/.gitignore create mode 100644 tests/codeception/console/_bootstrap.php create mode 100644 tests/codeception/console/_output/.gitignore create mode 100644 tests/codeception/console/codeception.yml create mode 100644 tests/codeception/console/unit.suite.yml create mode 100644 tests/codeception/console/unit/DbTestCase.php create mode 100644 tests/codeception/console/unit/TestCase.php create mode 100644 tests/codeception/console/unit/_bootstrap.php create mode 100644 tests/codeception/console/unit/fixtures/data/.gitkeep create mode 100644 tests/codeception/frontend/.gitignore create mode 100644 tests/codeception/frontend/_bootstrap.php create mode 100644 tests/codeception/frontend/_output/.gitignore create mode 100644 tests/codeception/frontend/_pages/AboutPage.php create mode 100644 tests/codeception/frontend/_pages/ContactPage.php create mode 100644 tests/codeception/frontend/_pages/SignupPage.php create mode 100644 tests/codeception/frontend/acceptance.suite.yml create mode 100644 tests/codeception/frontend/acceptance/AboutCept.php create mode 100644 tests/codeception/frontend/acceptance/ContactCept.php create mode 100644 tests/codeception/frontend/acceptance/HomeCept.php create mode 100644 tests/codeception/frontend/acceptance/LoginCept.php create mode 100644 tests/codeception/frontend/acceptance/SignupCest.php create mode 100644 tests/codeception/frontend/acceptance/_bootstrap.php create mode 100644 tests/codeception/frontend/codeception.yml create mode 100644 tests/codeception/frontend/functional.suite.yml create mode 100644 tests/codeception/frontend/functional/AboutCept.php create mode 100644 tests/codeception/frontend/functional/ContactCept.php create mode 100644 tests/codeception/frontend/functional/HomeCept.php create mode 100644 tests/codeception/frontend/functional/LoginCept.php create mode 100644 tests/codeception/frontend/functional/SignupCest.php create mode 100644 tests/codeception/frontend/functional/_bootstrap.php create mode 100644 tests/codeception/frontend/unit.suite.yml create mode 100644 tests/codeception/frontend/unit/DbTestCase.php create mode 100644 tests/codeception/frontend/unit/TestCase.php create mode 100644 tests/codeception/frontend/unit/_bootstrap.php create mode 100644 tests/codeception/frontend/unit/fixtures/data/models/user.php create mode 100644 tests/codeception/frontend/unit/models/ContactFormTest.php create mode 100644 tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php create mode 100644 tests/codeception/frontend/unit/models/ResetPasswordFormTest.php create mode 100644 tests/codeception/frontend/unit/models/SignupFormTest.php create mode 100644 yii create mode 100644 yii.bat diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 0000000..1669168 --- /dev/null +++ b/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory" : "vendor/bower" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5d27534 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea +/uploads \ No newline at end of file diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..29c3bec --- /dev/null +++ b/.htaccess @@ -0,0 +1,18 @@ +Mod_Autoindex + + # Запрещаем просмотр содержимого папок + Options -Indexes + + +Mod_Rewrite + + Options +FollowSymlinks + # Включаем mod_rewrite + RewriteEngine On + IndexIgnore */* + # Перенаправляем administrator на входной скрипт админки + RewriteRule ^administrator/(.*)?$ /backend/web/$1 [L,PT] + RewriteRule ^storage/(.*)?$ /storage/$1 [L,PT] + # Перенаправляем все запросы на входной скрипт + RewriteRule ^([^/].*)?$ /frontend/web/$1 + \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..e98f03d --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,32 @@ +The Yii framework is free software. It is released under the terms of +the following BSD License. + +Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Yii Software LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..45e56ad --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +Yii 2 Advanced Project Template +=============================== + +Yii 2 Advanced 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 +is a separate Yii application. + +The template is designed to work in a team development environment. It supports +deploying the application in different environments. + +Documentation is at [docs/guide/README.md](docs/guide/README.md). + +[![Latest Stable Version](https://poser.pugx.org/yiisoft/yii2-app-advanced/v/stable.png)](https://packagist.org/packages/yiisoft/yii2-app-advanced) +[![Total Downloads](https://poser.pugx.org/yiisoft/yii2-app-advanced/downloads.png)](https://packagist.org/packages/yiisoft/yii2-app-advanced) +[![Build Status](https://travis-ci.org/yiisoft/yii2-app-advanced.svg?branch=master)](https://travis-ci.org/yiisoft/yii2-app-advanced) + +DIRECTORY STRUCTURE +------------------- + +``` +common + config/ contains shared configurations + mail/ contains view files for e-mails + models/ contains model classes used in both backend and frontend +console + config/ contains console configurations + controllers/ contains console controllers (commands) + migrations/ contains database migrations + models/ contains console-specific model classes + runtime/ contains files generated during runtime +backend + assets/ contains application assets such as JavaScript and CSS + config/ contains backend configurations + controllers/ contains Web controller classes + models/ contains backend-specific model classes + runtime/ contains files generated during runtime + views/ contains view files for the Web application + web/ contains the entry script and Web resources +frontend + assets/ contains application assets such as JavaScript and CSS + config/ contains frontend configurations + controllers/ contains Web controller classes + models/ contains frontend-specific model classes + runtime/ contains files generated during runtime + views/ contains view files for the Web application + web/ contains the entry script and Web resources + widgets/ contains frontend widgets +vendor/ contains dependent 3rd-party packages +environments/ contains environment-based overrides +tests contains various tests for the advanced application + codeception/ contains tests developed with Codeception PHP Testing Framework +``` diff --git a/backend/assets/AppAsset.php b/backend/assets/AppAsset.php new file mode 100644 index 0000000..c262142 --- /dev/null +++ b/backend/assets/AppAsset.php @@ -0,0 +1,29 @@ + + * @since 2.0 + */ +class AppAsset extends AssetBundle +{ + public $basePath = '@webroot'; + public $baseUrl = '@web'; + public $css = [ + 'css/site.css', + ]; + public $js = [ + ]; + public $depends = [ + 'yii\web\YiiAsset', + 'yii\bootstrap\BootstrapAsset', + ]; +} diff --git a/backend/config/.gitignore b/backend/config/.gitignore new file mode 100644 index 0000000..20da318 --- /dev/null +++ b/backend/config/.gitignore @@ -0,0 +1,2 @@ +main-local.php +params-local.php \ No newline at end of file diff --git a/backend/config/bootstrap.php b/backend/config/bootstrap.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/backend/config/bootstrap.php @@ -0,0 +1 @@ + 'app-backend', + 'basePath' => dirname(__DIR__), + 'controllerNamespace' => 'backend\controllers', + 'bootstrap' => ['log'], + 'modules' => [], + 'components' => [ + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + ], + 'log' => [ + 'traceLevel' => YII_DEBUG ? 3 : 0, + 'targets' => [ + [ + 'class' => 'yii\log\FileTarget', + 'levels' => ['error', 'warning'], + ], + ], + ], + 'errorHandler' => [ + 'errorAction' => 'site/error', + ], + ], + 'params' => $params, +]; diff --git a/backend/config/params.php b/backend/config/params.php new file mode 100644 index 0000000..7f754b9 --- /dev/null +++ b/backend/config/params.php @@ -0,0 +1,4 @@ + 'admin@example.com', +]; diff --git a/backend/controllers/ParserController.php b/backend/controllers/ParserController.php new file mode 100644 index 0000000..6637d68 --- /dev/null +++ b/backend/controllers/ParserController.php @@ -0,0 +1,70 @@ + [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'actions' => ['index'], + 'allow' => true, + 'roles' => ['@'], + ], + ], + ], + 'verbs' => [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'logout' => ['post'], + ], + ], + ]; + } + + /** + * @inheritdoc + */ + public function actions() + { + return [ + 'error' => [ + 'class' => 'yii\web\ErrorAction', + ], + ]; + } + + public function actionIndex() + { + $model = new UploadForm(); + + if (Yii::$app->request->isPost) { + $model->file = UploadedFile::getInstance($model, 'file'); + + if ($model->file && $model->validate()) { + $model->file->saveAs(Yii::getAlias('@webroot') . '/uploads/' . $model->file->baseName . '.' . $model->file->extension); + } + } + + return $this->render('parser', ['model' => $model]); + } + + + +} diff --git a/backend/controllers/SiteController.php b/backend/controllers/SiteController.php new file mode 100644 index 0000000..db3259a --- /dev/null +++ b/backend/controllers/SiteController.php @@ -0,0 +1,83 @@ + [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'actions' => ['login', 'error'], + 'allow' => true, + ], + [ + 'actions' => ['logout', 'index'], + 'allow' => true, + 'roles' => ['@'], + ], + ], + ], + 'verbs' => [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'logout' => ['post'], + ], + ], + ]; + } + + /** + * @inheritdoc + */ + public function actions() + { + return [ + 'error' => [ + 'class' => 'yii\web\ErrorAction', + ], + ]; + } + + public function actionIndex() + { + return $this->render('index'); + } + + public function actionLogin() + { + if (!\Yii::$app->user->isGuest) { + return $this->goHome(); + } + + $model = new LoginForm(); + if ($model->load(Yii::$app->request->post()) && $model->login()) { + return $this->goBack(); + } else { + return $this->render('login', [ + 'model' => $model, + ]); + } + } + + public function actionLogout() + { + Yii::$app->user->logout(); + + return $this->goHome(); + } +} diff --git a/backend/models/.gitkeep b/backend/models/.gitkeep new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/backend/models/.gitkeep @@ -0,0 +1 @@ +* diff --git a/backend/models/UploadForm.php b/backend/models/UploadForm.php new file mode 100644 index 0000000..35f91cf --- /dev/null +++ b/backend/models/UploadForm.php @@ -0,0 +1,26 @@ + +beginPage() ?> + + + + + + + <?= Html::encode($this->title) ?> + head() ?> + + +beginBody() ?> + +
+ + +
+
+ +
+
+ ['class' => 'nav nav-pills nav-stacked'], + 'items' => [ + ['label' => 'Загрузка прайсов', 'url' => ['parser/index']], +// + ], + ]); + ?> + +
+ +
+ +
+
+ +
+
+ + endBody() ?> + + +endPage() ?> diff --git a/backend/views/parser/parser.php b/backend/views/parser/parser.php new file mode 100644 index 0000000..fe48efd --- /dev/null +++ b/backend/views/parser/parser.php @@ -0,0 +1,11 @@ + + + ['enctype' => 'multipart/form-data']]) ?> + +field($model, 'file')->fileInput() ?> + + + + \ No newline at end of file diff --git a/backend/views/site/error.php b/backend/views/site/error.php new file mode 100644 index 0000000..0ba2574 --- /dev/null +++ b/backend/views/site/error.php @@ -0,0 +1,27 @@ +title = $name; +?> +
+ +

title) ?>

+ +
+ +
+ +

+ The above error occurred while the Web server was processing your request. +

+

+ Please contact us if you think this is a server error. Thank you. +

+ +
diff --git a/backend/views/site/index.php b/backend/views/site/index.php new file mode 100644 index 0000000..e6eb575 --- /dev/null +++ b/backend/views/site/index.php @@ -0,0 +1,16 @@ +title = 'Ital auto'; +?> +
+ +
+
+

Админка

+
+
+ +
+
diff --git a/backend/views/site/login.php b/backend/views/site/login.php new file mode 100644 index 0000000..ec9cc06 --- /dev/null +++ b/backend/views/site/login.php @@ -0,0 +1,35 @@ +title = 'Login'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+

title) ?>

+ +

Please fill out the following fields to login:

+ +
+
+ 'login-form']); ?> + + field($model, 'username') ?> + + field($model, 'password')->passwordInput() ?> + + field($model, 'rememberMe')->checkbox() ?> + +
+ 'btn btn-primary', 'name' => 'login-button']) ?> +
+ + +
+
+
diff --git a/backend/web/.gitignore b/backend/web/.gitignore new file mode 100644 index 0000000..3adbc3f --- /dev/null +++ b/backend/web/.gitignore @@ -0,0 +1,3 @@ +/index.php +/index-test.php +uploads/ diff --git a/backend/web/.htaccess b/backend/web/.htaccess new file mode 100644 index 0000000..fa96d7a --- /dev/null +++ b/backend/web/.htaccess @@ -0,0 +1,8 @@ +RewriteEngine on + +RewriteBase / + +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_FILENAME} !-f + +RewriteRule . index.php \ No newline at end of file diff --git a/backend/web/assets/.gitignore b/backend/web/assets/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/backend/web/assets/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/backend/web/css/site.css b/backend/web/css/site.css new file mode 100644 index 0000000..10988f6 --- /dev/null +++ b/backend/web/css/site.css @@ -0,0 +1,145 @@ +html, +body { + height: 100%; +} + +.wrap { + min-height: 100%; + height: auto; + margin: 0 auto -60px; + padding: 0 0 60px; +} + +.wrap > .container { + padding: 70px 15px 20px; +} + +.footer { + height: 60px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + padding-top: 20px; +} + +.jumbotron { + text-align: center; + background-color: transparent; +} + +.jumbotron .btn { + font-size: 21px; + padding: 14px 24px; +} + +.not-set { + color: #c55; + font-style: italic; +} + +/* add sorting icons to gridview sort links */ +a.asc:after, a.desc:after { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + padding-left: 5px; +} + +a.asc:after { + content: /*"\e113"*/ "\e151"; +} + +a.desc:after { + content: /*"\e114"*/ "\e152"; +} + +.sort-numerical a.asc:after { + content: "\e153"; +} + +.sort-numerical a.desc:after { + content: "\e154"; +} + +.sort-ordinal a.asc:after { + content: "\e155"; +} + +.sort-ordinal a.desc:after { + content: "\e156"; +} + +.grid-view th { + white-space: nowrap; +} + +.hint-block { + display: block; + margin-top: 5px; + color: #999; +} + +.error-summary { + color: #a94442; + background: #fdf7f7; + border-left: 3px solid #eed3d7; + padding: 10px 20px; + margin: 0 0 15px 0; +} + +.container{ + min-width: 960px; +} + +.left_block{ + width: 15%; + float: left; +} +.right_block{ + float: left; + width: 80%; + margin-left: 20px; +} +.active_{ + background: none; +} +.non_active{ + background: #adadad; +} + +.site-login { + width: 700px; + margin: 100px auto; +} + +.gallery_image{ + + position: relative; + margin-left: 20px; + margin-top: 20px; + display: inline-block; +} +.delete-gallery-item{ + background-color: #fff; + opacity: 0.5; + font-size: 20px; + position: absolute; + top: 5px; + right: 5px; + cursor: pointer; +} + +.delete-field-item{ + position: absolute; + top: 33%; + right: -35px; + font-size: 15px; + cursor: pointer; +} + +.form-group{ + position: relative; +} \ No newline at end of file diff --git a/backend/web/favicon.ico b/backend/web/favicon.ico new file mode 100644 index 0000000..580ed73 Binary files /dev/null and b/backend/web/favicon.ico differ diff --git a/backend/web/robots.txt b/backend/web/robots.txt new file mode 100644 index 0000000..1f53798 --- /dev/null +++ b/backend/web/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / diff --git a/common/config/.gitignore b/common/config/.gitignore new file mode 100644 index 0000000..97c0f01 --- /dev/null +++ b/common/config/.gitignore @@ -0,0 +1,2 @@ +main-local.php +params-local.php diff --git a/common/config/bootstrap.php b/common/config/bootstrap.php new file mode 100644 index 0000000..ecc13e5 --- /dev/null +++ b/common/config/bootstrap.php @@ -0,0 +1,5 @@ + dirname(dirname(__DIR__)) . '/vendor', + 'components' => [ + 'cache' => [ + 'class' => 'yii\caching\FileCache', + ], + ], +]; diff --git a/common/config/params.php b/common/config/params.php new file mode 100644 index 0000000..4ec9ba6 --- /dev/null +++ b/common/config/params.php @@ -0,0 +1,6 @@ + 'admin@example.com', + 'supportEmail' => 'support@example.com', + 'user.passwordResetTokenExpire' => 3600, +]; diff --git a/common/mail/layouts/html.php b/common/mail/layouts/html.php new file mode 100644 index 0000000..bddbc61 --- /dev/null +++ b/common/mail/layouts/html.php @@ -0,0 +1,22 @@ + +beginPage() ?> + + + + + <?= Html::encode($this->title) ?> + head() ?> + + + beginBody() ?> + + endBody() ?> + + +endPage() ?> diff --git a/common/mail/layouts/text.php b/common/mail/layouts/text.php new file mode 100644 index 0000000..7087cea --- /dev/null +++ b/common/mail/layouts/text.php @@ -0,0 +1,12 @@ + +beginPage() ?> +beginBody() ?> + +endBody() ?> +endPage() ?> diff --git a/common/mail/passwordResetToken-html.php b/common/mail/passwordResetToken-html.php new file mode 100644 index 0000000..f3daf49 --- /dev/null +++ b/common/mail/passwordResetToken-html.php @@ -0,0 +1,15 @@ +urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]); +?> +
+

Hello username) ?>,

+ +

Follow the link below to reset your password:

+ +

+
diff --git a/common/mail/passwordResetToken-text.php b/common/mail/passwordResetToken-text.php new file mode 100644 index 0000000..244c0cb --- /dev/null +++ b/common/mail/passwordResetToken-text.php @@ -0,0 +1,12 @@ +urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]); +?> +Hello username ?>, + +Follow the link below to reset your password: + + diff --git a/common/models/LoginForm.php b/common/models/LoginForm.php new file mode 100644 index 0000000..afc1c23 --- /dev/null +++ b/common/models/LoginForm.php @@ -0,0 +1,78 @@ +hasErrors()) { + $user = $this->getUser(); + if (!$user || !$user->validatePassword($this->password)) { + $this->addError($attribute, 'Incorrect username or password.'); + } + } + } + + /** + * Logs in a user using the provided username and password. + * + * @return boolean whether the user is logged in successfully + */ + public function login() + { + if ($this->validate()) { + return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0); + } else { + return false; + } + } + + /** + * Finds user by [[username]] + * + * @return User|null + */ + protected function getUser() + { + if ($this->_user === null) { + $this->_user = User::findByUsername($this->username); + } + + return $this->_user; + } +} diff --git a/common/models/User.php b/common/models/User.php new file mode 100644 index 0000000..ce78fcd --- /dev/null +++ b/common/models/User.php @@ -0,0 +1,188 @@ + self::STATUS_ACTIVE], + ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]], + ]; + } + + /** + * @inheritdoc + */ + public static function findIdentity($id) + { + return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]); + } + + /** + * @inheritdoc + */ + public static function findIdentityByAccessToken($token, $type = null) + { + throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); + } + + /** + * Finds user by username + * + * @param string $username + * @return static|null + */ + public static function findByUsername($username) + { + return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); + } + + /** + * Finds user by password reset token + * + * @param string $token password reset token + * @return static|null + */ + public static function findByPasswordResetToken($token) + { + if (!static::isPasswordResetTokenValid($token)) { + return null; + } + + return static::findOne([ + 'password_reset_token' => $token, + 'status' => self::STATUS_ACTIVE, + ]); + } + + /** + * Finds out if password reset token is valid + * + * @param string $token password reset token + * @return boolean + */ + public static function isPasswordResetTokenValid($token) + { + if (empty($token)) { + return false; + } + + $timestamp = (int) substr($token, strrpos($token, '_') + 1); + $expire = Yii::$app->params['user.passwordResetTokenExpire']; + return $timestamp + $expire >= time(); + } + + /** + * @inheritdoc + */ + public function getId() + { + return $this->getPrimaryKey(); + } + + /** + * @inheritdoc + */ + public function getAuthKey() + { + return $this->auth_key; + } + + /** + * @inheritdoc + */ + public function validateAuthKey($authKey) + { + return $this->getAuthKey() === $authKey; + } + + /** + * Validates password + * + * @param string $password password to validate + * @return boolean if password provided is valid for current user + */ + public function validatePassword($password) + { + return Yii::$app->security->validatePassword($password, $this->password_hash); + } + + /** + * Generates password hash from password and sets it to the model + * + * @param string $password + */ + public function setPassword($password) + { + $this->password_hash = Yii::$app->security->generatePasswordHash($password); + } + + /** + * Generates "remember me" authentication key + */ + public function generateAuthKey() + { + $this->auth_key = Yii::$app->security->generateRandomString(); + } + + /** + * Generates new password reset token + */ + public function generatePasswordResetToken() + { + $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); + } + + /** + * Removes password reset token + */ + public function removePasswordResetToken() + { + $this->password_reset_token = null; + } +} diff --git a/common/widgets/Alert.php b/common/widgets/Alert.php new file mode 100644 index 0000000..8f1e590 --- /dev/null +++ b/common/widgets/Alert.php @@ -0,0 +1,79 @@ +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']); + * ``` + * + * @author Kartik Visweswaran + * @author Alexander Makarov + */ +class Alert extends \yii\bootstrap\Widget +{ + /** + * @var array the alert types configuration for the flash messages. + * This array is setup as $key => $value, where: + * - $key is the name of the session flash variable + * - $value is the bootstrap alert type (i.e. danger, success, info, warning) + */ + public $alertTypes = [ + 'error' => 'alert-danger', + 'danger' => 'alert-danger', + 'success' => 'alert-success', + '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; + $flashes = $session->getAllFlashes(); + $appendCss = isset($this->options['class']) ? ' ' . $this->options['class'] : ''; + + foreach ($flashes as $type => $data) { + if (isset($this->alertTypes[$type])) { + $data = (array) $data; + foreach ($data as $i => $message) { + /* initialize css class for each alert box */ + $this->options['class'] = $this->alertTypes[$type] . $appendCss; + + /* assign unique id to each alert box */ + $this->options['id'] = $this->getId() . '-' . $type . '-' . $i; + + echo \yii\bootstrap\Alert::widget([ + 'body' => $message, + 'closeButton' => $this->closeButton, + 'options' => $this->options, + ]); + } + + $session->removeFlash($type); + } + } + } +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..22993b0 --- /dev/null +++ b/composer.json @@ -0,0 +1,37 @@ +{ + "name": "yiisoft/yii2-app-advanced", + "description": "Yii 2 Advanced Project Template", + "keywords": ["yii2", "framework", "advanced", "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": "stable", + "require": { + "php": ">=5.4.0", + "yiisoft/yii2": ">=2.0.6", + "yiisoft/yii2-bootstrap": "*", + "yiisoft/yii2-swiftmailer": "*" + }, + "require-dev": { + "yiisoft/yii2-codeception": "*", + "yiisoft/yii2-debug": "*", + "yiisoft/yii2-gii": "*", + "yiisoft/yii2-faker": "*" + }, + "config": { + "process-timeout": 1800 + }, + "extra": { + "asset-installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..8ff5113 --- /dev/null +++ b/composer.lock @@ -0,0 +1,924 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "8580bd82955b1fbb80d47024e184056e", + "packages": [ + { + "name": "bower-asset/bootstrap", + "version": "v3.3.5", + "source": { + "type": "git", + "url": "https://github.com/twbs/bootstrap.git", + "reference": "16b48259a62f576e52c903c476bd42b90ab22482" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twbs/bootstrap/zipball/16b48259a62f576e52c903c476bd42b90ab22482", + "reference": "16b48259a62f576e52c903c476bd42b90ab22482", + "shasum": "" + }, + "require": { + "bower-asset/jquery": ">=1.9.1" + }, + "type": "bower-asset-library", + "extra": { + "bower-asset-main": [ + "less/bootstrap.less", + "dist/js/bootstrap.js" + ], + "bower-asset-ignore": [ + "/.*", + "_config.yml", + "CNAME", + "composer.json", + "CONTRIBUTING.md", + "docs", + "js/tests", + "test-infra" + ] + }, + "license": [ + "MIT" + ], + "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", + "keywords": [ + "css", + "framework", + "front-end", + "js", + "less", + "mobile-first", + "responsive", + "web" + ] + }, + { + "name": "bower-asset/jquery", + "version": "2.1.4", + "source": { + "type": "git", + "url": "https://github.com/jquery/jquery.git", + "reference": "7751e69b615c6eca6f783a81e292a55725af6b85" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jquery/jquery/zipball/7751e69b615c6eca6f783a81e292a55725af6b85", + "reference": "7751e69b615c6eca6f783a81e292a55725af6b85", + "shasum": "" + }, + "require-dev": { + "bower-asset/qunit": "1.14.0", + "bower-asset/requirejs": "2.1.10", + "bower-asset/sinon": "1.8.1", + "bower-asset/sizzle": "2.1.1-patch2" + }, + "type": "bower-asset-library", + "extra": { + "bower-asset-main": "dist/jquery.js", + "bower-asset-ignore": [ + "**/.*", + "build", + "dist/cdn", + "speed", + "test", + "*.md", + "AUTHORS.txt", + "Gruntfile.js", + "package.json" + ] + }, + "license": [ + "MIT" + ], + "keywords": [ + "javascript", + "jquery", + "library" + ] + }, + { + "name": "bower-asset/jquery.inputmask", + "version": "3.1.63", + "source": { + "type": "git", + "url": "https://github.com/RobinHerbots/jquery.inputmask.git", + "reference": "c40c7287eadc31e341ebbf0c02352eb55b9cbc48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/c40c7287eadc31e341ebbf0c02352eb55b9cbc48", + "reference": "c40c7287eadc31e341ebbf0c02352eb55b9cbc48", + "shasum": "" + }, + "require": { + "bower-asset/jquery": ">=1.7" + }, + "type": "bower-asset-library", + "extra": { + "bower-asset-main": [ + "./dist/inputmask/jquery.inputmask.js", + "./dist/inputmask/jquery.inputmask.extensions.js", + "./dist/inputmask/jquery.inputmask.date.extensions.js", + "./dist/inputmask/jquery.inputmask.numeric.extensions.js", + "./dist/inputmask/jquery.inputmask.phone.extensions.js", + "./dist/inputmask/jquery.inputmask.regex.extensions.js" + ], + "bower-asset-ignore": [ + "**/.*", + "qunit/", + "nuget/", + "tools/", + "js/", + "*.md", + "build.properties", + "build.xml", + "jquery.inputmask.jquery.json" + ] + }, + "license": [ + "http://opensource.org/licenses/mit-license.php" + ], + "description": "jquery.inputmask is a jquery plugin which create an input mask.", + "keywords": [ + "form", + "input", + "inputmask", + "jquery", + "mask", + "plugins" + ] + }, + { + "name": "bower-asset/punycode", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/bestiejs/punycode.js.git", + "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3", + "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3", + "shasum": "" + }, + "type": "bower-asset-library", + "extra": { + "bower-asset-main": "punycode.js", + "bower-asset-ignore": [ + "coverage", + "tests", + ".*", + "component.json", + "Gruntfile.js", + "node_modules", + "package.json" + ] + } + }, + { + "name": "bower-asset/yii2-pjax", + "version": "v2.0.4", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/jquery-pjax.git", + "reference": "3f20897307cca046fca5323b318475ae9dac0ca0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/3f20897307cca046fca5323b318475ae9dac0ca0", + "reference": "3f20897307cca046fca5323b318475ae9dac0ca0", + "shasum": "" + }, + "require": { + "bower-asset/jquery": ">=1.8" + }, + "type": "bower-asset-library", + "extra": { + "bower-asset-main": "./jquery.pjax.js", + "bower-asset-ignore": [ + ".travis.yml", + "Gemfile", + "Gemfile.lock", + "vendor/", + "script/", + "test/" + ] + }, + "license": [ + "MIT" + ] + }, + { + "name": "cebe/markdown", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/cebe/markdown.git", + "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cebe/markdown/zipball/54a2c49de31cc44e864ebf0500a35ef21d0010b2", + "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2", + "shasum": "" + }, + "require": { + "lib-pcre": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "cebe/indent": "*", + "facebook/xhprof": "*@dev", + "phpunit/phpunit": "4.1.*" + }, + "bin": [ + "bin/markdown" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "cebe\\markdown\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "http://cebe.cc/", + "role": "Creator" + } + ], + "description": "A super fast, highly extensible markdown parser for PHP", + "homepage": "https://github.com/cebe/markdown#readme", + "keywords": [ + "extensible", + "fast", + "gfm", + "markdown", + "markdown-extra" + ], + "time": "2015-03-06 05:28:07" + }, + { + "name": "ezyang/htmlpurifier", + "version": "v4.6.0", + "source": { + "type": "git", + "url": "https://github.com/ezyang/htmlpurifier.git", + "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/6f389f0f25b90d0b495308efcfa073981177f0fd", + "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd", + "shasum": "" + }, + "require": { + "php": ">=5.2" + }, + "type": "library", + "autoload": { + "psr-0": { + "HTMLPurifier": "library/" + }, + "files": [ + "library/HTMLPurifier.composer.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL" + ], + "authors": [ + { + "name": "Edward Z. Yang", + "email": "admin@htmlpurifier.org", + "homepage": "http://ezyang.com" + } + ], + "description": "Standards compliant HTML filter written in PHP", + "homepage": "http://htmlpurifier.org/", + "keywords": [ + "html" + ], + "time": "2013-11-30 08:25:19" + }, + { + "name": "swiftmailer/swiftmailer", + "version": "v5.4.1", + "source": { + "type": "git", + "url": "https://github.com/swiftmailer/swiftmailer.git", + "reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/0697e6aa65c83edf97bb0f23d8763f94e3f11421", + "reference": "0697e6aa65c83edf97bb0f23d8763f94e3f11421", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "mockery/mockery": "~0.9.1,<0.9.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "files": [ + "lib/swift_required.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Corbyn" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Swiftmailer, free feature-rich PHP mailer", + "homepage": "http://swiftmailer.org", + "keywords": [ + "email", + "mail", + "mailer" + ], + "time": "2015-06-06 14:19:39" + }, + { + "name": "yiisoft/yii2", + "version": "2.0.6", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-framework.git", + "reference": "f42b2eb80f61992438661b01d0d74c6738e2ff38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/f42b2eb80f61992438661b01d0d74c6738e2ff38", + "reference": "f42b2eb80f61992438661b01d0d74c6738e2ff38", + "shasum": "" + }, + "require": { + "bower-asset/jquery": "2.1.*@stable | 1.11.*@stable", + "bower-asset/jquery.inputmask": "3.1.*", + "bower-asset/punycode": "1.3.*", + "bower-asset/yii2-pjax": ">=2.0.1", + "cebe/markdown": "~1.0.0 | ~1.1.0", + "ext-mbstring": "*", + "ezyang/htmlpurifier": "4.6.*", + "lib-pcre": "*", + "php": ">=5.4.0", + "yiisoft/yii2-composer": "*" + }, + "bin": [ + "yii" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com", + "homepage": "http://www.yiiframework.com/", + "role": "Founder and project lead" + }, + { + "name": "Alexander Makarov", + "email": "sam@rmcreative.ru", + "homepage": "http://rmcreative.ru/", + "role": "Core framework development" + }, + { + "name": "Maurizio Domba", + "homepage": "http://mdomba.info/", + "role": "Core framework development" + }, + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "http://cebe.cc/", + "role": "Core framework development" + }, + { + "name": "Timur Ruziev", + "email": "resurtm@gmail.com", + "homepage": "http://resurtm.com/", + "role": "Core framework development" + }, + { + "name": "Paul Klimov", + "email": "klimov.paul@gmail.com", + "role": "Core framework development" + } + ], + "description": "Yii PHP Framework Version 2", + "homepage": "http://www.yiiframework.com/", + "keywords": [ + "framework", + "yii2" + ], + "time": "2015-08-05 22:00:30" + }, + { + "name": "yiisoft/yii2-bootstrap", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-bootstrap.git", + "reference": "1b6b1e61cf91c3cdd517d6a7e71d30bb212e4af0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/1b6b1e61cf91c3cdd517d6a7e71d30bb212e4af0", + "reference": "1b6b1e61cf91c3cdd517d6a7e71d30bb212e4af0", + "shasum": "" + }, + "require": { + "bower-asset/bootstrap": "3.3.* | 3.2.* | 3.1.*", + "yiisoft/yii2": ">=2.0.4" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + }, + "asset-installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } + }, + "autoload": { + "psr-4": { + "yii\\bootstrap\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com" + } + ], + "description": "The Twitter Bootstrap extension for the Yii framework", + "keywords": [ + "bootstrap", + "yii2" + ], + "time": "2015-05-10 22:08:17" + }, + { + "name": "yiisoft/yii2-composer", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-composer.git", + "reference": "ca8d23707ae47d20b0454e4b135c156f6da6d7be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/ca8d23707ae47d20b0454e4b135c156f6da6d7be", + "reference": "ca8d23707ae47d20b0454e4b135c156f6da6d7be", + "shasum": "" + }, + "require": { + "composer-plugin-api": "1.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "yii\\composer\\Plugin", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\composer\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com" + } + ], + "description": "The composer plugin for Yii extension installer", + "keywords": [ + "composer", + "extension installer", + "yii2" + ], + "time": "2015-03-01 06:22:44" + }, + { + "name": "yiisoft/yii2-swiftmailer", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-swiftmailer.git", + "reference": "4ec435a89e30b203cea99770910fb5499cb3627a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-swiftmailer/zipball/4ec435a89e30b203cea99770910fb5499cb3627a", + "reference": "4ec435a89e30b203cea99770910fb5499cb3627a", + "shasum": "" + }, + "require": { + "swiftmailer/swiftmailer": "~5.0", + "yiisoft/yii2": ">=2.0.4" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\swiftmailer\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Paul Klimov", + "email": "klimov.paul@gmail.com" + } + ], + "description": "The SwiftMailer integration for the Yii framework", + "keywords": [ + "email", + "mail", + "mailer", + "swift", + "swiftmailer", + "yii2" + ], + "time": "2015-05-10 22:12:32" + } + ], + "packages-dev": [ + { + "name": "bower-asset/typeahead.js", + "version": "v0.10.5", + "source": { + "type": "git", + "url": "https://github.com/twitter/typeahead.js.git", + "reference": "5f198b87d1af845da502ea9df93a5e84801ce742" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twitter/typeahead.js/zipball/5f198b87d1af845da502ea9df93a5e84801ce742", + "reference": "5f198b87d1af845da502ea9df93a5e84801ce742", + "shasum": "" + }, + "require": { + "bower-asset/jquery": ">=1.7" + }, + "require-dev": { + "bower-asset/jasmine-ajax": "~1.3.1", + "bower-asset/jasmine-jquery": "~1.5.2", + "bower-asset/jquery": "~1.7" + }, + "type": "bower-asset-library", + "extra": { + "bower-asset-main": "dist/typeahead.bundle.js" + } + }, + { + "name": "fzaninotto/faker", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/fzaninotto/Faker.git", + "reference": "d0190b156bcca848d401fb80f31f504f37141c8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/d0190b156bcca848d401fb80f31f504f37141c8d", + "reference": "d0190b156bcca848d401fb80f31f504f37141c8d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~1.5" + }, + "suggest": { + "ext-intl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "time": "2015-05-29 06:29:14" + }, + { + "name": "phpspec/php-diff", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/phpspec/php-diff.git", + "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a", + "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Diff": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Chris Boulton", + "homepage": "http://github.com/chrisboulton", + "role": "Original developer" + } + ], + "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", + "time": "2013-11-01 13:02:21" + }, + { + "name": "yiisoft/yii2-codeception", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-codeception.git", + "reference": "de5007e7a99359597abbfe1c88dca3ce620061c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-codeception/zipball/de5007e7a99359597abbfe1c88dca3ce620061c5", + "reference": "de5007e7a99359597abbfe1c88dca3ce620061c5", + "shasum": "" + }, + "require": { + "yiisoft/yii2": ">=2.0.4" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\codeception\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Mark Jebri", + "email": "mark.github@yandex.ru" + } + ], + "description": "The Codeception integration for the Yii framework", + "keywords": [ + "codeception", + "yii2" + ], + "time": "2015-05-10 22:08:30" + }, + { + "name": "yiisoft/yii2-debug", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-debug.git", + "reference": "5c7081b2be71c61d3a50d978b31edc3e0b6f2f97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/5c7081b2be71c61d3a50d978b31edc3e0b6f2f97", + "reference": "5c7081b2be71c61d3a50d978b31edc3e0b6f2f97", + "shasum": "" + }, + "require": { + "yiisoft/yii2": ">=2.0.4", + "yiisoft/yii2-bootstrap": "*" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\debug\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com" + } + ], + "description": "The debugger extension for the Yii framework", + "keywords": [ + "debug", + "debugger", + "yii2" + ], + "time": "2015-05-10 22:08:56" + }, + { + "name": "yiisoft/yii2-faker", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-faker.git", + "reference": "b88ca69ee226a3610b2c26c026c3203d7ac50f6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-faker/zipball/b88ca69ee226a3610b2c26c026c3203d7ac50f6c", + "reference": "b88ca69ee226a3610b2c26c026c3203d7ac50f6c", + "shasum": "" + }, + "require": { + "fzaninotto/faker": "*", + "yiisoft/yii2": "*" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\faker\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Mark Jebri", + "email": "mark.github@yandex.ru" + } + ], + "description": "Fixture generator. The Faker integration for the Yii framework.", + "keywords": [ + "Fixture", + "faker", + "yii2" + ], + "time": "2015-03-01 06:22:44" + }, + { + "name": "yiisoft/yii2-gii", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-gii.git", + "reference": "e5a023e8779bd774194842ec1b8fb4917cf04007" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/e5a023e8779bd774194842ec1b8fb4917cf04007", + "reference": "e5a023e8779bd774194842ec1b8fb4917cf04007", + "shasum": "" + }, + "require": { + "bower-asset/typeahead.js": "0.10.*", + "phpspec/php-diff": ">=1.0.2", + "yiisoft/yii2": ">=2.0.4", + "yiisoft/yii2-bootstrap": "~2.0" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + }, + "asset-installer-paths": { + "npm-asset-library": "vendor/npm", + "bower-asset-library": "vendor/bower" + } + }, + "autoload": { + "psr-4": { + "yii\\gii\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Qiang Xue", + "email": "qiang.xue@gmail.com" + } + ], + "description": "The Gii extension for the Yii framework", + "keywords": [ + "code generator", + "gii", + "yii2" + ], + "time": "2015-05-10 22:09:31" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.4.0" + }, + "platform-dev": [] +} diff --git a/console/config/.gitignore b/console/config/.gitignore new file mode 100644 index 0000000..20da318 --- /dev/null +++ b/console/config/.gitignore @@ -0,0 +1,2 @@ +main-local.php +params-local.php \ No newline at end of file diff --git a/console/config/bootstrap.php b/console/config/bootstrap.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/console/config/bootstrap.php @@ -0,0 +1 @@ + 'app-console', + 'basePath' => dirname(__DIR__), + 'bootstrap' => ['log'], + 'controllerNamespace' => 'console\controllers', + 'components' => [ + 'log' => [ + 'targets' => [ + [ + 'class' => 'yii\log\FileTarget', + 'levels' => ['error', 'warning'], + ], + ], + ], + ], + 'params' => $params, +]; diff --git a/console/config/params.php b/console/config/params.php new file mode 100644 index 0000000..7f754b9 --- /dev/null +++ b/console/config/params.php @@ -0,0 +1,4 @@ + 'admin@example.com', +]; diff --git a/console/controllers/.gitkeep b/console/controllers/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/console/controllers/.gitkeep diff --git a/console/migrations/m130524_201442_init.php b/console/migrations/m130524_201442_init.php new file mode 100644 index 0000000..81a322a --- /dev/null +++ b/console/migrations/m130524_201442_init.php @@ -0,0 +1,34 @@ +db->driverName === 'mysql') { + // http://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci + $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB'; + } + + $this->createTable('{{%user}}', [ + 'id' => $this->primaryKey(), + 'username' => $this->string()->notNull()->unique(), + 'auth_key' => $this->string(32)->notNull(), + 'password_hash' => $this->string()->notNull(), + 'password_reset_token' => $this->string()->unique(), + 'email' => $this->string()->notNull()->unique(), + + 'status' => $this->smallInteger()->notNull()->defaultValue(10), + 'created_at' => $this->integer()->notNull(), + 'updated_at' => $this->integer()->notNull(), + ], $tableOptions); + } + + public function down() + { + $this->dropTable('{{%user}}'); + } +} diff --git a/console/models/.gitkeep b/console/models/.gitkeep new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/console/models/.gitkeep @@ -0,0 +1 @@ +* diff --git a/console/runtime/.gitignore b/console/runtime/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/console/runtime/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/environments/dev/backend/config/main-local.php b/environments/dev/backend/config/main-local.php new file mode 100644 index 0000000..d9a8ceb --- /dev/null +++ b/environments/dev/backend/config/main-local.php @@ -0,0 +1,25 @@ + [ + 'request' => [ + // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation + 'cookieValidationKey' => '', + ], + ], +]; + +if (!YII_ENV_TEST) { + // configuration adjustments for 'dev' environment + $config['bootstrap'][] = 'debug'; + $config['modules']['debug'] = [ + 'class' => 'yii\debug\Module', + ]; + + $config['bootstrap'][] = 'gii'; + $config['modules']['gii'] = [ + 'class' => 'yii\gii\Module', + ]; +} + +return $config; diff --git a/environments/dev/backend/config/params-local.php b/environments/dev/backend/config/params-local.php new file mode 100644 index 0000000..d0b9c34 --- /dev/null +++ b/environments/dev/backend/config/params-local.php @@ -0,0 +1,3 @@ +run(); diff --git a/environments/dev/backend/web/index.php b/environments/dev/backend/web/index.php new file mode 100644 index 0000000..6038167 --- /dev/null +++ b/environments/dev/backend/web/index.php @@ -0,0 +1,18 @@ +run(); diff --git a/environments/dev/common/config/main-local.php b/environments/dev/common/config/main-local.php new file mode 100644 index 0000000..43db30e --- /dev/null +++ b/environments/dev/common/config/main-local.php @@ -0,0 +1,20 @@ + [ + 'db' => [ + 'class' => 'yii\db\Connection', + 'dsn' => 'mysql:host=localhost;dbname=yii2advanced', + 'username' => 'root', + 'password' => '', + 'charset' => 'utf8', + ], + 'mailer' => [ + 'class' => 'yii\swiftmailer\Mailer', + 'viewPath' => '@common/mail', + // send all mails to a file by default. You have to set + // 'useFileTransport' to false and configure a transport + // for the mailer to send real emails. + 'useFileTransport' => true, + ], + ], +]; diff --git a/environments/dev/common/config/params-local.php b/environments/dev/common/config/params-local.php new file mode 100644 index 0000000..d0b9c34 --- /dev/null +++ b/environments/dev/common/config/params-local.php @@ -0,0 +1,3 @@ + ['gii'], + 'modules' => [ + 'gii' => 'yii\gii\Module', + ], +]; diff --git a/environments/dev/console/config/params-local.php b/environments/dev/console/config/params-local.php new file mode 100644 index 0000000..d0b9c34 --- /dev/null +++ b/environments/dev/console/config/params-local.php @@ -0,0 +1,3 @@ + [ + 'request' => [ + // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation + 'cookieValidationKey' => '', + ], + ], +]; + +if (!YII_ENV_TEST) { + // configuration adjustments for 'dev' environment + $config['bootstrap'][] = 'debug'; + $config['modules']['debug'] = 'yii\debug\Module'; + + $config['bootstrap'][] = 'gii'; + $config['modules']['gii'] = 'yii\gii\Module'; +} + +return $config; diff --git a/environments/dev/frontend/config/params-local.php b/environments/dev/frontend/config/params-local.php new file mode 100644 index 0000000..d0b9c34 --- /dev/null +++ b/environments/dev/frontend/config/params-local.php @@ -0,0 +1,3 @@ +run(); diff --git a/environments/dev/frontend/web/index.php b/environments/dev/frontend/web/index.php new file mode 100644 index 0000000..6038167 --- /dev/null +++ b/environments/dev/frontend/web/index.php @@ -0,0 +1,18 @@ +run(); diff --git a/environments/dev/yii b/environments/dev/yii new file mode 100644 index 0000000..6f0c6d2 --- /dev/null +++ b/environments/dev/yii @@ -0,0 +1,28 @@ +#!/usr/bin/env php +run(); +exit($exitCode); diff --git a/environments/index.php b/environments/index.php new file mode 100644 index 0000000..19c989d --- /dev/null +++ b/environments/index.php @@ -0,0 +1,65 @@ + [ + * 'path' => 'directory storing the local files', + * 'skipFiles' => [ + * // list of files that should only copied once and skipped if they already exist + * ], + * 'setWritable' => [ + * // list of directories that should be set writable + * ], + * 'setExecutable' => [ + * // list of files that should be set executable + * ], + * 'setCookieValidationKey' => [ + * // list of config files that need to be inserted with automatically generated cookie validation keys + * ], + * 'createSymlink' => [ + * // list of symlinks to be created. Keys are symlinks, and values are the targets. + * ], + * ], + * ]; + * ``` + */ +return [ + 'Development' => [ + 'path' => 'dev', + 'setWritable' => [ + 'backend/runtime', + 'backend/web/assets', + 'frontend/runtime', + 'frontend/web/assets', + ], + 'setExecutable' => [ + 'yii', + 'tests/codeception/bin/yii', + ], + 'setCookieValidationKey' => [ + 'backend/config/main-local.php', + 'frontend/config/main-local.php', + ], + ], + 'Production' => [ + 'path' => 'prod', + 'setWritable' => [ + 'backend/runtime', + 'backend/web/assets', + 'frontend/runtime', + 'frontend/web/assets', + ], + 'setExecutable' => [ + 'yii', + ], + 'setCookieValidationKey' => [ + 'backend/config/main-local.php', + 'frontend/config/main-local.php', + ], + ], +]; diff --git a/environments/prod/backend/config/main-local.php b/environments/prod/backend/config/main-local.php new file mode 100644 index 0000000..af46ba3 --- /dev/null +++ b/environments/prod/backend/config/main-local.php @@ -0,0 +1,9 @@ + [ + 'request' => [ + // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation + 'cookieValidationKey' => '', + ], + ], +]; diff --git a/environments/prod/backend/config/params-local.php b/environments/prod/backend/config/params-local.php new file mode 100644 index 0000000..d0b9c34 --- /dev/null +++ b/environments/prod/backend/config/params-local.php @@ -0,0 +1,3 @@ +run(); diff --git a/environments/prod/common/config/main-local.php b/environments/prod/common/config/main-local.php new file mode 100644 index 0000000..84c4d9f --- /dev/null +++ b/environments/prod/common/config/main-local.php @@ -0,0 +1,16 @@ + [ + 'db' => [ + 'class' => 'yii\db\Connection', + 'dsn' => 'mysql:host=localhost;dbname=yii2advanced', + 'username' => 'root', + 'password' => '', + 'charset' => 'utf8', + ], + 'mailer' => [ + 'class' => 'yii\swiftmailer\Mailer', + 'viewPath' => '@common/mail', + ], + ], +]; diff --git a/environments/prod/common/config/params-local.php b/environments/prod/common/config/params-local.php new file mode 100644 index 0000000..d0b9c34 --- /dev/null +++ b/environments/prod/common/config/params-local.php @@ -0,0 +1,3 @@ + [ + 'request' => [ + // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation + 'cookieValidationKey' => '', + ], + ], +]; diff --git a/environments/prod/frontend/config/params-local.php b/environments/prod/frontend/config/params-local.php new file mode 100644 index 0000000..d0b9c34 --- /dev/null +++ b/environments/prod/frontend/config/params-local.php @@ -0,0 +1,3 @@ +run(); diff --git a/environments/prod/yii b/environments/prod/yii new file mode 100644 index 0000000..1fe0342 --- /dev/null +++ b/environments/prod/yii @@ -0,0 +1,28 @@ +#!/usr/bin/env php +run(); +exit($exitCode); diff --git a/frontend/assets/AppAsset.php b/frontend/assets/AppAsset.php new file mode 100644 index 0000000..995e3dc --- /dev/null +++ b/frontend/assets/AppAsset.php @@ -0,0 +1,29 @@ + + * @since 2.0 + */ +class AppAsset extends AssetBundle +{ + public $basePath = '@webroot'; + public $baseUrl = '@web'; + public $css = [ + 'css/site.css', + ]; + public $js = [ + ]; + public $depends = [ + 'yii\web\YiiAsset', + 'yii\bootstrap\BootstrapAsset', + ]; +} diff --git a/frontend/config/.gitignore b/frontend/config/.gitignore new file mode 100644 index 0000000..20da318 --- /dev/null +++ b/frontend/config/.gitignore @@ -0,0 +1,2 @@ +main-local.php +params-local.php \ No newline at end of file diff --git a/frontend/config/bootstrap.php b/frontend/config/bootstrap.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/frontend/config/bootstrap.php @@ -0,0 +1 @@ + 'app-frontend', + 'basePath' => dirname(__DIR__), + 'bootstrap' => ['log'], + 'controllerNamespace' => 'frontend\controllers', + 'components' => [ + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + ], + 'log' => [ + 'traceLevel' => YII_DEBUG ? 3 : 0, + 'targets' => [ + [ + 'class' => 'yii\log\FileTarget', + 'levels' => ['error', 'warning'], + ], + ], + ], + 'errorHandler' => [ + 'errorAction' => 'site/error', + ], + ], + 'params' => $params, +]; diff --git a/frontend/config/params.php b/frontend/config/params.php new file mode 100644 index 0000000..7f754b9 --- /dev/null +++ b/frontend/config/params.php @@ -0,0 +1,4 @@ + 'admin@example.com', +]; diff --git a/frontend/controllers/SiteController.php b/frontend/controllers/SiteController.php new file mode 100644 index 0000000..cf691ae --- /dev/null +++ b/frontend/controllers/SiteController.php @@ -0,0 +1,213 @@ + [ + 'class' => AccessControl::className(), + 'only' => ['logout', 'signup'], + 'rules' => [ + [ + 'actions' => ['signup'], + 'allow' => true, + 'roles' => ['?'], + ], + [ + 'actions' => ['logout'], + 'allow' => true, + 'roles' => ['@'], + ], + ], + ], + 'verbs' => [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'logout' => ['post'], + ], + ], + ]; + } + + /** + * @inheritdoc + */ + public function actions() + { + return [ + 'error' => [ + 'class' => 'yii\web\ErrorAction', + ], + 'captcha' => [ + 'class' => 'yii\captcha\CaptchaAction', + 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, + ], + ]; + } + + /** + * Displays homepage. + * + * @return mixed + */ + public function actionIndex() + { + return $this->render('index'); + } + + /** + * Logs in a user. + * + * @return mixed + */ + public function actionLogin() + { + if (!\Yii::$app->user->isGuest) { + return $this->goHome(); + } + + $model = new LoginForm(); + if ($model->load(Yii::$app->request->post()) && $model->login()) { + return $this->goBack(); + } else { + return $this->render('login', [ + 'model' => $model, + ]); + } + } + + /** + * Logs out the current user. + * + * @return mixed + */ + public function actionLogout() + { + Yii::$app->user->logout(); + + return $this->goHome(); + } + + /** + * Displays contact page. + * + * @return mixed + */ + public function actionContact() + { + $model = new ContactForm(); + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + 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.'); + } + + return $this->refresh(); + } else { + return $this->render('contact', [ + 'model' => $model, + ]); + } + } + + /** + * Displays about page. + * + * @return mixed + */ + public function actionAbout() + { + return $this->render('about'); + } + + /** + * Signs user up. + * + * @return mixed + */ + public function actionSignup() + { + $model = new SignupForm(); + if ($model->load(Yii::$app->request->post())) { + if ($user = $model->signup()) { + if (Yii::$app->getUser()->login($user)) { + return $this->goHome(); + } + } + } + + return $this->render('signup', [ + 'model' => $model, + ]); + } + + /** + * Requests password reset. + * + * @return mixed + */ + public function actionRequestPasswordReset() + { + $model = new PasswordResetRequestForm(); + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + if ($model->sendEmail()) { + Yii::$app->session->setFlash('success', 'Check your email for further instructions.'); + + return $this->goHome(); + } else { + Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for email provided.'); + } + } + + return $this->render('requestPasswordResetToken', [ + 'model' => $model, + ]); + } + + /** + * Resets password. + * + * @param string $token + * @return mixed + * @throws BadRequestHttpException + */ + public function actionResetPassword($token) + { + try { + $model = new ResetPasswordForm($token); + } catch (InvalidParamException $e) { + throw new BadRequestHttpException($e->getMessage()); + } + + if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) { + Yii::$app->session->setFlash('success', 'New password was saved.'); + + return $this->goHome(); + } + + return $this->render('resetPassword', [ + 'model' => $model, + ]); + } +} diff --git a/frontend/models/ContactForm.php b/frontend/models/ContactForm.php new file mode 100644 index 0000000..613abb5 --- /dev/null +++ b/frontend/models/ContactForm.php @@ -0,0 +1,59 @@ + 'Verification Code', + ]; + } + + /** + * 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 + */ + public function sendEmail($email) + { + return Yii::$app->mailer->compose() + ->setTo($email) + ->setFrom([$this->email => $this->name]) + ->setSubject($this->subject) + ->setTextBody($this->body) + ->send(); + } +} diff --git a/frontend/models/PasswordResetRequestForm.php b/frontend/models/PasswordResetRequestForm.php new file mode 100644 index 0000000..20c6810 --- /dev/null +++ b/frontend/models/PasswordResetRequestForm.php @@ -0,0 +1,60 @@ + 'trim'], + ['email', 'required'], + ['email', 'email'], + ['email', 'exist', + 'targetClass' => '\common\models\User', + 'filter' => ['status' => User::STATUS_ACTIVE], + 'message' => 'There is no user with such email.' + ], + ]; + } + + /** + * Sends an email with a link, for resetting the password. + * + * @return boolean whether the email was send + */ + public function sendEmail() + { + /* @var $user User */ + $user = User::findOne([ + 'status' => User::STATUS_ACTIVE, + 'email' => $this->email, + ]); + + if ($user) { + if (!User::isPasswordResetTokenValid($user->password_reset_token)) { + $user->generatePasswordResetToken(); + } + + if ($user->save()) { + return \Yii::$app->mailer->compose(['html' => 'passwordResetToken-html', 'text' => 'passwordResetToken-text'], ['user' => $user]) + ->setFrom([\Yii::$app->params['supportEmail'] => \Yii::$app->name . ' robot']) + ->setTo($this->email) + ->setSubject('Password reset for ' . \Yii::$app->name) + ->send(); + } + } + + return false; + } +} diff --git a/frontend/models/ResetPasswordForm.php b/frontend/models/ResetPasswordForm.php new file mode 100644 index 0000000..dd48f52 --- /dev/null +++ b/frontend/models/ResetPasswordForm.php @@ -0,0 +1,65 @@ +_user = User::findByPasswordResetToken($token); + if (!$this->_user) { + throw new InvalidParamException('Wrong password reset token.'); + } + parent::__construct($config); + } + + /** + * @inheritdoc + */ + public function rules() + { + return [ + ['password', 'required'], + ['password', 'string', 'min' => 6], + ]; + } + + /** + * Resets password. + * + * @return boolean if password was reset. + */ + public function resetPassword() + { + $user = $this->_user; + $user->setPassword($this->password); + $user->removePasswordResetToken(); + + return $user->save(false); + } +} diff --git a/frontend/models/SignupForm.php b/frontend/models/SignupForm.php new file mode 100644 index 0000000..e83963b --- /dev/null +++ b/frontend/models/SignupForm.php @@ -0,0 +1,59 @@ + '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', 'required'], + ['email', 'email'], + ['email', 'string', 'max' => 255], + ['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'], + + ['password', 'required'], + ['password', 'string', 'min' => 6], + ]; + } + + /** + * Signs user up. + * + * @return User|null the saved model or null if saving fails + */ + public function signup() + { + if ($this->validate()) { + $user = new User(); + $user->username = $this->username; + $user->email = $this->email; + $user->setPassword($this->password); + $user->generateAuthKey(); + if ($user->save()) { + return $user; + } + } + + return null; + } +} diff --git a/frontend/runtime/.gitignore b/frontend/runtime/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/frontend/runtime/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/frontend/views/layouts/main.php b/frontend/views/layouts/main.php new file mode 100644 index 0000000..3e09838 --- /dev/null +++ b/frontend/views/layouts/main.php @@ -0,0 +1,79 @@ + +beginPage() ?> + + + + + + + <?= Html::encode($this->title) ?> + head() ?> + + +beginBody() ?> + +
+ 'My Company', + 'brandUrl' => Yii::$app->homeUrl, + 'options' => [ + 'class' => 'navbar-inverse navbar-fixed-top', + ], + ]); + $menuItems = [ + ['label' => 'Home', 'url' => ['/site/index']], + ['label' => 'About', 'url' => ['/site/about']], + ['label' => 'Contact', 'url' => ['/site/contact']], + ]; + if (Yii::$app->user->isGuest) { + $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']]; + $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']]; + } else { + $menuItems[] = [ + 'label' => 'Logout (' . Yii::$app->user->identity->username . ')', + 'url' => ['/site/logout'], + 'linkOptions' => ['data-method' => 'post'] + ]; + } + echo Nav::widget([ + 'options' => ['class' => 'navbar-nav navbar-right'], + 'items' => $menuItems, + ]); + NavBar::end(); + ?> + +
+ isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], + ]) ?> + + +
+
+ +
+
+

© My Company

+ +

+
+
+ +endBody() ?> + + +endPage() ?> diff --git a/frontend/views/site/about.php b/frontend/views/site/about.php new file mode 100644 index 0000000..8eb0764 --- /dev/null +++ b/frontend/views/site/about.php @@ -0,0 +1,16 @@ +title = 'About'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+

title) ?>

+ +

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

+ + +
diff --git a/frontend/views/site/contact.php b/frontend/views/site/contact.php new file mode 100644 index 0000000..16ebdb2 --- /dev/null +++ b/frontend/views/site/contact.php @@ -0,0 +1,45 @@ +title = 'Contact'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+

title) ?>

+ +

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

+ +
+
+ 'contact-form']); ?> + + field($model, 'name') ?> + + field($model, 'email') ?> + + field($model, 'subject') ?> + + field($model, 'body')->textArea(['rows' => 6]) ?> + + field($model, 'verifyCode')->widget(Captcha::className(), [ + 'template' => '
{image}
{input}
', + ]) ?> + +
+ 'btn btn-primary', 'name' => 'contact-button']) ?> +
+ + +
+
+ +
diff --git a/frontend/views/site/error.php b/frontend/views/site/error.php new file mode 100644 index 0000000..0ba2574 --- /dev/null +++ b/frontend/views/site/error.php @@ -0,0 +1,27 @@ +title = $name; +?> +
+ +

title) ?>

+ +
+ +
+ +

+ The above error occurred while the Web server was processing your request. +

+

+ Please contact us if you think this is a server error. Thank you. +

+ +
diff --git a/frontend/views/site/index.php b/frontend/views/site/index.php new file mode 100644 index 0000000..ff41da9 --- /dev/null +++ b/frontend/views/site/index.php @@ -0,0 +1,53 @@ +title = 'Автозапчасти, каталог запчастей, запчасти для иномарок в магазине ИталАвто'; +?> +
+ +
+

Congratulations!

+ +

You have successfully created your Yii-powered application.

+ +

Get started with Yii

+
+ +
+ +
+
+

Heading

+ +

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

+ +

Yii Documentation »

+
+
+

Heading

+ +

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

+ +

Yii Forum »

+
+
+

Heading

+ +

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

+ +

Yii Extensions »

+
+
+ +
+
diff --git a/frontend/views/site/login.php b/frontend/views/site/login.php new file mode 100644 index 0000000..fe67ee0 --- /dev/null +++ b/frontend/views/site/login.php @@ -0,0 +1,39 @@ +title = 'Login'; +$this->params['breadcrumbs'][] = $this->title; +?> + diff --git a/frontend/views/site/requestPasswordResetToken.php b/frontend/views/site/requestPasswordResetToken.php new file mode 100644 index 0000000..494ddb3 --- /dev/null +++ b/frontend/views/site/requestPasswordResetToken.php @@ -0,0 +1,31 @@ +title = 'Request password reset'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+

title) ?>

+ +

Please fill out your email. A link to reset password will be sent there.

+ +
+
+ 'request-password-reset-form']); ?> + + field($model, 'email') ?> + +
+ 'btn btn-primary']) ?> +
+ + +
+
+
diff --git a/frontend/views/site/resetPassword.php b/frontend/views/site/resetPassword.php new file mode 100644 index 0000000..8e6d93f --- /dev/null +++ b/frontend/views/site/resetPassword.php @@ -0,0 +1,31 @@ +title = 'Reset password'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+

title) ?>

+ +

Please choose your new password:

+ +
+
+ 'reset-password-form']); ?> + + field($model, 'password')->passwordInput() ?> + +
+ 'btn btn-primary']) ?> +
+ + +
+
+
diff --git a/frontend/views/site/signup.php b/frontend/views/site/signup.php new file mode 100644 index 0000000..58ccd8e --- /dev/null +++ b/frontend/views/site/signup.php @@ -0,0 +1,35 @@ +title = 'Signup'; +$this->params['breadcrumbs'][] = $this->title; +?> + diff --git a/frontend/web/.gitignore b/frontend/web/.gitignore new file mode 100644 index 0000000..25c74e6 --- /dev/null +++ b/frontend/web/.gitignore @@ -0,0 +1,2 @@ +/index.php +/index-test.php diff --git a/frontend/web/.htaccess b/frontend/web/.htaccess new file mode 100644 index 0000000..35a2d28 --- /dev/null +++ b/frontend/web/.htaccess @@ -0,0 +1,8 @@ +RewriteEngine on +RewriteBase / +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d + +RewriteRule . index.php + +Options -Indexes \ No newline at end of file diff --git a/frontend/web/assets/.gitignore b/frontend/web/assets/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/frontend/web/assets/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/frontend/web/css/site.css b/frontend/web/css/site.css new file mode 100644 index 0000000..698be70 --- /dev/null +++ b/frontend/web/css/site.css @@ -0,0 +1,91 @@ +html, +body { + height: 100%; +} + +.wrap { + min-height: 100%; + height: auto; + margin: 0 auto -60px; + padding: 0 0 60px; +} + +.wrap > .container { + padding: 70px 15px 20px; +} + +.footer { + height: 60px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + padding-top: 20px; +} + +.jumbotron { + text-align: center; + background-color: transparent; +} + +.jumbotron .btn { + font-size: 21px; + padding: 14px 24px; +} + +.not-set { + color: #c55; + font-style: italic; +} + +/* add sorting icons to gridview sort links */ +a.asc:after, a.desc:after { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + padding-left: 5px; +} + +a.asc:after { + content: /*"\e113"*/ "\e151"; +} + +a.desc:after { + content: /*"\e114"*/ "\e152"; +} + +.sort-numerical a.asc:after { + content: "\e153"; +} + +.sort-numerical a.desc:after { + content: "\e154"; +} + +.sort-ordinal a.asc:after { + content: "\e155"; +} + +.sort-ordinal a.desc:after { + content: "\e156"; +} + +.grid-view th { + white-space: nowrap; +} + +.hint-block { + display: block; + margin-top: 5px; + color: #999; +} + +.error-summary { + color: #a94442; + background: #fdf7f7; + border-left: 3px solid #eed3d7; + padding: 10px 20px; + margin: 0 0 15px 0; +} diff --git a/frontend/web/favicon.ico b/frontend/web/favicon.ico new file mode 100644 index 0000000..580ed73 Binary files /dev/null and b/frontend/web/favicon.ico differ diff --git a/frontend/web/robots.txt b/frontend/web/robots.txt new file mode 100644 index 0000000..6f27bb6 --- /dev/null +++ b/frontend/web/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: \ No newline at end of file diff --git a/init b/init new file mode 100644 index 0000000..1b35927 --- /dev/null +++ b/init @@ -0,0 +1,209 @@ +#!/usr/bin/env php + + * + * @link http://www.yiiframework.com/ + * @copyright Copyright (c) 2008 Yii Software LLC + * @license http://www.yiiframework.com/license/ + */ + +if (!extension_loaded('openssl')) { + die('The OpenSSL PHP extension is required by Yii2.'); +} + +$params = getParams(); +$root = str_replace('\\', '/', __DIR__); +$envs = require("$root/environments/index.php"); +$envNames = array_keys($envs); + +echo "Yii Application Initialization Tool v1.0\n\n"; + +$envName = null; +if (empty($params['env']) || $params['env'] === '1') { + echo "Which environment do you want the application to be initialized in?\n\n"; + foreach ($envNames as $i => $name) { + echo " [$i] $name\n"; + } + echo "\n Your choice [0-" . (count($envs) - 1) . ', or "q" to quit] '; + $answer = trim(fgets(STDIN)); + + if (!ctype_digit($answer) || !in_array($answer, range(0, count($envs) - 1))) { + echo "\n Quit initialization.\n"; + exit(0); + } + + if (isset($envNames[$answer])) { + $envName = $envNames[$answer]; + } +} else { + $envName = $params['env']; +} + +if (!in_array($envName, $envNames)) { + $envsList = implode(', ', $envNames); + echo "\n $envName is not a valid environment. Try one of the following: $envsList. \n"; + exit(2); +} + +$env = $envs[$envName]; + +if (empty($params['env'])) { + echo "\n Initialize the application under '{$envNames[$answer]}' environment? [yes|no] "; + $answer = trim(fgets(STDIN)); + if (strncasecmp($answer, 'y', 1)) { + echo "\n Quit initialization.\n"; + exit(0); + } +} + +echo "\n Start initialization ...\n\n"; +$files = getFileList("$root/environments/{$env['path']}"); +if (isset($env['skipFiles'])) { + $skipFiles = $env['skipFiles']; + array_walk($skipFiles, function(&$value) use($env, $root) { $value = "$root/$value"; }); + $files = array_diff($files, array_intersect_key($env['skipFiles'], array_filter($skipFiles, 'file_exists'))); +} +$all = false; +foreach ($files as $file) { + if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) { + break; + } +} + +$callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable', 'createSymlink']; +foreach ($callbacks as $callback) { + if (!empty($env[$callback])) { + $callback($root, $env[$callback]); + } +} + +echo "\n ... initialization completed.\n\n"; + +function getFileList($root, $basePath = '') +{ + $files = []; + $handle = opendir($root); + while (($path = readdir($handle)) !== false) { + if ($path === '.git' || $path === '.svn' || $path === '.' || $path === '..') { + continue; + } + $fullPath = "$root/$path"; + $relativePath = $basePath === '' ? $path : "$basePath/$path"; + if (is_dir($fullPath)) { + $files = array_merge($files, getFileList($fullPath, $relativePath)); + } else { + $files[] = $relativePath; + } + } + closedir($handle); + return $files; +} + +function copyFile($root, $source, $target, &$all, $params) +{ + if (!is_file($root . '/' . $source)) { + echo " skip $target ($source not exist)\n"; + return true; + } + if (is_file($root . '/' . $target)) { + if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) { + echo " unchanged $target\n"; + return true; + } + if ($all) { + echo " overwrite $target\n"; + } else { + echo " exist $target\n"; + echo " ...overwrite? [Yes|No|All|Quit] "; + + + $answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN)); + if (!strncasecmp($answer, 'q', 1)) { + return false; + } else { + if (!strncasecmp($answer, 'y', 1)) { + echo " overwrite $target\n"; + } else { + if (!strncasecmp($answer, 'a', 1)) { + echo " overwrite $target\n"; + $all = true; + } else { + echo " skip $target\n"; + return true; + } + } + } + } + file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); + return true; + } + echo " generate $target\n"; + @mkdir(dirname($root . '/' . $target), 0777, true); + file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source)); + return true; +} + +function getParams() +{ + $rawParams = []; + if (isset($_SERVER['argv'])) { + $rawParams = $_SERVER['argv']; + array_shift($rawParams); + } + + $params = []; + foreach ($rawParams as $param) { + if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) { + $name = $matches[1]; + $params[$name] = isset($matches[3]) ? $matches[3] : true; + } else { + $params[] = $param; + } + } + return $params; +} + +function setWritable($root, $paths) +{ + foreach ($paths as $writable) { + echo " chmod 0777 $writable\n"; + @chmod("$root/$writable", 0777); + } +} + +function setExecutable($root, $paths) +{ + foreach ($paths as $executable) { + echo " chmod 0755 $executable\n"; + @chmod("$root/$executable", 0755); + } +} + +function setCookieValidationKey($root, $paths) +{ + foreach ($paths as $file) { + echo " generate cookie validation key in $file\n"; + $file = $root . '/' . $file; + $length = 32; + $bytes = openssl_random_pseudo_bytes($length); + $key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.'); + $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file)); + file_put_contents($file, $content); + } +} + +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); + @symlink($root . "/" . $target, $root . "/" . $link); + } +} diff --git a/init.bat b/init.bat new file mode 100644 index 0000000..e50c242 --- /dev/null +++ b/init.bat @@ -0,0 +1,20 @@ +@echo off + +rem ------------------------------------------------------------- +rem Yii command line init script for Windows. +rem +rem @author Qiang Xue +rem @link http://www.yiiframework.com/ +rem @copyright Copyright (c) 2008 Yii Software LLC +rem @license http://www.yiiframework.com/license/ +rem ------------------------------------------------------------- + +@setlocal + +set YII_PATH=%~dp0 + +if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe + +"%PHP_COMMAND%" "%YII_PATH%init" %* + +@endlocal diff --git a/requirements.php b/requirements.php new file mode 100644 index 0000000..fd84f47 --- /dev/null +++ b/requirements.php @@ -0,0 +1,132 @@ +Error'; + echo '

The path to yii framework seems to be incorrect.

'; + echo '

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

'; + echo '

Please refer to the README on how to install Yii.

'; +} + +require_once($frameworkPath . '/requirements/YiiRequirementChecker.php'); +$requirementsChecker = new YiiRequirementChecker(); + +$gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.'; +$gdOK = $imagickOK = false; + +if (extension_loaded('imagick')) { + $imagick = new Imagick(); + $imagickFormats = $imagick->queryFormats('PNG'); + if (in_array('PNG', $imagickFormats)) { + $imagickOK = true; + } else { + $imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.'; + } +} + +if (extension_loaded('gd')) { + $gdInfo = gd_info(); + if (!empty($gdInfo['FreeType Support'])) { + $gdOK = true; + } else { + $gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.'; + } +} + +/** + * Adjust requirements according to your application specifics. + */ +$requirements = array( + // Database : + array( + 'name' => 'PDO extension', + 'mandatory' => true, + 'condition' => extension_loaded('pdo'), + 'by' => 'All DB-related classes', + ), + array( + 'name' => 'PDO SQLite extension', + 'mandatory' => false, + 'condition' => extension_loaded('pdo_sqlite'), + 'by' => 'All DB-related classes', + 'memo' => 'Required for SQLite database.', + ), + array( + 'name' => 'PDO MySQL extension', + 'mandatory' => false, + 'condition' => extension_loaded('pdo_mysql'), + 'by' => 'All DB-related classes', + 'memo' => 'Required for MySQL database.', + ), + array( + 'name' => 'PDO PostgreSQL extension', + 'mandatory' => false, + 'condition' => extension_loaded('pdo_pgsql'), + 'by' => 'All DB-related classes', + 'memo' => 'Required for PostgreSQL database.', + ), + // Cache : + array( + 'name' => 'Memcache extension', + 'mandatory' => false, + 'condition' => extension_loaded('memcache') || extension_loaded('memcached'), + 'by' => 'MemCache', + 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true.' : '' + ), + array( + 'name' => 'APC extension', + 'mandatory' => false, + 'condition' => extension_loaded('apc'), + 'by' => 'ApcCache', + ), + // CAPTCHA: + array( + 'name' => 'GD PHP extension with FreeType support', + 'mandatory' => false, + 'condition' => $gdOK, + 'by' => 'Captcha', + 'memo' => $gdMemo, + ), + array( + 'name' => 'ImageMagick PHP extension with PNG support', + 'mandatory' => false, + 'condition' => $imagickOK, + 'by' => 'Captcha', + 'memo' => $imagickMemo, + ), + // PHP ini : + 'phpExposePhp' => array( + 'name' => 'Expose PHP', + 'mandatory' => false, + 'condition' => $requirementsChecker->checkPhpIniOff("expose_php"), + 'by' => 'Security reasons', + 'memo' => '"expose_php" should be disabled at php.ini', + ), + 'phpAllowUrlInclude' => array( + 'name' => 'PHP allow url include', + 'mandatory' => false, + 'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"), + 'by' => 'Security reasons', + 'memo' => '"allow_url_include" should be disabled at php.ini', + ), + 'phpSmtp' => array( + 'name' => 'PHP mail SMTP', + 'mandatory' => false, + 'condition' => strlen(ini_get('SMTP')) > 0, + 'by' => 'Email sending', + 'memo' => 'PHP mail SMTP server required', + ), +); +$requirementsChecker->checkYii()->check($requirements)->render(); diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..ad7f016 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,58 @@ +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.0.*" "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 `yii2_advanced_tests` database 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 new file mode 100644 index 0000000..1a793ed --- /dev/null +++ b/tests/codeception.yml @@ -0,0 +1,11 @@ +include: + - codeception/common + - codeception/console + - codeception/backend + - codeception/frontend + +paths: + log: codeception/_output + +settings: + colors: true diff --git a/tests/codeception/_output/.gitignore b/tests/codeception/_output/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/tests/codeception/_output/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/codeception/backend/.gitignore b/tests/codeception/backend/.gitignore new file mode 100644 index 0000000..985dbb4 --- /dev/null +++ b/tests/codeception/backend/.gitignore @@ -0,0 +1,4 @@ +# 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 new file mode 100644 index 0000000..a28a3d2 --- /dev/null +++ b/tests/codeception/backend/_bootstrap.php @@ -0,0 +1,23 @@ +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->seeLink('Logout (erau)'); +$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 new file mode 100644 index 0000000..411855e --- /dev/null +++ b/tests/codeception/backend/acceptance/_bootstrap.php @@ -0,0 +1,2 @@ +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->seeLink('Logout (erau)'); +$I->dontSeeLink('Login'); +$I->dontSeeLink('Signup'); diff --git a/tests/codeception/backend/functional/_bootstrap.php b/tests/codeception/backend/functional/_bootstrap.php new file mode 100644 index 0000000..94f3fbd --- /dev/null +++ b/tests/codeception/backend/functional/_bootstrap.php @@ -0,0 +1,2 @@ +run(); +exit($exitCode); diff --git a/tests/codeception/bin/yii.bat b/tests/codeception/bin/yii.bat new file mode 100644 index 0000000..d516b3a --- /dev/null +++ b/tests/codeception/bin/yii.bat @@ -0,0 +1,20 @@ +@echo off + +rem ------------------------------------------------------------- +rem Yii command line bootstrap script for Windows. +rem +rem @author Qiang Xue +rem @link http://www.yiiframework.com/ +rem @copyright Copyright (c) 2008 Yii Software LLC +rem @license http://www.yiiframework.com/license/ +rem ------------------------------------------------------------- + +@setlocal + +set YII_PATH=%~dp0 + +if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe + +"%PHP_COMMAND%" "%YII_PATH%yii" %* + +@endlocal diff --git a/tests/codeception/common/.gitignore b/tests/codeception/common/.gitignore new file mode 100644 index 0000000..985dbb4 --- /dev/null +++ b/tests/codeception/common/.gitignore @@ -0,0 +1,4 @@ +# these files are auto generated by codeception build +/unit/UnitTester.php +/functional/FunctionalTester.php +/acceptance/AcceptanceTester.php diff --git a/tests/codeception/common/_bootstrap.php b/tests/codeception/common/_bootstrap.php new file mode 100644 index 0000000..cea3ee5 --- /dev/null +++ b/tests/codeception/common/_bootstrap.php @@ -0,0 +1,15 @@ +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 new file mode 100644 index 0000000..c5ebcf1 --- /dev/null +++ b/tests/codeception/common/_support/FixtureHelper.php @@ -0,0 +1,72 @@ +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 new file mode 100644 index 0000000..e8a3407 --- /dev/null +++ b/tests/codeception/common/codeception.yml @@ -0,0 +1,13 @@ +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/fixtures/UserFixture.php b/tests/codeception/common/fixtures/UserFixture.php new file mode 100644 index 0000000..7153c8c --- /dev/null +++ b/tests/codeception/common/fixtures/UserFixture.php @@ -0,0 +1,13 @@ + '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/common/templates/fixtures/user.php b/tests/codeception/common/templates/fixtures/user.php new file mode 100644 index 0000000..d3f83b5 --- /dev/null +++ b/tests/codeception/common/templates/fixtures/user.php @@ -0,0 +1,17 @@ +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 new file mode 100644 index 0000000..a0582a5 --- /dev/null +++ b/tests/codeception/common/unit.suite.yml @@ -0,0 +1,6 @@ +# 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 new file mode 100644 index 0000000..2159a69 --- /dev/null +++ b/tests/codeception/common/unit/DbTestCase.php @@ -0,0 +1,11 @@ + 'bayer.hudson', + 'auth_key' => 'HP187Mvq7Mmm3CTU80dLkGmni_FUH_lR', + //password_0 + 'password_hash' => '$2y$13$EjaPFBnZOQsHdGuHI.xvhuDp1fHpo8hKRSk6yshqa9c5EG8s3C3lO', + 'password_reset_token' => 'ExzkCOaYc1L8IOBs4wdTGGbgNiG3Wz1I_1402312317', + 'created_at' => '1402312317', + 'updated_at' => '1402312317', + 'email' => 'nicole.paucek@schultz.info', + ], +]; diff --git a/tests/codeception/common/unit/models/LoginFormTest.php b/tests/codeception/common/unit/models/LoginFormTest.php new file mode 100644 index 0000000..54c8209 --- /dev/null +++ b/tests/codeception/common/unit/models/LoginFormTest.php @@ -0,0 +1,93 @@ + [ + '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/acceptance.php b/tests/codeception/config/acceptance.php new file mode 100644 index 0000000..9318da5 --- /dev/null +++ b/tests/codeception/config/acceptance.php @@ -0,0 +1,7 @@ + 'app-common', + 'basePath' => dirname(__DIR__), + ] +); diff --git a/tests/codeception/config/config.php b/tests/codeception/config/config.php new file mode 100644 index 0000000..b478679 --- /dev/null +++ b/tests/codeception/config/config.php @@ -0,0 +1,26 @@ + '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 new file mode 100644 index 0000000..4d3aeb0 --- /dev/null +++ b/tests/codeception/config/console/unit.php @@ -0,0 +1,14 @@ + [ + '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 new file mode 100644 index 0000000..6bd08d3 --- /dev/null +++ b/tests/codeception/config/unit.php @@ -0,0 +1,7 @@ + $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 new file mode 100644 index 0000000..0e1cefa --- /dev/null +++ b/tests/codeception/frontend/_pages/SignupPage.php @@ -0,0 +1,27 @@ + $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 new file mode 100644 index 0000000..1828a04 --- /dev/null +++ b/tests/codeception/frontend/acceptance.suite.yml @@ -0,0 +1,28 @@ +# 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 new file mode 100644 index 0000000..50bf9ba --- /dev/null +++ b/tests/codeception/frontend/acceptance/AboutCept.php @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..f7a6bc8 --- /dev/null +++ b/tests/codeception/frontend/acceptance/ContactCept.php @@ -0,0 +1,56 @@ +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 adress 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 new file mode 100644 index 0000000..9566a2e --- /dev/null +++ b/tests/codeception/frontend/acceptance/HomeCept.php @@ -0,0 +1,12 @@ +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 new file mode 100644 index 0000000..599e24f --- /dev/null +++ b/tests/codeception/frontend/acceptance/LoginCept.php @@ -0,0 +1,34 @@ +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->seeLink('Logout (erau)'); +$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 new file mode 100644 index 0000000..ab4b7bb --- /dev/null +++ b/tests/codeception/frontend/acceptance/SignupCest.php @@ -0,0 +1,82 @@ + '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->seeLink('Logout (tester)'); + } +} diff --git a/tests/codeception/frontend/acceptance/_bootstrap.php b/tests/codeception/frontend/acceptance/_bootstrap.php new file mode 100644 index 0000000..b0a40ef --- /dev/null +++ b/tests/codeception/frontend/acceptance/_bootstrap.php @@ -0,0 +1,2 @@ +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 new file mode 100644 index 0000000..c61d4c2 --- /dev/null +++ b/tests/codeception/frontend/functional/ContactCept.php @@ -0,0 +1,47 @@ +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 adress 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 new file mode 100644 index 0000000..f340061 --- /dev/null +++ b/tests/codeception/frontend/functional/HomeCept.php @@ -0,0 +1,12 @@ +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 new file mode 100644 index 0000000..daca12c --- /dev/null +++ b/tests/codeception/frontend/functional/LoginCept.php @@ -0,0 +1,29 @@ +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->seeLink('Logout (erau)'); +$I->dontSeeLink('Login'); +$I->dontSeeLink('Signup'); diff --git a/tests/codeception/frontend/functional/SignupCest.php b/tests/codeception/frontend/functional/SignupCest.php new file mode 100644 index 0000000..525b037 --- /dev/null +++ b/tests/codeception/frontend/functional/SignupCest.php @@ -0,0 +1,90 @@ + '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\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->seeLink('Logout (tester)'); + } +} diff --git a/tests/codeception/frontend/functional/_bootstrap.php b/tests/codeception/frontend/functional/_bootstrap.php new file mode 100644 index 0000000..1abc491 --- /dev/null +++ b/tests/codeception/frontend/functional/_bootstrap.php @@ -0,0 +1,3 @@ + 'okirlin', + 'auth_key' => 'iwTNae9t34OmnK6l4vT4IeaTk-YWI2Rv', + 'password_hash' => '$2y$13$CXT0Rkle1EMJ/c1l5bylL.EylfmQ39O5JlHJVFpNn618OUS1HwaIi', + 'password_reset_token' => 't5GU9NwpuGYSfb7FEZMAxqtuz2PkEvv_' . time(), + 'created_at' => '1391885313', + 'updated_at' => '1391885313', + 'email' => 'brady.renner@rutherford.com', + ], + [ + 'username' => 'troy.becker', + 'auth_key' => 'EdKfXrx88weFMV0vIxuTMWKgfK2tS3Lp', + 'password_hash' => '$2y$13$g5nv41Px7VBqhS3hVsVN2.MKfgT3jFdkXEsMC4rQJLfaMa7VaJqL2', + 'password_reset_token' => '4BSNyiZNAuxjs5Mty990c47sVrgllIi_' . time(), + 'created_at' => '1391885313', + 'updated_at' => '1391885313', + 'email' => 'nicolas.dianna@hotmail.com', + 'status' => '0', + ], +]; diff --git a/tests/codeception/frontend/unit/models/ContactFormTest.php b/tests/codeception/frontend/unit/models/ContactFormTest.php new file mode 100644 index 0000000..9aaf595 --- /dev/null +++ b/tests/codeception/frontend/unit/models/ContactFormTest.php @@ -0,0 +1,59 @@ +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 new file mode 100644 index 0000000..ced8cce --- /dev/null +++ b/tests/codeception/frontend/unit/models/PasswordResetRequestFormTest.php @@ -0,0 +1,87 @@ +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 new file mode 100644 index 0000000..a4dd021 --- /dev/null +++ b/tests/codeception/frontend/unit/models/ResetPasswordFormTest.php @@ -0,0 +1,43 @@ +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 new file mode 100644 index 0000000..4d08e8c --- /dev/null +++ b/tests/codeception/frontend/unit/models/SignupFormTest.php @@ -0,0 +1,52 @@ + '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/yii b/yii new file mode 100644 index 0000000..6f0c6d2 --- /dev/null +++ b/yii @@ -0,0 +1,28 @@ +#!/usr/bin/env php +run(); +exit($exitCode); diff --git a/yii.bat b/yii.bat new file mode 100644 index 0000000..d516b3a --- /dev/null +++ b/yii.bat @@ -0,0 +1,20 @@ +@echo off + +rem ------------------------------------------------------------- +rem Yii command line bootstrap script for Windows. +rem +rem @author Qiang Xue +rem @link http://www.yiiframework.com/ +rem @copyright Copyright (c) 2008 Yii Software LLC +rem @license http://www.yiiframework.com/license/ +rem ------------------------------------------------------------- + +@setlocal + +set YII_PATH=%~dp0 + +if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe + +"%PHP_COMMAND%" "%YII_PATH%yii" %* + +@endlocal -- libgit2 0.21.4