From b87eb71ca78ed3b0a2c27d908844d0af34426c9b Mon Sep 17 00:00:00 2001
From: den
Date: Tue, 21 Nov 2023 19:51:44 +0300
Subject: [PATCH] first commit
---
.bowerrc | 3 +
.gitignore | 43 +
LICENSE.md | 29 +
README.md | 60 +
Vagrantfile | 88 +
backend/Dockerfile | 4 +
backend/assets/AppAsset.php | 23 +
backend/codeception.yml | 15 +
backend/config/.gitignore | 4 +
backend/config/bootstrap.php | 1 +
backend/config/main.php | 66 +
backend/config/params.php | 5 +
backend/config/test.php | 15 +
backend/controllers/SiteController.php | 104 +
backend/models/.gitkeep | 1 +
backend/modules/banner/Banner.php | 24 +
.../banner/controllers/BannerController.php | 151 +
.../banner/controllers/DefaultController.php | 20 +
backend/modules/banner/views/banner/_form.php | 41 +
.../modules/banner/views/banner/create.php | 20 +
backend/modules/banner/views/banner/index.php | 42 +
.../modules/banner/views/banner/update.php | 21 +
backend/modules/banner/views/banner/view.php | 38 +
.../modules/banner/views/default/index.php | 12 +
backend/modules/category/Category.php | 24 +
.../controllers/CategoryController.php | 144 +
.../controllers/DefaultController.php | 20 +
.../modules/category/views/category/_form.php | 27 +
.../category/views/category/create.php | 20 +
.../modules/category/views/category/index.php | 43 +
.../category/views/category/update.php | 21 +
.../modules/category/views/category/view.php | 39 +
.../modules/category/views/default/index.php | 12 +
backend/modules/order/Order.php | 24 +
.../order/controllers/DefaultController.php | 20 +
.../order/controllers/OrderController.php | 144 +
backend/modules/order/views/default/index.php | 12 +
backend/modules/order/views/order/_form.php | 35 +
backend/modules/order/views/order/create.php | 20 +
backend/modules/order/views/order/index.php | 47 +
backend/modules/order/views/order/update.php | 21 +
backend/modules/order/views/order/view.php | 43 +
backend/modules/product/Product.php | 24 +
.../product/controllers/DefaultController.php | 20 +
.../product/controllers/ProductController.php | 151 +
.../modules/product/views/default/index.php | 12 +
.../modules/product/views/product/_form.php | 66 +
.../modules/product/views/product/create.php | 20 +
.../modules/product/views/product/index.php | 49 +
.../modules/product/views/product/update.php | 21 +
.../modules/product/views/product/view.php | 45 +
backend/modules/table/Table.php | 24 +
.../table/controllers/DefaultController.php | 20 +
.../table/controllers/TableController.php | 144 +
backend/modules/table/views/default/index.php | 12 +
backend/modules/table/views/table/_form.php | 29 +
backend/modules/table/views/table/create.php | 20 +
backend/modules/table/views/table/index.php | 44 +
backend/modules/table/views/table/update.php | 21 +
backend/modules/table/views/table/view.php | 40 +
backend/runtime/.gitignore | 2 +
backend/tests/_bootstrap.php | 10 +
backend/tests/_data/.gitignore | 0
backend/tests/_data/login_data.php | 13 +
backend/tests/_output/.gitignore | 2 +
backend/tests/_support/.gitignore | 1 +
backend/tests/_support/FunctionalTester.php | 26 +
backend/tests/_support/UnitTester.php | 26 +
backend/tests/functional.suite.yml | 5 +
backend/tests/functional/LoginCest.php | 44 +
backend/tests/functional/_bootstrap.php | 16 +
backend/tests/unit.suite.yml | 2 +
backend/tests/unit/_bootstrap.php | 16 +
backend/views/layouts/blank.php | 33 +
backend/views/layouts/content.php | 42 +
backend/views/layouts/control-sidebar.php | 5 +
backend/views/layouts/footer.php | 7 +
backend/views/layouts/main-login.php | 38 +
backend/views/layouts/main.php | 54 +
backend/views/layouts/navbar.php | 26 +
backend/views/layouts/sidebar.php | 47 +
backend/views/site/error.php | 27 +
backend/views/site/index.php | 53 +
backend/views/site/login.php | 32 +
backend/web/assets/.gitignore | 2 +
backend/web/css/site.css | 90 +
backend/web/favicon.ico | Bin 0 -> 318 bytes
codeception.yml | 9 +
common/classes/Debug.php | 20 +
common/codeception.yml | 15 +
common/config/.gitignore | 4 +
common/config/__autocomplete.php | 33 +
common/config/bootstrap.php | 5 +
common/config/main.php | 13 +
common/config/params.php | 9 +
common/config/test.php | 11 +
common/fixtures/UserFixture.php | 10 +
common/mail/emailVerify-html.php | 16 +
common/mail/emailVerify-text.php | 12 +
common/mail/layouts/html.php | 24 +
common/mail/layouts/text.php | 12 +
common/mail/passwordResetToken-html.php | 16 +
common/mail/passwordResetToken-text.php | 12 +
common/models/Banner.php | 46 +
common/models/Category.php | 59 +
common/models/LoginForm.php | 80 +
common/models/Order.php | 109 +
common/models/OrderProduct.php | 70 +
common/models/Product.php | 123 +
common/models/Table.php | 62 +
common/models/User.php | 213 +
common/tests/_bootstrap.php | 9 +
common/tests/_data/user.php | 14 +
common/tests/_output/.gitignore | 2 +
common/tests/_support/.gitignore | 1 +
common/tests/_support/UnitTester.php | 26 +
common/tests/unit.suite.yml | 7 +
common/tests/unit/models/LoginFormTest.php | 67 +
common/widgets/Alert.php | 76 +
composer.json | 59 +
composer.lock | 7270 +++++++++++++++++
console/config/.gitignore | 3 +
console/config/bootstrap.php | 1 +
console/config/main.php | 36 +
console/config/params.php | 5 +
console/config/test.php | 4 +
console/controllers/.gitkeep | 0
console/migrations/m130524_201442_init.php | 33 +
...erification_token_column_to_user_table.php | 16 +
.../m231012_102457_create_table_table.php | 31 +
.../m231012_102916_create_product_table.php | 35 +
.../m231017_091537_create_category_table.php | 31 +
...dd_category_id_column_to_product_table.php | 50 +
.../m231019_110637_create_order_table.php | 68 +
...1019_123857_create_order_product_table.php | 63 +
.../m231023_142702_create_banner_table.php | 29 +
...5405_add_photo_column_to_product_table.php | 25 +
console/models/.gitkeep | 1 +
console/runtime/.gitignore | 2 +
docker-compose.yml | 38 +
.../dev/backend/config/codeception-local.php | 11 +
.../dev/backend/config/main-local.php | 25 +
.../dev/backend/config/params-local.php | 4 +
.../dev/backend/config/test-local.php | 4 +
environments/dev/backend/web/index-test.php | 27 +
environments/dev/backend/web/index.php | 18 +
environments/dev/backend/web/robots.txt | 2 +
.../dev/common/config/codeception-local.php | 16 +
environments/dev/common/config/main-local.php | 43 +
.../dev/common/config/params-local.php | 4 +
environments/dev/common/config/test-local.php | 9 +
.../dev/console/config/main-local.php | 8 +
.../dev/console/config/params-local.php | 4 +
.../dev/console/config/test-local.php | 4 +
.../dev/frontend/config/codeception-local.php | 11 +
.../dev/frontend/config/main-local.php | 25 +
.../dev/frontend/config/params-local.php | 4 +
.../dev/frontend/config/test-local.php | 4 +
environments/dev/frontend/web/index-test.php | 28 +
environments/dev/frontend/web/index.php | 18 +
environments/dev/frontend/web/robots.txt | 2 +
environments/dev/yii | 24 +
environments/dev/yii_test | 28 +
environments/dev/yii_test.bat | 15 +
environments/index.php | 68 +
.../prod/backend/config/main-local.php | 10 +
.../prod/backend/config/params-local.php | 4 +
environments/prod/backend/web/index.php | 18 +
environments/prod/backend/web/robots.txt | 2 +
.../prod/common/config/main-local.php | 17 +
.../prod/common/config/params-local.php | 4 +
.../prod/console/config/main-local.php | 4 +
.../prod/console/config/params-local.php | 4 +
.../prod/frontend/config/main-local.php | 10 +
.../prod/frontend/config/params-local.php | 4 +
environments/prod/frontend/web/index.php | 18 +
environments/prod/frontend/web/robots.txt | 2 +
environments/prod/yii | 24 +
frontend/Dockerfile | 4 +
frontend/assets/AppAsset.php | 23 +
frontend/codeception.yml | 15 +
frontend/config/.gitignore | 4 +
frontend/config/bootstrap.php | 1 +
frontend/config/main.php | 50 +
frontend/config/params.php | 4 +
frontend/config/test.php | 18 +
frontend/controllers/BaseApiController.php | 78 +
frontend/controllers/CategoryController.php | 33 +
frontend/controllers/OrderController.php | 30 +
frontend/controllers/ProductController.php | 28 +
frontend/controllers/SiteController.php | 217 +
frontend/models/ContactForm.php | 61 +
frontend/models/PasswordResetRequestForm.php | 69 +
.../models/ResendVerificationEmailForm.php | 61 +
frontend/models/ResetPasswordForm.php | 67 +
frontend/models/SignupForm.php | 80 +
frontend/models/VerifyEmailForm.php | 52 +
frontend/runtime/.gitignore | 2 +
frontend/tests/_bootstrap.php | 10 +
frontend/tests/_data/login_data.php | 25 +
frontend/tests/_data/user.php | 45 +
frontend/tests/_output/.gitignore | 2 +
frontend/tests/_support/.gitignore | 1 +
frontend/tests/_support/FunctionalTester.php | 34 +
frontend/tests/_support/UnitTester.php | 26 +
frontend/tests/acceptance.suite.yml.example | 9 +
frontend/tests/acceptance/HomeCest.php | 21 +
frontend/tests/acceptance/_bootstrap.php | 16 +
frontend/tests/functional.suite.yml | 7 +
frontend/tests/functional/AboutCest.php | 14 +
frontend/tests/functional/ContactCest.php | 60 +
frontend/tests/functional/HomeCest.php | 17 +
frontend/tests/functional/LoginCest.php | 66 +
.../ResendVerificationEmailCest.php | 83 +
frontend/tests/functional/SignupCest.php | 59 +
frontend/tests/functional/VerifyEmailCest.php | 68 +
frontend/tests/functional/_bootstrap.php | 16 +
frontend/tests/unit.suite.yml | 7 +
frontend/tests/unit/_bootstrap.php | 16 +
.../tests/unit/models/ContactFormTest.php | 35 +
.../models/PasswordResetRequestFormTest.php | 59 +
.../ResendVerificationEmailFormTest.php | 85 +
.../unit/models/ResetPasswordFormTest.php | 44 +
frontend/tests/unit/models/SignupFormTest.php | 72 +
.../tests/unit/models/VerifyEmailFormTest.php | 55 +
frontend/views/layouts/main.php | 84 +
frontend/views/site/about.php | 16 +
frontend/views/site/contact.php | 45 +
frontend/views/site/error.php | 27 +
frontend/views/site/index.php | 52 +
frontend/views/site/login.php | 41 +
.../views/site/requestPasswordResetToken.php | 31 +
.../views/site/resendVerificationEmail.php | 31 +
frontend/views/site/resetPassword.php | 31 +
frontend/views/site/signup.php | 35 +
frontend/web/assets/.gitignore | 2 +
frontend/web/css/site.css | 103 +
frontend/web/favicon.ico | Bin 0 -> 318 bytes
.../banner/image_2023-10-28_15-29-32.png | Bin 0 -> 42487 bytes
frontend/web/images/product/DSC_8254.jpg | Bin 0 -> 8772491 bytes
.../product/image_2023-10-28_15-29-32.png | Bin 0 -> 42487 bytes
init | 356 +
init.bat | 15 +
requirements.php | 155 +
vagrant/config/.gitignore | 2 +
vagrant/config/vagrant-local.example.yml | 22 +
vagrant/nginx/app.conf | 77 +
vagrant/nginx/log/.gitignore | 5 +
vagrant/provision/always-as-root.sh | 12 +
vagrant/provision/common.sh | 9 +
vagrant/provision/once-as-root.sh | 74 +
vagrant/provision/once-as-vagrant.sh | 32 +
vagrant/provision/provision.awk | 70 +
yii.bat | 15 +
254 files changed, 15630 insertions(+)
create mode 100755 .bowerrc
create mode 100755 .gitignore
create mode 100755 LICENSE.md
create mode 100755 README.md
create mode 100755 Vagrantfile
create mode 100755 backend/Dockerfile
create mode 100755 backend/assets/AppAsset.php
create mode 100755 backend/codeception.yml
create mode 100755 backend/config/.gitignore
create mode 100755 backend/config/bootstrap.php
create mode 100755 backend/config/main.php
create mode 100755 backend/config/params.php
create mode 100755 backend/config/test.php
create mode 100755 backend/controllers/SiteController.php
create mode 100755 backend/models/.gitkeep
create mode 100755 backend/modules/banner/Banner.php
create mode 100755 backend/modules/banner/controllers/BannerController.php
create mode 100755 backend/modules/banner/controllers/DefaultController.php
create mode 100755 backend/modules/banner/views/banner/_form.php
create mode 100755 backend/modules/banner/views/banner/create.php
create mode 100755 backend/modules/banner/views/banner/index.php
create mode 100755 backend/modules/banner/views/banner/update.php
create mode 100755 backend/modules/banner/views/banner/view.php
create mode 100755 backend/modules/banner/views/default/index.php
create mode 100755 backend/modules/category/Category.php
create mode 100755 backend/modules/category/controllers/CategoryController.php
create mode 100755 backend/modules/category/controllers/DefaultController.php
create mode 100755 backend/modules/category/views/category/_form.php
create mode 100755 backend/modules/category/views/category/create.php
create mode 100755 backend/modules/category/views/category/index.php
create mode 100755 backend/modules/category/views/category/update.php
create mode 100755 backend/modules/category/views/category/view.php
create mode 100755 backend/modules/category/views/default/index.php
create mode 100755 backend/modules/order/Order.php
create mode 100755 backend/modules/order/controllers/DefaultController.php
create mode 100755 backend/modules/order/controllers/OrderController.php
create mode 100755 backend/modules/order/views/default/index.php
create mode 100755 backend/modules/order/views/order/_form.php
create mode 100755 backend/modules/order/views/order/create.php
create mode 100755 backend/modules/order/views/order/index.php
create mode 100755 backend/modules/order/views/order/update.php
create mode 100755 backend/modules/order/views/order/view.php
create mode 100755 backend/modules/product/Product.php
create mode 100755 backend/modules/product/controllers/DefaultController.php
create mode 100755 backend/modules/product/controllers/ProductController.php
create mode 100755 backend/modules/product/views/default/index.php
create mode 100755 backend/modules/product/views/product/_form.php
create mode 100755 backend/modules/product/views/product/create.php
create mode 100755 backend/modules/product/views/product/index.php
create mode 100755 backend/modules/product/views/product/update.php
create mode 100755 backend/modules/product/views/product/view.php
create mode 100755 backend/modules/table/Table.php
create mode 100755 backend/modules/table/controllers/DefaultController.php
create mode 100755 backend/modules/table/controllers/TableController.php
create mode 100755 backend/modules/table/views/default/index.php
create mode 100755 backend/modules/table/views/table/_form.php
create mode 100755 backend/modules/table/views/table/create.php
create mode 100755 backend/modules/table/views/table/index.php
create mode 100755 backend/modules/table/views/table/update.php
create mode 100755 backend/modules/table/views/table/view.php
create mode 100755 backend/runtime/.gitignore
create mode 100755 backend/tests/_bootstrap.php
create mode 100755 backend/tests/_data/.gitignore
create mode 100755 backend/tests/_data/login_data.php
create mode 100755 backend/tests/_output/.gitignore
create mode 100755 backend/tests/_support/.gitignore
create mode 100755 backend/tests/_support/FunctionalTester.php
create mode 100755 backend/tests/_support/UnitTester.php
create mode 100755 backend/tests/functional.suite.yml
create mode 100755 backend/tests/functional/LoginCest.php
create mode 100755 backend/tests/functional/_bootstrap.php
create mode 100755 backend/tests/unit.suite.yml
create mode 100755 backend/tests/unit/_bootstrap.php
create mode 100755 backend/views/layouts/blank.php
create mode 100755 backend/views/layouts/content.php
create mode 100755 backend/views/layouts/control-sidebar.php
create mode 100755 backend/views/layouts/footer.php
create mode 100755 backend/views/layouts/main-login.php
create mode 100755 backend/views/layouts/main.php
create mode 100755 backend/views/layouts/navbar.php
create mode 100755 backend/views/layouts/sidebar.php
create mode 100755 backend/views/site/error.php
create mode 100755 backend/views/site/index.php
create mode 100755 backend/views/site/login.php
create mode 100755 backend/web/assets/.gitignore
create mode 100755 backend/web/css/site.css
create mode 100755 backend/web/favicon.ico
create mode 100755 codeception.yml
create mode 100755 common/classes/Debug.php
create mode 100755 common/codeception.yml
create mode 100755 common/config/.gitignore
create mode 100755 common/config/__autocomplete.php
create mode 100755 common/config/bootstrap.php
create mode 100755 common/config/main.php
create mode 100755 common/config/params.php
create mode 100755 common/config/test.php
create mode 100755 common/fixtures/UserFixture.php
create mode 100755 common/mail/emailVerify-html.php
create mode 100755 common/mail/emailVerify-text.php
create mode 100755 common/mail/layouts/html.php
create mode 100755 common/mail/layouts/text.php
create mode 100755 common/mail/passwordResetToken-html.php
create mode 100755 common/mail/passwordResetToken-text.php
create mode 100755 common/models/Banner.php
create mode 100755 common/models/Category.php
create mode 100755 common/models/LoginForm.php
create mode 100755 common/models/Order.php
create mode 100755 common/models/OrderProduct.php
create mode 100755 common/models/Product.php
create mode 100755 common/models/Table.php
create mode 100755 common/models/User.php
create mode 100755 common/tests/_bootstrap.php
create mode 100755 common/tests/_data/user.php
create mode 100755 common/tests/_output/.gitignore
create mode 100755 common/tests/_support/.gitignore
create mode 100755 common/tests/_support/UnitTester.php
create mode 100755 common/tests/unit.suite.yml
create mode 100755 common/tests/unit/models/LoginFormTest.php
create mode 100755 common/widgets/Alert.php
create mode 100755 composer.json
create mode 100755 composer.lock
create mode 100755 console/config/.gitignore
create mode 100755 console/config/bootstrap.php
create mode 100755 console/config/main.php
create mode 100755 console/config/params.php
create mode 100755 console/config/test.php
create mode 100755 console/controllers/.gitkeep
create mode 100755 console/migrations/m130524_201442_init.php
create mode 100755 console/migrations/m190124_110200_add_verification_token_column_to_user_table.php
create mode 100755 console/migrations/m231012_102457_create_table_table.php
create mode 100755 console/migrations/m231012_102916_create_product_table.php
create mode 100755 console/migrations/m231017_091537_create_category_table.php
create mode 100755 console/migrations/m231017_112159_add_category_id_column_to_product_table.php
create mode 100755 console/migrations/m231019_110637_create_order_table.php
create mode 100755 console/migrations/m231019_123857_create_order_product_table.php
create mode 100755 console/migrations/m231023_142702_create_banner_table.php
create mode 100755 console/migrations/m231025_085405_add_photo_column_to_product_table.php
create mode 100755 console/models/.gitkeep
create mode 100755 console/runtime/.gitignore
create mode 100755 docker-compose.yml
create mode 100755 environments/dev/backend/config/codeception-local.php
create mode 100755 environments/dev/backend/config/main-local.php
create mode 100755 environments/dev/backend/config/params-local.php
create mode 100755 environments/dev/backend/config/test-local.php
create mode 100755 environments/dev/backend/web/index-test.php
create mode 100755 environments/dev/backend/web/index.php
create mode 100755 environments/dev/backend/web/robots.txt
create mode 100755 environments/dev/common/config/codeception-local.php
create mode 100755 environments/dev/common/config/main-local.php
create mode 100755 environments/dev/common/config/params-local.php
create mode 100755 environments/dev/common/config/test-local.php
create mode 100755 environments/dev/console/config/main-local.php
create mode 100755 environments/dev/console/config/params-local.php
create mode 100755 environments/dev/console/config/test-local.php
create mode 100755 environments/dev/frontend/config/codeception-local.php
create mode 100755 environments/dev/frontend/config/main-local.php
create mode 100755 environments/dev/frontend/config/params-local.php
create mode 100755 environments/dev/frontend/config/test-local.php
create mode 100755 environments/dev/frontend/web/index-test.php
create mode 100755 environments/dev/frontend/web/index.php
create mode 100755 environments/dev/frontend/web/robots.txt
create mode 100755 environments/dev/yii
create mode 100755 environments/dev/yii_test
create mode 100755 environments/dev/yii_test.bat
create mode 100755 environments/index.php
create mode 100755 environments/prod/backend/config/main-local.php
create mode 100755 environments/prod/backend/config/params-local.php
create mode 100755 environments/prod/backend/web/index.php
create mode 100755 environments/prod/backend/web/robots.txt
create mode 100755 environments/prod/common/config/main-local.php
create mode 100755 environments/prod/common/config/params-local.php
create mode 100755 environments/prod/console/config/main-local.php
create mode 100755 environments/prod/console/config/params-local.php
create mode 100755 environments/prod/frontend/config/main-local.php
create mode 100755 environments/prod/frontend/config/params-local.php
create mode 100755 environments/prod/frontend/web/index.php
create mode 100755 environments/prod/frontend/web/robots.txt
create mode 100755 environments/prod/yii
create mode 100755 frontend/Dockerfile
create mode 100755 frontend/assets/AppAsset.php
create mode 100755 frontend/codeception.yml
create mode 100755 frontend/config/.gitignore
create mode 100755 frontend/config/bootstrap.php
create mode 100755 frontend/config/main.php
create mode 100755 frontend/config/params.php
create mode 100755 frontend/config/test.php
create mode 100755 frontend/controllers/BaseApiController.php
create mode 100755 frontend/controllers/CategoryController.php
create mode 100755 frontend/controllers/OrderController.php
create mode 100755 frontend/controllers/ProductController.php
create mode 100755 frontend/controllers/SiteController.php
create mode 100755 frontend/models/ContactForm.php
create mode 100755 frontend/models/PasswordResetRequestForm.php
create mode 100755 frontend/models/ResendVerificationEmailForm.php
create mode 100755 frontend/models/ResetPasswordForm.php
create mode 100755 frontend/models/SignupForm.php
create mode 100755 frontend/models/VerifyEmailForm.php
create mode 100755 frontend/runtime/.gitignore
create mode 100755 frontend/tests/_bootstrap.php
create mode 100755 frontend/tests/_data/login_data.php
create mode 100755 frontend/tests/_data/user.php
create mode 100755 frontend/tests/_output/.gitignore
create mode 100755 frontend/tests/_support/.gitignore
create mode 100755 frontend/tests/_support/FunctionalTester.php
create mode 100755 frontend/tests/_support/UnitTester.php
create mode 100755 frontend/tests/acceptance.suite.yml.example
create mode 100755 frontend/tests/acceptance/HomeCest.php
create mode 100755 frontend/tests/acceptance/_bootstrap.php
create mode 100755 frontend/tests/functional.suite.yml
create mode 100755 frontend/tests/functional/AboutCest.php
create mode 100755 frontend/tests/functional/ContactCest.php
create mode 100755 frontend/tests/functional/HomeCest.php
create mode 100755 frontend/tests/functional/LoginCest.php
create mode 100755 frontend/tests/functional/ResendVerificationEmailCest.php
create mode 100755 frontend/tests/functional/SignupCest.php
create mode 100755 frontend/tests/functional/VerifyEmailCest.php
create mode 100755 frontend/tests/functional/_bootstrap.php
create mode 100755 frontend/tests/unit.suite.yml
create mode 100755 frontend/tests/unit/_bootstrap.php
create mode 100755 frontend/tests/unit/models/ContactFormTest.php
create mode 100755 frontend/tests/unit/models/PasswordResetRequestFormTest.php
create mode 100755 frontend/tests/unit/models/ResendVerificationEmailFormTest.php
create mode 100755 frontend/tests/unit/models/ResetPasswordFormTest.php
create mode 100755 frontend/tests/unit/models/SignupFormTest.php
create mode 100755 frontend/tests/unit/models/VerifyEmailFormTest.php
create mode 100755 frontend/views/layouts/main.php
create mode 100755 frontend/views/site/about.php
create mode 100755 frontend/views/site/contact.php
create mode 100755 frontend/views/site/error.php
create mode 100755 frontend/views/site/index.php
create mode 100755 frontend/views/site/login.php
create mode 100755 frontend/views/site/requestPasswordResetToken.php
create mode 100755 frontend/views/site/resendVerificationEmail.php
create mode 100755 frontend/views/site/resetPassword.php
create mode 100755 frontend/views/site/signup.php
create mode 100755 frontend/web/assets/.gitignore
create mode 100755 frontend/web/css/site.css
create mode 100755 frontend/web/favicon.ico
create mode 100644 frontend/web/images/banner/image_2023-10-28_15-29-32.png
create mode 100644 frontend/web/images/product/DSC_8254.jpg
create mode 100644 frontend/web/images/product/image_2023-10-28_15-29-32.png
create mode 100755 init
create mode 100755 init.bat
create mode 100755 requirements.php
create mode 100755 vagrant/config/.gitignore
create mode 100755 vagrant/config/vagrant-local.example.yml
create mode 100755 vagrant/nginx/app.conf
create mode 100755 vagrant/nginx/log/.gitignore
create mode 100755 vagrant/provision/always-as-root.sh
create mode 100755 vagrant/provision/common.sh
create mode 100755 vagrant/provision/once-as-root.sh
create mode 100755 vagrant/provision/once-as-vagrant.sh
create mode 100755 vagrant/provision/provision.awk
create mode 100755 yii.bat
diff --git a/.bowerrc b/.bowerrc
new file mode 100755
index 0000000..a39b5b0
--- /dev/null
+++ b/.bowerrc
@@ -0,0 +1,3 @@
+{
+ "directory" : "vendor/bower-asset"
+}
diff --git a/.gitignore b/.gitignore
new file mode 100755
index 0000000..3cafba1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,43 @@
+# yii console commands
+/yii
+/yii_test
+/yii_test.bat
+
+# phpstorm project files
+.idea
+
+# netbeans project files
+nbproject
+
+# zend studio for eclipse project files
+.buildpath
+.project
+.settings
+
+# windows thumbnail cache
+Thumbs.db
+
+# composer vendor dir
+/vendor
+
+# composer itself is not needed
+composer.phar
+
+# Mac DS_Store Files
+.DS_Store
+
+# phpunit itself is not needed
+phpunit.phar
+# local phpunit config
+/phpunit.xml
+
+# vagrant runtime
+/.vagrant
+
+# ignore generated files
+/frontend/web/index.php
+/frontend/web/index-test.php
+/frontend/web/robots.txt
+/backend/web/index.php
+/backend/web/index-test.php
+/backend/web/robots.txt
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100755
index 0000000..ee872b9
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,29 @@
+Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Yii Software LLC nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100755
index 0000000..ea3d192
--- /dev/null
+++ b/README.md
@@ -0,0 +1,60 @@
+
+
+
+
+
Yii 2 Advanced Project Template
+
+
+
+Yii 2 Advanced Project Template is a skeleton [Yii 2](https://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://img.shields.io/packagist/v/yiisoft/yii2-app-advanced.svg)](https://packagist.org/packages/yiisoft/yii2-app-advanced)
+[![Total Downloads](https://img.shields.io/packagist/dt/yiisoft/yii2-app-advanced.svg)](https://packagist.org/packages/yiisoft/yii2-app-advanced)
+[![build](https://github.com/yiisoft/yii2-app-advanced/workflows/build/badge.svg)](https://github.com/yiisoft/yii2-app-advanced/actions?query=workflow%3Abuild)
+
+DIRECTORY STRUCTURE
+-------------------
+
+```
+common
+ config/ contains shared configurations
+ mail/ contains view files for e-mails
+ models/ contains model classes used in both backend and frontend
+ tests/ contains tests for common classes
+console
+ config/ contains console configurations
+ controllers/ contains console controllers (commands)
+ 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
+ tests/ contains tests for backend application
+ views/ contains view files for the Web application
+ web/ contains the entry script and Web resources
+frontend
+ assets/ contains 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
+ tests/ contains tests for frontend application
+ 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
+```
diff --git a/Vagrantfile b/Vagrantfile
new file mode 100755
index 0000000..3940bfb
--- /dev/null
+++ b/Vagrantfile
@@ -0,0 +1,88 @@
+require 'yaml'
+require 'fileutils'
+
+required_plugins_installed = nil
+required_plugins = %w( vagrant-hostmanager vagrant-vbguest )
+required_plugins.each do |plugin|
+ unless Vagrant.has_plugin? plugin
+ system "vagrant plugin install #{plugin}"
+ required_plugins_installed = true
+ end
+end
+
+# IF plugin[s] was just installed - restart required
+if required_plugins_installed
+ # Get CLI command[s] and call again
+ system 'vagrant' + ARGV.to_s.gsub(/\[\"|\", \"|\"\]/, ' ')
+ exit
+end
+
+domains = {
+ frontend: 'y2aa-frontend.test',
+ backend: 'y2aa-backend.test'
+}
+
+config = {
+ local: './vagrant/config/vagrant-local.yml',
+ example: './vagrant/config/vagrant-local.example.yml'
+}
+
+# copy config from example if local config not exists
+FileUtils.cp config[:example], config[:local] unless File.exist?(config[:local])
+# read config
+options = YAML.load_file config[:local]
+
+# check github token
+if options['github_token'].nil? || options['github_token'].to_s.length != 40
+ puts "You must place REAL GitHub token into configuration:\n/yii2-app-advanced/vagrant/config/vagrant-local.yml"
+ exit
+end
+
+# vagrant configurate
+Vagrant.configure(2) do |config|
+ # select the box
+ config.vm.box = 'bento/ubuntu-18.04'
+
+ # should we ask about box updates?
+ config.vm.box_check_update = options['box_check_update']
+
+ config.vm.provider 'virtualbox' do |vb|
+ # machine cpus count
+ vb.cpus = options['cpus']
+ # machine memory size
+ vb.memory = options['memory']
+ # machine name (for VirtualBox UI)
+ vb.name = options['machine_name']
+ end
+
+ # machine name (for vagrant console)
+ config.vm.define options['machine_name']
+
+ # machine name (for guest machine console)
+ config.vm.hostname = options['machine_name']
+
+ # network settings
+ config.vm.network 'private_network', ip: options['ip']
+
+ # sync: folder 'yii2-app-advanced' (host machine) -> folder '/app' (guest machine)
+ config.vm.synced_folder './', '/app', owner: 'vagrant', group: 'vagrant'
+
+ # disable folder '/vagrant' (guest machine)
+ config.vm.synced_folder '.', '/vagrant', disabled: true
+
+ # hosts settings (host machine)
+ config.vm.provision :hostmanager
+ config.hostmanager.enabled = true
+ config.hostmanager.manage_host = true
+ config.hostmanager.ignore_private_ip = false
+ config.hostmanager.include_offline = true
+ config.hostmanager.aliases = domains.values
+
+ # provisioners
+ config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone'], options['ip']]
+ config.vm.provision 'shell', path: './vagrant/provision/once-as-vagrant.sh', args: [options['github_token']], privileged: false
+ config.vm.provision 'shell', path: './vagrant/provision/always-as-root.sh', run: 'always'
+
+ # post-install message (vagrant console)
+ config.vm.post_up_message = "Frontend URL: http://#{domains[:frontend]}\nBackend URL: http://#{domains[:backend]}"
+end
diff --git a/backend/Dockerfile b/backend/Dockerfile
new file mode 100755
index 0000000..0515d35
--- /dev/null
+++ b/backend/Dockerfile
@@ -0,0 +1,4 @@
+FROM yiisoftware/yii2-php:8.1-apache
+
+# Change document root for Apache
+RUN sed -i -e 's|/app/web|/app/backend/web|g' /etc/apache2/sites-available/000-default.conf
diff --git a/backend/assets/AppAsset.php b/backend/assets/AppAsset.php
new file mode 100755
index 0000000..7494859
--- /dev/null
+++ b/backend/assets/AppAsset.php
@@ -0,0 +1,23 @@
+ 'app-backend',
+ 'basePath' => dirname(__DIR__),
+ 'controllerNamespace' => 'backend\controllers',
+ 'bootstrap' => ['log'],
+ 'homeUrl' => '/secure',
+ 'modules' => [
+ 'table' => [
+ 'class' => 'app\modules\table\Table',
+ ],
+ 'category' => [
+ 'class' => 'app\modules\category\Category',
+ ],
+ 'product' => [
+ 'class' => 'app\modules\product\Product',
+ ],
+ 'order' => [
+ 'class' => 'app\modules\order\Order',
+ ],
+ 'banner' => [
+ 'class' => 'app\modules\banner\Banner',
+ ],
+ ],
+ 'components' => [
+ 'request' => [
+ 'csrfParam' => '_csrf-backend',
+ 'baseUrl' => '/secure',
+ ],
+ 'user' => [
+ 'identityClass' => 'common\models\User',
+ 'enableAutoLogin' => true,
+ 'identityCookie' => ['name' => '_identity-backend', 'httpOnly' => true],
+ ],
+ 'session' => [
+ // this is the name of the session cookie used for login on the backend
+ 'name' => 'advanced-backend',
+ ],
+ 'log' => [
+ 'traceLevel' => YII_DEBUG ? 3 : 0,
+ 'targets' => [
+ [
+ 'class' => \yii\log\FileTarget::class,
+ 'levels' => ['error', 'warning'],
+ ],
+ ],
+ ],
+ 'errorHandler' => [
+ 'errorAction' => 'site/error',
+ ],
+ 'urlManager' => [
+ 'enablePrettyUrl' => true,
+ 'showScriptName' => false,
+ 'rules' => [
+ ],
+ ],
+ ],
+ 'params' => $params,
+];
diff --git a/backend/config/params.php b/backend/config/params.php
new file mode 100755
index 0000000..b881a76
--- /dev/null
+++ b/backend/config/params.php
@@ -0,0 +1,5 @@
+ 'admin@example.com',
+ 'bsVersion' => '4.x'
+];
diff --git a/backend/config/test.php b/backend/config/test.php
new file mode 100755
index 0000000..411b05f
--- /dev/null
+++ b/backend/config/test.php
@@ -0,0 +1,15 @@
+ 'app-backend-tests',
+ 'components' => [
+ 'assetManager' => [
+ 'basePath' => __DIR__ . '/../web/assets',
+ ],
+ 'urlManager' => [
+ 'showScriptName' => true,
+ ],
+ 'request' => [
+ 'cookieValidationKey' => 'test',
+ ],
+ ],
+];
diff --git a/backend/controllers/SiteController.php b/backend/controllers/SiteController.php
new file mode 100755
index 0000000..45101d0
--- /dev/null
+++ b/backend/controllers/SiteController.php
@@ -0,0 +1,104 @@
+ [
+ 'class' => AccessControl::class,
+ 'rules' => [
+ [
+ 'actions' => ['login', 'error'],
+ 'allow' => true,
+ ],
+ [
+ 'actions' => ['logout', 'index'],
+ 'allow' => true,
+ 'roles' => ['@'],
+ ],
+ ],
+ ],
+ 'verbs' => [
+ 'class' => VerbFilter::class,
+ 'actions' => [
+ 'logout' => ['post'],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function actions()
+ {
+ return [
+ 'error' => [
+ 'class' => \yii\web\ErrorAction::class,
+ ],
+ ];
+ }
+
+ /**
+ * Displays homepage.
+ *
+ * @return string
+ */
+ public function actionIndex()
+ {
+ return $this->render('index');
+ }
+
+ /**
+ * Login action.
+ *
+ * @return string|Response
+ */
+ public function actionLogin()
+ {
+ if (!Yii::$app->user->isGuest) {
+ return $this->goHome();
+ }
+
+ $this->layout = 'blank';
+
+ $model = new LoginForm();
+ if ($model->load(Yii::$app->request->post()) && $model->login()) {
+ return $this->goBack();
+ }
+
+ $model->password = '';
+
+ return $this->render('login', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Logout action.
+ *
+ * @return Response
+ */
+ public function actionLogout()
+ {
+ Yii::$app->user->logout();
+
+ return $this->goHome();
+ }
+}
diff --git a/backend/models/.gitkeep b/backend/models/.gitkeep
new file mode 100755
index 0000000..72e8ffc
--- /dev/null
+++ b/backend/models/.gitkeep
@@ -0,0 +1 @@
+*
diff --git a/backend/modules/banner/Banner.php b/backend/modules/banner/Banner.php
new file mode 100755
index 0000000..1d2c9dd
--- /dev/null
+++ b/backend/modules/banner/Banner.php
@@ -0,0 +1,24 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Lists all Banner models.
+ *
+ * @return string
+ */
+ public function actionIndex()
+ {
+ $dataProvider = new ActiveDataProvider([
+ 'query' => Banner::find(),
+ /*
+ 'pagination' => [
+ 'pageSize' => 50
+ ],
+ 'sort' => [
+ 'defaultOrder' => [
+ 'id' => SORT_DESC,
+ ]
+ ],
+ */
+ ]);
+
+ return $this->render('index', [
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Banner model.
+ * @param int $id ID
+ * @return string
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new Banner model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return string|\yii\web\Response
+ */
+ public function actionCreate()
+ {
+ $model = new Banner();
+
+ if ($this->request->isPost) {
+ $model->load($this->request->post());
+ if (UploadedFile::getInstance($model, 'photo')) {
+ $model->photo = UploadedFile::getInstance($model, 'photo');
+ $model->photo->saveAs("@frontend/web/images/banner/{$model->photo->baseName}.{$model->photo->extension}");
+ $model->photo = '/frontend/web/images/banner/' . $model->photo->baseName . $model->photo->extension;
+ }
+ if ($model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+ } else {
+ $model->loadDefaultValues();
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Updates an existing Banner model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id ID
+ * @return string|\yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Deletes an existing Banner model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id ID
+ * @return \yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the Banner model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ * @param int $id ID
+ * @return Banner the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Banner::findOne(['id' => $id])) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/backend/modules/banner/controllers/DefaultController.php b/backend/modules/banner/controllers/DefaultController.php
new file mode 100755
index 0000000..f7da05e
--- /dev/null
+++ b/backend/modules/banner/controllers/DefaultController.php
@@ -0,0 +1,20 @@
+render('index');
+ }
+}
diff --git a/backend/modules/banner/views/banner/_form.php b/backend/modules/banner/views/banner/_form.php
new file mode 100755
index 0000000..1ef7d19
--- /dev/null
+++ b/backend/modules/banner/views/banner/_form.php
@@ -0,0 +1,41 @@
+
+
+
diff --git a/backend/modules/banner/views/banner/create.php b/backend/modules/banner/views/banner/create.php
new file mode 100755
index 0000000..f8db101
--- /dev/null
+++ b/backend/modules/banner/views/banner/create.php
@@ -0,0 +1,20 @@
+title = 'Create Banner';
+$this->params['breadcrumbs'][] = ['label' => 'Banners', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/banner/views/banner/index.php b/backend/modules/banner/views/banner/index.php
new file mode 100755
index 0000000..10c51bd
--- /dev/null
+++ b/backend/modules/banner/views/banner/index.php
@@ -0,0 +1,42 @@
+title = 'Banners';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Create Banner', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ 'id',
+ 'photo',
+ 'rating',
+ [
+ 'class' => ActionColumn::className(),
+ 'urlCreator' => function ($action, Banner $model, $key, $index, $column) {
+ return Url::toRoute([$action, 'id' => $model->id]);
+ }
+ ],
+ ],
+ ]); ?>
+
+
+
diff --git a/backend/modules/banner/views/banner/update.php b/backend/modules/banner/views/banner/update.php
new file mode 100755
index 0000000..928220a
--- /dev/null
+++ b/backend/modules/banner/views/banner/update.php
@@ -0,0 +1,21 @@
+title = 'Update Banner: ' . $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Banners', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/banner/views/banner/view.php b/backend/modules/banner/views/banner/view.php
new file mode 100755
index 0000000..c2220d3
--- /dev/null
+++ b/backend/modules/banner/views/banner/view.php
@@ -0,0 +1,38 @@
+title = $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Banners', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Delete', ['delete', 'id' => $model->id], [
+ 'class' => 'btn btn-danger',
+ 'data' => [
+ 'confirm' => 'Are you sure you want to delete this item?',
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
+ = DetailView::widget([
+ 'model' => $model,
+ 'attributes' => [
+ 'id',
+ 'photo',
+ 'rating',
+ ],
+ ]) ?>
+
+
diff --git a/backend/modules/banner/views/default/index.php b/backend/modules/banner/views/default/index.php
new file mode 100755
index 0000000..9a8dbff
--- /dev/null
+++ b/backend/modules/banner/views/default/index.php
@@ -0,0 +1,12 @@
+
+
= $this->context->action->uniqueId ?>
+
+ This is the view content for action "= $this->context->action->id ?>".
+ The action belongs to the controller "= get_class($this->context) ?>"
+ in the "= $this->context->module->id ?>" module.
+
+
+ You may customize this page by editing the following file:
+ = __FILE__ ?>
+
+
diff --git a/backend/modules/category/Category.php b/backend/modules/category/Category.php
new file mode 100755
index 0000000..7877dea
--- /dev/null
+++ b/backend/modules/category/Category.php
@@ -0,0 +1,24 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Lists all Category models.
+ *
+ * @return string
+ */
+ public function actionIndex()
+ {
+ $dataProvider = new ActiveDataProvider([
+ 'query' => Category::find(),
+ /*
+ 'pagination' => [
+ 'pageSize' => 50
+ ],
+ 'sort' => [
+ 'defaultOrder' => [
+ 'id' => SORT_DESC,
+ ]
+ ],
+ */
+ ]);
+
+ return $this->render('index', [
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Category model.
+ * @param int $id ID
+ * @return string
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new Category model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return string|\yii\web\Response
+ */
+ public function actionCreate()
+ {
+ $model = new Category();
+
+ if ($this->request->isPost) {
+ if ($model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+ } else {
+ $model->loadDefaultValues();
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Updates an existing Category model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id ID
+ * @return string|\yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Deletes an existing Category model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id ID
+ * @return \yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the Category model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ * @param int $id ID
+ * @return Category the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Category::findOne(['id' => $id])) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/backend/modules/category/controllers/DefaultController.php b/backend/modules/category/controllers/DefaultController.php
new file mode 100755
index 0000000..ba7846a
--- /dev/null
+++ b/backend/modules/category/controllers/DefaultController.php
@@ -0,0 +1,20 @@
+render('index');
+ }
+}
diff --git a/backend/modules/category/views/category/_form.php b/backend/modules/category/views/category/_form.php
new file mode 100755
index 0000000..99dd92e
--- /dev/null
+++ b/backend/modules/category/views/category/_form.php
@@ -0,0 +1,27 @@
+
+
+
diff --git a/backend/modules/category/views/category/create.php b/backend/modules/category/views/category/create.php
new file mode 100755
index 0000000..54005b1
--- /dev/null
+++ b/backend/modules/category/views/category/create.php
@@ -0,0 +1,20 @@
+title = 'Create Category';
+$this->params['breadcrumbs'][] = ['label' => 'Categories', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/category/views/category/index.php b/backend/modules/category/views/category/index.php
new file mode 100755
index 0000000..318f633
--- /dev/null
+++ b/backend/modules/category/views/category/index.php
@@ -0,0 +1,43 @@
+title = 'Categories';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Create Category', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ 'id',
+ 'name',
+ 'description',
+ 'slug',
+ [
+ 'class' => ActionColumn::className(),
+ 'urlCreator' => function ($action, Category $model, $key, $index, $column) {
+ return Url::toRoute([$action, 'id' => $model->id]);
+ }
+ ],
+ ],
+ ]); ?>
+
+
+
diff --git a/backend/modules/category/views/category/update.php b/backend/modules/category/views/category/update.php
new file mode 100755
index 0000000..d1f1e62
--- /dev/null
+++ b/backend/modules/category/views/category/update.php
@@ -0,0 +1,21 @@
+title = 'Update Category: ' . $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Categories', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/category/views/category/view.php b/backend/modules/category/views/category/view.php
new file mode 100755
index 0000000..9c4cebc
--- /dev/null
+++ b/backend/modules/category/views/category/view.php
@@ -0,0 +1,39 @@
+title = $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Categories', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Delete', ['delete', 'id' => $model->id], [
+ 'class' => 'btn btn-danger',
+ 'data' => [
+ 'confirm' => 'Are you sure you want to delete this item?',
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
+ = DetailView::widget([
+ 'model' => $model,
+ 'attributes' => [
+ 'id',
+ 'name',
+ 'description',
+ 'slug',
+ ],
+ ]) ?>
+
+
diff --git a/backend/modules/category/views/default/index.php b/backend/modules/category/views/default/index.php
new file mode 100755
index 0000000..97fd19c
--- /dev/null
+++ b/backend/modules/category/views/default/index.php
@@ -0,0 +1,12 @@
+
+
= $this->context->action->uniqueId ?>
+
+ This is the view content for action "= $this->context->action->id ?>".
+ The action belongs to the controller "= get_class($this->context) ?>"
+ in the "= $this->context->module->id ?>" module.
+
+
+ You may customize this page by editing the following file:
+ = __FILE__ ?>
+
+
diff --git a/backend/modules/order/Order.php b/backend/modules/order/Order.php
new file mode 100755
index 0000000..2fd004d
--- /dev/null
+++ b/backend/modules/order/Order.php
@@ -0,0 +1,24 @@
+render('index');
+ }
+}
diff --git a/backend/modules/order/controllers/OrderController.php b/backend/modules/order/controllers/OrderController.php
new file mode 100755
index 0000000..be03080
--- /dev/null
+++ b/backend/modules/order/controllers/OrderController.php
@@ -0,0 +1,144 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Lists all Order models.
+ *
+ * @return string
+ */
+ public function actionIndex()
+ {
+ $dataProvider = new ActiveDataProvider([
+ 'query' => Order::find(),
+ /*
+ 'pagination' => [
+ 'pageSize' => 50
+ ],
+ 'sort' => [
+ 'defaultOrder' => [
+ 'id' => SORT_DESC,
+ ]
+ ],
+ */
+ ]);
+
+ return $this->render('index', [
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Order model.
+ * @param int $id ID
+ * @return string
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new Order model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return string|\yii\web\Response
+ */
+ public function actionCreate()
+ {
+ $model = new Order();
+
+ if ($this->request->isPost) {
+ if ($model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+ } else {
+ $model->loadDefaultValues();
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Updates an existing Order model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id ID
+ * @return string|\yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Deletes an existing Order model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id ID
+ * @return \yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the Order model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ * @param int $id ID
+ * @return Order the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Order::findOne(['id' => $id])) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/backend/modules/order/views/default/index.php b/backend/modules/order/views/default/index.php
new file mode 100755
index 0000000..430d708
--- /dev/null
+++ b/backend/modules/order/views/default/index.php
@@ -0,0 +1,12 @@
+
+
= $this->context->action->uniqueId ?>
+
+ This is the view content for action "= $this->context->action->id ?>".
+ The action belongs to the controller "= get_class($this->context) ?>"
+ in the "= $this->context->module->id ?>" module.
+
+
+ You may customize this page by editing the following file:
+ = __FILE__ ?>
+
+
diff --git a/backend/modules/order/views/order/_form.php b/backend/modules/order/views/order/_form.php
new file mode 100755
index 0000000..dffa284
--- /dev/null
+++ b/backend/modules/order/views/order/_form.php
@@ -0,0 +1,35 @@
+
+
+
diff --git a/backend/modules/order/views/order/create.php b/backend/modules/order/views/order/create.php
new file mode 100755
index 0000000..573f12b
--- /dev/null
+++ b/backend/modules/order/views/order/create.php
@@ -0,0 +1,20 @@
+title = 'Create Order';
+$this->params['breadcrumbs'][] = ['label' => 'Orders', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/order/views/order/index.php b/backend/modules/order/views/order/index.php
new file mode 100755
index 0000000..2b6447b
--- /dev/null
+++ b/backend/modules/order/views/order/index.php
@@ -0,0 +1,47 @@
+title = 'Orders';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Create Order', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ 'id',
+ 'user_id',
+ 'table_id',
+ 'strength',
+ 'amount',
+ //'status',
+ //'created_at',
+ //'updated_at',
+ [
+ 'class' => ActionColumn::className(),
+ 'urlCreator' => function ($action, Order $model, $key, $index, $column) {
+ return Url::toRoute([$action, 'id' => $model->id]);
+ }
+ ],
+ ],
+ ]); ?>
+
+
+
diff --git a/backend/modules/order/views/order/update.php b/backend/modules/order/views/order/update.php
new file mode 100755
index 0000000..9ef0546
--- /dev/null
+++ b/backend/modules/order/views/order/update.php
@@ -0,0 +1,21 @@
+title = 'Update Order: ' . $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Orders', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/order/views/order/view.php b/backend/modules/order/views/order/view.php
new file mode 100755
index 0000000..d957bbe
--- /dev/null
+++ b/backend/modules/order/views/order/view.php
@@ -0,0 +1,43 @@
+title = $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Orders', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Delete', ['delete', 'id' => $model->id], [
+ 'class' => 'btn btn-danger',
+ 'data' => [
+ 'confirm' => 'Are you sure you want to delete this item?',
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
+ = DetailView::widget([
+ 'model' => $model,
+ 'attributes' => [
+ 'id',
+ 'user_id',
+ 'table_id',
+ 'strength',
+ 'amount',
+ 'status',
+ 'created_at',
+ 'updated_at',
+ ],
+ ]) ?>
+
+
diff --git a/backend/modules/product/Product.php b/backend/modules/product/Product.php
new file mode 100755
index 0000000..ff2ebbf
--- /dev/null
+++ b/backend/modules/product/Product.php
@@ -0,0 +1,24 @@
+render('index');
+ }
+}
diff --git a/backend/modules/product/controllers/ProductController.php b/backend/modules/product/controllers/ProductController.php
new file mode 100755
index 0000000..cef006e
--- /dev/null
+++ b/backend/modules/product/controllers/ProductController.php
@@ -0,0 +1,151 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Lists all Product models.
+ *
+ * @return string
+ */
+ public function actionIndex()
+ {
+ $dataProvider = new ActiveDataProvider([
+ 'query' => Product::find(),
+ /*
+ 'pagination' => [
+ 'pageSize' => 50
+ ],
+ 'sort' => [
+ 'defaultOrder' => [
+ 'id' => SORT_DESC,
+ ]
+ ],
+ */
+ ]);
+
+ return $this->render('index', [
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Product model.
+ * @param int $id ID
+ * @return string
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new Product model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return string|\yii\web\Response
+ */
+ public function actionCreate()
+ {
+ $model = new Product();
+
+ if ($this->request->isPost) {
+ $model->load($this->request->post());
+ if (UploadedFile::getInstance($model, 'photo')) {
+ $model->photo = UploadedFile::getInstance($model, 'photo');
+ $model->photo->saveAs("@frontend/web/images/product/{$model->photo->baseName}.{$model->photo->extension}");
+ $model->photo = '/frontend/web/images/product/' . $model->photo->baseName . $model->photo->extension;
+ }
+ if ($model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+ } else {
+ $model->loadDefaultValues();
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Updates an existing Product model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id ID
+ * @return string|\yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Deletes an existing Product model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id ID
+ * @return \yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the Product model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ * @param int $id ID
+ * @return Product the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Product::findOne(['id' => $id])) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/backend/modules/product/views/default/index.php b/backend/modules/product/views/default/index.php
new file mode 100755
index 0000000..218cc44
--- /dev/null
+++ b/backend/modules/product/views/default/index.php
@@ -0,0 +1,12 @@
+
+
= $this->context->action->uniqueId ?>
+
+ This is the view content for action "= $this->context->action->id ?>".
+ The action belongs to the controller "= get_class($this->context) ?>"
+ in the "= $this->context->module->id ?>" module.
+
+
+ You may customize this page by editing the following file:
+ = __FILE__ ?>
+
+
diff --git a/backend/modules/product/views/product/_form.php b/backend/modules/product/views/product/_form.php
new file mode 100755
index 0000000..b82a45e
--- /dev/null
+++ b/backend/modules/product/views/product/_form.php
@@ -0,0 +1,66 @@
+
+
+
diff --git a/backend/modules/product/views/product/create.php b/backend/modules/product/views/product/create.php
new file mode 100755
index 0000000..fa8abe3
--- /dev/null
+++ b/backend/modules/product/views/product/create.php
@@ -0,0 +1,20 @@
+title = 'Create Product';
+$this->params['breadcrumbs'][] = ['label' => 'Products', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/product/views/product/index.php b/backend/modules/product/views/product/index.php
new file mode 100755
index 0000000..ddde22e
--- /dev/null
+++ b/backend/modules/product/views/product/index.php
@@ -0,0 +1,49 @@
+title = 'Products';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Create Product', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ 'id',
+ 'type',
+ 'name',
+ 'description',
+ 'price',
+ //'status',
+ //'quantity',
+ //'taste',
+ //'strength',
+ //'category_id',
+ [
+ 'class' => ActionColumn::className(),
+ 'urlCreator' => function ($action, Product $model, $key, $index, $column) {
+ return Url::toRoute([$action, 'id' => $model->id]);
+ }
+ ],
+ ],
+ ]); ?>
+
+
+
diff --git a/backend/modules/product/views/product/update.php b/backend/modules/product/views/product/update.php
new file mode 100755
index 0000000..c1e2740
--- /dev/null
+++ b/backend/modules/product/views/product/update.php
@@ -0,0 +1,21 @@
+title = 'Update Product: ' . $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Products', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/product/views/product/view.php b/backend/modules/product/views/product/view.php
new file mode 100755
index 0000000..429e909
--- /dev/null
+++ b/backend/modules/product/views/product/view.php
@@ -0,0 +1,45 @@
+title = $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Products', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Delete', ['delete', 'id' => $model->id], [
+ 'class' => 'btn btn-danger',
+ 'data' => [
+ 'confirm' => 'Are you sure you want to delete this item?',
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
+ = DetailView::widget([
+ 'model' => $model,
+ 'attributes' => [
+ 'id',
+ 'type',
+ 'name',
+ 'description',
+ 'price',
+ 'status',
+ 'quantity',
+ 'taste',
+ 'strength',
+ 'category_id',
+ ],
+ ]) ?>
+
+
diff --git a/backend/modules/table/Table.php b/backend/modules/table/Table.php
new file mode 100755
index 0000000..ed9bb31
--- /dev/null
+++ b/backend/modules/table/Table.php
@@ -0,0 +1,24 @@
+render('index');
+ }
+}
diff --git a/backend/modules/table/controllers/TableController.php b/backend/modules/table/controllers/TableController.php
new file mode 100755
index 0000000..9d1de50
--- /dev/null
+++ b/backend/modules/table/controllers/TableController.php
@@ -0,0 +1,144 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Lists all Table models.
+ *
+ * @return string
+ */
+ public function actionIndex()
+ {
+ $dataProvider = new ActiveDataProvider([
+ 'query' => Table::find(),
+ /*
+ 'pagination' => [
+ 'pageSize' => 50
+ ],
+ 'sort' => [
+ 'defaultOrder' => [
+ 'id' => SORT_DESC,
+ ]
+ ],
+ */
+ ]);
+
+ return $this->render('index', [
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Table model.
+ * @param int $id ID
+ * @return string
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new Table model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return string|\yii\web\Response
+ */
+ public function actionCreate()
+ {
+ $model = new Table();
+
+ if ($this->request->isPost) {
+ if ($model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+ } else {
+ $model->loadDefaultValues();
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Updates an existing Table model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id ID
+ * @return string|\yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Deletes an existing Table model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id ID
+ * @return \yii\web\Response
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the Table model based on its primary key value.
+ * If the model is not found, a 404 HTTP exception will be thrown.
+ * @param int $id ID
+ * @return Table the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Table::findOne(['id' => $id])) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/backend/modules/table/views/default/index.php b/backend/modules/table/views/default/index.php
new file mode 100755
index 0000000..46ee0c0
--- /dev/null
+++ b/backend/modules/table/views/default/index.php
@@ -0,0 +1,12 @@
+
+
= $this->context->action->uniqueId ?>
+
+ This is the view content for action "= $this->context->action->id ?>".
+ The action belongs to the controller "= get_class($this->context) ?>"
+ in the "= $this->context->module->id ?>" module.
+
+
+ You may customize this page by editing the following file:
+ = __FILE__ ?>
+
+
diff --git a/backend/modules/table/views/table/_form.php b/backend/modules/table/views/table/_form.php
new file mode 100755
index 0000000..e36bd31
--- /dev/null
+++ b/backend/modules/table/views/table/_form.php
@@ -0,0 +1,29 @@
+
+
+
diff --git a/backend/modules/table/views/table/create.php b/backend/modules/table/views/table/create.php
new file mode 100755
index 0000000..22eb219
--- /dev/null
+++ b/backend/modules/table/views/table/create.php
@@ -0,0 +1,20 @@
+title = 'Create Table';
+$this->params['breadcrumbs'][] = ['label' => 'Tables', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/table/views/table/index.php b/backend/modules/table/views/table/index.php
new file mode 100755
index 0000000..7e19c6d
--- /dev/null
+++ b/backend/modules/table/views/table/index.php
@@ -0,0 +1,44 @@
+title = 'Tables';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Create Table', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ 'id',
+ 'name',
+ 'places',
+ 'type',
+ 'slug',
+ [
+ 'class' => ActionColumn::className(),
+ 'urlCreator' => function ($action, Table $model, $key, $index, $column) {
+ return Url::toRoute([$action, 'id' => $model->id]);
+ }
+ ],
+ ],
+ ]); ?>
+
+
+
diff --git a/backend/modules/table/views/table/update.php b/backend/modules/table/views/table/update.php
new file mode 100755
index 0000000..7e60046
--- /dev/null
+++ b/backend/modules/table/views/table/update.php
@@ -0,0 +1,21 @@
+title = 'Update Table: ' . $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Tables', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
= Html::encode($this->title) ?>
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/backend/modules/table/views/table/view.php b/backend/modules/table/views/table/view.php
new file mode 100755
index 0000000..d57be96
--- /dev/null
+++ b/backend/modules/table/views/table/view.php
@@ -0,0 +1,40 @@
+title = $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Tables', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = Html::a('Update', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Delete', ['delete', 'id' => $model->id], [
+ 'class' => 'btn btn-danger',
+ 'data' => [
+ 'confirm' => 'Are you sure you want to delete this item?',
+ 'method' => 'post',
+ ],
+ ]) ?>
+
+
+ = DetailView::widget([
+ 'model' => $model,
+ 'attributes' => [
+ 'id',
+ 'name',
+ 'places',
+ 'type',
+ 'slug',
+ ],
+ ]) ?>
+
+
diff --git a/backend/runtime/.gitignore b/backend/runtime/.gitignore
new file mode 100755
index 0000000..c96a04f
--- /dev/null
+++ b/backend/runtime/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/backend/tests/_bootstrap.php b/backend/tests/_bootstrap.php
new file mode 100755
index 0000000..637ce14
--- /dev/null
+++ b/backend/tests/_bootstrap.php
@@ -0,0 +1,10 @@
+ '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/backend/tests/_output/.gitignore b/backend/tests/_output/.gitignore
new file mode 100755
index 0000000..d6b7ef3
--- /dev/null
+++ b/backend/tests/_output/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/backend/tests/_support/.gitignore b/backend/tests/_support/.gitignore
new file mode 100755
index 0000000..36e264c
--- /dev/null
+++ b/backend/tests/_support/.gitignore
@@ -0,0 +1 @@
+_generated
diff --git a/backend/tests/_support/FunctionalTester.php b/backend/tests/_support/FunctionalTester.php
new file mode 100755
index 0000000..a2bb8cb
--- /dev/null
+++ b/backend/tests/_support/FunctionalTester.php
@@ -0,0 +1,26 @@
+ [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'login_data.php'
+ ]
+ ];
+ }
+
+ /**
+ * @param FunctionalTester $I
+ */
+ public function loginUser(FunctionalTester $I)
+ {
+ $I->amOnRoute('/site/login');
+ $I->fillField('Username', 'erau');
+ $I->fillField('Password', 'password_0');
+ $I->click('login-button');
+
+ $I->see('Logout (erau)', 'form button[type=submit]');
+ $I->dontSeeLink('Login');
+ $I->dontSeeLink('Signup');
+ }
+}
diff --git a/backend/tests/functional/_bootstrap.php b/backend/tests/functional/_bootstrap.php
new file mode 100755
index 0000000..30ed54b
--- /dev/null
+++ b/backend/tests/functional/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Cests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
\ No newline at end of file
diff --git a/backend/tests/unit.suite.yml b/backend/tests/unit.suite.yml
new file mode 100755
index 0000000..f90030f
--- /dev/null
+++ b/backend/tests/unit.suite.yml
@@ -0,0 +1,2 @@
+suite_namespace: backend\tests\unit
+actor: UnitTester
diff --git a/backend/tests/unit/_bootstrap.php b/backend/tests/unit/_bootstrap.php
new file mode 100755
index 0000000..e432ce5
--- /dev/null
+++ b/backend/tests/unit/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Tests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
diff --git a/backend/views/layouts/blank.php b/backend/views/layouts/blank.php
new file mode 100755
index 0000000..c843320
--- /dev/null
+++ b/backend/views/layouts/blank.php
@@ -0,0 +1,33 @@
+
+beginPage() ?>
+
+
+
+
+
+ registerCsrfMetaTags() ?>
+ = Html::encode($this->title) ?>
+ head() ?>
+
+
+beginBody() ?>
+
+
+
+ = $content ?>
+
+
+
+endBody() ?>
+
+
+endPage();
diff --git a/backend/views/layouts/content.php b/backend/views/layouts/content.php
new file mode 100755
index 0000000..80660af
--- /dev/null
+++ b/backend/views/layouts/content.php
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+ = $content ?>
+
+
+
\ No newline at end of file
diff --git a/backend/views/layouts/control-sidebar.php b/backend/views/layouts/control-sidebar.php
new file mode 100755
index 0000000..addd3b1
--- /dev/null
+++ b/backend/views/layouts/control-sidebar.php
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/backend/views/layouts/footer.php b/backend/views/layouts/footer.php
new file mode 100755
index 0000000..f335ebd
--- /dev/null
+++ b/backend/views/layouts/footer.php
@@ -0,0 +1,7 @@
+
+ Copyright © 2014-2021 AdminLTE.io .
+ All rights reserved.
+
+ Version 3.1.0
+
+
\ No newline at end of file
diff --git a/backend/views/layouts/main-login.php b/backend/views/layouts/main-login.php
new file mode 100755
index 0000000..416b310
--- /dev/null
+++ b/backend/views/layouts/main-login.php
@@ -0,0 +1,38 @@
+registerCssFile('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700');
+$this->registerCssFile('https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css');
+\hail812\adminlte3\assets\PluginAsset::register($this)->add(['fontawesome', 'icheck-bootstrap']);
+?>
+beginPage() ?>
+
+
+
+
+
+ AdminLTE 3 | Log in
+
+
+ registerCsrfMetaTags() ?>
+ head() ?>
+
+
+beginBody() ?>
+
+
+
+endBody() ?>
+
+
+endPage() ?>
\ No newline at end of file
diff --git a/backend/views/layouts/main.php b/backend/views/layouts/main.php
new file mode 100755
index 0000000..80ca4b5
--- /dev/null
+++ b/backend/views/layouts/main.php
@@ -0,0 +1,54 @@
+registerCssFile('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback');
+
+$assetDir = Yii::$app->assetManager->getPublishedUrl('@vendor/almasaeed2010/adminlte/dist');
+
+$publishedRes = Yii::$app->assetManager->publish('@vendor/hail812/yii2-adminlte3/src/web/js');
+$this->registerJsFile($publishedRes[1].'/control_sidebar.js', ['depends' => '\hail812\adminlte3\assets\AdminLteAsset']);
+?>
+beginPage() ?>
+
+
+
+
+
+
+ registerCsrfMetaTags() ?>
+ = Html::encode($this->title) ?>
+ head() ?>
+
+
+beginBody() ?>
+
+
+
+ = $this->render('navbar', ['assetDir' => $assetDir]) ?>
+
+
+
+ = $this->render('sidebar', ['assetDir' => $assetDir]) ?>
+
+
+ = $this->render('content', ['content' => $content, 'assetDir' => $assetDir]) ?>
+
+
+
+ = $this->render('control-sidebar') ?>
+
+
+
+ = $this->render('footer') ?>
+
+
+endBody() ?>
+
+
+endPage() ?>
diff --git a/backend/views/layouts/navbar.php b/backend/views/layouts/navbar.php
new file mode 100755
index 0000000..075ac11
--- /dev/null
+++ b/backend/views/layouts/navbar.php
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+ = Html::a(' ', ['/site/logout'], ['data-method' => 'post', 'class' => 'nav-link']) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/backend/views/layouts/sidebar.php b/backend/views/layouts/sidebar.php
new file mode 100755
index 0000000..8fb2817
--- /dev/null
+++ b/backend/views/layouts/sidebar.php
@@ -0,0 +1,47 @@
+
diff --git a/backend/views/site/error.php b/backend/views/site/error.php
new file mode 100755
index 0000000..e0f8b65
--- /dev/null
+++ b/backend/views/site/error.php
@@ -0,0 +1,27 @@
+title = $name;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = nl2br(Html::encode($message)) ?>
+
+
+
+ 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 100755
index 0000000..4ced35c
--- /dev/null
+++ b/backend/views/site/index.php
@@ -0,0 +1,53 @@
+title = 'My Yii Application';
+?>
+
+
+
+
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/backend/views/site/login.php b/backend/views/site/login.php
new file mode 100755
index 0000000..d4b5a3b
--- /dev/null
+++ b/backend/views/site/login.php
@@ -0,0 +1,32 @@
+title = 'Login';
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
Please fill out the following fields to login:
+
+ 'login-form']); ?>
+
+ = $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
+
+ = $form->field($model, 'password')->passwordInput() ?>
+
+ = $form->field($model, 'rememberMe')->checkbox() ?>
+
+
+ = Html::submitButton('Login', ['class' => 'btn btn-primary btn-block', 'name' => 'login-button']) ?>
+
+
+
+
+
diff --git a/backend/web/assets/.gitignore b/backend/web/assets/.gitignore
new file mode 100755
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 100755
index 0000000..34c35c6
--- /dev/null
+++ b/backend/web/css/site.css
@@ -0,0 +1,90 @@
+main > .container {
+ padding: 70px 15px 20px;
+}
+
+.footer {
+ background-color: #f5f5f5;
+ font-size: .9em;
+ height: 60px;
+}
+
+.footer > .container {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+
+.not-set {
+ color: #c55;
+ font-style: italic;
+}
+
+/* add sorting icons to gridview sort links */
+a.asc:after, a.desc:after {
+ content: '';
+ left: 3px;
+ display: inline-block;
+ width: 0;
+ height: 0;
+ border: solid 5px transparent;
+ margin: 4px 4px 2px 4px;
+ background: transparent;
+}
+
+a.asc:after {
+ border-bottom: solid 7px #212529;
+ border-top-width: 0;
+}
+
+a.desc:after {
+ border-top: solid 7px #212529;
+ border-bottom-width: 0;
+}
+
+.grid-view th,
+.grid-view td:last-child {
+ white-space: nowrap;
+}
+
+.grid-view .filters input,
+.grid-view .filters select {
+ min-width: 50px;
+}
+
+.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;
+}
+
+/* align the logout "link" (button in form) of the navbar */
+.nav li > form > button.logout {
+ padding-top: 7px;
+ color: rgba(255, 255, 255, 0.5);
+}
+
+@media(max-width:767px) {
+ .nav li > form > button.logout {
+ display:block;
+ text-align: left;
+ width: 100%;
+ padding: 10px 0;
+ }
+}
+
+.nav > li > form > button.logout:focus,
+.nav > li > form > button.logout:hover {
+ text-decoration: none;
+ color: rgba(255, 255, 255, 0.75);
+}
+
+.nav > li > form > button.logout:focus {
+ outline: none;
+}
diff --git a/backend/web/favicon.ico b/backend/web/favicon.ico
new file mode 100755
index 0000000000000000000000000000000000000000..580ed732e86556ec57f3f3395a210246d679c076
GIT binary patch
literal 318
zcmZQzU<5(|0RbS%!l1#(z#zuJz@P!d0zj+)#2|4HXaJKC0wf0lAEr2iX{M9K3=BR0
y!E90pK{x=K$Oz&POT#sS8N$ZKhC)h8ip0_|-T#43{vnSYgXBQCu@O54$pHYIza?e>
literal 0
HcmV?d00001
diff --git a/codeception.yml b/codeception.yml
new file mode 100755
index 0000000..c6f0143
--- /dev/null
+++ b/codeception.yml
@@ -0,0 +1,9 @@
+# global codeception file to run tests from all apps
+include:
+ - common
+ - frontend
+ - backend
+paths:
+ output: console/runtime/output
+settings:
+ colors: true
\ No newline at end of file
diff --git a/common/classes/Debug.php b/common/classes/Debug.php
new file mode 100755
index 0000000..24e49b0
--- /dev/null
+++ b/common/classes/Debug.php
@@ -0,0 +1,20 @@
+';
+ print_r($content);
+ echo '';
+ }
+ public static function dd($content)
+ {
+ echo '';
+ print_r($content);
+ echo ' ';
+ die();
+ }
+}
\ No newline at end of file
diff --git a/common/codeception.yml b/common/codeception.yml
new file mode 100755
index 0000000..1dfaf97
--- /dev/null
+++ b/common/codeception.yml
@@ -0,0 +1,15 @@
+namespace: common\tests
+actor_suffix: Tester
+paths:
+ tests: tests
+ output: tests/_output
+ data: tests/_data
+ support: tests/_support
+bootstrap: _bootstrap.php
+settings:
+ colors: true
+ memory_limit: 1024M
+modules:
+ config:
+ Yii2:
+ configFile: 'config/codeception-local.php'
diff --git a/common/config/.gitignore b/common/config/.gitignore
new file mode 100755
index 0000000..7c090d2
--- /dev/null
+++ b/common/config/.gitignore
@@ -0,0 +1,4 @@
+codeception-local.php
+main-local.php
+params-local.php
+test-local.php
diff --git a/common/config/__autocomplete.php b/common/config/__autocomplete.php
new file mode 100755
index 0000000..d99dea5
--- /dev/null
+++ b/common/config/__autocomplete.php
@@ -0,0 +1,33 @@
+ [
+ '@bower' => '@vendor/bower-asset',
+ '@npm' => '@vendor/npm-asset',
+ ],
+ 'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
+ 'components' => [
+ 'cache' => [
+ 'class' => \yii\caching\FileCache::class,
+ ],
+ ],
+];
diff --git a/common/config/params.php b/common/config/params.php
new file mode 100755
index 0000000..9361512
--- /dev/null
+++ b/common/config/params.php
@@ -0,0 +1,9 @@
+ 'admin@example.com',
+ 'supportEmail' => 'support@example.com',
+ 'senderEmail' => 'noreply@example.com',
+ 'senderName' => 'Example.com mailer',
+ 'user.passwordResetTokenExpire' => 3600,
+ 'user.passwordMinLength' => 8,
+];
diff --git a/common/config/test.php b/common/config/test.php
new file mode 100755
index 0000000..c50955f
--- /dev/null
+++ b/common/config/test.php
@@ -0,0 +1,11 @@
+ 'app-common-tests',
+ 'basePath' => dirname(__DIR__),
+ 'components' => [
+ 'user' => [
+ 'class' => \yii\web\User::class,
+ 'identityClass' => 'common\models\User',
+ ],
+ ],
+];
diff --git a/common/fixtures/UserFixture.php b/common/fixtures/UserFixture.php
new file mode 100755
index 0000000..6df7a98
--- /dev/null
+++ b/common/fixtures/UserFixture.php
@@ -0,0 +1,10 @@
+urlManager->createAbsoluteUrl(['site/verify-email', 'token' => $user->verification_token]);
+?>
+
+
Hello = Html::encode($user->username) ?>,
+
+
Follow the link below to verify your email:
+
+
= Html::a(Html::encode($verifyLink), $verifyLink) ?>
+
diff --git a/common/mail/emailVerify-text.php b/common/mail/emailVerify-text.php
new file mode 100755
index 0000000..48a68fc
--- /dev/null
+++ b/common/mail/emailVerify-text.php
@@ -0,0 +1,12 @@
+urlManager->createAbsoluteUrl(['site/verify-email', 'token' => $user->verification_token]);
+?>
+Hello = $user->username ?>,
+
+Follow the link below to verify your email:
+
+= $verifyLink ?>
diff --git a/common/mail/layouts/html.php b/common/mail/layouts/html.php
new file mode 100755
index 0000000..8560d47
--- /dev/null
+++ b/common/mail/layouts/html.php
@@ -0,0 +1,24 @@
+
+beginPage() ?>
+
+
+
+
+ = Html::encode($this->title) ?>
+ head() ?>
+
+
+ beginBody() ?>
+ = $content ?>
+ endBody() ?>
+
+
+endPage();
diff --git a/common/mail/layouts/text.php b/common/mail/layouts/text.php
new file mode 100755
index 0000000..9b4c548
--- /dev/null
+++ b/common/mail/layouts/text.php
@@ -0,0 +1,12 @@
+
+beginPage() ?>
+beginBody() ?>
+= $content ?>
+endBody() ?>
+endPage() ?>
diff --git a/common/mail/passwordResetToken-html.php b/common/mail/passwordResetToken-html.php
new file mode 100755
index 0000000..9f6e470
--- /dev/null
+++ b/common/mail/passwordResetToken-html.php
@@ -0,0 +1,16 @@
+urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
+?>
+
+
Hello = Html::encode($user->username) ?>,
+
+
Follow the link below to reset your password:
+
+
= Html::a(Html::encode($resetLink), $resetLink) ?>
+
diff --git a/common/mail/passwordResetToken-text.php b/common/mail/passwordResetToken-text.php
new file mode 100755
index 0000000..6a5120f
--- /dev/null
+++ b/common/mail/passwordResetToken-text.php
@@ -0,0 +1,12 @@
+urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);
+?>
+Hello = $user->username ?>,
+
+Follow the link below to reset your password:
+
+= $resetLink ?>
diff --git a/common/models/Banner.php b/common/models/Banner.php
new file mode 100755
index 0000000..99ab665
--- /dev/null
+++ b/common/models/Banner.php
@@ -0,0 +1,46 @@
+ 255],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'photo' => 'Photo',
+ 'rating' => 'Rating',
+ ];
+ }
+}
diff --git a/common/models/Category.php b/common/models/Category.php
new file mode 100755
index 0000000..0410e9e
--- /dev/null
+++ b/common/models/Category.php
@@ -0,0 +1,59 @@
+ 255],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'name' => 'Name',
+ 'description' => 'Description',
+ 'slug' => 'Slug',
+ ];
+ }
+
+ /**
+ * Gets query for [[Products]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getProducts()
+ {
+ return $this->hasMany(Product::class, ['category_id' => 'id']);
+ }
+}
diff --git a/common/models/LoginForm.php b/common/models/LoginForm.php
new file mode 100755
index 0000000..4f1f0a4
--- /dev/null
+++ b/common/models/LoginForm.php
@@ -0,0 +1,80 @@
+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 bool 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);
+ }
+
+ 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/Order.php b/common/models/Order.php
new file mode 100755
index 0000000..8fb5700
--- /dev/null
+++ b/common/models/Order.php
@@ -0,0 +1,109 @@
+ 255],
+ [['table_id'], 'exist', 'skipOnError' => true, 'targetClass' => Table::class, 'targetAttribute' => ['table_id' => 'id']],
+ [['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::class, 'targetAttribute' => ['user_id' => 'id']],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'user_id' => 'User ID',
+ 'table_id' => 'Table ID',
+ 'strength' => 'Strength',
+ 'amount' => 'Amount',
+ 'status' => 'Status',
+ 'created_at' => 'Created At',
+ 'updated_at' => 'Updated At',
+ ];
+ }
+
+ /**
+ * Gets query for [[OrderProducts]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getOrderProducts()
+ {
+ return $this->hasMany(OrderProduct::class, ['order_id' => 'id']);
+ }
+
+ /**
+ * Gets query for [[Table]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getTable()
+ {
+ return $this->hasOne(Table::class, ['id' => 'table_id']);
+ }
+
+ /**
+ * Gets query for [[User]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getUser()
+ {
+ return $this->hasOne(User::class, ['id' => 'user_id']);
+ }
+
+ /**
+ * Gets query for [[Products]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getProducts()
+ {
+ return $this->hasMany(Product::class, ['id' => 'product_id'])
+ ->viaTable('order_product', ['order_id' => 'id']);
+ }
+}
diff --git a/common/models/OrderProduct.php b/common/models/OrderProduct.php
new file mode 100755
index 0000000..e918680
--- /dev/null
+++ b/common/models/OrderProduct.php
@@ -0,0 +1,70 @@
+ true, 'targetClass' => Order::class, 'targetAttribute' => ['order_id' => 'id']],
+ [['product_id'], 'exist', 'skipOnError' => true, 'targetClass' => Product::class, 'targetAttribute' => ['product_id' => 'id']],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'order_id' => 'Order ID',
+ 'product_id' => 'Product ID',
+ ];
+ }
+
+ /**
+ * Gets query for [[Order]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getOrder()
+ {
+ return $this->hasOne(Order::class, ['id' => 'order_id']);
+ }
+
+ /**
+ * Gets query for [[Product]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getProduct()
+ {
+ return $this->hasOne(Product::class, ['id' => 'product_id']);
+ }
+}
diff --git a/common/models/Product.php b/common/models/Product.php
new file mode 100755
index 0000000..f1fced4
--- /dev/null
+++ b/common/models/Product.php
@@ -0,0 +1,123 @@
+ 255],
+ [['category_id'], 'exist', 'skipOnError' => true, 'targetClass' => Category::class, 'targetAttribute' => ['category_id' => 'id']],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'type' => 'Type',
+ 'name' => 'Name',
+ 'description' => 'Description',
+ 'price' => 'Price',
+ 'status' => 'Status',
+ 'quantity' => 'Quantity',
+ 'taste' => 'Taste',
+ 'strength' => 'Strength',
+ 'category_id' => 'Category ID',
+ ];
+ }
+
+ /**
+ * Gets query for [[Category]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getCategory()
+ {
+ return $this->hasOne(Category::class, ['id' => 'category_id']);
+ }
+
+ /**
+ * Gets query for [[OrderProducts]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getOrderProducts()
+ {
+ return $this->hasMany(OrderProduct::class, ['product_id' => 'id']);
+ }
+
+ /**
+ * Gets query for [[Orders]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getOrders()
+ {
+ return $this->hasMany(Order::class, ['id' => 'product_id'])
+ ->viaTable('order_product', ['order_id' => 'id']);
+ }
+
+ public static function TypesWIthLabels()
+ {
+ return [
+ 0 => 'другое',
+ 1 => 'табак'
+ ];
+ }
+
+ public static function TabacooStrengthWithLabel()
+ {
+ return [
+ 0 => 'Легкий',
+ 1 => 'Средний',
+ 2 => 'Тяжелый'
+ ];
+ }
+}
diff --git a/common/models/Table.php b/common/models/Table.php
new file mode 100755
index 0000000..c6c1015
--- /dev/null
+++ b/common/models/Table.php
@@ -0,0 +1,62 @@
+ 255],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function attributeLabels()
+ {
+ return [
+ 'id' => 'ID',
+ 'name' => 'Name',
+ 'places' => 'Places',
+ 'type' => 'Type',
+ 'slug' => 'Slug',
+ ];
+ }
+
+ /**
+ * Gets query for [[Orders]].
+ *
+ * @return \yii\db\ActiveQuery
+ */
+ public function getOrders()
+ {
+ return $this->hasMany(Order::class, ['table_id' => 'id']);
+ }
+}
diff --git a/common/models/User.php b/common/models/User.php
new file mode 100755
index 0000000..1ff6f4f
--- /dev/null
+++ b/common/models/User.php
@@ -0,0 +1,213 @@
+ self::STATUS_INACTIVE],
+ ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_INACTIVE, 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)
+ {
+ return static::findOne(['access_token' => $token]);
+ }
+
+ /**
+ * 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 user by verification email token
+ *
+ * @param string $token verify email token
+ * @return static|null
+ */
+ public static function findByVerificationToken($token) {
+ return static::findOne([
+ 'verification_token' => $token,
+ 'status' => self::STATUS_INACTIVE
+ ]);
+ }
+
+ /**
+ * Finds out if password reset token is valid
+ *
+ * @param string $token password reset token
+ * @return bool
+ */
+ 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 bool 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();
+ }
+
+ /**
+ * Generates new token for email verification
+ */
+ public function generateEmailVerificationToken()
+ {
+ $this->verification_token = Yii::$app->security->generateRandomString() . '_' . time();
+ }
+
+ /**
+ * Removes password reset token
+ */
+ public function removePasswordResetToken()
+ {
+ $this->password_reset_token = null;
+ }
+}
diff --git a/common/tests/_bootstrap.php b/common/tests/_bootstrap.php
new file mode 100755
index 0000000..9915cc3
--- /dev/null
+++ b/common/tests/_bootstrap.php
@@ -0,0 +1,9 @@
+ '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/common/tests/_output/.gitignore b/common/tests/_output/.gitignore
new file mode 100755
index 0000000..d6b7ef3
--- /dev/null
+++ b/common/tests/_output/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/common/tests/_support/.gitignore b/common/tests/_support/.gitignore
new file mode 100755
index 0000000..36e264c
--- /dev/null
+++ b/common/tests/_support/.gitignore
@@ -0,0 +1 @@
+_generated
diff --git a/common/tests/_support/UnitTester.php b/common/tests/_support/UnitTester.php
new file mode 100755
index 0000000..a0cc7a7
--- /dev/null
+++ b/common/tests/_support/UnitTester.php
@@ -0,0 +1,26 @@
+ [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ]
+ ];
+ }
+
+ public function testLoginNoUser()
+ {
+ $model = new LoginForm([
+ 'username' => 'not_existing_username',
+ 'password' => 'not_existing_password',
+ ]);
+
+ verify($model->login())->false();
+ verify(Yii::$app->user->isGuest)->true();
+ }
+
+ public function testLoginWrongPassword()
+ {
+ $model = new LoginForm([
+ 'username' => 'bayer.hudson',
+ 'password' => 'wrong_password',
+ ]);
+
+ verify($model->login())->false();
+ verify( $model->errors)->arrayHasKey('password');
+ verify(Yii::$app->user->isGuest)->true();
+ }
+
+ public function testLoginCorrect()
+ {
+ $model = new LoginForm([
+ 'username' => 'bayer.hudson',
+ 'password' => 'password_0',
+ ]);
+
+ verify($model->login())->true();
+ verify($model->errors)->arrayHasNotKey('password');
+ verify(Yii::$app->user->isGuest)->false();
+ }
+}
diff --git a/common/widgets/Alert.php b/common/widgets/Alert.php
new file mode 100755
index 0000000..4ac3d15
--- /dev/null
+++ b/common/widgets/Alert.php
@@ -0,0 +1,76 @@
+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\bootstrap5\Widget
+{
+ /**
+ * @var array the alert types configuration for the flash messages.
+ * This array is setup as $key => $value, where:
+ * - key: the name of the session flash variable
+ * - value: 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.
+ * Array will be passed to [[\yii\bootstrap\Alert::closeButton]].
+ */
+ public $closeButton = [];
+
+
+ /**
+ * {@inheritdoc}
+ */
+ public function run()
+ {
+ $session = Yii::$app->session;
+ $flashes = $session->getAllFlashes();
+ $appendClass = isset($this->options['class']) ? ' ' . $this->options['class'] : '';
+
+ foreach ($flashes as $type => $flash) {
+ if (!isset($this->alertTypes[$type])) {
+ continue;
+ }
+
+ foreach ((array) $flash as $i => $message) {
+ echo \yii\bootstrap5\Alert::widget([
+ 'body' => $message,
+ 'closeButton' => $this->closeButton,
+ 'options' => array_merge($this->options, [
+ 'id' => $this->getId() . '-' . $type . '-' . $i,
+ 'class' => $this->alertTypes[$type] . $appendClass,
+ ]),
+ ]);
+ }
+
+ $session->removeFlash($type);
+ }
+ }
+}
diff --git a/composer.json b/composer.json
new file mode 100755
index 0000000..581152a
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,59 @@
+{
+ "name": "yiisoft/yii2-app-advanced",
+ "description": "Yii 2 Advanced Project Template",
+ "keywords": ["yii2", "framework", "advanced", "project template"],
+ "homepage": "https://www.yiiframework.com/",
+ "type": "project",
+ "license": "BSD-3-Clause",
+ "support": {
+ "issues": "https://github.com/yiisoft/yii2/issues?state=open",
+ "forum": "https://www.yiiframework.com/forum/",
+ "wiki": "https://www.yiiframework.com/wiki/",
+ "irc": "ircs://irc.libera.chat:6697/yii",
+ "source": "https://github.com/yiisoft/yii2"
+ },
+ "minimum-stability": "stable",
+ "require": {
+ "php": ">=7.4.0",
+ "yiisoft/yii2": "~2.0.45",
+ "yiisoft/yii2-bootstrap5": "~2.0.2",
+ "kartik-v/yii2-widgets": "dev-master",
+ "yiisoft/yii2-symfonymailer": "~2.0.3",
+ "hail812/yii2-adminlte3": "~1.1"
+ },
+ "require-dev": {
+ "yiisoft/yii2-debug": "~2.1.0",
+ "yiisoft/yii2-gii": "~2.2.0",
+ "yiisoft/yii2-faker": "~2.0.0",
+ "phpunit/phpunit": "~9.5.0",
+ "codeception/codeception": "^5.0.0 || ^4.0",
+ "codeception/lib-innerbrowser": "^4.0 || ^3.0 || ^1.1",
+ "codeception/module-asserts": "^3.0 || ^1.1",
+ "codeception/module-yii2": "^1.1",
+ "codeception/module-filesystem": "^3.0 || ^2.0 || ^1.1",
+ "codeception/verify": "^3.0 || ^2.2",
+ "symfony/browser-kit": "^6.0 || >=2.7 <=4.2.4"
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "common\\tests\\": ["common/tests/", "common/tests/_support"],
+ "backend\\tests\\": ["backend/tests/", "backend/tests/_support"],
+ "frontend\\tests\\": ["frontend/tests/", "frontend/tests/_support"]
+ }
+ },
+ "config": {
+ "allow-plugins": {
+ "yiisoft/yii2-composer" : true
+ },
+ "process-timeout": 1800,
+ "fxp-asset": {
+ "enabled": false
+ }
+ },
+ "repositories": [
+ {
+ "type": "composer",
+ "url": "https://asset-packagist.org"
+ }
+ ]
+}
diff --git a/composer.lock b/composer.lock
new file mode 100755
index 0000000..d0a59c6
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,7270 @@
+{
+ "_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#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "2e35fee6abd11c9feb0b9c29db7831bb",
+ "packages": [
+ {
+ "name": "almasaeed2010/adminlte",
+ "version": "v3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ColorlibHQ/AdminLTE.git",
+ "reference": "bd4d9c72931f1dd28601b6bfb387554a381ad540"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ColorlibHQ/AdminLTE/zipball/bd4d9c72931f1dd28601b6bfb387554a381ad540",
+ "reference": "bd4d9c72931f1dd28601b6bfb387554a381ad540",
+ "shasum": ""
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Colorlib"
+ }
+ ],
+ "description": "AdminLTE - admin control panel and dashboard that's based on Bootstrap 4",
+ "homepage": "https://adminlte.io/",
+ "keywords": [
+ "JS",
+ "admin",
+ "back-end",
+ "css",
+ "less",
+ "responsive",
+ "template",
+ "theme",
+ "web"
+ ],
+ "support": {
+ "issues": "https://github.com/ColorlibHQ/AdminLTE/issues",
+ "source": "https://github.com/ColorlibHQ/AdminLTE/tree/v3.2.0"
+ },
+ "time": "2022-02-07T20:33:09+00:00"
+ },
+ {
+ "name": "bower-asset/bootstrap",
+ "version": "v5.2.3",
+ "source": {
+ "type": "git",
+ "url": "git@github.com:twbs/bootstrap.git",
+ "reference": "cb021439c683d9805e2864c58095b92d405e9b11"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twbs/bootstrap/zipball/cb021439c683d9805e2864c58095b92d405e9b11",
+ "reference": "cb021439c683d9805e2864c58095b92d405e9b11"
+ },
+ "type": "bower-asset"
+ },
+ {
+ "name": "bower-asset/inputmask",
+ "version": "3.3.11",
+ "source": {
+ "type": "git",
+ "url": "git@github.com:RobinHerbots/Inputmask.git",
+ "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/5e670ad62f50c738388d4dcec78d2888505ad77b",
+ "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
+ },
+ "require": {
+ "bower-asset/jquery": ">=1.7"
+ },
+ "type": "bower-asset",
+ "license": [
+ "http://opensource.org/licenses/mit-license.php"
+ ]
+ },
+ {
+ "name": "bower-asset/jquery",
+ "version": "3.6.4",
+ "source": {
+ "type": "git",
+ "url": "git@github.com:jquery/jquery-dist.git",
+ "reference": "91ef2d8836342875f2519b5815197ea0f23613cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/91ef2d8836342875f2519b5815197ea0f23613cf",
+ "reference": "91ef2d8836342875f2519b5815197ea0f23613cf"
+ },
+ "type": "bower-asset",
+ "license": [
+ "MIT"
+ ]
+ },
+ {
+ "name": "bower-asset/punycode",
+ "version": "v1.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/mathiasbynens/punycode.js.git",
+ "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/mathiasbynens/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3",
+ "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
+ },
+ "type": "bower-asset"
+ },
+ {
+ "name": "bower-asset/yii2-pjax",
+ "version": "2.0.8",
+ "source": {
+ "type": "git",
+ "url": "git@github.com:yiisoft/jquery-pjax.git",
+ "reference": "a9298d57da63d14a950f1b94366a864bc62264fb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/a9298d57da63d14a950f1b94366a864bc62264fb",
+ "reference": "a9298d57da63d14a950f1b94366a864bc62264fb"
+ },
+ "require": {
+ "bower-asset/jquery": ">=1.8"
+ },
+ "type": "bower-asset",
+ "license": [
+ "MIT"
+ ]
+ },
+ {
+ "name": "cebe/markdown",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cebe/markdown.git",
+ "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cebe/markdown/zipball/9bac5e971dd391e2802dca5400bbeacbaea9eb86",
+ "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86",
+ "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.2.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"
+ ],
+ "support": {
+ "issues": "https://github.com/cebe/markdown/issues",
+ "source": "https://github.com/cebe/markdown"
+ },
+ "time": "2018-03-26T11:24:36+00:00"
+ },
+ {
+ "name": "doctrine/lexer",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/lexer.git",
+ "reference": "84a527db05647743d50373e0ec53a152f2cde568"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568",
+ "reference": "84a527db05647743d50373e0ec53a152f2cde568",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^10",
+ "phpstan/phpstan": "^1.9",
+ "phpunit/phpunit": "^9.5",
+ "psalm/plugin-phpunit": "^0.18.3",
+ "vimeo/psalm": "^5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Lexer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
+ "homepage": "https://www.doctrine-project.org/projects/lexer.html",
+ "keywords": [
+ "annotations",
+ "docblock",
+ "lexer",
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/3.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-15T16:57:16+00:00"
+ },
+ {
+ "name": "egulias/email-validator",
+ "version": "4.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/egulias/EmailValidator.git",
+ "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ebaaf5be6c0286928352e054f2d5125608e5405e",
+ "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/lexer": "^2.0 || ^3.0",
+ "php": ">=8.1",
+ "symfony/polyfill-intl-idn": "^1.26"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.2",
+ "vimeo/psalm": "^5.12"
+ },
+ "suggest": {
+ "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Egulias\\EmailValidator\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Eduardo Gulias Davis"
+ }
+ ],
+ "description": "A library for validating emails against several RFCs",
+ "homepage": "https://github.com/egulias/EmailValidator",
+ "keywords": [
+ "email",
+ "emailvalidation",
+ "emailvalidator",
+ "validation",
+ "validator"
+ ],
+ "support": {
+ "issues": "https://github.com/egulias/EmailValidator/issues",
+ "source": "https://github.com/egulias/EmailValidator/tree/4.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/egulias",
+ "type": "github"
+ }
+ ],
+ "time": "2023-10-06T06:47:41+00:00"
+ },
+ {
+ "name": "ezyang/htmlpurifier",
+ "version": "v4.16.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ezyang/htmlpurifier.git",
+ "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/523407fb06eb9e5f3d59889b3978d5bfe94299c8",
+ "reference": "523407fb06eb9e5f3d59889b3978d5bfe94299c8",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0"
+ },
+ "require-dev": {
+ "cerdic/css-tidy": "^1.7 || ^2.0",
+ "simpletest/simpletest": "dev-master"
+ },
+ "suggest": {
+ "cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
+ "ext-bcmath": "Used for unit conversion and imagecrash protection",
+ "ext-iconv": "Converts text to and from non-UTF-8 encodings",
+ "ext-tidy": "Used for pretty-printing HTML"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "library/HTMLPurifier.composer.php"
+ ],
+ "psr-0": {
+ "HTMLPurifier": "library/"
+ },
+ "exclude-from-classmap": [
+ "/library/HTMLPurifier/Language/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-or-later"
+ ],
+ "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"
+ ],
+ "support": {
+ "issues": "https://github.com/ezyang/htmlpurifier/issues",
+ "source": "https://github.com/ezyang/htmlpurifier/tree/v4.16.0"
+ },
+ "time": "2022-09-18T07:06:19+00:00"
+ },
+ {
+ "name": "hail812/yii2-adminlte-widgets",
+ "version": "v1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/hail812/yii2-adminlte-widgets.git",
+ "reference": "bc942430d7a5f5636f6c492553b5f444bf4a6df6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/hail812/yii2-adminlte-widgets/zipball/bc942430d7a5f5636f6c492553b5f444bf4a6df6",
+ "reference": "bc942430d7a5f5636f6c492553b5f444bf4a6df6",
+ "shasum": ""
+ },
+ "require": {
+ "yiisoft/yii2": "~2.0.0",
+ "yiisoft/yii2-bootstrap4": "~2.0.8"
+ },
+ "type": "yii2-extension",
+ "autoload": {
+ "psr-4": {
+ "hail812\\adminlte\\widgets\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "hail",
+ "email": "hail812@163.com"
+ }
+ ],
+ "description": "yii2 adminlte widgets",
+ "keywords": [
+ "extension",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/hail812/yii2-adminlte-widgets/issues",
+ "source": "https://github.com/hail812/yii2-adminlte-widgets/tree/v1.0.5"
+ },
+ "time": "2022-05-25T05:58:29+00:00"
+ },
+ {
+ "name": "hail812/yii2-adminlte3",
+ "version": "v1.1.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/hail812/yii2-adminlte3.git",
+ "reference": "bcdec8f5e2f9caf7f3a34fad8cdfdd5dbc3a9c31"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/hail812/yii2-adminlte3/zipball/bcdec8f5e2f9caf7f3a34fad8cdfdd5dbc3a9c31",
+ "reference": "bcdec8f5e2f9caf7f3a34fad8cdfdd5dbc3a9c31",
+ "shasum": ""
+ },
+ "require": {
+ "almasaeed2010/adminlte": "~3.1",
+ "hail812/yii2-adminlte-widgets": "~1.0.2",
+ "php": ">=7.0",
+ "yiisoft/yii2": "~2.0.0",
+ "yiisoft/yii2-bootstrap4": "~2.0.8"
+ },
+ "type": "yii2-extension",
+ "autoload": {
+ "psr-4": {
+ "hail812\\adminlte3\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "hail",
+ "email": "hail812@163.com"
+ }
+ ],
+ "description": "adminlte3 for yii2",
+ "keywords": [
+ "AdminLTE",
+ "extension",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/hail812/yii2-adminlte3/issues",
+ "source": "https://github.com/hail812/yii2-adminlte3/tree/v1.1.9"
+ },
+ "time": "2023-10-23T05:58:30+00:00"
+ },
+ {
+ "name": "kartik-v/bootstrap-fileinput",
+ "version": "v5.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/bootstrap-fileinput.git",
+ "reference": "35c29cd9fd5bc47eae5238feaabee95b2d7efe3c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/bootstrap-fileinput/zipball/35c29cd9fd5bc47eae5238feaabee95b2d7efe3c",
+ "reference": "35c29cd9fd5bc47eae5238feaabee95b2d7efe3c",
+ "shasum": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.5.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\plugins\\fileinput\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "An enhanced HTML 5 file input for Bootstrap 5.x, 4.x, and 3.x with features for file preview for many file types, multiple selection, ajax uploads, and more.",
+ "homepage": "https://github.com/kartik-v/bootstrap-fileinput",
+ "keywords": [
+ "ajax",
+ "bootstrap",
+ "delete",
+ "file",
+ "image",
+ "input",
+ "jquery",
+ "multiple",
+ "preview",
+ "progress",
+ "upload"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/bootstrap-fileinput/issues",
+ "source": "https://github.com/kartik-v/bootstrap-fileinput/tree/v5.5.2"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/bootstrap-fileinput",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2022-10-13T06:16:39+00:00"
+ },
+ {
+ "name": "kartik-v/bootstrap-star-rating",
+ "version": "v4.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/bootstrap-star-rating.git",
+ "reference": "c301efed4c82e9d5f11a0845ae428ba60931b44e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/bootstrap-star-rating/zipball/c301efed4c82e9d5f11a0845ae428ba60931b44e",
+ "reference": "c301efed4c82e9d5f11a0845ae428ba60931b44e",
+ "shasum": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.1.x-dev"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "A simple yet powerful JQuery star rating plugin for Bootstrap.",
+ "homepage": "https://github.com/kartik-v/bootstrap-star-rating",
+ "keywords": [
+ "Rating",
+ "awesome",
+ "bootstrap",
+ "font",
+ "glyphicon",
+ "star",
+ "svg"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/bootstrap-star-rating/issues",
+ "source": "https://github.com/kartik-v/bootstrap-star-rating/tree/v4.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/bootstrap-star-rating",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2021-09-20T03:06:01+00:00"
+ },
+ {
+ "name": "kartik-v/dependent-dropdown",
+ "version": "v1.4.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/dependent-dropdown.git",
+ "reference": "54a8806002ee21b744508a2edb95ed01d35c6cf9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/dependent-dropdown/zipball/54a8806002ee21b744508a2edb95ed01d35c6cf9",
+ "reference": "54a8806002ee21b744508a2edb95ed01d35c6cf9",
+ "shasum": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\plugins\\depdrop\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "A multi level dependent dropdown JQuery plugin that allows nested dependencies.",
+ "homepage": "https://github.com/kartik-v/dependent-dropdown",
+ "keywords": [
+ "dependent",
+ "dropdown",
+ "jquery",
+ "option",
+ "select"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/dependent-dropdown/issues",
+ "source": "https://github.com/kartik-v/dependent-dropdown/tree/master"
+ },
+ "time": "2019-03-09T10:53:11+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-krajee-base",
+ "version": "v3.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-krajee-base.git",
+ "reference": "5c095126d1be47e0bb1f92779b7dc099f6feae31"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-krajee-base/zipball/5c095126d1be47e0bb1f92779b7dc099f6feae31",
+ "reference": "5c095126d1be47e0bb1f92779b7dc099f6feae31",
+ "shasum": ""
+ },
+ "suggest": {
+ "yiisoft/yii2-bootstrap": "for Krajee extensions to work with Bootstrap 3.x version",
+ "yiisoft/yii2-bootstrap4": "for Krajee extensions to work with Bootstrap 4.x version",
+ "yiisoft/yii2-bootstrap5": "for Krajee extensions to work with Bootstrap 5.x version"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\base\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "Base library and foundation components for all Yii2 Krajee extensions.",
+ "homepage": "https://github.com/kartik-v/yii2-krajee-base",
+ "keywords": [
+ "base",
+ "extension",
+ "foundation",
+ "krajee",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-krajee-base/issues",
+ "source": "https://github.com/kartik-v/yii2-krajee-base/tree/v3.0.5"
+ },
+ "time": "2022-06-01T14:05:39+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-activeform",
+ "version": "v1.6.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-activeform.git",
+ "reference": "697407c8fa9c81593a7bb9bef4b7ad53f7d38b79"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-activeform/zipball/697407c8fa9c81593a7bb9bef4b7ad53f7d38b79",
+ "reference": "697407c8fa9c81593a7bb9bef4b7ad53f7d38b79",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=3.0.3"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.6.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\form\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "Enhanced Yii2 active-form and active-field with full bootstrap styling support (sub repo split from yii2-widgets).",
+ "homepage": "https://github.com/kartik-v/yii2-widget-activeform",
+ "keywords": [
+ "activefield",
+ "activeform",
+ "extension",
+ "field",
+ "form",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-activeform/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-activeform/tree/v1.6.4"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/yii2-widgets",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2023-07-31T11:33:59+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-affix",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-affix.git",
+ "reference": "2184119bfa518c285406156f744769b13b861712"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-affix/zipball/2184119bfa518c285406156f744769b13b861712",
+ "reference": "2184119bfa518c285406156f744769b13b861712",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": "*"
+ },
+ "type": "yii2-extension",
+ "autoload": {
+ "psr-4": {
+ "kartik\\affix\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD 3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "A scrollspy and affixed enhanced navigation to highlight page sections (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-affix",
+ "keywords": [
+ "affix",
+ "bootstrap",
+ "extension",
+ "jquery",
+ "navigation",
+ "plugin",
+ "scrollspy",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-affix/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-affix/tree/master"
+ },
+ "time": "2014-11-09T04:56:27+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-alert",
+ "version": "v1.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-alert.git",
+ "reference": "6a45d7dc294eecd578cf8cb9acb671d1cafa0727"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-alert/zipball/6a45d7dc294eecd578cf8cb9acb671d1cafa0727",
+ "reference": "6a45d7dc294eecd578cf8cb9acb671d1cafa0727",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-widget-growl": ">=1.1.2"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\alert\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "A widget to generate alert based notifications using bootstrap-alert plugin (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-alert",
+ "keywords": [
+ "alert",
+ "block",
+ "bootstrap",
+ "extension",
+ "flash",
+ "jquery",
+ "notification",
+ "plugin",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-alert/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-alert/tree/v1.1.5"
+ },
+ "time": "2021-10-16T10:23:22+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-colorinput",
+ "version": "v1.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-colorinput.git",
+ "reference": "e35e6c7615a735b65557d6c38d112b77e2628c69"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-colorinput/zipball/e35e6c7615a735b65557d6c38d112b77e2628c69",
+ "reference": "e35e6c7615a735b65557d6c38d112b77e2628c69",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=1.9"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\color\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "An enhanced Yii 2 widget encapsulating the HTML 5 color input (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-colorinput",
+ "keywords": [
+ "HTML5",
+ "color",
+ "extension",
+ "form",
+ "input",
+ "jquery",
+ "plugin",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-colorinput/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-colorinput/tree/v1.0.6"
+ },
+ "time": "2020-10-23T17:50:44+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-datepicker",
+ "version": "v1.4.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-datepicker.git",
+ "reference": "f5f8b396cf03d4a383aad5e7b338f8cb065abf66"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-datepicker/zipball/f5f8b396cf03d4a383aad5e7b338f8cb065abf66",
+ "reference": "f5f8b396cf03d4a383aad5e7b338f8cb065abf66",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=2.0.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\date\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "Enhanced Yii2 wrapper for the bootstrap datepicker plugin (sub repo split from yii2-widgets).",
+ "homepage": "https://github.com/kartik-v/yii2-widget-datepicker",
+ "keywords": [
+ "date",
+ "extension",
+ "form",
+ "jquery",
+ "picker",
+ "plugin",
+ "select2",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-datepicker/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-datepicker/tree/v1.4.8"
+ },
+ "time": "2021-10-28T03:58:09+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-datetimepicker",
+ "version": "v1.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-datetimepicker.git",
+ "reference": "85b22d38553ca207f86be198f37e6531347e9a23"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-datetimepicker/zipball/85b22d38553ca207f86be198f37e6531347e9a23",
+ "reference": "85b22d38553ca207f86be198f37e6531347e9a23",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=3.0.4"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.5.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\datetime\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "Enhanced Yii2 wrapper for the bootstrap datetimepicker plugin (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-datetimepicker",
+ "keywords": [
+ "datetime",
+ "extension",
+ "form",
+ "jquery",
+ "picker",
+ "plugin",
+ "select2",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-datetimepicker/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-datetimepicker/tree/v1.5.1"
+ },
+ "time": "2022-03-18T17:42:22+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-depdrop",
+ "version": "v1.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-depdrop.git",
+ "reference": "ea347e3793fbd8273cc9bd1eb94c4b32bb55d318"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-depdrop/zipball/ea347e3793fbd8273cc9bd1eb94c4b32bb55d318",
+ "reference": "ea347e3793fbd8273cc9bd1eb94c4b32bb55d318",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/dependent-dropdown": "~1.4",
+ "kartik-v/yii2-krajee-base": ">=2.0.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\depdrop\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "Widget that enables setting up dependent dropdowns with nested dependencies (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-depdrop",
+ "keywords": [
+ "dependent",
+ "dropdown",
+ "extension",
+ "form",
+ "jquery",
+ "plugin",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-depdrop/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-depdrop/tree/v1.0.6"
+ },
+ "time": "2019-04-19T07:02:48+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-fileinput",
+ "version": "v1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-fileinput.git",
+ "reference": "b5500b6855526837154694c2afab8dbc3afc8abd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-fileinput/zipball/b5500b6855526837154694c2afab8dbc3afc8abd",
+ "reference": "b5500b6855526837154694c2afab8dbc3afc8abd",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/bootstrap-fileinput": ">=5.5.0",
+ "kartik-v/yii2-krajee-base": ">=3.0.5"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\file\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "An enhanced FileInput widget for Bootstrap 3.x, 4.x & 5.x with file preview, multiple selection, and more features (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-fileinput",
+ "keywords": [
+ "extension",
+ "file",
+ "form",
+ "input",
+ "jquery",
+ "plugin",
+ "upload",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-fileinput/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-fileinput/tree/v1.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/yii2-widget-fileinput",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2022-06-28T04:31:04+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-growl",
+ "version": "v1.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-growl.git",
+ "reference": "37e8f9f10d3bc9d71f3ef64c4aaa0e2fc83dd5dc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-growl/zipball/37e8f9f10d3bc9d71f3ef64c4aaa0e2fc83dd5dc",
+ "reference": "37e8f9f10d3bc9d71f3ef64c4aaa0e2fc83dd5dc",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=2.0.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\growl\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "A widget to generate growl based notifications using bootstrap-growl plugin (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-growl",
+ "keywords": [
+ "alert",
+ "bootstrap",
+ "extension",
+ "growl",
+ "jquery",
+ "notification",
+ "plugin",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-growl/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-growl/tree/v1.1.2"
+ },
+ "time": "2021-05-19T12:44:49+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-rangeinput",
+ "version": "v1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-rangeinput.git",
+ "reference": "dd9019bab7e5bf570a02870d9e74387891bbdb32"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-rangeinput/zipball/dd9019bab7e5bf570a02870d9e74387891bbdb32",
+ "reference": "dd9019bab7e5bf570a02870d9e74387891bbdb32",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=1.9"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\range\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "An enhanced Yii 2 widget encapsulating the HTML 5 range input (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-rangeinput",
+ "keywords": [
+ "HTML5",
+ "extension",
+ "form",
+ "input",
+ "jquery",
+ "plugin",
+ "range",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-rangeinput/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-rangeinput/tree/master"
+ },
+ "time": "2018-09-07T10:05:08+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-rating",
+ "version": "v1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-rating.git",
+ "reference": "d3d7249490044f80e65f8f3938191f39a76586b2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-rating/zipball/d3d7249490044f80e65f8f3938191f39a76586b2",
+ "reference": "d3d7249490044f80e65f8f3938191f39a76586b2",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/bootstrap-star-rating": "~4.0",
+ "kartik-v/yii2-krajee-base": ">=1.9"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\rating\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "A Yii2 widget for the simple yet powerful bootstrap-star-rating plugin with fractional rating support (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-rating",
+ "keywords": [
+ "Rating",
+ "bootstrap",
+ "extension",
+ "form",
+ "input",
+ "jquery",
+ "plugin",
+ "star",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-rating/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-rating/tree/v1.0.5"
+ },
+ "time": "2021-11-20T05:26:05+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-select2",
+ "version": "v2.2.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-select2.git",
+ "reference": "4b8ef7dd9780531fc997fa23a53a38a1f7674bec"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-select2/zipball/4b8ef7dd9780531fc997fa23a53a38a1f7674bec",
+ "reference": "4b8ef7dd9780531fc997fa23a53a38a1f7674bec",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=3.0.4",
+ "select2/select2": ">=4.0.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\select2\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "Enhanced Yii2 wrapper for the Select2 jQuery plugin (sub repo split from yii2-widgets).",
+ "homepage": "https://github.com/kartik-v/yii2-widget-select2",
+ "keywords": [
+ "dropdown",
+ "extension",
+ "form",
+ "jquery",
+ "plugin",
+ "select2",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-select2/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-select2/tree/v2.2.5"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/yii2-widget-select2",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2023-06-22T07:43:31+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-sidenav",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-sidenav.git",
+ "reference": "87e9c815624aa966d70bb4507b3d53c158db0d43"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-sidenav/zipball/87e9c815624aa966d70bb4507b3d53c158db0d43",
+ "reference": "87e9c815624aa966d70bb4507b3d53c158db0d43",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": "*"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\sidenav\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "An enhanced side navigation menu styled for bootstrap (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-sidenav",
+ "keywords": [
+ "bootstrap",
+ "extension",
+ "jquery",
+ "menu",
+ "navigation",
+ "plugin",
+ "sidenav",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-sidenav/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-sidenav/tree/v1.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/yii2-widget-sidenav",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2021-04-08T17:49:26+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-spinner",
+ "version": "v1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-spinner.git",
+ "reference": "eb10dad17a107bf14f173c99994770ca23c548a6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-spinner/zipball/eb10dad17a107bf14f173c99994770ca23c548a6",
+ "reference": "eb10dad17a107bf14f173c99994770ca23c548a6",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=2.0.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\spinner\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "A widget to render animated CSS3 loading spinners with VML fallback for IE (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-spinner",
+ "keywords": [
+ "CSS3",
+ "extension",
+ "jquery",
+ "loading",
+ "plugin",
+ "spinner",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-spinner/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-spinner/tree/master"
+ },
+ "time": "2018-10-09T11:54:03+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-switchinput",
+ "version": "v1.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-switchinput.git",
+ "reference": "7d8ee999d79bcdc1601da5cd59439ac7eb1f5ea6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-switchinput/zipball/7d8ee999d79bcdc1601da5cd59439ac7eb1f5ea6",
+ "reference": "7d8ee999d79bcdc1601da5cd59439ac7eb1f5ea6",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": "*"
+ },
+ "type": "yii2-extension",
+ "autoload": {
+ "psr-4": {
+ "kartik\\switchinput\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD 3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "A Yii2 wrapper widget for the Bootstrap Switch plugin to use checkboxes & radios as toggle switchinputes (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-switchinput",
+ "keywords": [
+ "bootstrap",
+ "extension",
+ "form",
+ "input",
+ "jquery",
+ "plugin",
+ "switchinput",
+ "toggle",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-switchinput/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-switchinput/tree/master"
+ },
+ "time": "2016-01-10T16:47:35+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-timepicker",
+ "version": "v1.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-timepicker.git",
+ "reference": "680aec2d79846e926c072da455cf6f33e1c3bb12"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-timepicker/zipball/680aec2d79846e926c072da455cf6f33e1c3bb12",
+ "reference": "680aec2d79846e926c072da455cf6f33e1c3bb12",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=2.0.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\time\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "Enhanced Yii2 wrapper for the bootstrap timepicker plugin (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-timepicker",
+ "keywords": [
+ "bootstrap",
+ "extension",
+ "form",
+ "jquery",
+ "picker",
+ "plugin",
+ "time",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-timepicker/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-timepicker/tree/v1.0.5"
+ },
+ "time": "2021-10-28T03:49:56+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-touchspin",
+ "version": "v1.2.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-touchspin.git",
+ "reference": "1eec4c3f3a8bf9a170e1e0682c2c89f2929d65e9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-touchspin/zipball/1eec4c3f3a8bf9a170e1e0682c2c89f2929d65e9",
+ "reference": "1eec4c3f3a8bf9a170e1e0682c2c89f2929d65e9",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=3.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\touchspin\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "A Yii2 wrapper widget for the Bootstrap Switch plugin to use checkboxes & radios as toggle touchspines (sub repo split from yii2-widgets)",
+ "homepage": "https://github.com/kartik-v/yii2-widget-touchspin",
+ "keywords": [
+ "bootstrap",
+ "extension",
+ "form",
+ "input",
+ "jquery",
+ "plugin",
+ "spinner",
+ "touch",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-touchspin/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-touchspin/tree/v1.2.4"
+ },
+ "time": "2021-09-02T12:50:50+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widget-typeahead",
+ "version": "v1.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widget-typeahead.git",
+ "reference": "7b7041a3cbbeb2db0a608e9f6c9b3f4f63b0069d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widget-typeahead/zipball/7b7041a3cbbeb2db0a608e9f6c9b3f4f63b0069d",
+ "reference": "7b7041a3cbbeb2db0a608e9f6c9b3f4f63b0069d",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": ">=2.0.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\typeahead\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "Enhanced Yii2 wrapper for the Twitter Typeahead plugin (sub repo split from yii2-widgets).",
+ "homepage": "https://github.com/kartik-v/yii2-widget-typeahead",
+ "keywords": [
+ "dropdown",
+ "extension",
+ "form",
+ "jquery",
+ "plugin",
+ "typeahead",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widget-typeahead/issues",
+ "source": "https://github.com/kartik-v/yii2-widget-typeahead/tree/master"
+ },
+ "time": "2019-05-29T12:06:56+00:00"
+ },
+ {
+ "name": "kartik-v/yii2-widgets",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kartik-v/yii2-widgets.git",
+ "reference": "0674838c869e5ccabc15756ee0c065ccecd09969"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kartik-v/yii2-widgets/zipball/0674838c869e5ccabc15756ee0c065ccecd09969",
+ "reference": "0674838c869e5ccabc15756ee0c065ccecd09969",
+ "shasum": ""
+ },
+ "require": {
+ "kartik-v/yii2-krajee-base": "*",
+ "kartik-v/yii2-widget-activeform": "*",
+ "kartik-v/yii2-widget-affix": "*",
+ "kartik-v/yii2-widget-alert": "*",
+ "kartik-v/yii2-widget-colorinput": "*",
+ "kartik-v/yii2-widget-datepicker": "*",
+ "kartik-v/yii2-widget-datetimepicker": "*",
+ "kartik-v/yii2-widget-depdrop": "*",
+ "kartik-v/yii2-widget-fileinput": "*",
+ "kartik-v/yii2-widget-growl": "*",
+ "kartik-v/yii2-widget-rangeinput": "*",
+ "kartik-v/yii2-widget-rating": "*",
+ "kartik-v/yii2-widget-select2": "*",
+ "kartik-v/yii2-widget-sidenav": "*",
+ "kartik-v/yii2-widget-spinner": "*",
+ "kartik-v/yii2-widget-switchinput": "*",
+ "kartik-v/yii2-widget-timepicker": "*",
+ "kartik-v/yii2-widget-touchspin": "*",
+ "kartik-v/yii2-widget-typeahead": "*"
+ },
+ "default-branch": true,
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "kartik\\widgets\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kartik Visweswaran",
+ "email": "kartikv2@gmail.com",
+ "homepage": "http://www.krajee.com/"
+ }
+ ],
+ "description": "Collection of useful widgets for Yii Framework 2.0 extending functionalities for Bootstrap",
+ "homepage": "https://github.com/kartik-v/yii2-widgets",
+ "keywords": [
+ "extension",
+ "form",
+ "widget",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/kartik-v/yii2-widgets/issues",
+ "source": "https://github.com/kartik-v/yii2-widgets/tree/master"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/yii2-widgets",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2019-09-03T03:11:11+00:00"
+ },
+ {
+ "name": "npm-asset/bootstrap",
+ "version": "4.6.2",
+ "dist": {
+ "type": "tar",
+ "url": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz"
+ },
+ "type": "npm-asset",
+ "license": [
+ "MIT"
+ ]
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v9.99.100",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">= 7"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*",
+ "vimeo/psalm": "^1"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "type": "library",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "polyfill",
+ "pseudorandom",
+ "random"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/random_compat/issues",
+ "source": "https://github.com/paragonie/random_compat"
+ },
+ "time": "2020-10-15T08:29:30+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/2.0.2"
+ },
+ "time": "2021-11-05T16:47:00+00:00"
+ },
+ {
+ "name": "psr/event-dispatcher",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/event-dispatcher.git",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\EventDispatcher\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Standard interfaces for event handling.",
+ "keywords": [
+ "events",
+ "psr",
+ "psr-14"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/event-dispatcher/issues",
+ "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
+ },
+ "time": "2019-01-08T18:20:26+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
+ "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/3.0.0"
+ },
+ "time": "2021-07-14T16:46:02+00:00"
+ },
+ {
+ "name": "select2/select2",
+ "version": "4.0.13",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/select2/select2.git",
+ "reference": "45f2b83ceed5231afa7b3d5b12b58ad335edd82e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/select2/select2/zipball/45f2b83ceed5231afa7b3d5b12b58ad335edd82e",
+ "reference": "45f2b83ceed5231afa7b3d5b12b58ad335edd82e",
+ "shasum": ""
+ },
+ "type": "component",
+ "extra": {
+ "component": {
+ "scripts": [
+ "dist/js/select2.js"
+ ],
+ "styles": [
+ "dist/css/select2.css"
+ ],
+ "files": [
+ "dist/js/select2.js",
+ "dist/js/i18n/*.js",
+ "dist/css/select2.css"
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Select2 is a jQuery based replacement for select boxes.",
+ "homepage": "https://select2.org/",
+ "support": {
+ "issues": "https://github.com/select2/select2/issues",
+ "source": "https://github.com/select2/select2/tree/4.0.13"
+ },
+ "time": "2020-01-28T05:01:22+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "v3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf",
+ "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-23T14:45:45+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v6.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e",
+ "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/event-dispatcher-contracts": "^2.5|^3"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<5.4",
+ "symfony/service-contracts": "<2.5"
+ },
+ "provide": {
+ "psr/event-dispatcher-implementation": "1.0",
+ "symfony/event-dispatcher-implementation": "2.0|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/error-handler": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/stopwatch": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-07-06T06:56:43+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher-contracts",
+ "version": "v3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+ "reference": "a76aed96a42d2b521153fb382d418e30d18b59df"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df",
+ "reference": "a76aed96a42d2b521153fb382d418e30d18b59df",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/event-dispatcher": "^1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\EventDispatcher\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to dispatching event",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-23T14:45:45+00:00"
+ },
+ {
+ "name": "symfony/mailer",
+ "version": "v6.3.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/mailer.git",
+ "reference": "d89611a7830d51b5e118bca38e390dea92f9ea06"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/mailer/zipball/d89611a7830d51b5e118bca38e390dea92f9ea06",
+ "reference": "d89611a7830d51b5e118bca38e390dea92f9ea06",
+ "shasum": ""
+ },
+ "require": {
+ "egulias/email-validator": "^2.1.10|^3|^4",
+ "php": ">=8.1",
+ "psr/event-dispatcher": "^1",
+ "psr/log": "^1|^2|^3",
+ "symfony/event-dispatcher": "^5.4|^6.0",
+ "symfony/mime": "^6.2",
+ "symfony/service-contracts": "^2.5|^3"
+ },
+ "conflict": {
+ "symfony/http-client-contracts": "<2.5",
+ "symfony/http-kernel": "<5.4",
+ "symfony/messenger": "<6.2",
+ "symfony/mime": "<6.2",
+ "symfony/twig-bridge": "<6.2.1"
+ },
+ "require-dev": {
+ "symfony/console": "^5.4|^6.0",
+ "symfony/http-client": "^5.4|^6.0",
+ "symfony/messenger": "^6.2",
+ "symfony/twig-bridge": "^6.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Mailer\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Helps sending emails",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/mailer/tree/v6.3.5"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-09-06T09:47:15+00:00"
+ },
+ {
+ "name": "symfony/mime",
+ "version": "v6.3.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/mime.git",
+ "reference": "d5179eedf1cb2946dbd760475ebf05c251ef6a6e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/d5179eedf1cb2946dbd760475ebf05c251ef6a6e",
+ "reference": "d5179eedf1cb2946dbd760475ebf05c251ef6a6e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-intl-idn": "^1.10",
+ "symfony/polyfill-mbstring": "^1.0"
+ },
+ "conflict": {
+ "egulias/email-validator": "~3.0.0",
+ "phpdocumentor/reflection-docblock": "<3.2.2",
+ "phpdocumentor/type-resolver": "<1.4.0",
+ "symfony/mailer": "<5.4",
+ "symfony/serializer": "<6.2.13|>=6.3,<6.3.2"
+ },
+ "require-dev": {
+ "egulias/email-validator": "^2.1.10|^3.1|^4",
+ "league/html-to-markdown": "^5.0",
+ "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/property-access": "^5.4|^6.0",
+ "symfony/property-info": "^5.4|^6.0",
+ "symfony/serializer": "~6.2.13|^6.3.2"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Mime\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Allows manipulating MIME messages",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "mime",
+ "mime-type"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/mime/tree/v6.3.5"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-09-29T06:59:36+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-idn",
+ "version": "v1.28.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-idn.git",
+ "reference": "ecaafce9f77234a6a449d29e49267ba10499116d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d",
+ "reference": "ecaafce9f77234a6a449d29e49267ba10499116d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1",
+ "symfony/polyfill-intl-normalizer": "^1.10",
+ "symfony/polyfill-php72": "^1.10"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Idn\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Laurent Bassin",
+ "email": "laurent@bassin.info"
+ },
+ {
+ "name": "Trevor Rowbotham",
+ "email": "trevor.rowbotham@pm.me"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "idn",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-01-26T09:30:37+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.28.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
+ "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-01-26T09:26:14+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.28.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "42292d99c55abe617799667f454222c54c60e229"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
+ "reference": "42292d99c55abe617799667f454222c54c60e229",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-mbstring": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-07-28T09:04:16+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php72",
+ "version": "v1.28.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php72.git",
+ "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179",
+ "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php72\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-01-26T09:26:14+00:00"
+ },
+ {
+ "name": "symfony/service-contracts",
+ "version": "v3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838",
+ "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/container": "^2.0"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Service\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Test/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to writing services",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/v3.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-07-30T20:28:31+00:00"
+ },
+ {
+ "name": "yiisoft/yii2",
+ "version": "2.0.49.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-framework.git",
+ "reference": "783f65c9a743dfd7484b6026f1aa6f25e37159d9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/783f65c9a743dfd7484b6026f1aa6f25e37159d9",
+ "reference": "783f65c9a743dfd7484b6026f1aa6f25e37159d9",
+ "shasum": ""
+ },
+ "require": {
+ "bower-asset/inputmask": "~3.2.2 | ~3.3.5",
+ "bower-asset/jquery": "3.7.*@stable | 3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
+ "bower-asset/punycode": "1.3.*",
+ "bower-asset/yii2-pjax": "~2.0.1",
+ "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0",
+ "ext-ctype": "*",
+ "ext-mbstring": "*",
+ "ezyang/htmlpurifier": "^4.6",
+ "lib-pcre": "*",
+ "paragonie/random_compat": ">=1",
+ "php": ">=5.4.0",
+ "yiisoft/yii2-composer": "~2.0.4"
+ },
+ "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": "https://www.yiiframework.com/",
+ "role": "Founder and project lead"
+ },
+ {
+ "name": "Alexander Makarov",
+ "email": "sam@rmcreative.ru",
+ "homepage": "https://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": "https://www.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"
+ },
+ {
+ "name": "Dmitry Naumenko",
+ "email": "d.naumenko.a@gmail.com",
+ "role": "Core framework development"
+ },
+ {
+ "name": "Boudewijn Vahrmeijer",
+ "email": "info@dynasource.eu",
+ "homepage": "http://dynasource.eu",
+ "role": "Core framework development"
+ }
+ ],
+ "description": "Yii PHP Framework Version 2",
+ "homepage": "https://www.yiiframework.com/",
+ "keywords": [
+ "framework",
+ "yii2"
+ ],
+ "support": {
+ "forum": "https://forum.yiiframework.com/",
+ "irc": "ircs://irc.libera.chat:6697/yii",
+ "issues": "https://github.com/yiisoft/yii2/issues?state=open",
+ "source": "https://github.com/yiisoft/yii2",
+ "wiki": "https://www.yiiframework.com/wiki"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/yiisoft",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/yiisoft",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-10-31T15:39:08+00:00"
+ },
+ {
+ "name": "yiisoft/yii2-bootstrap4",
+ "version": "2.0.11",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-bootstrap4.git",
+ "reference": "6681a7ca2319499c1c35f09e803c5337e56b3dae"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap4/zipball/6681a7ca2319499c1c35f09e803c5337e56b3dae",
+ "reference": "6681a7ca2319499c1c35f09e803c5337e56b3dae",
+ "shasum": ""
+ },
+ "require": {
+ "npm-asset/bootstrap": "^4.3",
+ "yiisoft/yii2": "^2.0.43"
+ },
+ "require-dev": {
+ "cweagans/composer-patches": "^1.7",
+ "phpunit/phpunit": "4.8.34",
+ "yiisoft/yii2-coding-standards": "~2.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ },
+ "patches": {
+ "phpunit/phpunit-mock-objects": {
+ "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
+ },
+ "phpunit/phpunit": {
+ "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
+ "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "yii\\bootstrap4\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Qiang Xue",
+ "email": "qiang.xue@gmail.com",
+ "homepage": "https://www.yiiframework.com/"
+ },
+ {
+ "name": "Alexander Makarov",
+ "email": "sam@rmcreative.ru",
+ "homepage": "https://rmcreative.ru/"
+ },
+ {
+ "name": "Antonio Ramirez",
+ "email": "amigo.cobos@gmail.com"
+ },
+ {
+ "name": "Paul Klimov",
+ "email": "klimov.paul@gmail.com"
+ },
+ {
+ "name": "Simon Karlen",
+ "email": "simi.albi@outlook.com"
+ }
+ ],
+ "description": "The Twitter Bootstrap extension for the Yii framework",
+ "keywords": [
+ "bootstrap",
+ "bootstrap4",
+ "yii2"
+ ],
+ "support": {
+ "forum": "https://www.yiiframework.com/forum/",
+ "irc": "irc://irc.freenode.net/yii",
+ "issues": "https://github.com/yiisoft/yii2-bootstrap4/issues",
+ "source": "https://github.com/yiisoft/yii2-bootstrap4",
+ "wiki": "https://www.yiiframework.com/wiki/"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/yiisoft",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/yiisoft",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-bootstrap4",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-22T18:39:25+00:00"
+ },
+ {
+ "name": "yiisoft/yii2-bootstrap5",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-bootstrap5.git",
+ "reference": "0ce35f80ca07763fa2c6f38d1c0a1aaf65c76d2e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap5/zipball/0ce35f80ca07763fa2c6f38d1c0a1aaf65c76d2e",
+ "reference": "0ce35f80ca07763fa2c6f38d1c0a1aaf65c76d2e",
+ "shasum": ""
+ },
+ "require": {
+ "bower-asset/bootstrap": "^5.1.0",
+ "ext-json": "*",
+ "php": ">=7.0",
+ "yiisoft/yii2": "^2.0.42"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6.5.14",
+ "twbs/bootstrap-icons": "^1.7.2",
+ "yiisoft/yii2-coding-standards": "~2.0"
+ },
+ "suggest": {
+ "twbs/bootstrap-icons": "Add this package to the `require` section of your `composer.json` if you'd like to use the bootstrap icon asset."
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ },
+ "bootstrap": "yii\\bootstrap5\\i18n\\TranslationBootstrap"
+ },
+ "autoload": {
+ "psr-4": {
+ "yii\\bootstrap5\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sergey Zhukovskiy",
+ "email": "mylistryx@gmail.com",
+ "homepage": "https://net23.ru/"
+ },
+ {
+ "name": "Simon Karlen",
+ "email": "simi.albi@outlook.com"
+ }
+ ],
+ "description": "The Twitter Bootstrap v5 extension for the Yii framework",
+ "keywords": [
+ "bootstrap",
+ "bootstrap5",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/yiisoft/yii2-bootstrap5/issues",
+ "source": "https://github.com/yiisoft/yii2-bootstrap5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/yiisoft",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/yiisoft",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-bootstrap5",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-30T08:25:21+00:00"
+ },
+ {
+ "name": "yiisoft/yii2-composer",
+ "version": "2.0.10",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-composer.git",
+ "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/94bb3f66e779e2774f8776d6e1bdeab402940510",
+ "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0 | ^2.0"
+ },
+ "require-dev": {
+ "composer/composer": "^1.0 | ^2.0@dev",
+ "phpunit/phpunit": "<7"
+ },
+ "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"
+ },
+ {
+ "name": "Carsten Brandt",
+ "email": "mail@cebe.cc"
+ }
+ ],
+ "description": "The composer plugin for Yii extension installer",
+ "keywords": [
+ "composer",
+ "extension installer",
+ "yii2"
+ ],
+ "support": {
+ "forum": "http://www.yiiframework.com/forum/",
+ "irc": "irc://irc.freenode.net/yii",
+ "issues": "https://github.com/yiisoft/yii2-composer/issues",
+ "source": "https://github.com/yiisoft/yii2-composer",
+ "wiki": "http://www.yiiframework.com/wiki/"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/yiisoft",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/yiisoft",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-06-24T00:04:01+00:00"
+ },
+ {
+ "name": "yiisoft/yii2-symfonymailer",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-symfonymailer.git",
+ "reference": "82f5902551a160633c4734b5096977ce76a809d9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-symfonymailer/zipball/82f5902551a160633c4734b5096977ce76a809d9",
+ "reference": "82f5902551a160633c4734b5096977ce76a809d9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.4.0",
+ "symfony/mailer": ">=5.4.0",
+ "yiisoft/yii2": ">=2.0.4"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "9.5.10"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "yii\\symfonymailer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kirill Petrov",
+ "email": "archibeardrinker@gmail.com"
+ }
+ ],
+ "description": "The SymfonyMailer integration for the Yii framework",
+ "keywords": [
+ "email",
+ "mail",
+ "mailer",
+ "symfony",
+ "symfonymailer",
+ "yii2"
+ ],
+ "support": {
+ "forum": "http://www.yiiframework.com/forum/",
+ "irc": "irc://irc.freenode.net/yii",
+ "issues": "https://github.com/yiisoft/yii2-symfonymailer/issues",
+ "source": "https://github.com/yiisoft/yii2-symfonymailer",
+ "wiki": "http://www.yiiframework.com/wiki/"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/yiisoft",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/yiisoft",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-symfonymailer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-09-04T10:48:21+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "behat/gherkin",
+ "version": "v4.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Behat/Gherkin.git",
+ "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Behat/Gherkin/zipball/0bc8d1e30e96183e4f36db9dc79caead300beff4",
+ "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4",
+ "shasum": ""
+ },
+ "require": {
+ "php": "~7.2|~8.0"
+ },
+ "require-dev": {
+ "cucumber/cucumber": "dev-gherkin-22.0.0",
+ "phpunit/phpunit": "~8|~9",
+ "symfony/yaml": "~3|~4|~5"
+ },
+ "suggest": {
+ "symfony/yaml": "If you want to parse features, represented in YAML files"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Behat\\Gherkin": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ }
+ ],
+ "description": "Gherkin DSL parser for PHP",
+ "homepage": "http://behat.org/",
+ "keywords": [
+ "BDD",
+ "Behat",
+ "Cucumber",
+ "DSL",
+ "gherkin",
+ "parser"
+ ],
+ "support": {
+ "issues": "https://github.com/Behat/Gherkin/issues",
+ "source": "https://github.com/Behat/Gherkin/tree/v4.9.0"
+ },
+ "time": "2021-10-12T13:05:09+00:00"
+ },
+ {
+ "name": "codeception/codeception",
+ "version": "5.0.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/Codeception.git",
+ "reference": "7f528f5fd8cdcd05cd0a85eb1e24d05df989e0c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/Codeception/zipball/7f528f5fd8cdcd05cd0a85eb1e24d05df989e0c4",
+ "reference": "7f528f5fd8cdcd05cd0a85eb1e24d05df989e0c4",
+ "shasum": ""
+ },
+ "require": {
+ "behat/gherkin": "^4.6.2",
+ "codeception/lib-asserts": "^2.0",
+ "codeception/stub": "^4.1",
+ "ext-curl": "*",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "php": "^8.0",
+ "phpunit/php-code-coverage": "^9.2 || ^10.0",
+ "phpunit/php-text-template": "^2.0 || ^3.0",
+ "phpunit/php-timer": "^5.0.3 || ^6.0",
+ "phpunit/phpunit": "^9.5.20 || ^10.0",
+ "psy/psysh": "^0.11.2",
+ "sebastian/comparator": "^4.0.5 || ^5.0",
+ "sebastian/diff": "^4.0.3 || ^5.0",
+ "symfony/console": ">=4.4.24 <7.0",
+ "symfony/css-selector": ">=4.4.24 <7.0",
+ "symfony/event-dispatcher": ">=4.4.24 <7.0",
+ "symfony/finder": ">=4.4.24 <7.0",
+ "symfony/var-dumper": ">=4.4.24 < 7.0",
+ "symfony/yaml": ">=4.4.24 <7.0"
+ },
+ "conflict": {
+ "codeception/lib-innerbrowser": "<3.1.3",
+ "codeception/module-filesystem": "<3.0",
+ "codeception/module-phpbrowser": "<2.5"
+ },
+ "replace": {
+ "codeception/phpunit-wrapper": "*"
+ },
+ "require-dev": {
+ "codeception/lib-innerbrowser": "*@dev",
+ "codeception/lib-web": "^1.0",
+ "codeception/module-asserts": "*@dev",
+ "codeception/module-cli": "*@dev",
+ "codeception/module-db": "*@dev",
+ "codeception/module-filesystem": "*@dev",
+ "codeception/module-phpbrowser": "*@dev",
+ "codeception/util-universalframework": "*@dev",
+ "ext-simplexml": "*",
+ "jetbrains/phpstorm-attributes": "^1.0",
+ "symfony/dotenv": ">=4.4.24 <7.0",
+ "symfony/process": ">=4.4.24 <7.0",
+ "vlucas/phpdotenv": "^5.1"
+ },
+ "suggest": {
+ "codeception/specify": "BDD-style code blocks",
+ "codeception/verify": "BDD-style assertions",
+ "ext-simplexml": "For loading params from XML files",
+ "stecman/symfony-console-completion": "For BASH autocompletion",
+ "symfony/dotenv": "For loading params from .env files",
+ "symfony/phpunit-bridge": "For phpunit-bridge support",
+ "vlucas/phpdotenv": "For loading params from .env files"
+ },
+ "bin": [
+ "codecept"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "functions.php"
+ ],
+ "psr-4": {
+ "Codeception\\": "src/Codeception",
+ "Codeception\\Extension\\": "ext"
+ },
+ "classmap": [
+ "src/PHPUnit/TestCase.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Bodnarchuk",
+ "email": "davert.ua@gmail.com",
+ "homepage": "https://codeception.com"
+ }
+ ],
+ "description": "BDD-style testing framework",
+ "homepage": "https://codeception.com/",
+ "keywords": [
+ "BDD",
+ "TDD",
+ "acceptance testing",
+ "functional testing",
+ "unit testing"
+ ],
+ "support": {
+ "issues": "https://github.com/Codeception/Codeception/issues",
+ "source": "https://github.com/Codeception/Codeception/tree/5.0.12"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/codeception",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2023-10-15T18:04:50+00:00"
+ },
+ {
+ "name": "codeception/lib-asserts",
+ "version": "2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/lib-asserts.git",
+ "reference": "b8c7dff552249e560879c682ba44a4b963af91bc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/lib-asserts/zipball/b8c7dff552249e560879c682ba44a4b963af91bc",
+ "reference": "b8c7dff552249e560879c682ba44a4b963af91bc",
+ "shasum": ""
+ },
+ "require": {
+ "codeception/phpunit-wrapper": "^7.7.1 | ^8.0.3 | ^9.0",
+ "ext-dom": "*",
+ "php": "^7.4 | ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Bodnarchuk",
+ "email": "davert@mail.ua",
+ "homepage": "http://codegyre.com"
+ },
+ {
+ "name": "Gintautas Miselis"
+ },
+ {
+ "name": "Gustavo Nieves",
+ "homepage": "https://medium.com/@ganieves"
+ }
+ ],
+ "description": "Assertion methods used by Codeception core and Asserts module",
+ "homepage": "https://codeception.com/",
+ "keywords": [
+ "codeception"
+ ],
+ "support": {
+ "issues": "https://github.com/Codeception/lib-asserts/issues",
+ "source": "https://github.com/Codeception/lib-asserts/tree/2.1.0"
+ },
+ "time": "2023-02-10T18:36:23+00:00"
+ },
+ {
+ "name": "codeception/lib-innerbrowser",
+ "version": "3.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/lib-innerbrowser.git",
+ "reference": "10482f7e34c0537bf5b87bc82a3d65a1842a8b4f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/lib-innerbrowser/zipball/10482f7e34c0537bf5b87bc82a3d65a1842a8b4f",
+ "reference": "10482f7e34c0537bf5b87bc82a3d65a1842a8b4f",
+ "shasum": ""
+ },
+ "require": {
+ "codeception/codeception": "^5.0",
+ "codeception/lib-web": "^1.0.1",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "php": "^8.0",
+ "phpunit/phpunit": "^9.5",
+ "symfony/browser-kit": "^4.4.24 || ^5.4 || ^6.0",
+ "symfony/dom-crawler": "^4.4.30 || ^5.4 || ^6.0"
+ },
+ "require-dev": {
+ "codeception/util-universalframework": "dev-master"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Bodnarchuk",
+ "email": "davert@mail.ua",
+ "homepage": "https://codegyre.com"
+ },
+ {
+ "name": "Gintautas Miselis"
+ }
+ ],
+ "description": "Parent library for all Codeception framework modules and PhpBrowser",
+ "homepage": "https://codeception.com/",
+ "keywords": [
+ "codeception"
+ ],
+ "support": {
+ "issues": "https://github.com/Codeception/lib-innerbrowser/issues",
+ "source": "https://github.com/Codeception/lib-innerbrowser/tree/3.1.3"
+ },
+ "time": "2022-10-03T15:33:34+00:00"
+ },
+ {
+ "name": "codeception/lib-web",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/lib-web.git",
+ "reference": "f488ff9bc08c8985d43796db28da0bd18813bcae"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/lib-web/zipball/f488ff9bc08c8985d43796db28da0bd18813bcae",
+ "reference": "f488ff9bc08c8985d43796db28da0bd18813bcae",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "guzzlehttp/psr7": "^2.0",
+ "php": "^8.0",
+ "symfony/css-selector": ">=4.4.24 <7.0"
+ },
+ "conflict": {
+ "codeception/codeception": "<5.0.0-alpha3"
+ },
+ "require-dev": {
+ "php-webdriver/webdriver": "^1.12",
+ "phpunit/phpunit": "^9.5 | ^10.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gintautas Miselis"
+ }
+ ],
+ "description": "Library containing files used by module-webdriver and lib-innerbrowser or module-phpbrowser",
+ "homepage": "https://codeception.com/",
+ "keywords": [
+ "codeception"
+ ],
+ "support": {
+ "issues": "https://github.com/Codeception/lib-web/issues",
+ "source": "https://github.com/Codeception/lib-web/tree/1.0.2"
+ },
+ "time": "2023-04-18T20:32:51+00:00"
+ },
+ {
+ "name": "codeception/module-asserts",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/module-asserts.git",
+ "reference": "1b6b150b30586c3614e7e5761b31834ed7968603"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/module-asserts/zipball/1b6b150b30586c3614e7e5761b31834ed7968603",
+ "reference": "1b6b150b30586c3614e7e5761b31834ed7968603",
+ "shasum": ""
+ },
+ "require": {
+ "codeception/codeception": "*@dev",
+ "codeception/lib-asserts": "^2.0",
+ "php": "^8.0"
+ },
+ "conflict": {
+ "codeception/codeception": "<5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Bodnarchuk"
+ },
+ {
+ "name": "Gintautas Miselis"
+ },
+ {
+ "name": "Gustavo Nieves",
+ "homepage": "https://medium.com/@ganieves"
+ }
+ ],
+ "description": "Codeception module containing various assertions",
+ "homepage": "https://codeception.com/",
+ "keywords": [
+ "assertions",
+ "asserts",
+ "codeception"
+ ],
+ "support": {
+ "issues": "https://github.com/Codeception/module-asserts/issues",
+ "source": "https://github.com/Codeception/module-asserts/tree/3.0.0"
+ },
+ "time": "2022-02-16T19:48:08+00:00"
+ },
+ {
+ "name": "codeception/module-filesystem",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/module-filesystem.git",
+ "reference": "326ef1c1edf90f52ceec2965ff240a8d93c1ba63"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/module-filesystem/zipball/326ef1c1edf90f52ceec2965ff240a8d93c1ba63",
+ "reference": "326ef1c1edf90f52ceec2965ff240a8d93c1ba63",
+ "shasum": ""
+ },
+ "require": {
+ "codeception/codeception": "*@dev",
+ "php": "^8.0",
+ "symfony/finder": "^4.4 || ^5.4 || ^6.0"
+ },
+ "conflict": {
+ "codeception/codeception": "<5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Bodnarchuk"
+ },
+ {
+ "name": "Gintautas Miselis"
+ }
+ ],
+ "description": "Codeception module for testing local filesystem",
+ "homepage": "https://codeception.com/",
+ "keywords": [
+ "codeception",
+ "filesystem"
+ ],
+ "support": {
+ "issues": "https://github.com/Codeception/module-filesystem/issues",
+ "source": "https://github.com/Codeception/module-filesystem/tree/3.0.0"
+ },
+ "time": "2022-03-14T18:48:55+00:00"
+ },
+ {
+ "name": "codeception/module-yii2",
+ "version": "1.1.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/module-yii2.git",
+ "reference": "70ad7544fc256363acd082b4ef9e7220a18017a0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/module-yii2/zipball/70ad7544fc256363acd082b4ef9e7220a18017a0",
+ "reference": "70ad7544fc256363acd082b4ef9e7220a18017a0",
+ "shasum": ""
+ },
+ "require": {
+ "codeception/codeception": "^5.0.8",
+ "codeception/lib-innerbrowser": "^3.0 | ^4.0",
+ "php": "^8.0"
+ },
+ "require-dev": {
+ "codeception/module-asserts": "^3.0",
+ "codeception/module-filesystem": "^3.0",
+ "codeception/verify": "^3.0",
+ "codemix/yii2-localeurls": "^1.7",
+ "yiisoft/yii2": "dev-master",
+ "yiisoft/yii2-app-advanced": "dev-master"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Alexander Makarov"
+ },
+ {
+ "name": "Sam Mouse"
+ },
+ {
+ "name": "Michael Bodnarchuk"
+ }
+ ],
+ "description": "Codeception module for Yii2 framework",
+ "homepage": "https://codeception.com/",
+ "keywords": [
+ "codeception",
+ "yii2"
+ ],
+ "support": {
+ "issues": "https://github.com/Codeception/module-yii2/issues",
+ "source": "https://github.com/Codeception/module-yii2/tree/1.1.9"
+ },
+ "time": "2023-06-16T03:48:50+00:00"
+ },
+ {
+ "name": "codeception/stub",
+ "version": "4.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/Stub.git",
+ "reference": "f6bc56e33e3f5ba7a831dfb968c49b27cf1676ad"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/Stub/zipball/f6bc56e33e3f5ba7a831dfb968c49b27cf1676ad",
+ "reference": "f6bc56e33e3f5ba7a831dfb968c49b27cf1676ad",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 | ^8.0",
+ "phpunit/phpunit": "^8.4 | ^9.0 | ^10.0 | 10.0.x-dev"
+ },
+ "conflict": {
+ "codeception/codeception": "<5.0.6"
+ },
+ "require-dev": {
+ "consolidation/robo": "^3.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Codeception\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Flexible Stub wrapper for PHPUnit's Mock Builder",
+ "support": {
+ "issues": "https://github.com/Codeception/Stub/issues",
+ "source": "https://github.com/Codeception/Stub/tree/4.1.2"
+ },
+ "time": "2023-10-07T19:22:36+00:00"
+ },
+ {
+ "name": "codeception/verify",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/Verify.git",
+ "reference": "25b84a96f0fe7dcf28e8021f02b57643b751a707"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/Verify/zipball/25b84a96f0fe7dcf28e8021f02b57643b751a707",
+ "reference": "25b84a96f0fe7dcf28e8021f02b57643b751a707",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "php": "^7.4 || ^8.0",
+ "phpunit/phpunit": "^9.5 | ^10.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/Codeception/bootstrap.php"
+ ],
+ "psr-4": {
+ "Codeception\\": "src\\Codeception"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Bodnarchuk",
+ "email": "davert@codeception.com"
+ },
+ {
+ "name": "Gustavo Nieves",
+ "homepage": "https://medium.com/@ganieves"
+ }
+ ],
+ "description": "BDD assertion library for PHPUnit",
+ "support": {
+ "issues": "https://github.com/Codeception/Verify/issues",
+ "source": "https://github.com/Codeception/Verify/tree/3.0.0"
+ },
+ "time": "2023-02-09T07:33:00+00:00"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "2.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
+ "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^8.1"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^11",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpbench/phpbench": "^1.2",
+ "phpstan/phpstan": "^1.9.4",
+ "phpstan/phpstan-phpunit": "^1.3",
+ "phpunit/phpunit": "^9.5.27",
+ "vimeo/psalm": "^5.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "https://ocramius.github.io/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/2.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-30T00:23:10+00:00"
+ },
+ {
+ "name": "fakerphp/faker",
+ "version": "v1.23.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/FakerPHP/Faker.git",
+ "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e3daa170d00fde61ea7719ef47bb09bb8f1d9b01",
+ "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0",
+ "psr/container": "^1.0 || ^2.0",
+ "symfony/deprecation-contracts": "^2.2 || ^3.0"
+ },
+ "conflict": {
+ "fzaninotto/faker": "*"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.4.1",
+ "doctrine/persistence": "^1.3 || ^2.0",
+ "ext-intl": "*",
+ "phpunit/phpunit": "^9.5.26",
+ "symfony/phpunit-bridge": "^5.4.16"
+ },
+ "suggest": {
+ "doctrine/orm": "Required to use Faker\\ORM\\Doctrine",
+ "ext-curl": "Required by Faker\\Provider\\Image to download images.",
+ "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
+ "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
+ "ext-mbstring": "Required for multibyte Unicode string functionality."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "v1.21-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"
+ ],
+ "support": {
+ "issues": "https://github.com/FakerPHP/Faker/issues",
+ "source": "https://github.com/FakerPHP/Faker/tree/v1.23.0"
+ },
+ "time": "2023-06-12T08:44:38+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "2.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/be45764272e8873c72dbe3d2edcfdfcc3bc9f727",
+ "reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2.5 || ^8.0",
+ "psr/http-factory": "^1.0",
+ "psr/http-message": "^1.1 || ^2.0",
+ "ralouphie/getallheaders": "^3.0"
+ },
+ "provide": {
+ "psr/http-factory-implementation": "1.0",
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.8.1",
+ "http-interop/http-factory-tests": "^0.9",
+ "phpunit/phpunit": "^8.5.29 || ^9.5.23"
+ },
+ "suggest": {
+ "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
+ },
+ "type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": false
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Graham Campbell",
+ "email": "hello@gjcampbell.co.uk",
+ "homepage": "https://github.com/GrahamCampbell"
+ },
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "George Mponos",
+ "email": "gmponos@gmail.com",
+ "homepage": "https://github.com/gmponos"
+ },
+ {
+ "name": "Tobias Nyholm",
+ "email": "tobias.nyholm@gmail.com",
+ "homepage": "https://github.com/Nyholm"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://github.com/sagikazarmark"
+ },
+ {
+ "name": "Tobias Schultze",
+ "email": "webmaster@tubo-world.de",
+ "homepage": "https://github.com/Tobion"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://sagikazarmark.hu"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "psr-7",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/psr7/issues",
+ "source": "https://github.com/guzzle/psr7/tree/2.6.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-08-27T10:13:57+00:00"
+ },
+ {
+ "name": "masterminds/html5",
+ "version": "2.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Masterminds/html5-php.git",
+ "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf",
+ "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Masterminds\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matt Butcher",
+ "email": "technosophos@gmail.com"
+ },
+ {
+ "name": "Matt Farina",
+ "email": "matt@mattfarina.com"
+ },
+ {
+ "name": "Asmir Mustafic",
+ "email": "goetas@gmail.com"
+ }
+ ],
+ "description": "An HTML5 parser and serializer.",
+ "homepage": "http://masterminds.github.io/html5-php",
+ "keywords": [
+ "HTML5",
+ "dom",
+ "html",
+ "parser",
+ "querypath",
+ "serializer",
+ "xml"
+ ],
+ "support": {
+ "issues": "https://github.com/Masterminds/html5-php/issues",
+ "source": "https://github.com/Masterminds/html5-php/tree/2.8.1"
+ },
+ "time": "2023-05-10T11:58:31+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.11.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/collections": "<1.6.8",
+ "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.6.8",
+ "doctrine/common": "^2.13.3 || ^3.2.2",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ],
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "support": {
+ "issues": "https://github.com/myclabs/DeepCopy/issues",
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-08T13:26:56+00:00"
+ },
+ {
+ "name": "nikic/php-parser",
+ "version": "v4.17.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
+ "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Nikita Popov"
+ }
+ ],
+ "description": "A PHP parser written in PHP",
+ "keywords": [
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
+ },
+ "time": "2023-08-13T19:53:39+00:00"
+ },
+ {
+ "name": "phar-io/manifest",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
+ "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-phar": "*",
+ "ext-xmlwriter": "*",
+ "phar-io/version": "^3.0.1",
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "support": {
+ "issues": "https://github.com/phar-io/manifest/issues",
+ "source": "https://github.com/phar-io/manifest/tree/2.0.3"
+ },
+ "time": "2021-07-20T11:28:43+00:00"
+ },
+ {
+ "name": "phar-io/version",
+ "version": "3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/version.git",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Library for handling version information and constraints",
+ "support": {
+ "issues": "https://github.com/phar-io/version/issues",
+ "source": "https://github.com/phar-io/version/tree/3.2.1"
+ },
+ "time": "2022-02-21T01:04:05+00:00"
+ },
+ {
+ "name": "phpspec/php-diff",
+ "version": "v1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpspec/php-diff.git",
+ "reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpspec/php-diff/zipball/fc1156187f9f6c8395886fe85ed88a0a245d72e9",
+ "reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9",
+ "shasum": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Diff": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Chris Boulton",
+ "homepage": "http://github.com/chrisboulton"
+ }
+ ],
+ "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
+ "support": {
+ "source": "https://github.com/phpspec/php-diff/tree/v1.1.3"
+ },
+ "time": "2020-09-18T13:47:07+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "9.2.29",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76",
+ "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-xmlwriter": "*",
+ "nikic/php-parser": "^4.15",
+ "php": ">=7.3",
+ "phpunit/php-file-iterator": "^3.0.3",
+ "phpunit/php-text-template": "^2.0.2",
+ "sebastian/code-unit-reverse-lookup": "^2.0.2",
+ "sebastian/complexity": "^2.0",
+ "sebastian/environment": "^5.1.2",
+ "sebastian/lines-of-code": "^1.0.3",
+ "sebastian/version": "^3.0.1",
+ "theseer/tokenizer": "^1.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-pcov": "PHP extension that provides line coverage",
+ "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "9.2-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-09-19T04:57:46+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "3.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-12-02T12:48:52+00:00"
+ },
+ {
+ "name": "phpunit/php-invoker",
+ "version": "3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-invoker.git",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "ext-pcntl": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-pcntl": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Invoke callables with a timeout",
+ "homepage": "https://github.com/sebastianbergmann/php-invoker/",
+ "keywords": [
+ "process"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
+ "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T05:58:55+00:00"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T05:33:50+00:00"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "5.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:16:10+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "9.5.28",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "954ca3113a03bf780d22f07bf055d883ee04b65e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/954ca3113a03bf780d22f07bf055d883ee04b65e",
+ "reference": "954ca3113a03bf780d22f07bf055d883ee04b65e",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.3.1 || ^2",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-xmlwriter": "*",
+ "myclabs/deep-copy": "^1.10.1",
+ "phar-io/manifest": "^2.0.3",
+ "phar-io/version": "^3.0.2",
+ "php": ">=7.3",
+ "phpunit/php-code-coverage": "^9.2.13",
+ "phpunit/php-file-iterator": "^3.0.5",
+ "phpunit/php-invoker": "^3.1.1",
+ "phpunit/php-text-template": "^2.0.3",
+ "phpunit/php-timer": "^5.0.2",
+ "sebastian/cli-parser": "^1.0.1",
+ "sebastian/code-unit": "^1.0.6",
+ "sebastian/comparator": "^4.0.8",
+ "sebastian/diff": "^4.0.3",
+ "sebastian/environment": "^5.1.3",
+ "sebastian/exporter": "^4.0.5",
+ "sebastian/global-state": "^5.0.1",
+ "sebastian/object-enumerator": "^4.0.3",
+ "sebastian/resource-operations": "^3.0.3",
+ "sebastian/type": "^3.2",
+ "sebastian/version": "^3.0.2"
+ },
+ "suggest": {
+ "ext-soap": "*",
+ "ext-xdebug": "*"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "9.5-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/Framework/Assert/Functions.php"
+ ],
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.28"
+ },
+ "funding": [
+ {
+ "url": "https://phpunit.de/sponsors.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-01-14T12:32:24+00:00"
+ },
+ {
+ "name": "psr/http-factory",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-factory.git",
+ "reference": "e616d01114759c4c489f93b099585439f795fe35"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35",
+ "reference": "e616d01114759c4c489f93b099585439f795fe35",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.0.0",
+ "psr/http-message": "^1.0 || ^2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for PSR-7 HTTP message factories",
+ "keywords": [
+ "factory",
+ "http",
+ "message",
+ "psr",
+ "psr-17",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-factory/tree/1.0.2"
+ },
+ "time": "2023-04-10T20:10:41+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
+ "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/2.0"
+ },
+ "time": "2023-04-04T09:54:51+00:00"
+ },
+ {
+ "name": "psy/psysh",
+ "version": "v0.11.22",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/bobthecow/psysh.git",
+ "reference": "128fa1b608be651999ed9789c95e6e2a31b5802b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/bobthecow/psysh/zipball/128fa1b608be651999ed9789c95e6e2a31b5802b",
+ "reference": "128fa1b608be651999ed9789c95e6e2a31b5802b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "nikic/php-parser": "^4.0 || ^3.1",
+ "php": "^8.0 || ^7.0.8",
+ "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4",
+ "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4"
+ },
+ "conflict": {
+ "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.2"
+ },
+ "suggest": {
+ "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)",
+ "ext-pdo-sqlite": "The doc command requires SQLite to work.",
+ "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.",
+ "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history."
+ },
+ "bin": [
+ "bin/psysh"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-0.11": "0.11.x-dev"
+ },
+ "bamarni-bin": {
+ "bin-links": false,
+ "forward-command": false
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "Psy\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Justin Hileman",
+ "email": "justin@justinhileman.info",
+ "homepage": "http://justinhileman.com"
+ }
+ ],
+ "description": "An interactive shell for modern PHP.",
+ "homepage": "http://psysh.org",
+ "keywords": [
+ "REPL",
+ "console",
+ "interactive",
+ "shell"
+ ],
+ "support": {
+ "issues": "https://github.com/bobthecow/psysh/issues",
+ "source": "https://github.com/bobthecow/psysh/tree/v0.11.22"
+ },
+ "time": "2023-10-14T21:56:36+00:00"
+ },
+ {
+ "name": "ralouphie/getallheaders",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ralouphie/getallheaders.git",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5 || ^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/getallheaders.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
+ }
+ ],
+ "description": "A polyfill for getallheaders.",
+ "support": {
+ "issues": "https://github.com/ralouphie/getallheaders/issues",
+ "source": "https://github.com/ralouphie/getallheaders/tree/develop"
+ },
+ "time": "2019-03-08T08:55:37+00:00"
+ },
+ {
+ "name": "sebastian/cli-parser",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/cli-parser.git",
+ "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+ "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for parsing CLI options",
+ "homepage": "https://github.com/sebastianbergmann/cli-parser",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:08:49+00:00"
+ },
+ {
+ "name": "sebastian/code-unit",
+ "version": "1.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit.git",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Collection of value objects that represent the PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/code-unit",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:08:54+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T05:30:19+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "4.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "fa0f136dd2334583309d32b62544682ee972b51a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a",
+ "reference": "fa0f136dd2334583309d32b62544682ee972b51a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/diff": "^4.0",
+ "sebastian/exporter": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-09-14T12:41:17+00:00"
+ },
+ {
+ "name": "sebastian/complexity",
+ "version": "2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/complexity.git",
+ "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
+ "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.7",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for calculating the complexity of PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/complexity",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/complexity/issues",
+ "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T15:52:27+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "4.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
+ "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3",
+ "symfony/process": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-05-07T05:35:17+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "5.1.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
+ "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-posix": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:03:51+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "4.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
+ "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "https://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/exporter/issues",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-09-14T06:03:37+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "5.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "bde739e7565280bda77be70044ac1047bc007e34"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34",
+ "reference": "bde739e7565280bda77be70044ac1047bc007e34",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "ext-dom": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-08-02T09:26:13+00:00"
+ },
+ {
+ "name": "sebastian/lines-of-code",
+ "version": "1.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+ "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
+ "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.6",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for counting the lines of code in PHP source code",
+ "homepage": "https://github.com/sebastianbergmann/lines-of-code",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-28T06:42:11+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "4.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:12:34+00:00"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:14:26+00:00"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "4.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+ "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "https://github.com/sebastianbergmann/recursion-context",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:07:39+00:00"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+ "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:45:17+00:00"
+ },
+ {
+ "name": "sebastian/type",
+ "version": "3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/type.git",
+ "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
+ "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.2-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Collection of value objects that represent the types of the PHP type system",
+ "homepage": "https://github.com/sebastianbergmann/type",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/type/issues",
+ "source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:13:03+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:39:44+00:00"
+ },
+ {
+ "name": "symfony/browser-kit",
+ "version": "v6.3.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/browser-kit.git",
+ "reference": "e270297dbee59168274c2b535ab1bccd593e6ffe"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/e270297dbee59168274c2b535ab1bccd593e6ffe",
+ "reference": "e270297dbee59168274c2b535ab1bccd593e6ffe",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/dom-crawler": "^5.4|^6.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "^5.4|^6.0",
+ "symfony/http-client": "^5.4|^6.0",
+ "symfony/mime": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\BrowserKit\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/browser-kit/tree/v6.3.8"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-10-31T08:07:48+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v6.3.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/0d14a9f6d04d4ac38a8cea1171f4554e325dae92",
+ "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/string": "^5.4|^6.0"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<5.4",
+ "symfony/dotenv": "<5.4",
+ "symfony/event-dispatcher": "<5.4",
+ "symfony/lock": "<5.4",
+ "symfony/process": "<5.4"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/event-dispatcher": "^5.4|^6.0",
+ "symfony/lock": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases the creation of beautiful and testable command line interfaces",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "cli",
+ "command-line",
+ "console",
+ "terminal"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v6.3.8"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-10-31T08:09:35+00:00"
+ },
+ {
+ "name": "symfony/css-selector",
+ "version": "v6.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "883d961421ab1709877c10ac99451632a3d6fa57"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/883d961421ab1709877c10ac99451632a3d6fa57",
+ "reference": "883d961421ab1709877c10ac99451632a3d6fa57",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\CssSelector\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Jean-François Simon",
+ "email": "jeanfrancois.simon@sensiolabs.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Converts CSS selectors to XPath expressions",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/css-selector/tree/v6.3.2"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-07-12T16:00:22+00:00"
+ },
+ {
+ "name": "symfony/dom-crawler",
+ "version": "v6.3.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "3fdd2a3d5fdc363b2e8dbf817f9726a4d013cbd1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/3fdd2a3d5fdc363b2e8dbf817f9726a4d013cbd1",
+ "reference": "3fdd2a3d5fdc363b2e8dbf817f9726a4d013cbd1",
+ "shasum": ""
+ },
+ "require": {
+ "masterminds/html5": "^2.6",
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\DomCrawler\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases DOM navigation for HTML and XML documents",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/dom-crawler/tree/v6.3.4"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-08-01T07:43:40+00:00"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v6.3.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4",
+ "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "symfony/filesystem": "^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Finder\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Finds files and directories via an intuitive fluent interface",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/finder/tree/v6.3.5"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-09-26T12:56:25+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.28.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
+ "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-ctype": "*"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-01-26T09:26:14+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.28.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "875e90aeea2777b6f135677f618529449334a612"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612",
+ "reference": "875e90aeea2777b6f135677f618529449334a612",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's grapheme_* functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "grapheme",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-01-26T09:26:14+00:00"
+ },
+ {
+ "name": "symfony/string",
+ "version": "v6.3.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "13880a87790c76ef994c91e87efb96134522577a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/13880a87790c76ef994c91e87efb96134522577a",
+ "reference": "13880a87790c76ef994c91e87efb96134522577a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-normalizer": "~1.0",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/translation-contracts": "<2.5"
+ },
+ "require-dev": {
+ "symfony/error-handler": "^5.4|^6.0",
+ "symfony/http-client": "^5.4|^6.0",
+ "symfony/intl": "^6.2",
+ "symfony/translation-contracts": "^2.5|^3.0",
+ "symfony/var-exporter": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\String\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v6.3.8"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-11-09T08:28:21+00:00"
+ },
+ {
+ "name": "symfony/var-dumper",
+ "version": "v6.3.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "81acabba9046550e89634876ca64bfcd3c06aa0a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/81acabba9046550e89634876ca64bfcd3c06aa0a",
+ "reference": "81acabba9046550e89634876ca64bfcd3c06aa0a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-mbstring": "~1.0"
+ },
+ "conflict": {
+ "symfony/console": "<5.4"
+ },
+ "require-dev": {
+ "ext-iconv": "*",
+ "symfony/console": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0",
+ "symfony/uid": "^5.4|^6.0",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "bin": [
+ "Resources/bin/var-dump-server"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions/dump.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\VarDumper\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides mechanisms for walking through any arbitrary PHP variable",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "debug",
+ "dump"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-dumper/tree/v6.3.8"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-11-08T10:42:36+00:00"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v6.3.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/3493af8a8dad7fa91c77fa473ba23ecd95334a92",
+ "reference": "3493af8a8dad7fa91c77fa473ba23ecd95334a92",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-ctype": "^1.8"
+ },
+ "conflict": {
+ "symfony/console": "<5.4"
+ },
+ "require-dev": {
+ "symfony/console": "^5.4|^6.0"
+ },
+ "bin": [
+ "Resources/bin/yaml-lint"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Loads and dumps YAML files",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/yaml/tree/v6.3.8"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-11-06T10:58:05+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
+ "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "support": {
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2021-07-28T10:34:58+00:00"
+ },
+ {
+ "name": "yiisoft/yii2-debug",
+ "version": "2.1.25",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-debug.git",
+ "reference": "4d011b9bfc83bde71cde43c9f6837f5a74685ea7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/4d011b9bfc83bde71cde43c9f6837f5a74685ea7",
+ "reference": "4d011b9bfc83bde71cde43c9f6837f5a74685ea7",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "php": ">=5.4",
+ "yiisoft/yii2": "~2.0.13"
+ },
+ "require-dev": {
+ "cweagans/composer-patches": "^1.7",
+ "phpunit/phpunit": "4.8.34",
+ "yiisoft/yii2-coding-standards": "~2.0",
+ "yiisoft/yii2-swiftmailer": "*"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ },
+ "composer-exit-on-patch-failure": true,
+ "patches": {
+ "phpunit/phpunit-mock-objects": {
+ "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
+ },
+ "phpunit/phpunit": {
+ "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
+ "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch",
+ "Fix PHP 8.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php81.patch"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "yii\\debug\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Qiang Xue",
+ "email": "qiang.xue@gmail.com"
+ },
+ {
+ "name": "Simon Karlen",
+ "email": "simi.albi@outlook.com"
+ }
+ ],
+ "description": "The debugger extension for the Yii framework",
+ "keywords": [
+ "debug",
+ "debugger",
+ "yii2"
+ ],
+ "support": {
+ "forum": "http://www.yiiframework.com/forum/",
+ "irc": "irc://irc.freenode.net/yii",
+ "issues": "https://github.com/yiisoft/yii2-debug/issues",
+ "source": "https://github.com/yiisoft/yii2-debug",
+ "wiki": "http://www.yiiframework.com/wiki/"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/yiisoft",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/yiisoft",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-debug",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-09-26T15:50:00+00:00"
+ },
+ {
+ "name": "yiisoft/yii2-faker",
+ "version": "2.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-faker.git",
+ "reference": "8c361657143bfaea58ff7dcc9bf51f1991a46f5d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-faker/zipball/8c361657143bfaea58ff7dcc9bf51f1991a46f5d",
+ "reference": "8c361657143bfaea58ff7dcc9bf51f1991a46f5d",
+ "shasum": ""
+ },
+ "require": {
+ "fakerphp/faker": "~1.9|~1.10",
+ "yiisoft/yii2": "~2.0.0"
+ },
+ "require-dev": {
+ "cweagans/composer-patches": "^1.7",
+ "phpunit/phpunit": "4.8.34"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ },
+ "composer-exit-on-patch-failure": true,
+ "patches": {
+ "phpunit/phpunit-mock-objects": {
+ "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
+ },
+ "phpunit/phpunit": {
+ "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
+ "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "yii\\faker\\": "src"
+ }
+ },
+ "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"
+ ],
+ "support": {
+ "forum": "http://www.yiiframework.com/forum/",
+ "irc": "irc://irc.freenode.net/yii",
+ "issues": "https://github.com/yiisoft/yii2-faker/issues",
+ "source": "https://github.com/yiisoft/yii2-faker",
+ "wiki": "http://www.yiiframework.com/wiki/"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/yiisoft",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/yiisoft",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-faker",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-11-10T12:27:35+00:00"
+ },
+ {
+ "name": "yiisoft/yii2-gii",
+ "version": "2.2.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/yiisoft/yii2-gii.git",
+ "reference": "ac574e7e2c29fd865145c8688719f252d19aae23"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/ac574e7e2c29fd865145c8688719f252d19aae23",
+ "reference": "ac574e7e2c29fd865145c8688719f252d19aae23",
+ "shasum": ""
+ },
+ "require": {
+ "phpspec/php-diff": "^1.1.0",
+ "yiisoft/yii2": "~2.0.46"
+ },
+ "require-dev": {
+ "cweagans/composer-patches": "^1.7",
+ "phpunit/phpunit": "4.8.34",
+ "yiisoft/yii2-coding-standards": "~2.0"
+ },
+ "type": "yii2-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ },
+ "composer-exit-on-patch-failure": true,
+ "patches": {
+ "phpunit/phpunit-mock-objects": {
+ "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
+ },
+ "phpunit/php-file-iterator": {
+ "Fix PHP 8.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_path_file_iterator.patch"
+ },
+ "phpunit/phpunit": {
+ "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
+ "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch",
+ "Fix PHP 8.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php81.patch"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "yii\\gii\\": "src"
+ }
+ },
+ "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"
+ ],
+ "support": {
+ "forum": "https://www.yiiframework.com/forum/",
+ "irc": "irc://irc.freenode.net/yii",
+ "issues": "https://github.com/yiisoft/yii2-gii/issues",
+ "source": "https://github.com/yiisoft/yii2-gii",
+ "wiki": "https://www.yiiframework.com/wiki/"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/yiisoft",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/yiisoft",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-gii",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-05-22T20:55:37+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": {
+ "kartik-v/yii2-widgets": 20
+ },
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=7.4.0"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.3.0"
+}
diff --git a/console/config/.gitignore b/console/config/.gitignore
new file mode 100755
index 0000000..42799dd
--- /dev/null
+++ b/console/config/.gitignore
@@ -0,0 +1,3 @@
+main-local.php
+params-local.php
+test-local.php
diff --git a/console/config/bootstrap.php b/console/config/bootstrap.php
new file mode 100755
index 0000000..b3d9bbc
--- /dev/null
+++ b/console/config/bootstrap.php
@@ -0,0 +1 @@
+ 'app-console',
+ 'basePath' => dirname(__DIR__),
+ 'bootstrap' => ['log'],
+ 'controllerNamespace' => 'console\controllers',
+ 'aliases' => [
+ '@bower' => '@vendor/bower-asset',
+ '@npm' => '@vendor/npm-asset',
+ ],
+ 'controllerMap' => [
+ 'fixture' => [
+ 'class' => \yii\console\controllers\FixtureController::class,
+ 'namespace' => 'common\fixtures',
+ ],
+ ],
+ 'components' => [
+ 'log' => [
+ 'targets' => [
+ [
+ 'class' => \yii\log\FileTarget::class,
+ 'levels' => ['error', 'warning'],
+ ],
+ ],
+ ],
+ ],
+ 'params' => $params,
+];
diff --git a/console/config/params.php b/console/config/params.php
new file mode 100755
index 0000000..6ebf279
--- /dev/null
+++ b/console/config/params.php
@@ -0,0 +1,5 @@
+ 'admin@example.com',
+];
diff --git a/console/config/test.php b/console/config/test.php
new file mode 100755
index 0000000..b625128
--- /dev/null
+++ b/console/config/test.php
@@ -0,0 +1,4 @@
+db->driverName === 'mysql') {
+ // https://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/migrations/m190124_110200_add_verification_token_column_to_user_table.php b/console/migrations/m190124_110200_add_verification_token_column_to_user_table.php
new file mode 100755
index 0000000..4a20dc7
--- /dev/null
+++ b/console/migrations/m190124_110200_add_verification_token_column_to_user_table.php
@@ -0,0 +1,16 @@
+addColumn('{{%user}}', 'verification_token', $this->string()->defaultValue(null));
+ }
+
+ public function down()
+ {
+ $this->dropColumn('{{%user}}', 'verification_token');
+ }
+}
diff --git a/console/migrations/m231012_102457_create_table_table.php b/console/migrations/m231012_102457_create_table_table.php
new file mode 100755
index 0000000..2e8e031
--- /dev/null
+++ b/console/migrations/m231012_102457_create_table_table.php
@@ -0,0 +1,31 @@
+createTable('{{%table}}', [
+ 'id' => $this->primaryKey(),
+ 'name' => $this->string(),
+ 'places' => $this->integer(),
+ 'type' => $this->string(),
+ 'slug' => $this->string()
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropTable('{{%table}}');
+ }
+}
diff --git a/console/migrations/m231012_102916_create_product_table.php b/console/migrations/m231012_102916_create_product_table.php
new file mode 100755
index 0000000..bdd8cc2
--- /dev/null
+++ b/console/migrations/m231012_102916_create_product_table.php
@@ -0,0 +1,35 @@
+createTable('{{%product}}', [
+ 'id' => $this->primaryKey(),
+ 'type' => $this->tinyInteger(),
+ 'name' => $this->string(),
+ 'description' => $this->string(),
+ 'price' => $this->float(),
+ 'status' => $this->tinyInteger(),
+ 'quantity' => $this->integer(),
+ 'taste' => $this->string(),
+ 'strength' => $this->tinyInteger()
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropTable('{{%product}}');
+ }
+}
diff --git a/console/migrations/m231017_091537_create_category_table.php b/console/migrations/m231017_091537_create_category_table.php
new file mode 100755
index 0000000..6bb3eca
--- /dev/null
+++ b/console/migrations/m231017_091537_create_category_table.php
@@ -0,0 +1,31 @@
+createTable('{{%category}}', [
+ 'id' => $this->primaryKey(),
+ 'name' => $this->string(),
+ 'description' => $this->string(),
+ 'slug' => $this->string(),
+ ]);
+
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropTable('{{%category}}');
+ }
+}
diff --git a/console/migrations/m231017_112159_add_category_id_column_to_product_table.php b/console/migrations/m231017_112159_add_category_id_column_to_product_table.php
new file mode 100755
index 0000000..9ed3f48
--- /dev/null
+++ b/console/migrations/m231017_112159_add_category_id_column_to_product_table.php
@@ -0,0 +1,50 @@
+addColumn('product', 'category_id', $this->integer());
+
+ $this->createIndex(
+ 'idx-product-category_id',
+ 'product',
+ 'category_id'
+ );
+
+ $this->addForeignKey(
+ 'fk-product-category_id',
+ 'product',
+ 'category_id',
+ 'category',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropForeignKey(
+ 'fk-product-category_id',
+ 'product'
+ );
+
+ $this->dropIndex(
+ 'idx-product-category_id',
+ 'product'
+ );
+
+ $this->dropColumn('product', 'category_id');
+ }
+}
diff --git a/console/migrations/m231019_110637_create_order_table.php b/console/migrations/m231019_110637_create_order_table.php
new file mode 100755
index 0000000..bd4f262
--- /dev/null
+++ b/console/migrations/m231019_110637_create_order_table.php
@@ -0,0 +1,68 @@
+createTable('{{%order}}', [
+ 'id' => $this->primaryKey(),
+ 'user_id' => $this->integer(),
+ 'table_id' => $this->integer(),
+ 'strength' => $this->tinyInteger(),
+ 'amount' => $this->float(),
+ 'status' => $this->tinyInteger(),
+ 'created_at' => $this->timestamp(),
+ 'updated_at' => $this->timestamp(),
+ ]);
+
+ $this->createIndex(
+ 'idx-order-user_id',
+ 'order',
+ 'user_id'
+ );
+
+ $this->addForeignKey(
+ 'fk-order-user_id',
+ 'order',
+ 'user_id',
+ 'user',
+ 'id',
+ 'CASCADE'
+ );
+
+ $this->createIndex(
+ 'idx-order-table_id',
+ 'order',
+ 'table_id'
+ );
+
+ $this->addForeignKey(
+ 'fk-order-table_id',
+ 'order',
+ 'table_id',
+ 'table',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropForeignKey('fk-order-user_id', 'order');
+ $this->dropIndex('idx-order-user_id', 'order');
+ $this->dropForeignKey('fk-order-table_id', 'order');
+ $this->dropIndex('idx-order-table_id', 'order');
+ $this->dropTable('{{%order}}');
+ }
+}
diff --git a/console/migrations/m231019_123857_create_order_product_table.php b/console/migrations/m231019_123857_create_order_product_table.php
new file mode 100755
index 0000000..da41e79
--- /dev/null
+++ b/console/migrations/m231019_123857_create_order_product_table.php
@@ -0,0 +1,63 @@
+createTable('{{%order_product}}', [
+ 'id' => $this->primaryKey(),
+ 'order_id' => $this->integer(),
+ 'product_id' => $this->integer()
+ ]);
+
+ $this->createIndex(
+ 'idx-order_product-order_id',
+ 'order_product',
+ 'order_id'
+ );
+
+ $this->addForeignKey(
+ 'fk-order_product-order_id',
+ 'order_product',
+ 'order_id',
+ 'order',
+ 'id',
+ 'CASCADE'
+ );
+
+ $this->createIndex(
+ 'idx-order_product-product_id',
+ 'order_product',
+ 'product_id'
+ );
+
+ $this->addForeignKey(
+ 'fk-order_product-product_id',
+ 'order_product',
+ 'product_id',
+ 'product',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropForeignKey('fk-order_product-order_id', 'order_product');
+ $this->dropIndex('idx-order_product-order_id', 'order_product');
+ $this->dropForeignKey('fk-order_product-product_id', 'order_product');
+ $this->dropIndex('idx-order_product-product_id', 'order_product');
+ $this->dropTable('{{%order_product}}');
+ }
+}
diff --git a/console/migrations/m231023_142702_create_banner_table.php b/console/migrations/m231023_142702_create_banner_table.php
new file mode 100755
index 0000000..2595638
--- /dev/null
+++ b/console/migrations/m231023_142702_create_banner_table.php
@@ -0,0 +1,29 @@
+createTable('{{%banner}}', [
+ 'id' => $this->primaryKey(),
+ 'photo' => $this->string(),
+ 'rating' => $this->integer(),
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropTable('{{%banner}}');
+ }
+}
diff --git a/console/migrations/m231025_085405_add_photo_column_to_product_table.php b/console/migrations/m231025_085405_add_photo_column_to_product_table.php
new file mode 100755
index 0000000..3f969f6
--- /dev/null
+++ b/console/migrations/m231025_085405_add_photo_column_to_product_table.php
@@ -0,0 +1,25 @@
+addColumn('product', 'photo', $this->string());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropColumn('product', 'photo');
+ }
+}
diff --git a/console/models/.gitkeep b/console/models/.gitkeep
new file mode 100755
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 100755
index 0000000..c96a04f
--- /dev/null
+++ b/console/runtime/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100755
index 0000000..c8ad750
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,38 @@
+version: '3.2'
+
+services:
+
+ frontend:
+ build: frontend
+ ports:
+ - 20080:80
+ volumes:
+ # Re-use local composer cache via host-volume
+ - ~/.composer-docker/cache:/root/.composer/cache:delegated
+ # Mount source-code for development
+ - ./:/app
+
+ backend:
+ build: backend
+ ports:
+ - 21080:80
+ volumes:
+ # Re-use local composer cache via host-volume
+ - ~/.composer-docker/cache:/root/.composer/cache:delegated
+ # Mount source-code for development
+ - ./:/app
+
+ mysql:
+ image: mysql:5.7
+ environment:
+ - MYSQL_ROOT_PASSWORD=verysecret
+ - MYSQL_DATABASE=yii2advanced
+ - MYSQL_USER=yii2advanced
+ - MYSQL_PASSWORD=secret
+
+ #pgsql:
+ # image: postgres:9.5
+ # environment:
+ # - POSTGRES_DB=yii2advanced
+ # - POSTGRES_USER=yii2advanced
+ # - POSTGRES_PASSWORD=secret
\ No newline at end of file
diff --git a/environments/dev/backend/config/codeception-local.php b/environments/dev/backend/config/codeception-local.php
new file mode 100755
index 0000000..2d875dd
--- /dev/null
+++ b/environments/dev/backend/config/codeception-local.php
@@ -0,0 +1,11 @@
+ [
+ '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::class,
+ ];
+
+ $config['bootstrap'][] = 'gii';
+ $config['modules']['gii'] = [
+ 'class' => \yii\gii\Module::class,
+ ];
+}
+
+return $config;
diff --git a/environments/dev/backend/config/params-local.php b/environments/dev/backend/config/params-local.php
new file mode 100755
index 0000000..b625128
--- /dev/null
+++ b/environments/dev/backend/config/params-local.php
@@ -0,0 +1,4 @@
+run();
diff --git a/environments/dev/backend/web/index.php b/environments/dev/backend/web/index.php
new file mode 100755
index 0000000..d0b6601
--- /dev/null
+++ b/environments/dev/backend/web/index.php
@@ -0,0 +1,18 @@
+run();
diff --git a/environments/dev/backend/web/robots.txt b/environments/dev/backend/web/robots.txt
new file mode 100755
index 0000000..77470cb
--- /dev/null
+++ b/environments/dev/backend/web/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
\ No newline at end of file
diff --git a/environments/dev/common/config/codeception-local.php b/environments/dev/common/config/codeception-local.php
new file mode 100755
index 0000000..654f801
--- /dev/null
+++ b/environments/dev/common/config/codeception-local.php
@@ -0,0 +1,16 @@
+ [
+ 'request' => [
+ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
+ 'cookieValidationKey' => '',
+ ],
+ ],
+ ]
+);
diff --git a/environments/dev/common/config/main-local.php b/environments/dev/common/config/main-local.php
new file mode 100755
index 0000000..d00db3e
--- /dev/null
+++ b/environments/dev/common/config/main-local.php
@@ -0,0 +1,43 @@
+ [
+ 'db' => [
+ 'class' => \yii\db\Connection::class,
+ 'dsn' => 'mysql:host=localhost;dbname=yii2advanced',
+ 'username' => 'root',
+ 'password' => '',
+ 'charset' => 'utf8',
+ ],
+ 'mailer' => [
+ 'class' => \yii\symfonymailer\Mailer::class,
+ 'viewPath' => '@common/mail',
+ // send all mails to a file by default.
+ 'useFileTransport' => true,
+ // You have to set
+ //
+ // 'useFileTransport' => false,
+ //
+ // and configure a transport for the mailer to send real emails.
+ //
+ // SMTP server example:
+ // 'transport' => [
+ // 'scheme' => 'smtps',
+ // 'host' => '',
+ // 'username' => '',
+ // 'password' => '',
+ // 'port' => 465,
+ // 'dsn' => 'native://default',
+ // ],
+ //
+ // DSN example:
+ // 'transport' => [
+ // 'dsn' => 'smtp://user:pass@smtp.example.com:25',
+ // ],
+ //
+ // See: https://symfony.com/doc/current/mailer.html#using-built-in-transports
+ // Or if you use a 3rd party service, see:
+ // https://symfony.com/doc/current/mailer.html#using-a-3rd-party-transport
+ ],
+ ],
+];
diff --git a/environments/dev/common/config/params-local.php b/environments/dev/common/config/params-local.php
new file mode 100755
index 0000000..b625128
--- /dev/null
+++ b/environments/dev/common/config/params-local.php
@@ -0,0 +1,4 @@
+ [
+ 'db' => [
+ 'dsn' => 'mysql:host=localhost;dbname=yii2advanced_test',
+ ],
+ ],
+];
diff --git a/environments/dev/console/config/main-local.php b/environments/dev/console/config/main-local.php
new file mode 100755
index 0000000..a3246e0
--- /dev/null
+++ b/environments/dev/console/config/main-local.php
@@ -0,0 +1,8 @@
+ ['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 100755
index 0000000..b625128
--- /dev/null
+++ b/environments/dev/console/config/params-local.php
@@ -0,0 +1,4 @@
+ [
+ '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::class,
+ ];
+
+ $config['bootstrap'][] = 'gii';
+ $config['modules']['gii'] = [
+ 'class' => \yii\gii\Module::class,
+ ];
+}
+
+return $config;
diff --git a/environments/dev/frontend/config/params-local.php b/environments/dev/frontend/config/params-local.php
new file mode 100755
index 0000000..b625128
--- /dev/null
+++ b/environments/dev/frontend/config/params-local.php
@@ -0,0 +1,4 @@
+run();
diff --git a/environments/dev/frontend/web/index.php b/environments/dev/frontend/web/index.php
new file mode 100755
index 0000000..d0b6601
--- /dev/null
+++ b/environments/dev/frontend/web/index.php
@@ -0,0 +1,18 @@
+run();
diff --git a/environments/dev/frontend/web/robots.txt b/environments/dev/frontend/web/robots.txt
new file mode 100755
index 0000000..77470cb
--- /dev/null
+++ b/environments/dev/frontend/web/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
\ No newline at end of file
diff --git a/environments/dev/yii b/environments/dev/yii
new file mode 100755
index 0000000..b93b5cf
--- /dev/null
+++ b/environments/dev/yii
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+run();
+exit($exitCode);
diff --git a/environments/dev/yii_test b/environments/dev/yii_test
new file mode 100755
index 0000000..63a4e7a
--- /dev/null
+++ b/environments/dev/yii_test
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+run();
+exit($exitCode);
diff --git a/environments/dev/yii_test.bat b/environments/dev/yii_test.bat
new file mode 100755
index 0000000..29fbbea
--- /dev/null
+++ b/environments/dev/yii_test.bat
@@ -0,0 +1,15 @@
+@echo off
+
+rem -------------------------------------------------------------
+rem Yii command line bootstrap script for Windows.
+rem -------------------------------------------------------------
+
+@setlocal
+
+set YII_PATH=%~dp0
+
+if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe
+
+"%PHP_COMMAND%" "%YII_PATH%yii_test" %*
+
+@endlocal
diff --git a/environments/index.php b/environments/index.php
new file mode 100755
index 0000000..1083c32
--- /dev/null
+++ b/environments/index.php
@@ -0,0 +1,68 @@
+ [
+ * 'path' => 'directory storing the local files',
+ * 'skipFiles' => [
+ * // list of files that should only be 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',
+ 'console/runtime',
+ 'frontend/runtime',
+ 'frontend/web/assets',
+ ],
+ 'setExecutable' => [
+ 'yii',
+ 'yii_test',
+ ],
+ 'setCookieValidationKey' => [
+ 'backend/config/main-local.php',
+ 'common/config/codeception-local.php',
+ 'frontend/config/main-local.php',
+ ],
+ ],
+ 'Production' => [
+ 'path' => 'prod',
+ 'setWritable' => [
+ 'backend/runtime',
+ 'backend/web/assets',
+ 'console/runtime',
+ '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 100755
index 0000000..babe4a4
--- /dev/null
+++ b/environments/prod/backend/config/main-local.php
@@ -0,0 +1,10 @@
+ [
+ '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 100755
index 0000000..b625128
--- /dev/null
+++ b/environments/prod/backend/config/params-local.php
@@ -0,0 +1,4 @@
+run();
diff --git a/environments/prod/backend/web/robots.txt b/environments/prod/backend/web/robots.txt
new file mode 100755
index 0000000..77470cb
--- /dev/null
+++ b/environments/prod/backend/web/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
\ No newline at end of file
diff --git a/environments/prod/common/config/main-local.php b/environments/prod/common/config/main-local.php
new file mode 100755
index 0000000..da5a6d3
--- /dev/null
+++ b/environments/prod/common/config/main-local.php
@@ -0,0 +1,17 @@
+ [
+ 'db' => [
+ 'class' => \yii\db\Connection::class,
+ 'dsn' => 'mysql:host=localhost;dbname=yii2advanced',
+ 'username' => 'root',
+ 'password' => '',
+ 'charset' => 'utf8',
+ ],
+ 'mailer' => [
+ 'class' => \yii\symfonymailer\Mailer::class,
+ 'viewPath' => '@common/mail',
+ ],
+ ],
+];
diff --git a/environments/prod/common/config/params-local.php b/environments/prod/common/config/params-local.php
new file mode 100755
index 0000000..b625128
--- /dev/null
+++ b/environments/prod/common/config/params-local.php
@@ -0,0 +1,4 @@
+ [
+ '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 100755
index 0000000..b625128
--- /dev/null
+++ b/environments/prod/frontend/config/params-local.php
@@ -0,0 +1,4 @@
+run();
diff --git a/environments/prod/frontend/web/robots.txt b/environments/prod/frontend/web/robots.txt
new file mode 100755
index 0000000..14267e9
--- /dev/null
+++ b/environments/prod/frontend/web/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Allow: /
\ No newline at end of file
diff --git a/environments/prod/yii b/environments/prod/yii
new file mode 100755
index 0000000..5b0d890
--- /dev/null
+++ b/environments/prod/yii
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+run();
+exit($exitCode);
diff --git a/frontend/Dockerfile b/frontend/Dockerfile
new file mode 100755
index 0000000..a0487d2
--- /dev/null
+++ b/frontend/Dockerfile
@@ -0,0 +1,4 @@
+FROM yiisoftware/yii2-php:8.1-apache
+
+# Change document root for Apache
+RUN sed -i -e 's|/app/web|/app/frontend/web|g' /etc/apache2/sites-available/000-default.conf
diff --git a/frontend/assets/AppAsset.php b/frontend/assets/AppAsset.php
new file mode 100755
index 0000000..f8478f6
--- /dev/null
+++ b/frontend/assets/AppAsset.php
@@ -0,0 +1,23 @@
+ 'app-frontend',
+ 'basePath' => dirname(__DIR__),
+ 'bootstrap' => ['log'],
+ 'controllerNamespace' => 'frontend\controllers',
+ 'components' => [
+ 'request' => [
+ 'csrfParam' => '_csrf-frontend',
+ 'baseUrl' => '',
+ 'enableCsrfValidation' => false
+ ],
+ 'user' => [
+ 'identityClass' => 'common\models\User',
+ 'enableAutoLogin' => true,
+ 'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
+ 'enableSession' => false,
+ ],
+ 'session' => [
+ // this is the name of the session cookie used for login on the frontend
+ 'name' => 'advanced-frontend',
+ ],
+ 'log' => [
+ 'traceLevel' => YII_DEBUG ? 3 : 0,
+ 'targets' => [
+ [
+ 'class' => \yii\log\FileTarget::class,
+ 'levels' => ['error', 'warning'],
+ ],
+ ],
+ ],
+ 'errorHandler' => [
+ 'errorAction' => 'site/error',
+ ],
+ 'urlManager' => [
+ 'enablePrettyUrl' => true,
+ 'showScriptName' => false,
+ 'rules' => [
+ ],
+ ],
+ ],
+ 'params' => $params,
+];
diff --git a/frontend/config/params.php b/frontend/config/params.php
new file mode 100755
index 0000000..7f754b9
--- /dev/null
+++ b/frontend/config/params.php
@@ -0,0 +1,4 @@
+ 'admin@example.com',
+];
diff --git a/frontend/config/test.php b/frontend/config/test.php
new file mode 100755
index 0000000..55d820c
--- /dev/null
+++ b/frontend/config/test.php
@@ -0,0 +1,18 @@
+ 'app-frontend-tests',
+ 'components' => [
+ 'assetManager' => [
+ 'basePath' => __DIR__ . '/../web/assets',
+ ],
+ 'urlManager' => [
+ 'showScriptName' => true,
+ ],
+ 'request' => [
+ 'cookieValidationKey' => 'test',
+ ],
+ 'mailer' => [
+ 'messageClass' => \yii\symfonymailer\Message::class
+ ]
+ ],
+];
diff --git a/frontend/controllers/BaseApiController.php b/frontend/controllers/BaseApiController.php
new file mode 100755
index 0000000..c88dc3e
--- /dev/null
+++ b/frontend/controllers/BaseApiController.php
@@ -0,0 +1,78 @@
+ [
+ 'class' => AccessControl::class,
+ 'only' => ['logout', 'signup'],
+ 'rules' => [
+ [
+ 'actions' => ['signup'],
+ 'allow' => true,
+ 'roles' => ['?'],
+ ],
+ [
+ 'actions' => ['logout'],
+ 'allow' => true,
+ 'roles' => ['@'],
+ ],
+ ],
+ ],
+ 'verbs' => [
+ 'class' => VerbFilter::class,
+ 'actions' => [
+ 'logout' => ['post'],
+ ],
+ ],
+ [
+ 'class' => ContentNegotiator::className(),
+ 'formats' => [
+ 'application/json' => Response::FORMAT_JSON,
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function actions()
+ {
+ return [
+ 'error' => [
+ 'class' => \yii\web\ErrorAction::class,
+ ],
+ 'captcha' => [
+ 'class' => \yii\captcha\CaptchaAction::class,
+ 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
+ ],
+ ];
+ }
+}
diff --git a/frontend/controllers/CategoryController.php b/frontend/controllers/CategoryController.php
new file mode 100755
index 0000000..adabac3
--- /dev/null
+++ b/frontend/controllers/CategoryController.php
@@ -0,0 +1,33 @@
+select(['id', 'name'])
+ ->all();
+ }
+
+ public function actionWithProducts()
+ {
+ return Category::find()
+ ->select(['id', 'name'])
+ ->with([
+ 'products' => function (\yii\db\ActiveQuery $query) {
+ $query->select(['name', 'description', 'price', 'category_id']);
+ }
+ ])
+ ->asArray()
+ ->all();
+ }
+}
diff --git a/frontend/controllers/OrderController.php b/frontend/controllers/OrderController.php
new file mode 100755
index 0000000..4d13fb3
--- /dev/null
+++ b/frontend/controllers/OrderController.php
@@ -0,0 +1,30 @@
+where(['user_id' => \Yii::$app->user->id])
+ ->select(['id', 'strength', 'amount', 'table_id'])
+ ->orderBy(['created_at' => SORT_DESC])
+ ->with([
+ 'table' => function (\yii\db\ActiveQuery $query) {
+ $query->select(['id', 'name']);
+ },
+ 'products' => function (\yii\db\ActiveQuery $query) {
+ $query->select(['id', 'taste']);
+ },
+ ])
+ ->asArray()
+ ->all();
+ }
+}
diff --git a/frontend/controllers/ProductController.php b/frontend/controllers/ProductController.php
new file mode 100755
index 0000000..774eb05
--- /dev/null
+++ b/frontend/controllers/ProductController.php
@@ -0,0 +1,28 @@
+where(['status' => Product::STATUS_ACTIVE, 'category_id' => $category_id])
+ ->select(['id', 'name', 'description', 'price'])
+ ->all();
+ }
+
+ public function actionGetById($id)
+ {
+ return Product::find()
+ ->where(['status' => Product::STATUS_ACTIVE, 'id' => $id])
+ ->select(['id', 'name', 'description', 'price'])
+ ->one();
+ }
+}
diff --git a/frontend/controllers/SiteController.php b/frontend/controllers/SiteController.php
new file mode 100755
index 0000000..d40c3fc
--- /dev/null
+++ b/frontend/controllers/SiteController.php
@@ -0,0 +1,217 @@
+ [
+ 'class' => AccessControl::class,
+ 'only' => ['logout', 'signup'],
+ 'rules' => [
+ [
+ 'actions' => ['signup'],
+ 'allow' => true,
+ 'roles' => ['?'],
+ ],
+ [
+ 'actions' => ['logout'],
+ 'allow' => true,
+ 'roles' => ['@'],
+ ],
+ ],
+ ],
+ 'verbs' => [
+ 'class' => VerbFilter::class,
+ 'actions' => [
+ 'logout' => ['post'],
+ ],
+ ],
+ [
+ 'class' => ContentNegotiator::className(),
+ 'formats' => [
+ 'application/json' => Response::FORMAT_JSON,
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function actions()
+ {
+ return [
+ 'error' => [
+ 'class' => \yii\web\ErrorAction::class,
+ ],
+ 'captcha' => [
+ 'class' => \yii\captcha\CaptchaAction::class,
+ 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
+ ],
+ ];
+ }
+
+ /**
+ * Logs in a user.
+ *
+ * @return mixed
+ */
+ public function actionLogin()
+ {
+ if (!Yii::$app->user->isGuest) {
+ return null;
+ }
+
+ $model = new LoginForm();
+ if ($model->load(Yii::$app->request->post(), '') && $model->login()) {
+ return $model;
+ } else {
+ return $model->errors;
+ }
+ }
+
+ /**
+ * Logs out the current user.
+ *
+ * @return mixed
+ */
+ public function actionLogout()
+ {
+ Yii::$app->user->logout();
+
+ return true;
+ }
+
+ /**
+ * Signs user up.
+ *
+ * @return mixed
+ */
+ public function actionSignup()
+ {
+ $model = new SignupForm();
+ if ($model->load(Yii::$app->request->post(), '') && $model->signup()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * 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();
+ }
+
+ Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for the provided email address.');
+ }
+
+ 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 (InvalidArgumentException $e) {
+ throw new BadRequestHttpException($e->getMessage());
+ }
+
+ if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
+ Yii::$app->session->setFlash('success', 'New password saved.');
+
+ return $this->goHome();
+ }
+
+ return $this->render('resetPassword', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Verify email address
+ *
+ * @param string $token
+ * @throws BadRequestHttpException
+ * @return yii\web\Response
+ */
+ public function actionVerifyEmail($token)
+ {
+ try {
+ $model = new VerifyEmailForm($token);
+ } catch (InvalidArgumentException $e) {
+ throw new BadRequestHttpException($e->getMessage());
+ }
+ if (($user = $model->verifyEmail()) && Yii::$app->user->login($user)) {
+ Yii::$app->session->setFlash('success', 'Your email has been confirmed!');
+ return $this->goHome();
+ }
+
+ Yii::$app->session->setFlash('error', 'Sorry, we are unable to verify your account with provided token.');
+ return $this->goHome();
+ }
+
+ /**
+ * Resend verification email
+ *
+ * @return mixed
+ */
+ public function actionResendVerificationEmail()
+ {
+ $model = new ResendVerificationEmailForm();
+ 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();
+ }
+ Yii::$app->session->setFlash('error', 'Sorry, we are unable to resend verification email for the provided email address.');
+ }
+
+ return $this->render('resendVerificationEmail', [
+ 'model' => $model
+ ]);
+ }
+}
diff --git a/frontend/models/ContactForm.php b/frontend/models/ContactForm.php
new file mode 100755
index 0000000..1dd419c
--- /dev/null
+++ b/frontend/models/ContactForm.php
@@ -0,0 +1,61 @@
+ '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 bool whether the email was sent
+ */
+ public function sendEmail($email)
+ {
+ return Yii::$app->mailer->compose()
+ ->setTo($email)
+ ->setFrom([Yii::$app->params['senderEmail'] => Yii::$app->params['senderName']])
+ ->setReplyTo([$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 100755
index 0000000..db963e3
--- /dev/null
+++ b/frontend/models/PasswordResetRequestForm.php
@@ -0,0 +1,69 @@
+ '\common\models\User',
+ 'filter' => ['status' => User::STATUS_ACTIVE],
+ 'message' => 'There is no user with this email address.'
+ ],
+ ];
+ }
+
+ /**
+ * Sends an email with a link, for resetting the password.
+ *
+ * @return bool whether the email was send
+ */
+ public function sendEmail()
+ {
+ /* @var $user User */
+ $user = User::findOne([
+ 'status' => User::STATUS_ACTIVE,
+ 'email' => $this->email,
+ ]);
+
+ if (!$user) {
+ return false;
+ }
+
+ if (!User::isPasswordResetTokenValid($user->password_reset_token)) {
+ $user->generatePasswordResetToken();
+ if (!$user->save()) {
+ return false;
+ }
+ }
+
+ 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();
+ }
+}
diff --git a/frontend/models/ResendVerificationEmailForm.php b/frontend/models/ResendVerificationEmailForm.php
new file mode 100755
index 0000000..8fb265b
--- /dev/null
+++ b/frontend/models/ResendVerificationEmailForm.php
@@ -0,0 +1,61 @@
+ '\common\models\User',
+ 'filter' => ['status' => User::STATUS_INACTIVE],
+ 'message' => 'There is no user with this email address.'
+ ],
+ ];
+ }
+
+ /**
+ * Sends confirmation email to user
+ *
+ * @return bool whether the email was sent
+ */
+ public function sendEmail()
+ {
+ $user = User::findOne([
+ 'email' => $this->email,
+ 'status' => User::STATUS_INACTIVE
+ ]);
+
+ if ($user === null) {
+ return false;
+ }
+
+ return Yii::$app
+ ->mailer
+ ->compose(
+ ['html' => 'emailVerify-html', 'text' => 'emailVerify-text'],
+ ['user' => $user]
+ )
+ ->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])
+ ->setTo($this->email)
+ ->setSubject('Account registration at ' . Yii::$app->name)
+ ->send();
+ }
+}
diff --git a/frontend/models/ResetPasswordForm.php b/frontend/models/ResetPasswordForm.php
new file mode 100755
index 0000000..31c786f
--- /dev/null
+++ b/frontend/models/ResetPasswordForm.php
@@ -0,0 +1,67 @@
+_user = User::findByPasswordResetToken($token);
+ if (!$this->_user) {
+ throw new InvalidArgumentException('Wrong password reset token.');
+ }
+ parent::__construct($config);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rules()
+ {
+ return [
+ ['password', 'required'],
+ ['password', 'string', 'min' => Yii::$app->params['user.passwordMinLength']],
+ ];
+ }
+
+ /**
+ * Resets password.
+ *
+ * @return bool if password was reset.
+ */
+ public function resetPassword()
+ {
+ $user = $this->_user;
+ $user->setPassword($this->password);
+ $user->removePasswordResetToken();
+ $user->generateAuthKey();
+
+ return $user->save(false);
+ }
+}
diff --git a/frontend/models/SignupForm.php b/frontend/models/SignupForm.php
new file mode 100755
index 0000000..e42a8ca
--- /dev/null
+++ b/frontend/models/SignupForm.php
@@ -0,0 +1,80 @@
+ '\common\models\User', 'message' => 'This username has already been taken.'],
+ ['username', 'string', 'min' => 2, 'max' => 255],
+
+ ['email', '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' => Yii::$app->params['user.passwordMinLength']],
+ ];
+ }
+
+ /**
+ * Signs user up.
+ *
+ * @return bool whether the creating new account was successful and email was sent
+ */
+ public function signup()
+ {
+ if (!$this->validate()) {
+ return null;
+ }
+
+ $user = new User();
+ $user->username = $this->username;
+ $user->email = $this->email;
+ $user->setPassword($this->password);
+ $user->generateAuthKey();
+ $user->generateEmailVerificationToken();
+
+ return $user->save() && $this->sendEmail($user);
+ }
+
+ /**
+ * Sends confirmation email to user
+ * @param User $user user model to with email should be send
+ * @return bool whether the email was sent
+ */
+ protected function sendEmail($user)
+ {
+ return Yii::$app
+ ->mailer
+ ->compose(
+ ['html' => 'emailVerify-html', 'text' => 'emailVerify-text'],
+ ['user' => $user]
+ )
+ ->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])
+ ->setTo($this->email)
+ ->setSubject('Account registration at ' . Yii::$app->name)
+ ->send();
+ }
+}
diff --git a/frontend/models/VerifyEmailForm.php b/frontend/models/VerifyEmailForm.php
new file mode 100755
index 0000000..0740746
--- /dev/null
+++ b/frontend/models/VerifyEmailForm.php
@@ -0,0 +1,52 @@
+_user = User::findByVerificationToken($token);
+ if (!$this->_user) {
+ throw new InvalidArgumentException('Wrong verify email token.');
+ }
+ parent::__construct($config);
+ }
+
+ /**
+ * Verify email
+ *
+ * @return User|null the saved model or null if saving fails
+ */
+ public function verifyEmail()
+ {
+ $user = $this->_user;
+ $user->status = User::STATUS_ACTIVE;
+ return $user->save(false) ? $user : null;
+ }
+}
diff --git a/frontend/runtime/.gitignore b/frontend/runtime/.gitignore
new file mode 100755
index 0000000..c96a04f
--- /dev/null
+++ b/frontend/runtime/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/frontend/tests/_bootstrap.php b/frontend/tests/_bootstrap.php
new file mode 100755
index 0000000..637ce14
--- /dev/null
+++ b/frontend/tests/_bootstrap.php
@@ -0,0 +1,10 @@
+ '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',
+ ],
+ [
+ 'username' => 'test.test',
+ 'auth_key' => 'O87GkY3_UfmMHYkyezZ7QLfmkKNsllzT',
+ // Test1234
+ 'password_hash' => 'O87GkY3_UfmMHYkyezZ7QLfmkKNsllzT',
+ 'email' => 'test@mail.com',
+ 'status' => '9',
+ 'created_at' => '1548675330',
+ 'updated_at' => '1548675330',
+ 'verification_token' => '4ch0qbfhvWwkcuWqjN8SWRq72SOw1KYT_1548675330',
+ ],
+];
diff --git a/frontend/tests/_data/user.php b/frontend/tests/_data/user.php
new file mode 100755
index 0000000..0b94332
--- /dev/null
+++ b/frontend/tests/_data/user.php
@@ -0,0 +1,45 @@
+ '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',
+ ],
+ [
+ 'username' => 'test.test',
+ 'auth_key' => 'O87GkY3_UfmMHYkyezZ7QLfmkKNsllzT',
+ //Test1234
+ 'password_hash' => '$2y$13$d17z0w/wKC4LFwtzBcmx6up4jErQuandJqhzKGKczfWuiEhLBtQBK',
+ 'email' => 'test@mail.com',
+ 'status' => '9',
+ 'created_at' => '1548675330',
+ 'updated_at' => '1548675330',
+ 'verification_token' => '4ch0qbfhvWwkcuWqjN8SWRq72SOw1KYT_1548675330',
+ ],
+ [
+ 'username' => 'test2.test',
+ 'auth_key' => '4XXdVqi3rDpa_a6JH6zqVreFxUPcUPvJ',
+ //Test1234
+ 'password_hash' => '$2y$13$d17z0w/wKC4LFwtzBcmx6up4jErQuandJqhzKGKczfWuiEhLBtQBK',
+ 'email' => 'test2@mail.com',
+ 'status' => '10',
+ 'created_at' => '1548675330',
+ 'updated_at' => '1548675330',
+ 'verification_token' => 'already_used_token_1548675330',
+ ],
+];
diff --git a/frontend/tests/_output/.gitignore b/frontend/tests/_output/.gitignore
new file mode 100755
index 0000000..d6b7ef3
--- /dev/null
+++ b/frontend/tests/_output/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/frontend/tests/_support/.gitignore b/frontend/tests/_support/.gitignore
new file mode 100755
index 0000000..36e264c
--- /dev/null
+++ b/frontend/tests/_support/.gitignore
@@ -0,0 +1 @@
+_generated
diff --git a/frontend/tests/_support/FunctionalTester.php b/frontend/tests/_support/FunctionalTester.php
new file mode 100755
index 0000000..77ad9c5
--- /dev/null
+++ b/frontend/tests/_support/FunctionalTester.php
@@ -0,0 +1,34 @@
+see($message, '.invalid-feedback');
+ }
+
+ public function dontSeeValidationError($message)
+ {
+ $this->dontSee($message, '.invalid-feedback');
+ }
+}
diff --git a/frontend/tests/_support/UnitTester.php b/frontend/tests/_support/UnitTester.php
new file mode 100755
index 0000000..91557de
--- /dev/null
+++ b/frontend/tests/_support/UnitTester.php
@@ -0,0 +1,26 @@
+amOnRoute(Url::toRoute('/site/index'));
+ $I->see('My Application');
+
+ $I->seeLink('About');
+ $I->click('About');
+ $I->wait(2); // wait for page to be opened
+
+ $I->see('This is the About page.');
+ }
+}
diff --git a/frontend/tests/acceptance/_bootstrap.php b/frontend/tests/acceptance/_bootstrap.php
new file mode 100755
index 0000000..47716f0
--- /dev/null
+++ b/frontend/tests/acceptance/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Cept
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
\ No newline at end of file
diff --git a/frontend/tests/functional.suite.yml b/frontend/tests/functional.suite.yml
new file mode 100755
index 0000000..d66644d
--- /dev/null
+++ b/frontend/tests/functional.suite.yml
@@ -0,0 +1,7 @@
+suite_namespace: frontend\tests\functional
+actor: FunctionalTester
+modules:
+ enabled:
+ - Filesystem
+ - Yii2
+ - Asserts
diff --git a/frontend/tests/functional/AboutCest.php b/frontend/tests/functional/AboutCest.php
new file mode 100755
index 0000000..1bcce2b
--- /dev/null
+++ b/frontend/tests/functional/AboutCest.php
@@ -0,0 +1,14 @@
+amOnRoute('site/about');
+ $I->see('About', 'h1');
+ }
+}
diff --git a/frontend/tests/functional/ContactCest.php b/frontend/tests/functional/ContactCest.php
new file mode 100755
index 0000000..9b5f90b
--- /dev/null
+++ b/frontend/tests/functional/ContactCest.php
@@ -0,0 +1,60 @@
+amOnRoute('site/contact');
+ }
+
+ public function checkContact(FunctionalTester $I)
+ {
+ $I->see('Contact', 'h1');
+ }
+
+ public function checkContactSubmitNoData(FunctionalTester $I)
+ {
+ $I->submitForm('#contact-form', []);
+ $I->see('Contact', 'h1');
+ $I->seeValidationError('Name cannot be blank');
+ $I->seeValidationError('Email cannot be blank');
+ $I->seeValidationError('Subject cannot be blank');
+ $I->seeValidationError('Body cannot be blank');
+ $I->seeValidationError('The verification code is incorrect');
+ }
+
+ public function checkContactSubmitNotCorrectEmail(FunctionalTester $I)
+ {
+ $I->submitForm('#contact-form', [
+ 'ContactForm[name]' => 'tester',
+ 'ContactForm[email]' => 'tester.email',
+ 'ContactForm[subject]' => 'test subject',
+ 'ContactForm[body]' => 'test content',
+ 'ContactForm[verifyCode]' => 'testme',
+ ]);
+ $I->seeValidationError('Email is not a valid email address.');
+ $I->dontSeeValidationError('Name cannot be blank');
+ $I->dontSeeValidationError('Subject cannot be blank');
+ $I->dontSeeValidationError('Body cannot be blank');
+ $I->dontSeeValidationError('The verification code is incorrect');
+ }
+
+ public function checkContactSubmitCorrectData(FunctionalTester $I)
+ {
+ $I->submitForm('#contact-form', [
+ 'ContactForm[name]' => 'tester',
+ 'ContactForm[email]' => 'tester@example.com',
+ 'ContactForm[subject]' => 'test subject',
+ 'ContactForm[body]' => 'test content',
+ 'ContactForm[verifyCode]' => 'testme',
+ ]);
+ $I->seeEmailIsSent();
+ $I->see('Thank you for contacting us. We will respond to you as soon as possible.');
+ }
+}
diff --git a/frontend/tests/functional/HomeCest.php b/frontend/tests/functional/HomeCest.php
new file mode 100755
index 0000000..99048af
--- /dev/null
+++ b/frontend/tests/functional/HomeCest.php
@@ -0,0 +1,17 @@
+amOnRoute(\Yii::$app->homeUrl);
+ $I->see('My Application');
+ $I->seeLink('About');
+ $I->click('About');
+ $I->see('This is the About page.');
+ }
+}
\ No newline at end of file
diff --git a/frontend/tests/functional/LoginCest.php b/frontend/tests/functional/LoginCest.php
new file mode 100755
index 0000000..ee160b6
--- /dev/null
+++ b/frontend/tests/functional/LoginCest.php
@@ -0,0 +1,66 @@
+ [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'login_data.php',
+ ],
+ ];
+ }
+
+ public function _before(FunctionalTester $I)
+ {
+ $I->amOnRoute('site/login');
+ }
+
+ protected function formParams($login, $password)
+ {
+ return [
+ 'LoginForm[username]' => $login,
+ 'LoginForm[password]' => $password,
+ ];
+ }
+
+ public function checkEmpty(FunctionalTester $I)
+ {
+ $I->submitForm('#login-form', $this->formParams('', ''));
+ $I->seeValidationError('Username cannot be blank.');
+ $I->seeValidationError('Password cannot be blank.');
+ }
+
+ public function checkWrongPassword(FunctionalTester $I)
+ {
+ $I->submitForm('#login-form', $this->formParams('admin', 'wrong'));
+ $I->seeValidationError('Incorrect username or password.');
+ }
+
+ public function checkInactiveAccount(FunctionalTester $I)
+ {
+ $I->submitForm('#login-form', $this->formParams('test.test', 'Test1234'));
+ $I->seeValidationError('Incorrect username or password');
+ }
+
+ public function checkValidLogin(FunctionalTester $I)
+ {
+ $I->submitForm('#login-form', $this->formParams('erau', 'password_0'));
+ $I->see('Logout (erau)', 'form button[type=submit]');
+ $I->dontSeeLink('Login');
+ $I->dontSeeLink('Signup');
+ }
+}
diff --git a/frontend/tests/functional/ResendVerificationEmailCest.php b/frontend/tests/functional/ResendVerificationEmailCest.php
new file mode 100755
index 0000000..8ecaeac
--- /dev/null
+++ b/frontend/tests/functional/ResendVerificationEmailCest.php
@@ -0,0 +1,83 @@
+ [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'user.php',
+ ],
+ ];
+ }
+
+ public function _before(FunctionalTester $I)
+ {
+ $I->amOnRoute('/site/resend-verification-email');
+ }
+
+ protected function formParams($email)
+ {
+ return [
+ 'ResendVerificationEmailForm[email]' => $email
+ ];
+ }
+
+ public function checkPage(FunctionalTester $I)
+ {
+ $I->see('Resend verification email', 'h1');
+ $I->see('Please fill out your email. A verification email will be sent there.');
+ }
+
+ public function checkEmptyField(FunctionalTester $I)
+ {
+ $I->submitForm($this->formId, $this->formParams(''));
+ $I->seeValidationError('Email cannot be blank.');
+ }
+
+ public function checkWrongEmailFormat(FunctionalTester $I)
+ {
+ $I->submitForm($this->formId, $this->formParams('abcd.com'));
+ $I->seeValidationError('Email is not a valid email address.');
+ }
+
+ public function checkWrongEmail(FunctionalTester $I)
+ {
+ $I->submitForm($this->formId, $this->formParams('wrong@email.com'));
+ $I->seeValidationError('There is no user with this email address.');
+ }
+
+ public function checkAlreadyVerifiedEmail(FunctionalTester $I)
+ {
+ $I->submitForm($this->formId, $this->formParams('test2@mail.com'));
+ $I->seeValidationError('There is no user with this email address.');
+ }
+
+ public function checkSendSuccessfully(FunctionalTester $I)
+ {
+ $I->submitForm($this->formId, $this->formParams('test@mail.com'));
+ $I->canSeeEmailIsSent();
+ $I->seeRecord('common\models\User', [
+ 'email' => 'test@mail.com',
+ 'username' => 'test.test',
+ 'status' => \common\models\User::STATUS_INACTIVE
+ ]);
+ $I->see('Check your email for further instructions.');
+ }
+}
diff --git a/frontend/tests/functional/SignupCest.php b/frontend/tests/functional/SignupCest.php
new file mode 100755
index 0000000..b83b795
--- /dev/null
+++ b/frontend/tests/functional/SignupCest.php
@@ -0,0 +1,59 @@
+amOnRoute('site/signup');
+ }
+
+ public function signupWithEmptyFields(FunctionalTester $I)
+ {
+ $I->see('Signup', 'h1');
+ $I->see('Please fill out the following fields to signup:');
+ $I->submitForm($this->formId, []);
+ $I->seeValidationError('Username cannot be blank.');
+ $I->seeValidationError('Email cannot be blank.');
+ $I->seeValidationError('Password cannot be blank.');
+
+ }
+
+ public function signupWithWrongEmail(FunctionalTester $I)
+ {
+ $I->submitForm(
+ $this->formId, [
+ 'SignupForm[username]' => 'tester',
+ 'SignupForm[email]' => 'ttttt',
+ 'SignupForm[password]' => 'tester_password',
+ ]
+ );
+ $I->dontSee('Username cannot be blank.', '.invalid-feedback');
+ $I->dontSee('Password cannot be blank.', '.invalid-feedback');
+ $I->see('Email is not a valid email address.', '.invalid-feedback');
+ }
+
+ public function signupSuccessfully(FunctionalTester $I)
+ {
+ $I->submitForm($this->formId, [
+ 'SignupForm[username]' => 'tester',
+ 'SignupForm[email]' => 'tester.email@example.com',
+ 'SignupForm[password]' => 'tester_password',
+ ]);
+
+ $I->seeRecord('common\models\User', [
+ 'username' => 'tester',
+ 'email' => 'tester.email@example.com',
+ 'status' => \common\models\User::STATUS_INACTIVE
+ ]);
+
+ $I->seeEmailIsSent();
+ $I->see('Thank you for registration. Please check your inbox for verification email.');
+ }
+}
diff --git a/frontend/tests/functional/VerifyEmailCest.php b/frontend/tests/functional/VerifyEmailCest.php
new file mode 100755
index 0000000..b227426
--- /dev/null
+++ b/frontend/tests/functional/VerifyEmailCest.php
@@ -0,0 +1,68 @@
+ [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'user.php',
+ ],
+ ];
+ }
+
+ public function checkEmptyToken(FunctionalTester $I)
+ {
+ $I->amOnRoute('site/verify-email', ['token' => '']);
+ $I->canSee('Bad Request', 'h1');
+ $I->canSee('Verify email token cannot be blank.');
+ }
+
+ public function checkInvalidToken(FunctionalTester $I)
+ {
+ $I->amOnRoute('site/verify-email', ['token' => 'wrong_token']);
+ $I->canSee('Bad Request', 'h1');
+ $I->canSee('Wrong verify email token.');
+ }
+
+ public function checkNoToken(FunctionalTester $I)
+ {
+ $I->amOnRoute('site/verify-email');
+ $I->canSee('Bad Request', 'h1');
+ $I->canSee('Missing required parameters: token');
+ }
+
+ public function checkAlreadyActivatedToken(FunctionalTester $I)
+ {
+ $I->amOnRoute('site/verify-email', ['token' => 'already_used_token_1548675330']);
+ $I->canSee('Bad Request', 'h1');
+ $I->canSee('Wrong verify email token.');
+ }
+
+ public function checkSuccessVerification(FunctionalTester $I)
+ {
+ $I->amOnRoute('site/verify-email', ['token' => '4ch0qbfhvWwkcuWqjN8SWRq72SOw1KYT_1548675330']);
+ $I->canSee('Your email has been confirmed!');
+ $I->canSee('Congratulations!', 'h1');
+ $I->see('Logout (test.test)', 'form button[type=submit]');
+
+ $I->seeRecord('common\models\User', [
+ 'username' => 'test.test',
+ 'email' => 'test@mail.com',
+ 'status' => \common\models\User::STATUS_ACTIVE
+ ]);
+ }
+}
diff --git a/frontend/tests/functional/_bootstrap.php b/frontend/tests/functional/_bootstrap.php
new file mode 100755
index 0000000..30ed54b
--- /dev/null
+++ b/frontend/tests/functional/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Cests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
\ No newline at end of file
diff --git a/frontend/tests/unit.suite.yml b/frontend/tests/unit.suite.yml
new file mode 100755
index 0000000..23ea63b
--- /dev/null
+++ b/frontend/tests/unit.suite.yml
@@ -0,0 +1,7 @@
+suite_namespace: frontend\tests\unit
+actor: UnitTester
+modules:
+ enabled:
+ - Yii2:
+ part: [orm, email, fixtures]
+ - Asserts
diff --git a/frontend/tests/unit/_bootstrap.php b/frontend/tests/unit/_bootstrap.php
new file mode 100755
index 0000000..e432ce5
--- /dev/null
+++ b/frontend/tests/unit/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Tests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
diff --git a/frontend/tests/unit/models/ContactFormTest.php b/frontend/tests/unit/models/ContactFormTest.php
new file mode 100755
index 0000000..1fb4525
--- /dev/null
+++ b/frontend/tests/unit/models/ContactFormTest.php
@@ -0,0 +1,35 @@
+attributes = [
+ 'name' => 'Tester',
+ 'email' => 'tester@example.com',
+ 'subject' => 'very important letter subject',
+ 'body' => 'body of current message',
+ ];
+
+ verify($model->sendEmail('admin@example.com'))->notEmpty();
+
+ // using Yii2 module actions to check email was sent
+ $this->tester->seeEmailIsSent();
+
+ /** @var MessageInterface $emailMessage */
+ $emailMessage = $this->tester->grabLastSentEmail();
+ verify($emailMessage)->instanceOf('yii\mail\MessageInterface');
+ verify($emailMessage->getTo())->arrayHasKey('admin@example.com');
+ verify($emailMessage->getFrom())->arrayHasKey('noreply@example.com');
+ verify($emailMessage->getReplyTo())->arrayHasKey('tester@example.com');
+ verify($emailMessage->getSubject())->equals('very important letter subject');
+ verify($emailMessage->toString())->stringContainsString('body of current message');
+ }
+}
diff --git a/frontend/tests/unit/models/PasswordResetRequestFormTest.php b/frontend/tests/unit/models/PasswordResetRequestFormTest.php
new file mode 100755
index 0000000..8492fba
--- /dev/null
+++ b/frontend/tests/unit/models/PasswordResetRequestFormTest.php
@@ -0,0 +1,59 @@
+tester->haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ]
+ ]);
+ }
+
+ public function testSendMessageWithWrongEmailAddress()
+ {
+ $model = new PasswordResetRequestForm();
+ $model->email = 'not-existing-email@example.com';
+ verify($model->sendEmail())->false();
+ }
+
+ public function testNotSendEmailsToInactiveUser()
+ {
+ $user = $this->tester->grabFixture('user', 1);
+ $model = new PasswordResetRequestForm();
+ $model->email = $user['email'];
+ verify($model->sendEmail())->false();
+ }
+
+ public function testSendEmailSuccessfully()
+ {
+ $userFixture = $this->tester->grabFixture('user', 0);
+
+ $model = new PasswordResetRequestForm();
+ $model->email = $userFixture['email'];
+ $user = User::findOne(['password_reset_token' => $userFixture['password_reset_token']]);
+
+ verify($model->sendEmail())->notEmpty();
+ verify($user->password_reset_token)->notEmpty();
+
+ $emailMessage = $this->tester->grabLastSentEmail();
+ verify($emailMessage)->instanceOf('yii\mail\MessageInterface');
+ verify($emailMessage->getTo())->arrayHasKey($model->email);
+ verify($emailMessage->getFrom())->arrayHasKey(Yii::$app->params['supportEmail']);
+ }
+}
diff --git a/frontend/tests/unit/models/ResendVerificationEmailFormTest.php b/frontend/tests/unit/models/ResendVerificationEmailFormTest.php
new file mode 100755
index 0000000..af3548a
--- /dev/null
+++ b/frontend/tests/unit/models/ResendVerificationEmailFormTest.php
@@ -0,0 +1,85 @@
+tester->haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ]
+ ]);
+ }
+
+ public function testWrongEmailAddress()
+ {
+ $model = new ResendVerificationEmailForm();
+ $model->attributes = [
+ 'email' => 'aaa@bbb.cc'
+ ];
+
+ verify($model->validate())->false();
+ verify($model->hasErrors())->true();
+ verify($model->getFirstError('email'))->equals('There is no user with this email address.');
+ }
+
+ public function testEmptyEmailAddress()
+ {
+ $model = new ResendVerificationEmailForm();
+ $model->attributes = [
+ 'email' => ''
+ ];
+
+ verify($model->validate())->false();
+ verify($model->hasErrors())->true();
+ verify($model->getFirstError('email'))->equals('Email cannot be blank.');
+ }
+
+ public function testResendToActiveUser()
+ {
+ $model = new ResendVerificationEmailForm();
+ $model->attributes = [
+ 'email' => 'test2@mail.com'
+ ];
+
+ verify($model->validate())->false();
+ verify($model->hasErrors())->true();
+ verify($model->getFirstError('email'))->equals('There is no user with this email address.');
+ }
+
+ public function testSuccessfullyResend()
+ {
+ $model = new ResendVerificationEmailForm();
+ $model->attributes = [
+ 'email' => 'test@mail.com'
+ ];
+
+ verify($model->validate())->true();
+ verify($model->hasErrors())->false();
+
+ verify($model->sendEmail())->true();
+ $this->tester->seeEmailIsSent();
+
+ $mail = $this->tester->grabLastSentEmail();
+
+ verify($mail)->instanceOf('yii\mail\MessageInterface');
+ verify($mail->getTo())->arrayHasKey('test@mail.com');
+ verify($mail->getFrom())->arrayHasKey(\Yii::$app->params['supportEmail']);
+ verify($mail->getSubject())->equals('Account registration at ' . \Yii::$app->name);
+ verify($mail->toString())->stringContainsString('4ch0qbfhvWwkcuWqjN8SWRq72SOw1KYT_1548675330');
+ }
+}
diff --git a/frontend/tests/unit/models/ResetPasswordFormTest.php b/frontend/tests/unit/models/ResetPasswordFormTest.php
new file mode 100755
index 0000000..8d969a6
--- /dev/null
+++ b/frontend/tests/unit/models/ResetPasswordFormTest.php
@@ -0,0 +1,44 @@
+tester->haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ],
+ ]);
+ }
+
+ public function testResetWrongToken()
+ {
+ $this->tester->expectThrowable('\yii\base\InvalidArgumentException', function() {
+ new ResetPasswordForm('');
+ });
+
+ $this->tester->expectThrowable('\yii\base\InvalidArgumentException', function() {
+ new ResetPasswordForm('notexistingtoken_1391882543');
+ });
+ }
+
+ public function testResetCorrectToken()
+ {
+ $user = $this->tester->grabFixture('user', 0);
+ $form = new ResetPasswordForm($user['password_reset_token']);
+ verify($form->resetPassword())->notEmpty();
+ }
+
+}
diff --git a/frontend/tests/unit/models/SignupFormTest.php b/frontend/tests/unit/models/SignupFormTest.php
new file mode 100755
index 0000000..332ba6b
--- /dev/null
+++ b/frontend/tests/unit/models/SignupFormTest.php
@@ -0,0 +1,72 @@
+tester->haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ]
+ ]);
+ }
+
+ public function testCorrectSignup()
+ {
+ $model = new SignupForm([
+ 'username' => 'some_username',
+ 'email' => 'some_email@example.com',
+ 'password' => 'some_password',
+ ]);
+
+ $user = $model->signup();
+ verify($user)->notEmpty();
+
+ /** @var \common\models\User $user */
+ $user = $this->tester->grabRecord('common\models\User', [
+ 'username' => 'some_username',
+ 'email' => 'some_email@example.com',
+ 'status' => \common\models\User::STATUS_INACTIVE
+ ]);
+
+ $this->tester->seeEmailIsSent();
+
+ $mail = $this->tester->grabLastSentEmail();
+
+ verify($mail)->instanceOf('yii\mail\MessageInterface');
+ verify($mail->getTo())->arrayHasKey('some_email@example.com');
+ verify($mail->getFrom())->arrayHasKey(\Yii::$app->params['supportEmail']);
+ verify($mail->getSubject())->equals('Account registration at ' . \Yii::$app->name);
+ verify($mail->toString())->stringContainsString($user->verification_token);
+ }
+
+ public function testNotCorrectSignup()
+ {
+ $model = new SignupForm([
+ 'username' => 'troy.becker',
+ 'email' => 'nicolas.dianna@hotmail.com',
+ 'password' => 'some_password',
+ ]);
+
+ verify($model->signup())->empty();
+ verify($model->getErrors('username'))->notEmpty();
+ verify($model->getErrors('email'))->notEmpty();
+
+ verify($model->getFirstError('username'))
+ ->equals('This username has already been taken.');
+ verify($model->getFirstError('email'))
+ ->equals('This email address has already been taken.');
+ }
+}
diff --git a/frontend/tests/unit/models/VerifyEmailFormTest.php b/frontend/tests/unit/models/VerifyEmailFormTest.php
new file mode 100755
index 0000000..e0fe2e4
--- /dev/null
+++ b/frontend/tests/unit/models/VerifyEmailFormTest.php
@@ -0,0 +1,55 @@
+tester->haveFixtures([
+ 'user' => [
+ 'class' => UserFixture::class,
+ 'dataFile' => codecept_data_dir() . 'user.php'
+ ]
+ ]);
+ }
+
+ public function testVerifyWrongToken()
+ {
+ $this->tester->expectThrowable('\yii\base\InvalidArgumentException', function() {
+ new VerifyEmailForm('');
+ });
+
+ $this->tester->expectThrowable('\yii\base\InvalidArgumentException', function() {
+ new VerifyEmailForm('notexistingtoken_1391882543');
+ });
+ }
+
+ public function testAlreadyActivatedToken()
+ {
+ $this->tester->expectThrowable('\yii\base\InvalidArgumentException', function() {
+ new VerifyEmailForm('already_used_token_1548675330');
+ });
+ }
+
+ public function testVerifyCorrectToken()
+ {
+ $model = new VerifyEmailForm('4ch0qbfhvWwkcuWqjN8SWRq72SOw1KYT_1548675330');
+ $user = $model->verifyEmail();
+ verify($user)->instanceOf('common\models\User');
+
+ verify($user->username)->equals('test.test');
+ verify($user->email)->equals('test@mail.com');
+ verify($user->status)->equals(\common\models\User::STATUS_ACTIVE);
+ verify($user->validatePassword('Test1234'))->true();
+ }
+}
diff --git a/frontend/views/layouts/main.php b/frontend/views/layouts/main.php
new file mode 100755
index 0000000..ae6eda7
--- /dev/null
+++ b/frontend/views/layouts/main.php
@@ -0,0 +1,84 @@
+
+beginPage() ?>
+
+
+
+
+
+ registerCsrfMetaTags() ?>
+ = Html::encode($this->title) ?>
+ head() ?>
+
+
+beginBody() ?>
+
+
+ Yii::$app->name,
+ 'brandUrl' => Yii::$app->homeUrl,
+ 'options' => [
+ 'class' => 'navbar navbar-expand-md navbar-dark bg-dark 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']];
+ }
+
+ echo Nav::widget([
+ 'options' => ['class' => 'navbar-nav me-auto mb-2 mb-md-0'],
+ 'items' => $menuItems,
+ ]);
+ if (Yii::$app->user->isGuest) {
+ echo Html::tag('div',Html::a('Login',['/site/login'],['class' => ['btn btn-link login text-decoration-none']]),['class' => ['d-flex']]);
+ } else {
+ echo Html::beginForm(['/site/logout'], 'post', ['class' => 'd-flex'])
+ . Html::submitButton(
+ 'Logout (' . Yii::$app->user->identity->username . ')',
+ ['class' => 'btn btn-link logout text-decoration-none']
+ )
+ . Html::endForm();
+ }
+ NavBar::end();
+ ?>
+
+
+
+
+ = Breadcrumbs::widget([
+ 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
+ ]) ?>
+ = Alert::widget() ?>
+ = $content ?>
+
+
+
+
+
+endBody() ?>
+
+
+endPage();
diff --git a/frontend/views/site/about.php b/frontend/views/site/about.php
new file mode 100755
index 0000000..b40ea44
--- /dev/null
+++ b/frontend/views/site/about.php
@@ -0,0 +1,16 @@
+title = 'About';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
This is the About page. You may modify the following file to customize its content:
+
+
= __FILE__ ?>
+
diff --git a/frontend/views/site/contact.php b/frontend/views/site/contact.php
new file mode 100755
index 0000000..6e6b8ac
--- /dev/null
+++ b/frontend/views/site/contact.php
@@ -0,0 +1,45 @@
+title = 'Contact';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
diff --git a/frontend/views/site/error.php b/frontend/views/site/error.php
new file mode 100755
index 0000000..1768747
--- /dev/null
+++ b/frontend/views/site/error.php
@@ -0,0 +1,27 @@
+title = $name;
+?>
+
+
+
= Html::encode($this->title) ?>
+
+
+ = nl2br(Html::encode($message)) ?>
+
+
+
+ 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 100755
index 0000000..613594c
--- /dev/null
+++ b/frontend/views/site/index.php
@@ -0,0 +1,52 @@
+title = 'My Yii Application';
+?>
+
+
+
+
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 100755
index 0000000..6685b8c
--- /dev/null
+++ b/frontend/views/site/login.php
@@ -0,0 +1,41 @@
+title = 'Login';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
Please fill out the following fields to login:
+
+
+
+ 'login-form']); ?>
+
+ = $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
+
+ = $form->field($model, 'password')->passwordInput() ?>
+
+ = $form->field($model, 'rememberMe')->checkbox() ?>
+
+
+ If you forgot your password you can = Html::a('reset it', ['site/request-password-reset']) ?>.
+
+ Need new verification email? = Html::a('Resend', ['site/resend-verification-email']) ?>
+
+
+
+ = Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
+
+
+
+
+
+
diff --git a/frontend/views/site/requestPasswordResetToken.php b/frontend/views/site/requestPasswordResetToken.php
new file mode 100755
index 0000000..72f1693
--- /dev/null
+++ b/frontend/views/site/requestPasswordResetToken.php
@@ -0,0 +1,31 @@
+title = 'Request password reset';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
Please fill out your email. A link to reset password will be sent there.
+
+
+
+ 'request-password-reset-form']); ?>
+
+ = $form->field($model, 'email')->textInput(['autofocus' => true]) ?>
+
+
+ = Html::submitButton('Send', ['class' => 'btn btn-primary']) ?>
+
+
+
+
+
+
diff --git a/frontend/views/site/resendVerificationEmail.php b/frontend/views/site/resendVerificationEmail.php
new file mode 100755
index 0000000..23f5666
--- /dev/null
+++ b/frontend/views/site/resendVerificationEmail.php
@@ -0,0 +1,31 @@
+title = 'Resend verification email';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
Please fill out your email. A verification email will be sent there.
+
+
+
+ 'resend-verification-email-form']); ?>
+
+ = $form->field($model, 'email')->textInput(['autofocus' => true]) ?>
+
+
+ = Html::submitButton('Send', ['class' => 'btn btn-primary']) ?>
+
+
+
+
+
+
diff --git a/frontend/views/site/resetPassword.php b/frontend/views/site/resetPassword.php
new file mode 100755
index 0000000..61e15b4
--- /dev/null
+++ b/frontend/views/site/resetPassword.php
@@ -0,0 +1,31 @@
+title = 'Reset password';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
Please choose your new password:
+
+
+
+ 'reset-password-form']); ?>
+
+ = $form->field($model, 'password')->passwordInput(['autofocus' => true]) ?>
+
+
+ = Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>
+
+
+
+
+
+
diff --git a/frontend/views/site/signup.php b/frontend/views/site/signup.php
new file mode 100755
index 0000000..3b005eb
--- /dev/null
+++ b/frontend/views/site/signup.php
@@ -0,0 +1,35 @@
+title = 'Signup';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
= Html::encode($this->title) ?>
+
+
Please fill out the following fields to signup:
+
+
+
+ 'form-signup']); ?>
+
+ = $form->field($model, 'username')->textInput(['autofocus' => true]) ?>
+
+ = $form->field($model, 'email') ?>
+
+ = $form->field($model, 'password')->passwordInput() ?>
+
+
+ = Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>
+
+
+
+
+
+
diff --git a/frontend/web/assets/.gitignore b/frontend/web/assets/.gitignore
new file mode 100755
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 100755
index 0000000..4a65ca7
--- /dev/null
+++ b/frontend/web/css/site.css
@@ -0,0 +1,103 @@
+main > .container, main > .container-fluid
+{
+ padding: 70px 15px 20px;
+}
+
+.footer {
+ background-color: #f5f5f5;
+ font-size: .9em;
+ height: 60px;
+}
+
+.footer > .container, .footer > .container-fluid {
+ padding-right: 15px;
+ padding-left: 15px;
+}
+
+.not-set {
+ color: #c55;
+ font-style: italic;
+}
+
+/* add sorting icons to gridview sort links */
+a.asc:after, a.desc:after {
+ content: '';
+ left: 3px;
+ display: inline-block;
+ width: 0;
+ height: 0;
+ border: solid 5px transparent;
+ margin: 4px 4px 2px 4px;
+ background: transparent;
+}
+
+a.asc:after {
+ border-bottom: solid 7px #212529;
+ border-top-width: 0;
+}
+
+a.desc:after {
+ border-top: solid 7px #212529;
+ border-bottom-width: 0;
+}
+
+.grid-view th,
+.grid-view td:last-child {
+ white-space: nowrap;
+}
+
+.grid-view .filters input,
+.grid-view .filters select {
+ min-width: 50px;
+}
+
+.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;
+}
+
+/* align the logout "link" (button in form) of the navbar */
+.navbar form > button.logout {
+ padding-top: 7px;
+ color: rgba(255, 255, 255, 0.5);
+}
+
+@media(max-width:767px) {
+ .navbar form > button.logout {
+ display:block;
+ text-align: left;
+ width: 100%;
+ padding: 10px 0;
+ }
+}
+
+.navbar form > button.logout:focus,
+.navbar form > button.logout:hover {
+ text-decoration: none;
+ color: rgba(255, 255, 255, 0.75);
+}
+
+.navbar form > button.logout:focus {
+ outline: none;
+}
+
+/* style breadcrumb widget as in previous bootstrap versions */
+.breadcrumb {
+ background-color: var(--bs-gray-200);
+ border-radius: .25rem;
+ padding: .75rem 1rem;
+}
+
+.breadcrumb-item > a
+{
+ text-decoration: none;
+}
\ No newline at end of file
diff --git a/frontend/web/favicon.ico b/frontend/web/favicon.ico
new file mode 100755
index 0000000000000000000000000000000000000000..580ed732e86556ec57f3f3395a210246d679c076
GIT binary patch
literal 318
zcmZQzU<5(|0RbS%!l1#(z#zuJz@P!d0zj+)#2|4HXaJKC0wf0lAEr2iX{M9K3=BR0
y!E90pK{x=K$Oz&POT#sS8N$ZKhC)h8ip0_|-T#43{vnSYgXBQCu@O54$pHYIza?e>
literal 0
HcmV?d00001
diff --git a/frontend/web/images/banner/image_2023-10-28_15-29-32.png b/frontend/web/images/banner/image_2023-10-28_15-29-32.png
new file mode 100644
index 0000000000000000000000000000000000000000..0fb084c7439fe98f8234f6df7b0c0a3e7b02b315
GIT binary patch
literal 42487
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
MY8x=wT=k$5N(gZG}t5F(Q3UUnvmj_R6V*>
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
literal 0
HcmV?d00001
diff --git a/frontend/web/images/product/DSC_8254.jpg b/frontend/web/images/product/DSC_8254.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..0cded4da8cae6df541783a0fb136195f2e2d8fc5
GIT binary patch
literal 8772491
zcmeFaWmFtZ+wa>m3{KF2;O?%$-Q6L$yL<3JaCZ$5+#Lc0OM+W)m*5E`Bte6-C-?n4
z?{n{Wop+zJ_Q$iRm9F~FRaISARrL&=>i(^ISbEqJK9PQ5XAJ=I@{9ly000O8AqXA-
z!ITc{Ao`a!hG}{b++TJuOml$104FSkRRlO;8VXCZV252K6YgoX8~|%{)BpEXes;IaxW#>2>X#EnR#(7ywRo
zPA&ls4gq#Pa!w8b9$o~#Mgxj2~q=g5J;e~(Za%ntsS))D%vaX=21{PE=9>BG{)Di8)BKp+r!2m(Aj0x|;Z
zKt)18Kte@BK|w`9LBmA*EBq_@`@?^aL5PTmPtcy=V`Ab%(b3VNe;VG9VL
zbp#wUO1BUwXL2DTZleU%2aV}1E{d)hk1MO-N_ysm*&*+}uacFuQXamR8d8zq>4>^B<@GN1y)>
zE9;3X&FD*CkD_cL-&dqyg9tkbijIlHO7-kfkA`I%s
zbM?(H4thmF{)w)LY8><0ujOD%b&lO!BttJ;u5``kTdKVl%2MeXMg)BD!_=wM(Qcau
zffWzk_j*$y1Wo)|$9+r3LR@t~3pA;9@#n?)1Fhu3|1!
z?RBKriYI(ITgQO%okm@KwFgr8JY~pl%et_@nr^c0{@87++T?=y6Z?eisGDMzpvh;{VLJ+5v``XxF38a
zln1}2{m`$VZ$q+?NRZypK`Ue(35I`>u&*%qz@5P1DtQu-P@WuZ&$%SzVw4<_42S;!
zrTfS&Q&GH3{eF6vxN_;H#XaHWBRJ_nHRi^!$K2GIyqu`i1kfMr+GDm
zb?{Z2p-v9R)cJs6FItSl)T_(w%K97(VI^UtJ*aiTcNy)-1Lw(e8VVWxnJ!JR0mOg1
z{$b`+89zQjYiTp=wRX`<^OokqkKvod8q=##K9o3(%AqLewJT#6%daHw0Say8=U?HG
z1Wgrc@HAD<5qHS!JJrnJP|`NClO@Cn&bpZdXh>7G^mWV-37qFL@AMEPJK;CWkc5
ziG;A2magAo+ZZZzo5dK2H+r^GLC=Uxy+=pzlT~a~Ff=aT<{hrLdFabYz?aLk-lhzv(8#;VV!!m^@KC9FNYOL#S
zx(~CbE`)o^b%FuM+9m$8xSD2?;jxByjRyMi!oLR$V3S!(M1E+GbPz(}&IkQ9pziuk
zi+>}s3_)CI_De{eh3V_{uZ01G?WmS2-*Xm6c}YzTdMjiJl?lF(G-S}vSKz0h#TEA8
z+8+1$B9CY!8V=63!;xAB(@2$Y(~gl9Qh&zRqeRZfbXFclMC32kGSQ@cDooZ(JLCRf
zx5f4_cWQsnuW7%(rU|ay3fF0JikV4$6(0TEVJjScqnp7{`+bs+pn3XX-&=T{sKzqz
zFrBfn|ImEx_gZWQ*7`ihO&mZ?-d#%0=Z2Y}hd|Wg$WrdD8~21z>l^!=wyYnX2A9PN
zfq2MU$=huiTfzpu$m>oa=T^*e`wu|ly++mU3q9m>Ka+H!w!p&=rQb4k6z2+G9nP$*
zN{!OkLFJ$HH_6b%?4;C;akV5bjxw!IvhmzL`0-9K|;J9z*kTH|MC@FIU(i`GV(
zQF%a9O99cn!1_z#26HrYjqv%d=)I*DgIL_R&n{Ajpc?q-$JZ>+N2w5W)AK5gMM|nK
zmV14o2Lbh@lw&fUD_-Rp(|0ijopwBmz81+&{o&O9b|X?+ZI1gvvZaa2qtY8
zO+wt036r!$^#{5+%Ae=!Ypt4JQ}z}MWUa>PM8HB;ICt{eQyQWu?PU3cIQ%J6+BbxC
zI~R@c5Q?buAWXUAGCanMCd2CkV)2sXNi4!jYjbaae(g1UQj3%iUQ+{?3|<%^<$2iy
zkN^oKIB!d3{b8yY>!dO{mF6Mc)@3cd*P&lEn?n{Me#7Z*SS3ULv(H%y64mJW06ff}
z28!I4wsv0=Yb;fWY+P0?=r0Br