+ */
+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 100644
index 0000000..f47f179
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,58 @@
+{
+ "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",
+ "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 100644
index 0000000..fd69d6d
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,5867 @@
+{
+ "_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": "825cc56cf0c423874be51a9d82a526fe",
+ "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": "https://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.7.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/jquery/jquery-dist.git",
+ "reference": "fde1f76e2799dd877c176abde0ec836553246991"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/fde1f76e2799dd877c176abde0ec836553246991",
+ "reference": "fde1f76e2799dd877c176abde0ec836553246991"
+ },
+ "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.17.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ezyang/htmlpurifier.git",
+ "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/bbc513d79acf6691fa9cf10f192c90dd2957f18c",
+ "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c",
+ "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 || ~8.3.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.17.0"
+ },
+ "time": "2023-11-17T15:01:25+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": "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": "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.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d76d2632cfc2206eecb5ad2b26cd5934082941b6",
+ "reference": "d76d2632cfc2206eecb5ad2b26cd5934082941b6",
+ "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|^7.0",
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/error-handler": "^5.4|^6.0|^7.0",
+ "symfony/expression-language": "^5.4|^6.0|^7.0",
+ "symfony/http-foundation": "^5.4|^6.0|^7.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/stopwatch": "^5.4|^6.0|^7.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.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-27T06:52: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.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/mailer.git",
+ "reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/mailer/zipball/ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba",
+ "reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba",
+ "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|^7.0",
+ "symfony/mime": "^6.2|^7.0",
+ "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|^7.0",
+ "symfony/http-client": "^5.4|^6.0|^7.0",
+ "symfony/messenger": "^6.2|^7.0",
+ "symfony/twig-bridge": "^6.2|^7.0"
+ },
+ "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.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-11-12T18:02:22+00:00"
+ },
+ {
+ "name": "symfony/mime",
+ "version": "v6.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/mime.git",
+ "reference": "ca4f58b2ef4baa8f6cecbeca2573f88cd577d205"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/ca4f58b2ef4baa8f6cecbeca2573f88cd577d205",
+ "reference": "ca4f58b2ef4baa8f6cecbeca2573f88cd577d205",
+ "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.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|^7.0",
+ "symfony/property-access": "^5.4|^6.0|^7.0",
+ "symfony/property-info": "^5.4|^6.0|^7.0",
+ "symfony/serializer": "^6.3.2|^7.0"
+ },
+ "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.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-10-17T11:49:05+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.13",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/Codeception.git",
+ "reference": "713a90195efa2926566e24bfc623da703ff42bba"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/Codeception/zipball/713a90195efa2926566e24bfc623da703ff42bba",
+ "reference": "713a90195efa2926566e24bfc623da703ff42bba",
+ "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 || ^0.12",
+ "sebastian/comparator": "^4.0.5 || ^5.0",
+ "sebastian/diff": "^4.0.3 || ^5.0",
+ "symfony/console": ">=4.4.24 <8.0",
+ "symfony/css-selector": ">=4.4.24 <8.0",
+ "symfony/event-dispatcher": ">=4.4.24 <8.0",
+ "symfony/finder": ">=4.4.24 <8.0",
+ "symfony/var-dumper": ">=4.4.24 <8.0",
+ "symfony/yaml": ">=4.4.24 <8.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 <8.0",
+ "symfony/process": ">=4.4.24 <8.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.13"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/codeception",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2023-12-22T19:32:40+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.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/lib-web.git",
+ "reference": "28cb2ed1169de18e720bec758015aadc37d8344c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/lib-web/zipball/28cb2ed1169de18e720bec758015aadc37d8344c",
+ "reference": "28cb2ed1169de18e720bec758015aadc37d8344c",
+ "shasum": ""
+ },
+ "require": {
+ "ext-mbstring": "*",
+ "guzzlehttp/psr7": "^2.0",
+ "php": "^8.0",
+ "symfony/css-selector": ">=4.4.24 <8.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.4"
+ },
+ "time": "2023-12-01T11:38:22+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.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Codeception/module-filesystem.git",
+ "reference": "0fd78cf941cb72dc2a650c6132c5999c26ad4f9a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Codeception/module-filesystem/zipball/0fd78cf941cb72dc2a650c6132c5999c26ad4f9a",
+ "reference": "0fd78cf941cb72dc2a650c6132c5999c26ad4f9a",
+ "shasum": ""
+ },
+ "require": {
+ "codeception/codeception": "*@dev",
+ "php": "^8.0",
+ "symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.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.1"
+ },
+ "time": "2023-12-08T19:23:28+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.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221",
+ "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221",
+ "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.2",
+ "http-interop/http-factory-tests": "^0.9",
+ "phpunit/phpunit": "^8.5.36 || ^9.6.15"
+ },
+ "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.2"
+ },
+ "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-12-03T20:05:35+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.18.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
+ "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
+ "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.18.0"
+ },
+ "time": "2023-12-10T21:03:43+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.30",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089",
+ "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-xmlwriter": "*",
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "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.30"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T06:47:57+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.12.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/bobthecow/psysh.git",
+ "reference": "750bf031a48fd07c673dbe3f11f72362ea306d0d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/bobthecow/psysh/zipball/750bf031a48fd07c673dbe3f11f72362ea306d0d",
+ "reference": "750bf031a48fd07c673dbe3f11f72362ea306d0d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "nikic/php-parser": "^5.0 || ^4.0",
+ "php": "^8.0 || ^7.4",
+ "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4",
+ "symfony/var-dumper": "^7.0 || ^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."
+ },
+ "bin": [
+ "bin/psysh"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "0.12.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.12.0"
+ },
+ "time": "2023-12-20T15:28:09+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.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/complexity.git",
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a",
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "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.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T06:19:30+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.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5",
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "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.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T06:20:34+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.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/browser-kit.git",
+ "reference": "a3bb210e001580ec75e1d02b27fae3452e6bf502"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/a3bb210e001580ec75e1d02b27fae3452e6bf502",
+ "reference": "a3bb210e001580ec75e1d02b27fae3452e6bf502",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/dom-crawler": "^5.4|^6.0|^7.0"
+ },
+ "require-dev": {
+ "symfony/css-selector": "^5.4|^6.0|^7.0",
+ "symfony/http-client": "^5.4|^6.0|^7.0",
+ "symfony/mime": "^5.4|^6.0|^7.0",
+ "symfony/process": "^5.4|^6.0|^7.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.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-10-31T08:18:17+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v6.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "a550a7c99daeedef3f9d23fb82e3531525ff11fd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/a550a7c99daeedef3f9d23fb82e3531525ff11fd",
+ "reference": "a550a7c99daeedef3f9d23fb82e3531525ff11fd",
+ "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|^7.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|^7.0",
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/event-dispatcher": "^5.4|^6.0|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/lock": "^5.4|^6.0|^7.0",
+ "symfony/messenger": "^5.4|^6.0|^7.0",
+ "symfony/process": "^5.4|^6.0|^7.0",
+ "symfony/stopwatch": "^5.4|^6.0|^7.0",
+ "symfony/var-dumper": "^5.4|^6.0|^7.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.4.1"
+ },
+ "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-30T10:54:28+00:00"
+ },
+ {
+ "name": "symfony/css-selector",
+ "version": "v6.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/d036c6c0d0b09e24a14a35f8292146a658f986e4",
+ "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4",
+ "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.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-10-31T08:40:20+00:00"
+ },
+ {
+ "name": "symfony/dom-crawler",
+ "version": "v6.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "14ff4fd2a5c8969d6158dbe7ef5b17d6a9c6ba33"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/14ff4fd2a5c8969d6158dbe7ef5b17d6a9c6ba33",
+ "reference": "14ff4fd2a5c8969d6158dbe7ef5b17d6a9c6ba33",
+ "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|^7.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.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-11-20T16:41:16+00:00"
+ },
+ {
+ "name": "symfony/finder",
+ "version": "v6.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "11d736e97f116ac375a81f96e662911a34cd50ce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce",
+ "reference": "11d736e97f116ac375a81f96e662911a34cd50ce",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "require-dev": {
+ "symfony/filesystem": "^6.0|^7.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.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-10-31T17:30:12+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.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/b45fcf399ea9c3af543a92edf7172ba21174d809",
+ "reference": "b45fcf399ea9c3af543a92edf7172ba21174d809",
+ "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|^7.0",
+ "symfony/http-client": "^5.4|^6.0|^7.0",
+ "symfony/intl": "^6.2|^7.0",
+ "symfony/translation-contracts": "^2.5|^3.0",
+ "symfony/var-exporter": "^5.4|^6.0|^7.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.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-11-28T20:41:49+00:00"
+ },
+ {
+ "name": "symfony/var-dumper",
+ "version": "v6.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c40f7d17e91d8b407582ed51a2bbf83c52c367f6",
+ "reference": "c40f7d17e91d8b407582ed51a2bbf83c52c367f6",
+ "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|^7.0",
+ "symfony/error-handler": "^6.3|^7.0",
+ "symfony/http-kernel": "^5.4|^6.0|^7.0",
+ "symfony/process": "^5.4|^6.0|^7.0",
+ "symfony/uid": "^5.4|^6.0|^7.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.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-11-09T08:28:32+00:00"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v6.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587",
+ "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587",
+ "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|^7.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.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-11-06T11:00:25+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
+ "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
+ "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.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2023-11-20T00:12:19+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": [],
+ "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 100644
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 100644
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 100644
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 100644
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 100644
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/m240110_152351_create_company_table.php b/console/migrations/m240110_152351_create_company_table.php
new file mode 100644
index 0000000..f1f91cb
--- /dev/null
+++ b/console/migrations/m240110_152351_create_company_table.php
@@ -0,0 +1,33 @@
+createTable('{{%company}}', [
+ 'id' => $this->primaryKey(),
+ 'inn' => $this->string(255)->notNull(),
+ 'name' => $this->string(255)->notNull(),
+ 'address' => $this->string(255),
+ 'created_at' => $this->dateTime(),
+ 'updated_at' => $this->dateTime(),
+ 'status' => $this->integer(1)->defaultValue(1)
+ ]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropTable('{{%company}}');
+ }
+}
diff --git a/console/migrations/m240110_153348_create_addresses_table.php b/console/migrations/m240110_153348_create_addresses_table.php
new file mode 100644
index 0000000..34e6bfc
--- /dev/null
+++ b/console/migrations/m240110_153348_create_addresses_table.php
@@ -0,0 +1,52 @@
+createTable('{{%addresses}}', [
+ 'id' => $this->primaryKey(),
+ 'address' => $this->string(255)->notNull(),
+ 'company_id' => $this->integer(11)->notNull(),
+ 'name' => $this->string(255),
+ ]);
+
+ $this->createIndex('idx-addresses-company_id', 'addresses', 'company_id');
+
+ $this->addForeignKey(
+ 'fk-addresses-company_id',
+ 'addresses',
+ 'company_id',
+ 'company',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropForeignKey(
+ 'fk-addresses-company_id',
+ 'addresses'
+ );
+
+ // drops index for column `author_id`
+ $this->dropIndex(
+ 'idx-addresses-company_id',
+ 'addresses'
+ );
+
+ $this->dropTable('{{%addresses}}');
+ }
+}
diff --git a/console/migrations/m240110_154916_create_product_table.php b/console/migrations/m240110_154916_create_product_table.php
new file mode 100644
index 0000000..4bae1ff
--- /dev/null
+++ b/console/migrations/m240110_154916_create_product_table.php
@@ -0,0 +1,55 @@
+createTable('{{%product}}', [
+ 'id' => $this->primaryKey(),
+ 'title' => $this->string(255)->notNull(),
+ 'article' => $this->string(255)->notNull(),
+ 'company_id' => $this->integer(11)->notNull(),
+ 'type' => $this->integer(1)->defaultValue(1),
+ 'price' => $this->integer(11)->defaultValue(0),
+ 'status' => $this->integer(1)->defaultValue(1),
+ ]);
+
+ $this->createIndex('idx-product-company_id', 'product', 'company_id');
+
+ $this->addForeignKey(
+ 'fk-product-company_id',
+ 'product',
+ 'company_id',
+ 'company',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropForeignKey(
+ 'fk-product-company_id',
+ 'product'
+ );
+
+ // drops index for column `author_id`
+ $this->dropIndex(
+ 'idx-product-company_id',
+ 'product'
+ );
+
+ $this->dropTable('{{%product}}');
+ }
+}
diff --git a/console/migrations/m240110_155920_create_check_table.php b/console/migrations/m240110_155920_create_check_table.php
new file mode 100644
index 0000000..999a919
--- /dev/null
+++ b/console/migrations/m240110_155920_create_check_table.php
@@ -0,0 +1,75 @@
+createTable('{{%check}}', [
+ 'id' => $this->primaryKey(),
+ 'number' => $this->string(255)->notNull(),
+ 'company_id' => $this->integer(11)->notNull(),
+ 'addresses_id' => $this->integer(11)->notNull(),
+ 'status' => $this->integer(1)->defaultValue(1),
+ ]);
+
+ $this->createIndex('idx-check-company_id', 'check', 'company_id');
+
+ $this->addForeignKey(
+ 'fk-check-company_id',
+ 'check',
+ 'company_id',
+ 'company',
+ 'id',
+ 'CASCADE'
+ );
+
+ $this->createIndex('idx-check-addresses_id', 'check', 'addresses_id');
+
+ $this->addForeignKey(
+ 'fk-check-addresses_id',
+ 'check',
+ 'addresses_id',
+ 'addresses',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropForeignKey(
+ 'fk-check-company_id',
+ 'check'
+ );
+
+ // drops index for column `author_id`
+ $this->dropIndex(
+ 'idx-check-company_id',
+ 'check'
+ );
+
+ $this->dropForeignKey(
+ 'fk-check-addresses_id',
+ 'check'
+ );
+
+ // drops index for column `author_id`
+ $this->dropIndex(
+ 'idx-check-addresses_id',
+ 'check'
+ );
+
+ $this->dropTable('{{%check}}');
+ }
+}
diff --git a/console/migrations/m240110_161944_create_junction_table_for_check_and_product_tables.php b/console/migrations/m240110_161944_create_junction_table_for_check_and_product_tables.php
new file mode 100644
index 0000000..46ad836
--- /dev/null
+++ b/console/migrations/m240110_161944_create_junction_table_for_check_and_product_tables.php
@@ -0,0 +1,92 @@
+createTable('{{%check_product}}', [
+ 'check_id' => $this->integer(11)->notNull(),
+ 'product_id' => $this->integer(11)->notNull(),
+ 'quantity' => $this->integer(11)->defaultValue(1),
+ 'PRIMARY KEY(check_id, product_id)',
+ ]);
+
+ // creates index for column `check_id`
+ $this->createIndex(
+ '{{%idx-check_product-check_id}}',
+ '{{%check_product}}',
+ 'check_id'
+ );
+
+ // add foreign key for table `{{%check}}`
+ $this->addForeignKey(
+ '{{%fk-check_product-check_id}}',
+ '{{%check_product}}',
+ 'check_id',
+ '{{%check}}',
+ 'id',
+ 'CASCADE'
+ );
+
+ // creates index for column `product_id`
+ $this->createIndex(
+ '{{%idx-check_product-product_id}}',
+ '{{%check_product}}',
+ 'product_id'
+ );
+
+ // add foreign key for table `{{%product}}`
+ $this->addForeignKey(
+ '{{%fk-check_product-product_id}}',
+ '{{%check_product}}',
+ 'product_id',
+ '{{%product}}',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ // drops foreign key for table `{{%check}}`
+ $this->dropForeignKey(
+ '{{%fk-check_product-check_id}}',
+ '{{%check_product}}'
+ );
+
+ // drops index for column `check_id`
+ $this->dropIndex(
+ '{{%idx-check_product-check_id}}',
+ '{{%check_product}}'
+ );
+
+ // drops foreign key for table `{{%product}}`
+ $this->dropForeignKey(
+ '{{%fk-check_product-product_id}}',
+ '{{%check_product}}'
+ );
+
+ // drops index for column `product_id`
+ $this->dropIndex(
+ '{{%idx-check_product-product_id}}',
+ '{{%check_product}}'
+ );
+
+ $this->dropTable('{{%check_product}}');
+ }
+}
diff --git a/console/migrations/m240110_223124_add_user_id_column_at_company_table.php b/console/migrations/m240110_223124_add_user_id_column_at_company_table.php
new file mode 100644
index 0000000..4cd30f7
--- /dev/null
+++ b/console/migrations/m240110_223124_add_user_id_column_at_company_table.php
@@ -0,0 +1,44 @@
+addColumn('company', 'user_id', $this->integer(11)->notNull());
+
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+
+ $this->dropColumn('company', 'user_id');
+
+ }
+
+ /*
+ // Use up()/down() to run migration code without a transaction.
+ public function up()
+ {
+
+ }
+
+ public function down()
+ {
+ echo "m240110_223124_add_user_id_column_at_company_table cannot be reverted.\n";
+
+ return false;
+ }
+ */
+}
diff --git a/console/migrations/m240117_203610_add_additional_column_at_check_table.php b/console/migrations/m240117_203610_add_additional_column_at_check_table.php
new file mode 100644
index 0000000..2169d02
--- /dev/null
+++ b/console/migrations/m240117_203610_add_additional_column_at_check_table.php
@@ -0,0 +1,40 @@
+addColumn('check', 'additional', $this->text()->after('company_id'));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropColumn('check', 'additional');
+ }
+
+ /*
+ // Use up()/down() to run migration code without a transaction.
+ public function up()
+ {
+
+ }
+
+ public function down()
+ {
+ echo "m240117_203610_add_additional_column_at_check_table cannot be reverted.\n";
+
+ return false;
+ }
+ */
+}
diff --git a/console/migrations/m240117_205124_add_title_column_at_check_table.php b/console/migrations/m240117_205124_add_title_column_at_check_table.php
new file mode 100644
index 0000000..e4fa66e
--- /dev/null
+++ b/console/migrations/m240117_205124_add_title_column_at_check_table.php
@@ -0,0 +1,40 @@
+addColumn('check', 'title', $this->text()->after('company_id'));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropColumn('check', 'title');
+ }
+
+ /*
+ // Use up()/down() to run migration code without a transaction.
+ public function up()
+ {
+
+ }
+
+ public function down()
+ {
+ echo "m240117_205124_add_title_column_at_check_table cannot be reverted.\n";
+
+ return false;
+ }
+ */
+}
diff --git a/console/migrations/m240212_213157_create_product_category_table.php b/console/migrations/m240212_213157_create_product_category_table.php
new file mode 100644
index 0000000..6bbd57f
--- /dev/null
+++ b/console/migrations/m240212_213157_create_product_category_table.php
@@ -0,0 +1,57 @@
+createTable('{{%product_category}}', [
+ 'id' => $this->primaryKey(),
+ 'title' => $this->string('255')->notNull(),
+ 'parent_id' => $this->integer(11)->defaultValue(0),
+ 'company_id' => $this->integer(11)->notNull(),
+ 'status' => $this->integer(1)->defaultValue(1),
+ ]);
+
+ $this->createIndex(
+ 'idx-product_category-company_id',
+ 'product_category',
+ 'company_id'
+ );
+
+ // add foreign key for table `user`
+ $this->addForeignKey(
+ 'fk-product_category-company_id',
+ 'product_category',
+ 'company_id',
+ 'company',
+ 'id',
+ 'CASCADE'
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function safeDown()
+ {
+ $this->dropForeignKey(
+ 'fk-product_category-company_id',
+ 'product_category'
+ );
+
+ // drops index for column `author_id`
+ $this->dropIndex(
+ 'idx-product_category-company_id',
+ 'product_category'
+ );
+ $this->dropTable('{{%product_category}}');
+ }
+}
diff --git a/console/models/.gitkeep b/console/models/.gitkeep
new file mode 100644
index 0000000..72e8ffc
--- /dev/null
+++ b/console/models/.gitkeep
@@ -0,0 +1 @@
+*
diff --git a/console/runtime/.gitignore b/console/runtime/.gitignore
new file mode 100644
index 0000000..c96a04f
--- /dev/null
+++ b/console/runtime/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000..f8478f6
--- /dev/null
+++ b/frontend/assets/AppAsset.php
@@ -0,0 +1,23 @@
+ 'app-frontend',
+ 'basePath' => dirname(__DIR__),
+ 'bootstrap' => ['log'],
+ 'controllerNamespace' => 'frontend\controllers',
+ 'modules' => [
+ 'company' => [
+ 'class' => 'frontend\modules\company\Company',
+ ],
+ 'product' => [
+ 'class' => 'frontend\modules\product\Product',
+ ],
+ 'addresses' => [
+ 'class' => 'frontend\modules\addresses\Addresses',
+ ],
+ 'check' => [
+ 'class' => 'frontend\modules\check\Check',
+ ],
+ 'product_category' => [
+ 'class' => 'frontend\modules\product_category\ProductCategory',
+ ],
+ ],
+ 'components' => [
+ 'request' => [
+ 'csrfParam' => '_csrf-frontend',
+ ],
+ 'user' => [
+ 'identityClass' => 'common\models\User',
+ 'enableAutoLogin' => true,
+ 'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
+ ],
+ 'session' => [
+ // this is the name of the session cookie used for login on the frontend
+ 'name' => 'advanced-frontend',
+ ],
+ 'view' => [
+
+ ],
+ '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 100644
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 100644
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/SiteController.php b/frontend/controllers/SiteController.php
new file mode 100644
index 0000000..e29f15e
--- /dev/null
+++ b/frontend/controllers/SiteController.php
@@ -0,0 +1,265 @@
+ [
+ 'class' => AccessControl::class,
+ 'only' => ['logout', 'signup'],
+ 'rules' => [
+ [
+ 'actions' => ['signup'],
+ 'allow' => true,
+ 'roles' => ['?'],
+ ],
+ [
+ 'actions' => ['logout'],
+ 'allow' => true,
+ 'roles' => ['@'],
+ ],
+ ],
+ ],
+ 'verbs' => [
+ 'class' => VerbFilter::class,
+ 'actions' => [
+ 'logout' => ['post'],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function actions()
+ {
+ return [
+ 'error' => [
+ 'class' => \yii\web\ErrorAction::class,
+ ],
+ 'captcha' => [
+ 'class' => \yii\captcha\CaptchaAction::class,
+ 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
+ ],
+ ];
+ }
+
+ /**
+ * Displays homepage.
+ *
+ * @return mixed
+ */
+ public function actionIndex()
+ {
+ return $this->render('index');
+ }
+
+ /**
+ * Logs in a user.
+ *
+ * @return mixed
+ */
+ public function actionLogin()
+ {
+ $this->layout = 'main-login';
+
+ if (!Yii::$app->user->isGuest) {
+ return $this->goHome();
+ }
+
+ $model = new LoginForm();
+ if ($model->load(Yii::$app->request->post()) && $model->login()) {
+ return $this->goBack();
+ }
+
+ $model->password = '';
+
+ return $this->render('login', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Logs out the current user.
+ *
+ * @return mixed
+ */
+ public function actionLogout()
+ {
+ Yii::$app->user->logout();
+
+ return $this->goHome();
+ }
+
+ /**
+ * Displays contact page.
+ *
+ * @return mixed
+ */
+ public function actionContact()
+ {
+ $model = new ContactForm();
+ if ($model->load(Yii::$app->request->post()) && $model->validate()) {
+ if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
+ Yii::$app->session->setFlash('success', 'Thank you for contacting us. We will respond to you as soon as possible.');
+ } else {
+ Yii::$app->session->setFlash('error', 'There was an error sending your message.');
+ }
+
+ return $this->refresh();
+ }
+
+ return $this->render('contact', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Displays about page.
+ *
+ * @return mixed
+ */
+ public function actionAbout()
+ {
+ return $this->render('about');
+ }
+
+ /**
+ * Signs user up.
+ *
+ * @return mixed
+ */
+ public function actionSignup()
+ {
+ $this->layout = 'main-login';
+
+ $model = new SignupForm();
+ if ($model->load(Yii::$app->request->post()) && $model->signup()) {
+ Yii::$app->session->setFlash('success', 'Спасиюо за регистрацию');
+ return $this->goHome();
+ }
+
+ return $this->render('signup', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Requests password reset.
+ *
+ * @return mixed
+ */
+ public function actionRequestPasswordReset()
+ {
+ $model = new PasswordResetRequestForm();
+ if ($model->load(Yii::$app->request->post()) && $model->validate()) {
+ if ($model->sendEmail()) {
+ Yii::$app->session->setFlash('success', 'Check your email for further instructions.');
+
+ return $this->goHome();
+ }
+
+ 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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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/modules/addresses/Addresses.php b/frontend/modules/addresses/Addresses.php
new file mode 100644
index 0000000..c67af94
--- /dev/null
+++ b/frontend/modules/addresses/Addresses.php
@@ -0,0 +1,24 @@
+companyService = new CompanyService();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function behaviors()
+ {
+ return [
+ 'verbs' => [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Lists all Addresses models.
+ * @return mixed
+ */
+ public function actionIndex()
+ {
+ $searchModel = new AddressesSearch();
+ $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
+
+ return $this->render('index', [
+ 'searchModel' => $searchModel,
+ 'dataProvider' => $dataProvider,
+ 'companyService' => $this->companyService,
+ ]);
+ }
+
+ /**
+ * Displays a single Addresses model.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ 'companyService' => $this->companyService,
+ ]);
+ }
+
+ /**
+ * Creates a new Addresses model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return mixed
+ */
+ public function actionCreate()
+ {
+ $model = new Addresses();
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ 'companyService' => $this->companyService,
+ ]);
+ }
+
+ /**
+ * Updates an existing Addresses model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ 'companyService' => $this->companyService
+ ]);
+ }
+
+ /**
+ * Deletes an existing Addresses model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the Addresses 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 Addresses the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Addresses::findOne($id)) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/frontend/modules/addresses/controllers/DefaultController.php b/frontend/modules/addresses/controllers/DefaultController.php
new file mode 100644
index 0000000..fed8c20
--- /dev/null
+++ b/frontend/modules/addresses/controllers/DefaultController.php
@@ -0,0 +1,20 @@
+render('index');
+ }
+}
diff --git a/frontend/modules/addresses/models/Addresses.php b/frontend/modules/addresses/models/Addresses.php
new file mode 100644
index 0000000..7decac8
--- /dev/null
+++ b/frontend/modules/addresses/models/Addresses.php
@@ -0,0 +1,8 @@
+ $query,
+ ]);
+
+ $this->load($params);
+
+ if (!$this->validate()) {
+ // uncomment the following line if you do not want to return any records when validation fails
+ // $query->where('0=1');
+ return $dataProvider;
+ }
+
+ // grid filtering conditions
+ $query->andFilterWhere([
+ 'id' => $this->id,
+ 'company_id' => $this->company_id,
+ ]);
+
+ $query->andFilterWhere(['like', 'address', $this->address])
+ ->andFilterWhere(['like', 'name', $this->name]);
+
+ return $dataProvider;
+ }
+}
diff --git a/frontend/modules/addresses/views/addresses/_form.php b/frontend/modules/addresses/views/addresses/_form.php
new file mode 100644
index 0000000..c26f675
--- /dev/null
+++ b/frontend/modules/addresses/views/addresses/_form.php
@@ -0,0 +1,29 @@
+
+
+
diff --git a/frontend/modules/addresses/views/addresses/_search.php b/frontend/modules/addresses/views/addresses/_search.php
new file mode 100644
index 0000000..d0f6134
--- /dev/null
+++ b/frontend/modules/addresses/views/addresses/_search.php
@@ -0,0 +1,36 @@
+
+
+
+
+
+ ['index'],
+ 'method' => 'get',
+ ]); ?>
+
+ = $form->field($model, 'id') ?>
+
+ = $form->field($model, 'address') ?>
+
+ = $form->field($model, 'company_id') ?>
+
+ = $form->field($model, 'name') ?>
+
+
+ = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
+ = Html::resetButton('Reset', ['class' => 'btn btn-outline-secondary']) ?>
+
+
+
+
+
+
+
diff --git a/frontend/modules/addresses/views/addresses/create.php b/frontend/modules/addresses/views/addresses/create.php
new file mode 100644
index 0000000..c4d7191
--- /dev/null
+++ b/frontend/modules/addresses/views/addresses/create.php
@@ -0,0 +1,30 @@
+title = 'Добавить отделение';
+$this->params['breadcrumbs'][] = ['label' => 'Отделения', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
+
+
+ =$this->render('_form', [
+ 'model' => $model,
+ 'companyService' => $companyService,
+ ]) ?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/addresses/views/addresses/index.php b/frontend/modules/addresses/views/addresses/index.php
new file mode 100644
index 0000000..1be0843
--- /dev/null
+++ b/frontend/modules/addresses/views/addresses/index.php
@@ -0,0 +1,62 @@
+title = 'Отделения';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
+
+
+
+ = Html::a('Добавить', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+
+
+ render('_search', ['model' => $searchModel]); ?>
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'filterModel' => $searchModel,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ 'id',
+ 'address',
+ [
+ 'attribute' => 'company_id',
+ 'value' => function($model) use ($companyService){
+ return $companyService->getCompany($model->company_id)->name ?? null;
+ }
+ ],
+ 'name',
+
+ ['class' => 'hail812\adminlte3\yii\grid\ActionColumn'],
+ ],
+ 'summaryOptions' => ['class' => 'summary mb-2'],
+ 'pager' => [
+ 'class' => 'yii\bootstrap4\LinkPager',
+ ]
+ ]); ?>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/modules/addresses/views/addresses/update.php b/frontend/modules/addresses/views/addresses/update.php
new file mode 100644
index 0000000..89c6683
--- /dev/null
+++ b/frontend/modules/addresses/views/addresses/update.php
@@ -0,0 +1,30 @@
+title = 'Update Addresses: ' . $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Addresses', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
+
+
+
+ =$this->render('_form', [
+ 'model' => $model,
+ 'companyService' => $companyService,
+ ]) ?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/addresses/views/addresses/view.php b/frontend/modules/addresses/views/addresses/view.php
new file mode 100644
index 0000000..f102c7a
--- /dev/null
+++ b/frontend/modules/addresses/views/addresses/view.php
@@ -0,0 +1,53 @@
+title = $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Addresses', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
+
+
+
+
+ = Html::a('Список', ['index'], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Редактировать', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Удалить', ['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',
+ 'address',
+ [
+ 'attribute' => 'company_id',
+ 'value' => $companyService->getCompany($model->company_id)->name ?? null,
+ ],
+ 'name',
+ ],
+ ]) ?>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/addresses/views/default/index.php b/frontend/modules/addresses/views/default/index.php
new file mode 100644
index 0000000..f891fb1
--- /dev/null
+++ b/frontend/modules/addresses/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/frontend/modules/check/Check.php b/frontend/modules/check/Check.php
new file mode 100644
index 0000000..049c5fe
--- /dev/null
+++ b/frontend/modules/check/Check.php
@@ -0,0 +1,24 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Lists all Check models.
+ * @return mixed
+ */
+ public function actionIndex()
+ {
+ $searchModel = new CheckSearch();
+ $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
+
+ return $this->render('index', [
+ 'searchModel' => $searchModel,
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Check model.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new Check model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return mixed
+ */
+ public function actionCreate()
+ {
+ $model = new Check();
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Updates an existing Check model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Deletes an existing Check model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the Check 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 Check the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Check::findOne($id)) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/frontend/modules/check/controllers/DefaultController.php b/frontend/modules/check/controllers/DefaultController.php
new file mode 100644
index 0000000..a22b4fb
--- /dev/null
+++ b/frontend/modules/check/controllers/DefaultController.php
@@ -0,0 +1,20 @@
+render('index');
+ }
+}
diff --git a/frontend/modules/check/models/Check.php b/frontend/modules/check/models/Check.php
new file mode 100644
index 0000000..3201843
--- /dev/null
+++ b/frontend/modules/check/models/Check.php
@@ -0,0 +1,8 @@
+ $query,
+ ]);
+
+ $this->load($params);
+
+ if (!$this->validate()) {
+ // uncomment the following line if you do not want to return any records when validation fails
+ // $query->where('0=1');
+ return $dataProvider;
+ }
+
+ // grid filtering conditions
+ $query->andFilterWhere([
+ 'id' => $this->id,
+ 'company_id' => $this->company_id,
+ 'addresses_id' => $this->addresses_id,
+ 'status' => $this->status,
+ ]);
+
+ $query->andFilterWhere(['like', 'number', $this->number])
+ ->andFilterWhere(['like', 'additional', $this->additional]);
+
+ return $dataProvider;
+ }
+}
diff --git a/frontend/modules/check/views/check/_form.php b/frontend/modules/check/views/check/_form.php
new file mode 100644
index 0000000..79f8add
--- /dev/null
+++ b/frontend/modules/check/views/check/_form.php
@@ -0,0 +1,27 @@
+
+
+
diff --git a/frontend/modules/check/views/check/_search.php b/frontend/modules/check/views/check/_search.php
new file mode 100644
index 0000000..edcc7e9
--- /dev/null
+++ b/frontend/modules/check/views/check/_search.php
@@ -0,0 +1,40 @@
+
+
+
+
+
+ ['index'],
+ 'method' => 'get',
+ ]); ?>
+
+ = $form->field($model, 'id') ?>
+
+ = $form->field($model, 'number') ?>
+
+ = $form->field($model, 'company_id') ?>
+
+ = $form->field($model, 'additional') ?>
+
+ = $form->field($model, 'addresses_id') ?>
+
+ field($model, 'status') ?>
+
+
+ = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
+ = Html::resetButton('Reset', ['class' => 'btn btn-outline-secondary']) ?>
+
+
+
+
+
+
+
diff --git a/frontend/modules/check/views/check/create.php b/frontend/modules/check/views/check/create.php
new file mode 100644
index 0000000..2395414
--- /dev/null
+++ b/frontend/modules/check/views/check/create.php
@@ -0,0 +1,27 @@
+title = 'Создать чек';
+$this->params['breadcrumbs'][] = ['label' => 'Чеки', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
+
+
+ =$this->render('_form', [
+ 'model' => $model
+ ]) ?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/check/views/check/index.php b/frontend/modules/check/views/check/index.php
new file mode 100644
index 0000000..34420f7
--- /dev/null
+++ b/frontend/modules/check/views/check/index.php
@@ -0,0 +1,58 @@
+title = 'Чеки';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
+
+
+
+ = Html::a('Создать чек', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+
+
+ render('_search', ['model' => $searchModel]); ?>
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'filterModel' => $searchModel,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+// 'id',
+ 'title',
+ 'number',
+ 'company_id',
+ 'additional:ntext',
+ //'addresses_id',
+ //'status',
+
+ ['class' => 'hail812\adminlte3\yii\grid\ActionColumn'],
+ ],
+ 'summaryOptions' => ['class' => 'summary mb-2'],
+ 'pager' => [
+ 'class' => 'yii\bootstrap4\LinkPager',
+ ]
+ ]); ?>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/modules/check/views/check/update.php b/frontend/modules/check/views/check/update.php
new file mode 100644
index 0000000..63ed140
--- /dev/null
+++ b/frontend/modules/check/views/check/update.php
@@ -0,0 +1,26 @@
+title = 'Update Check: ' . $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Checks', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
+
+
+
+ =$this->render('_form', [
+ 'model' => $model
+ ]) ?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/check/views/check/view.php b/frontend/modules/check/views/check/view.php
new file mode 100644
index 0000000..f08b15a
--- /dev/null
+++ b/frontend/modules/check/views/check/view.php
@@ -0,0 +1,49 @@
+title = $model->id;
+$this->params['breadcrumbs'][] = ['label' => 'Checks', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
+
+
+
+
+ = 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',
+ 'number',
+ 'company_id',
+ 'additional:ntext',
+ 'addresses_id',
+ 'status',
+ ],
+ ]) ?>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/check/views/default/index.php b/frontend/modules/check/views/default/index.php
new file mode 100644
index 0000000..9c7f0dc
--- /dev/null
+++ b/frontend/modules/check/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/frontend/modules/company/Company.php b/frontend/modules/company/Company.php
new file mode 100644
index 0000000..dc775fc
--- /dev/null
+++ b/frontend/modules/company/Company.php
@@ -0,0 +1,24 @@
+service = new CompanyService();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function behaviors()
+ {
+ return array_merge(
+ parent::behaviors(),
+ [
+ 'verbs' => [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ 'access' => [
+ 'class' => \yii\filters\AccessControl::className(),
+ 'rules' => [
+ [
+ 'allow' => true,
+ 'roles' => ['@'],
+ ],
+ ],
+ ],
+ ]
+ );
+ }
+
+ /**
+ * Lists all Company models.
+ *
+ * @return string
+ */
+ public function actionIndex()
+ {
+ $searchModel = new CompanySearch();
+ $dataProvider = $searchModel->search($this->request->queryParams);
+
+ return $this->render('index', [
+ 'searchModel' => $searchModel,
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Company 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 Company model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return string|\yii\web\Response
+ */
+ public function actionCreate()
+ {
+ $model = new Company();
+ $model->user_id = \Yii::$app->user->id;
+
+ 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,
+ 'companies' => $this->service->getCompaniesByUserArr(),
+ ]);
+ }
+
+ /**
+ * Updates an existing Company 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(int $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 Company 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 Company 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 Company the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = Company::findOne(['id' => $id])) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/frontend/modules/company/controllers/DefaultController.php b/frontend/modules/company/controllers/DefaultController.php
new file mode 100644
index 0000000..e527435
--- /dev/null
+++ b/frontend/modules/company/controllers/DefaultController.php
@@ -0,0 +1,20 @@
+render('index');
+ }
+}
diff --git a/frontend/modules/company/models/Company.php b/frontend/modules/company/models/Company.php
new file mode 100644
index 0000000..ef6da03
--- /dev/null
+++ b/frontend/modules/company/models/Company.php
@@ -0,0 +1,8 @@
+ $query,
+ ]);
+
+ $this->load($params);
+
+ if (!$this->validate()) {
+ // uncomment the following line if you do not want to return any records when validation fails
+ // $query->where('0=1');
+ return $dataProvider;
+ }
+
+ $query->where(['user_id' => \Yii::$app->user->id]);
+
+ // grid filtering conditions
+ $query->andFilterWhere([
+ 'id' => $this->id,
+ 'inn' => $this->inn,
+ 'created_at' => $this->created_at,
+ 'updated_at' => $this->updated_at,
+ 'status' => $this->status,
+ ]);
+
+ $query->andFilterWhere(['like', 'name', $this->name])
+ ->andFilterWhere(['like', 'address', $this->address]);
+
+ $query->orderBy("id DESC");
+
+ return $dataProvider;
+ }
+}
diff --git a/frontend/modules/company/views/company/_form.php b/frontend/modules/company/views/company/_form.php
new file mode 100644
index 0000000..3958f16
--- /dev/null
+++ b/frontend/modules/company/views/company/_form.php
@@ -0,0 +1,29 @@
+
+
+
diff --git a/frontend/modules/company/views/company/_search.php b/frontend/modules/company/views/company/_search.php
new file mode 100644
index 0000000..2e9a1a5
--- /dev/null
+++ b/frontend/modules/company/views/company/_search.php
@@ -0,0 +1,39 @@
+
+
+
+
+ ['index'],
+ 'method' => 'get',
+ ]); ?>
+
+ = $form->field($model, 'id') ?>
+
+ = $form->field($model, 'inn') ?>
+
+ = $form->field($model, 'name') ?>
+
+ = $form->field($model, 'address') ?>
+
+ = $form->field($model, 'created_at') ?>
+
+ field($model, 'updated_at') ?>
+
+ field($model, 'status') ?>
+
+
+ = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
+ = Html::resetButton('Reset', ['class' => 'btn btn-outline-secondary']) ?>
+
+
+
+
+
diff --git a/frontend/modules/company/views/company/create.php b/frontend/modules/company/views/company/create.php
new file mode 100644
index 0000000..3cdbc7f
--- /dev/null
+++ b/frontend/modules/company/views/company/create.php
@@ -0,0 +1,18 @@
+title = 'Добавить';
+$this->params['breadcrumbs'][] = ['label' => 'Компании', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/frontend/modules/company/views/company/index.php b/frontend/modules/company/views/company/index.php
new file mode 100644
index 0000000..cad38f9
--- /dev/null
+++ b/frontend/modules/company/views/company/index.php
@@ -0,0 +1,47 @@
+title = 'Компании';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+ = Html::a('Создать', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+ render('_search', ['model' => $searchModel]); ?>
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'filterModel' => $searchModel,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ 'id',
+ 'inn',
+ 'name',
+ 'address',
+ 'created_at',
+ //'updated_at',
+ //'status',
+ [
+ 'class' => ActionColumn::className(),
+ 'urlCreator' => function ($action, Company $model, $key, $index, $column) {
+ return Url::toRoute([$action, 'id' => $model->id]);
+ }
+ ],
+ ],
+ ]); ?>
+
+
+
diff --git a/frontend/modules/company/views/company/update.php b/frontend/modules/company/views/company/update.php
new file mode 100644
index 0000000..9c8f38a
--- /dev/null
+++ b/frontend/modules/company/views/company/update.php
@@ -0,0 +1,19 @@
+title = 'Редактировать: ' . $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Компании', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Редактировать';
+?>
+
+
+ = $this->render('_form', [
+ 'model' => $model,
+ ]) ?>
+
+
diff --git a/frontend/modules/company/views/company/view.php b/frontend/modules/company/views/company/view.php
new file mode 100644
index 0000000..d7a091c
--- /dev/null
+++ b/frontend/modules/company/views/company/view.php
@@ -0,0 +1,41 @@
+title = $model->name;
+$this->params['breadcrumbs'][] = ['label' => 'Компании', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
+ = Html::a('Список', ['index'], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Редактировать', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Удалить', ['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',
+ 'inn',
+ 'name',
+ 'address',
+ 'created_at',
+ 'updated_at',
+ 'status',
+ ],
+ ]) ?>
+
+
diff --git a/frontend/modules/company/views/default/index.php b/frontend/modules/company/views/default/index.php
new file mode 100644
index 0000000..9b6a7bf
--- /dev/null
+++ b/frontend/modules/company/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/frontend/modules/product/Product.php b/frontend/modules/product/Product.php
new file mode 100644
index 0000000..eb8e8a5
--- /dev/null
+++ b/frontend/modules/product/Product.php
@@ -0,0 +1,24 @@
+render('index');
+ }
+}
diff --git a/frontend/modules/product/controllers/ProductController.php b/frontend/modules/product/controllers/ProductController.php
new file mode 100644
index 0000000..1b33516
--- /dev/null
+++ b/frontend/modules/product/controllers/ProductController.php
@@ -0,0 +1,139 @@
+companyService = new CompanyService();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function behaviors()
+ {
+ return [
+ 'verbs' => [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Lists all Product models.
+ * @return mixed
+ */
+ public function actionIndex()
+ {
+ $searchModel = new ProductSearch();
+ $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
+
+ return $this->render('index', [
+ 'searchModel' => $searchModel,
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single Product model.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ 'companyService' => $this->companyService,
+ ]);
+ }
+
+ /**
+ * Creates a new Product model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return mixed
+ */
+ public function actionCreate()
+ {
+ $model = new Product();
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ 'companies' => $this->companyService->getCompaniesByUserArr(),
+ ]);
+ }
+
+ /**
+ * Updates an existing Product model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ 'companies' => $this->companyService->getCompaniesByUserArr(),
+ ]);
+ }
+
+ /**
+ * Deletes an existing Product model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id ID
+ * @return mixed
+ * @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)) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/frontend/modules/product/models/Product.php b/frontend/modules/product/models/Product.php
new file mode 100644
index 0000000..e162c4d
--- /dev/null
+++ b/frontend/modules/product/models/Product.php
@@ -0,0 +1,8 @@
+ $query,
+ ]);
+
+ $this->load($params);
+
+ if (!$this->validate()) {
+ // uncomment the following line if you do not want to return any records when validation fails
+ // $query->where('0=1');
+ return $dataProvider;
+ }
+
+ // grid filtering conditions
+ $query->andFilterWhere([
+ 'id' => $this->id,
+ 'company_id' => $this->company_id,
+ 'type' => $this->type,
+ 'price' => $this->price,
+ 'status' => $this->status,
+ ]);
+
+ $query->andFilterWhere(['like', 'title', $this->title])
+ ->andFilterWhere(['like', 'article', $this->article]);
+
+ return $dataProvider;
+ }
+}
diff --git a/frontend/modules/product/views/default/index.php b/frontend/modules/product/views/default/index.php
new file mode 100644
index 0000000..218cc44
--- /dev/null
+++ b/frontend/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/frontend/modules/product/views/product/_form.php b/frontend/modules/product/views/product/_form.php
new file mode 100644
index 0000000..aeca88c
--- /dev/null
+++ b/frontend/modules/product/views/product/_form.php
@@ -0,0 +1,34 @@
+
+
+
diff --git a/frontend/modules/product/views/product/_search.php b/frontend/modules/product/views/product/_search.php
new file mode 100644
index 0000000..69c1a50
--- /dev/null
+++ b/frontend/modules/product/views/product/_search.php
@@ -0,0 +1,42 @@
+
+
+
+
+
+ ['index'],
+ 'method' => 'get',
+ ]); ?>
+
+ = $form->field($model, 'id') ?>
+
+ = $form->field($model, 'title') ?>
+
+ = $form->field($model, 'article') ?>
+
+ = $form->field($model, 'company_id') ?>
+
+ = $form->field($model, 'type') ?>
+
+ field($model, 'price') ?>
+
+ field($model, 'status') ?>
+
+
+ = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
+ = Html::resetButton('Reset', ['class' => 'btn btn-outline-secondary']) ?>
+
+
+
+
+
+
+
diff --git a/frontend/modules/product/views/product/create.php b/frontend/modules/product/views/product/create.php
new file mode 100644
index 0000000..b272e64
--- /dev/null
+++ b/frontend/modules/product/views/product/create.php
@@ -0,0 +1,29 @@
+title = 'Добавить продукт';
+$this->params['breadcrumbs'][] = ['label' => 'Продукты', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
+
+
+ =$this->render('_form', [
+ 'model' => $model,
+ 'companies' => $companies,
+ ]) ?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/product/views/product/index.php b/frontend/modules/product/views/product/index.php
new file mode 100644
index 0000000..c061d8e
--- /dev/null
+++ b/frontend/modules/product/views/product/index.php
@@ -0,0 +1,58 @@
+title = 'Товары';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
+
+
+
+ = Html::a('Добавть', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+
+
+ render('_search', ['model' => $searchModel]); ?>
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'filterModel' => $searchModel,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ //'id',
+ 'title',
+ 'article',
+ //'company_id',
+ //'type',
+ //'price',
+ //'status',
+
+ ['class' => 'hail812\adminlte3\yii\grid\ActionColumn'],
+ ],
+ 'summaryOptions' => ['class' => 'summary mb-2'],
+ 'pager' => [
+ 'class' => 'yii\bootstrap4\LinkPager',
+ ]
+ ]); ?>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/modules/product/views/product/update.php b/frontend/modules/product/views/product/update.php
new file mode 100644
index 0000000..5778165
--- /dev/null
+++ b/frontend/modules/product/views/product/update.php
@@ -0,0 +1,28 @@
+title = 'Редактировать: ' . $model->title;
+$this->params['breadcrumbs'][] = ['label' => 'Товары', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->title, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Редактировать';
+?>
+
+
+
+
+
+
+ =$this->render('_form', [
+ 'model' => $model,
+ 'companies' => $companies,
+ ]) ?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/product/views/product/view.php b/frontend/modules/product/views/product/view.php
new file mode 100644
index 0000000..86e2e40
--- /dev/null
+++ b/frontend/modules/product/views/product/view.php
@@ -0,0 +1,62 @@
+title = $model->title;
+$this->params['breadcrumbs'][] = ['label' => 'Продукты', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
+
+
+
+
+ = Html::a('Список', ['index'], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Редактировать', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
+ = Html::a('Удалить', ['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',
+ 'title',
+ 'article',
+ [
+ 'attribute' => 'company_id',
+ 'value' => $companyService->getCompany($model->company_id)->name ?? null
+ ],
+ [
+ 'attribute' => 'type',
+ 'value' => \common\models\Product::getType()[$model->type]
+ ],
+ 'price',
+ [
+ 'attribute' => 'status',
+ 'value' => \common\models\Product::getStatus()[$model->status]
+ ],
+ ],
+ ]) ?>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/product_category/ProductCategory.php b/frontend/modules/product_category/ProductCategory.php
new file mode 100644
index 0000000..3b6005f
--- /dev/null
+++ b/frontend/modules/product_category/ProductCategory.php
@@ -0,0 +1,24 @@
+render('index');
+ }
+}
diff --git a/frontend/modules/product_category/controllers/ProductCategoryController.php b/frontend/modules/product_category/controllers/ProductCategoryController.php
new file mode 100644
index 0000000..9c09e16
--- /dev/null
+++ b/frontend/modules/product_category/controllers/ProductCategoryController.php
@@ -0,0 +1,132 @@
+ [
+ 'class' => VerbFilter::className(),
+ 'actions' => [
+ 'delete' => ['POST'],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Lists all ProductCategory models.
+ * @return mixed
+ */
+ public function actionIndex()
+ {
+ $searchModel = new ProductCategorySearch();
+ $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
+
+ return $this->render('index', [
+ 'searchModel' => $searchModel,
+ 'dataProvider' => $dataProvider,
+ ]);
+ }
+
+ /**
+ * Displays a single ProductCategory model.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionView($id)
+ {
+ return $this->render('view', [
+ 'model' => $this->findModel($id),
+ ]);
+ }
+
+ /**
+ * Creates a new ProductCategory model.
+ * If creation is successful, the browser will be redirected to the 'view' page.
+ * @return mixed
+ */
+ public function actionCreate()
+ {
+ $model = new ProductCategory();
+ $user = User::findOne(Yii::$app->user->id);
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('create', [
+ 'model' => $model,
+ 'user' => $user,
+ ]);
+ }
+
+ /**
+ * Updates an existing ProductCategory model.
+ * If update is successful, the browser will be redirected to the 'view' page.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionUpdate($id)
+ {
+ $model = $this->findModel($id);
+
+ if ($model->load(Yii::$app->request->post()) && $model->save()) {
+ return $this->redirect(['view', 'id' => $model->id]);
+ }
+
+ return $this->render('update', [
+ 'model' => $model,
+ ]);
+ }
+
+ /**
+ * Deletes an existing ProductCategory model.
+ * If deletion is successful, the browser will be redirected to the 'index' page.
+ * @param int $id ID
+ * @return mixed
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ public function actionDelete($id)
+ {
+ $this->findModel($id)->delete();
+
+ return $this->redirect(['index']);
+ }
+
+ /**
+ * Finds the ProductCategory 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 ProductCategory the loaded model
+ * @throws NotFoundHttpException if the model cannot be found
+ */
+ protected function findModel($id)
+ {
+ if (($model = ProductCategory::findOne($id)) !== null) {
+ return $model;
+ }
+
+ throw new NotFoundHttpException('The requested page does not exist.');
+ }
+}
diff --git a/frontend/modules/product_category/models/ProductCategory.php b/frontend/modules/product_category/models/ProductCategory.php
new file mode 100644
index 0000000..d2b5af7
--- /dev/null
+++ b/frontend/modules/product_category/models/ProductCategory.php
@@ -0,0 +1,8 @@
+ $query,
+ ]);
+
+ $this->load($params);
+
+ if (!$this->validate()) {
+ // uncomment the following line if you do not want to return any records when validation fails
+ // $query->where('0=1');
+ return $dataProvider;
+ }
+
+ // grid filtering conditions
+ $query->andFilterWhere([
+ 'id' => $this->id,
+ 'parent_id' => $this->parent_id,
+ 'company_id' => $this->company_id,
+ 'status' => $this->status,
+ ]);
+
+ $query->andFilterWhere(['like', 'title', $this->title]);
+
+ return $dataProvider;
+ }
+}
diff --git a/frontend/modules/product_category/views/default/index.php b/frontend/modules/product_category/views/default/index.php
new file mode 100644
index 0000000..7cc0ca0
--- /dev/null
+++ b/frontend/modules/product_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/frontend/modules/product_category/views/product-category/_form.php b/frontend/modules/product_category/views/product-category/_form.php
new file mode 100644
index 0000000..8a8304e
--- /dev/null
+++ b/frontend/modules/product_category/views/product-category/_form.php
@@ -0,0 +1,32 @@
+
+
+
diff --git a/frontend/modules/product_category/views/product-category/_search.php b/frontend/modules/product_category/views/product-category/_search.php
new file mode 100644
index 0000000..f5496f3
--- /dev/null
+++ b/frontend/modules/product_category/views/product-category/_search.php
@@ -0,0 +1,38 @@
+
+
+
+
+
+ ['index'],
+ 'method' => 'get',
+ ]); ?>
+
+ = $form->field($model, 'id') ?>
+
+ = $form->field($model, 'title') ?>
+
+ = $form->field($model, 'parent_id') ?>
+
+ = $form->field($model, 'company_id') ?>
+
+ = $form->field($model, 'status') ?>
+
+
+ = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
+ = Html::resetButton('Reset', ['class' => 'btn btn-outline-secondary']) ?>
+
+
+
+
+
+
+
diff --git a/frontend/modules/product_category/views/product-category/create.php b/frontend/modules/product_category/views/product-category/create.php
new file mode 100644
index 0000000..0c95871
--- /dev/null
+++ b/frontend/modules/product_category/views/product-category/create.php
@@ -0,0 +1,30 @@
+title = 'Добавить категорию';
+$this->params['breadcrumbs'][] = ['label' => 'Категории товаров', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
+
+
+ =$this->render('_form', [
+ 'model' => $model,
+ 'user' => $user,
+ ]) ?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/product_category/views/product-category/index.php b/frontend/modules/product_category/views/product-category/index.php
new file mode 100644
index 0000000..5b40cc2
--- /dev/null
+++ b/frontend/modules/product_category/views/product-category/index.php
@@ -0,0 +1,56 @@
+title = 'Категории товаров';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
+
+
+
+ = Html::a('Создать', ['create'], ['class' => 'btn btn-success']) ?>
+
+
+
+
+ render('_search', ['model' => $searchModel]); ?>
+
+ = GridView::widget([
+ 'dataProvider' => $dataProvider,
+ 'filterModel' => $searchModel,
+ 'columns' => [
+ ['class' => 'yii\grid\SerialColumn'],
+
+ 'id',
+ 'title',
+ //'parent_id',
+ 'company_id',
+ 'status',
+
+ ['class' => 'hail812\adminlte3\yii\grid\ActionColumn'],
+ ],
+ 'summaryOptions' => ['class' => 'summary mb-2'],
+ 'pager' => [
+ 'class' => 'yii\bootstrap4\LinkPager',
+ ]
+ ]); ?>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/modules/product_category/views/product-category/update.php b/frontend/modules/product_category/views/product-category/update.php
new file mode 100644
index 0000000..894b3a6
--- /dev/null
+++ b/frontend/modules/product_category/views/product-category/update.php
@@ -0,0 +1,30 @@
+title = 'Update Product Category: ' . $model->title;
+$this->params['breadcrumbs'][] = ['label' => 'Product Categories', 'url' => ['index']];
+$this->params['breadcrumbs'][] = ['label' => $model->title, 'url' => ['view', 'id' => $model->id]];
+$this->params['breadcrumbs'][] = 'Update';
+?>
+
+
+
+
+
+
+ =$this->render('_form', [
+ 'model' => $model,
+ 'user' => $user,
+ ]) ?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/modules/product_category/views/product-category/view.php b/frontend/modules/product_category/views/product-category/view.php
new file mode 100644
index 0000000..8dc5a28
--- /dev/null
+++ b/frontend/modules/product_category/views/product-category/view.php
@@ -0,0 +1,48 @@
+title = $model->title;
+$this->params['breadcrumbs'][] = ['label' => 'Product Categories', 'url' => ['index']];
+$this->params['breadcrumbs'][] = $this->title;
+\yii\web\YiiAsset::register($this);
+?>
+
+
+
+
+
+
+
+ = 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',
+ 'title',
+ 'parent_id',
+ 'company_id',
+ 'status',
+ ],
+ ]) ?>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/runtime/.gitignore b/frontend/runtime/.gitignore
new file mode 100644
index 0000000..c96a04f
--- /dev/null
+++ b/frontend/runtime/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/frontend/tests/_bootstrap.php b/frontend/tests/_bootstrap.php
new file mode 100644
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 100644
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 100644
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 100644
index 0000000..36e264c
--- /dev/null
+++ b/frontend/tests/_support/.gitignore
@@ -0,0 +1 @@
+_generated
diff --git a/frontend/tests/_support/FunctionalTester.php b/frontend/tests/_support/FunctionalTester.php
new file mode 100644
index 0000000..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 100644
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 100644
index 0000000..47716f0
--- /dev/null
+++ b/frontend/tests/acceptance/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Cept
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
\ No newline at end of file
diff --git a/frontend/tests/functional.suite.yml b/frontend/tests/functional.suite.yml
new file mode 100644
index 0000000..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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000..30ed54b
--- /dev/null
+++ b/frontend/tests/functional/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Cests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
\ No newline at end of file
diff --git a/frontend/tests/unit.suite.yml b/frontend/tests/unit.suite.yml
new file mode 100644
index 0000000..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 100644
index 0000000..e432ce5
--- /dev/null
+++ b/frontend/tests/unit/_bootstrap.php
@@ -0,0 +1,16 @@
+ 'davert']);
+ * ```
+ *
+ * In Tests
+ *
+ * ```php
+ * \Codeception\Util\Fixtures::get('user1');
+ * ```
+ */
diff --git a/frontend/tests/unit/models/ContactFormTest.php b/frontend/tests/unit/models/ContactFormTest.php
new file mode 100644
index 0000000..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 100644
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 100644
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 100644
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 100644
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 100644
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/content.php b/frontend/views/layouts/content.php
new file mode 100644
index 0000000..adba668
--- /dev/null
+++ b/frontend/views/layouts/content.php
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/views/layouts/control-sidebar.php b/frontend/views/layouts/control-sidebar.php
new file mode 100644
index 0000000..addd3b1
--- /dev/null
+++ b/frontend/views/layouts/control-sidebar.php
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/frontend/views/layouts/footer.php b/frontend/views/layouts/footer.php
new file mode 100644
index 0000000..f335ebd
--- /dev/null
+++ b/frontend/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/frontend/views/layouts/main-login.php b/frontend/views/layouts/main-login.php
new file mode 100644
index 0000000..6ed35ef
--- /dev/null
+++ b/frontend/views/layouts/main-login.php
@@ -0,0 +1,40 @@
+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() ?>
+
+
+
+
+
+
+
+ registerCsrfMetaTags() ?>
+ = Html::encode($this->title) ?>
+ head() ?>
+
+
+beginBody() ?>
+
+
+ Генератор чеков
+
+
+
+ = $content ?>
+
+
+
+endBody() ?>
+
+
+endPage() ?>
\ No newline at end of file
diff --git a/frontend/views/layouts/main.php b/frontend/views/layouts/main.php
new file mode 100644
index 0000000..80ca4b5
--- /dev/null
+++ b/frontend/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/frontend/views/layouts/navbar.php b/frontend/views/layouts/navbar.php
new file mode 100644
index 0000000..880fab4
--- /dev/null
+++ b/frontend/views/layouts/navbar.php
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3
+
+
+
+
+
+
+
+ 15
+
+
+
+
+ = Html::a(' ', ['/site/logout'], ['data-method' => 'post', 'class' => 'nav-link']) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/views/layouts/sidebar.php b/frontend/views/layouts/sidebar.php
new file mode 100644
index 0000000..7efb794
--- /dev/null
+++ b/frontend/views/layouts/sidebar.php
@@ -0,0 +1,87 @@
+
\ No newline at end of file
diff --git a/frontend/views/site/about.php b/frontend/views/site/about.php
new file mode 100644
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 100644
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 100644
index 0000000..b4d9932
--- /dev/null
+++ b/frontend/views/site/error.php
@@ -0,0 +1,40 @@
+title = $name;
+$this->params['breadcrumbs'] = [['label' => $this->title]];
+?>
+
+
+
= Html::encode($name) ?>
+
+
+ = 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.
+ Meanwhile, you may = Html::a('return to dashboard', Yii::$app->homeUrl); ?>
+ or try using the search form.
+
+
+
+
+
+
diff --git a/frontend/views/site/index.php b/frontend/views/site/index.php
new file mode 100644
index 0000000..b98184a
--- /dev/null
+++ b/frontend/views/site/index.php
@@ -0,0 +1,134 @@
+title = 'Starter Page';
+$this->params['breadcrumbs'] = [['label' => $this->title]];
+?>
+
+
+
+ = \hail812\adminlte\widgets\Alert::widget([
+ 'type' => 'success',
+ 'body' => '
Congratulations! ',
+ ]) ?>
+ = \hail812\adminlte\widgets\Callout::widget([
+ 'type' => 'danger',
+ 'head' => 'I am a danger callout!',
+ 'body' => 'There is a problem that we need to fix. A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart.'
+ ]) ?>
+
+
+
+
+
+ = \hail812\adminlte\widgets\InfoBox::widget([
+ 'text' => 'CPU Traffic',
+ 'number' => '10 % ',
+ 'icon' => 'fas fa-cog',
+ ]) ?>
+
+
+
+
+
+ = \hail812\adminlte\widgets\InfoBox::widget([
+ 'text' => 'Messages',
+ 'number' => '1,410',
+ 'icon' => 'far fa-envelope',
+ ]) ?>
+
+
+ = \hail812\adminlte\widgets\InfoBox::widget([
+ 'text' => 'Bookmarks',
+ 'number' => '410',
+ 'theme' => 'success',
+ 'icon' => 'far fa-flag',
+ ]) ?>
+
+
+ = \hail812\adminlte\widgets\InfoBox::widget([
+ 'text' => 'Uploads',
+ 'number' => '13,648',
+ 'theme' => 'gradient-warning',
+ 'icon' => 'far fa-copy',
+ ]) ?>
+
+
+
+
+
+ = \hail812\adminlte\widgets\InfoBox::widget([
+ 'text' => 'Bookmarks',
+ 'number' => '41,410',
+ 'icon' => 'far fa-bookmark',
+ 'progress' => [
+ 'width' => '70%',
+ 'description' => '70% Increase in 30 Days'
+ ]
+ ]) ?>
+
+
+ 'Likes',
+ 'number' => '41,410',
+ 'theme' => 'success',
+ 'icon' => 'far fa-thumbs-up',
+ 'progress' => [
+ 'width' => '70%',
+ 'description' => '70% Increase in 30 Days'
+ ]
+ ]) ?>
+ = \hail812\adminlte\widgets\Ribbon::widget([
+ 'id' => $infoBox->id.'-ribbon',
+ 'text' => 'Ribbon',
+ ]) ?>
+
+
+
+ = \hail812\adminlte\widgets\InfoBox::widget([
+ 'text' => 'Events',
+ 'number' => '41,410',
+ 'theme' => 'gradient-warning',
+ 'icon' => 'far fa-calendar-alt',
+ 'progress' => [
+ 'width' => '70%',
+ 'description' => '70% Increase in 30 Days'
+ ],
+ 'loadingStyle' => true
+ ]) ?>
+
+
+
+
+
+ = \hail812\adminlte\widgets\SmallBox::widget([
+ 'title' => '150',
+ 'text' => 'New Orders',
+ 'icon' => 'fas fa-shopping-cart',
+ ]) ?>
+
+
+ '150',
+ 'text' => 'New Orders',
+ 'icon' => 'fas fa-shopping-cart',
+ 'theme' => 'success'
+ ]) ?>
+ = \hail812\adminlte\widgets\Ribbon::widget([
+ 'id' => $smallBox->id.'-ribbon',
+ 'text' => 'Ribbon',
+ 'theme' => 'warning',
+ 'size' => 'lg',
+ 'textSize' => 'lg'
+ ]) ?>
+
+
+
+ = \hail812\adminlte\widgets\SmallBox::widget([
+ 'title' => '44',
+ 'text' => 'User Registrations',
+ 'icon' => 'fas fa-user-plus',
+ 'theme' => 'gradient-success',
+ 'loadingStyle' => true
+ ]) ?>
+
+
+
\ No newline at end of file
diff --git a/frontend/views/site/login.php b/frontend/views/site/login.php
new file mode 100644
index 0000000..1380361
--- /dev/null
+++ b/frontend/views/site/login.php
@@ -0,0 +1,64 @@
+
+
+
+
Авторизируйтесь для начала работы
+
+ 'login-form']) ?>
+
+ = $form->field($model,'username', [
+ 'options' => ['class' => 'form-group has-feedback'],
+ 'inputTemplate' => '{input}
',
+ 'template' => '{beginWrapper}{input}{error}{endWrapper}',
+ 'wrapperOptions' => ['class' => 'input-group mb-3']
+ ])
+ ->label(false)
+ ->textInput(['placeholder' => $model->getAttributeLabel('username')]) ?>
+
+ = $form->field($model, 'password', [
+ 'options' => ['class' => 'form-group has-feedback'],
+ 'inputTemplate' => '{input}
',
+ 'template' => '{beginWrapper}{input}{error}{endWrapper}',
+ 'wrapperOptions' => ['class' => 'input-group mb-3']
+ ])
+ ->label(false)
+ ->passwordInput(['placeholder' => $model->getAttributeLabel('password')]) ?>
+
+
+
+ = $form->field($model, 'rememberMe')->checkbox([
+ 'template' => '
{input}{label}
',
+ 'labelOptions' => [
+ 'class' => ''
+ ],
+ 'uncheck' => null
+ ]) ?>
+
+
+ = Html::submitButton('Вход', ['class' => 'btn btn-primary btn-block']) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Забыл пароль
+
+
+ = Html::a("Регистрация", \yii\helpers\Url::to(['site/signup']), ['class' => 'text-center']) ?>
+
+
+
+
\ No newline at end of file
diff --git a/frontend/views/site/requestPasswordResetToken.php b/frontend/views/site/requestPasswordResetToken.php
new file mode 100644
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 100644
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 100644
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 100644
index 0000000..fa74af1
--- /dev/null
+++ b/frontend/views/site/signup.php
@@ -0,0 +1,68 @@
+title = 'Регистрация';
+$this->params['breadcrumbs'][] = $this->title;
+?>
+
+
+
+
Регистрация
+
+ 'form-signup']) ?>
+
+ = $form->field($model,'username', [
+ 'options' => ['class' => 'form-group has-feedback'],
+ 'inputTemplate' => '{input}
',
+ 'template' => '{beginWrapper}{input}{error}{endWrapper}',
+ 'wrapperOptions' => ['class' => 'input-group mb-3']
+ ])
+ ->label(false)
+ ->textInput(['placeholder' => $model->getAttributeLabel('username')]) ?>
+
+ = $form->field($model,'email', [
+ 'options' => ['class' => 'form-group has-feedback'],
+ 'inputTemplate' => '{input}
',
+ 'template' => '{beginWrapper}{input}{error}{endWrapper}',
+ 'wrapperOptions' => ['class' => 'input-group mb-3']
+ ])
+ ->label(false)
+ ->textInput(['placeholder' => $model->getAttributeLabel('email')]) ?>
+
+ = $form->field($model, 'password', [
+ 'options' => ['class' => 'form-group has-feedback'],
+ 'inputTemplate' => '{input}
',
+ 'template' => '{beginWrapper}{input}{error}{endWrapper}',
+ 'wrapperOptions' => ['class' => 'input-group mb-3']
+ ])
+ ->label(false)
+ ->passwordInput(['placeholder' => $model->getAttributeLabel('password')]) ?>
+
+
+
+ = Html::submitButton('Регистрация', ['class' => 'btn btn-primary btn-block']) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/web/assets/.gitignore b/frontend/web/assets/.gitignore
new file mode 100644
index 0000000..d6b7ef3
--- /dev/null
+++ b/frontend/web/assets/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/frontend/web/css/site.css b/frontend/web/css/site.css
new file mode 100644
index 0000000..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 100644
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/init b/init
new file mode 100755
index 0000000..cf472c9
--- /dev/null
+++ b/init
@@ -0,0 +1,356 @@
+#!/usr/bin/env php
+ $name) {
+ echo " [$i] $name\n";
+ }
+ echo "\n Your choice [0-" . (count($envs) - 1) . ', or "q" to quit] ';
+ $answer = trim(fgets(STDIN));
+
+ if (!ctype_digit($answer) || !in_array($answer, range(0, count($envs) - 1))) {
+ echo "\n Quit initialization.\n";
+ exit(0);
+ }
+
+ if (isset($envNames[$answer])) {
+ $envName = $envNames[$answer];
+ }
+} else {
+ $envName = $params['env'];
+}
+
+if (!in_array($envName, $envNames, true)) {
+ $envsList = implode(', ', $envNames);
+ echo "\n $envName is not a valid environment. Try one of the following: $envsList. \n";
+ exit(2);
+}
+
+$env = $envs[$envName];
+
+if (empty($params['env'])) {
+ echo "\n Initialize the application under '{$envNames[$answer]}' environment? [yes|no] ";
+ $answer = trim(fgets(STDIN));
+ if (strncasecmp($answer, 'y', 1)) {
+ echo "\n Quit initialization.\n";
+ exit(0);
+ }
+}
+
+$rootPath = "$root/environments/{$env['path']}";
+if (!is_dir($rootPath)) {
+ printError("$rootPath directory does not exist. Check path in $envName environment.");
+ exit(3);
+}
+
+echo "\n Start initialization ...\n\n";
+
+$files = getFileList($rootPath);
+if (isset($env['skipFiles'])) {
+ $skipFiles = $env['skipFiles'];
+ array_walk($skipFiles, function(&$value) use($env, $root) { $value = "$root/$value"; });
+ $files = array_diff($files, array_intersect_key($env['skipFiles'], array_filter($skipFiles, 'file_exists')));
+}
+$all = false;
+foreach ($files as $file) {
+ if (!copyFile($root, "environments/{$env['path']}/$file", $file, $all, $params)) {
+ break;
+ }
+}
+
+$filesToRemove = [];
+$skipFiles = !empty($env['skipFiles']) ? $env['skipFiles'] : [];
+foreach(array_column($envs, 'path') as $envPath) {
+ if ($env['path'] === $envPath) continue;
+
+ $filesToRemove =
+ array_merge(
+ $filesToRemove,
+ array_diff(getFileList("$root/environments/{$envPath}"), $files, $filesToRemove, $skipFiles)
+ );
+}
+$filesToRemove = array_filter($filesToRemove, 'file_exists');
+if ($filesToRemove) {
+ echo "\n Remove files from other environments ...\n\n";
+
+ $all = false;
+ foreach ($filesToRemove as $file) {
+ if (!removeFile($root, $file, $all, $params)) {
+ break;
+ }
+ }
+ echo "\n";
+}
+
+$callbacks = ['setCookieValidationKey', 'setWritable', 'setExecutable', 'createSymlink'];
+foreach ($callbacks as $callback) {
+ if (!empty($env[$callback])) {
+ $callback($root, $env[$callback]);
+ }
+}
+
+echo "\n ... initialization completed.\n\n";
+
+function getFileList($root, $basePath = '')
+{
+ $files = [];
+ $handle = opendir($root);
+ while (($path = readdir($handle)) !== false) {
+ if ($path === '.git' || $path === '.svn' || $path === '.' || $path === '..') {
+ continue;
+ }
+ $fullPath = "$root/$path";
+ $relativePath = $basePath === '' ? $path : "$basePath/$path";
+ if (is_dir($fullPath)) {
+ $files = array_merge($files, getFileList($fullPath, $relativePath));
+ } else {
+ $files[] = $relativePath;
+ }
+ }
+ closedir($handle);
+ return $files;
+}
+
+function copyFile($root, $source, $target, &$all, $params)
+{
+ if (!is_file($root . '/' . $source)) {
+ echo " skip $target ($source not exist)\n";
+ return true;
+ }
+ if (is_file($root . '/' . $target)) {
+ if (file_get_contents($root . '/' . $source) === file_get_contents($root . '/' . $target)) {
+ echo " unchanged $target\n";
+ return true;
+ }
+ if ($all) {
+ echo " overwrite $target\n";
+ } else {
+ echo " exist $target\n";
+ echo " ...overwrite? [Yes|No|All|Quit] ";
+
+
+ $answer = !empty($params['overwrite']) ? $params['overwrite'] : trim(fgets(STDIN));
+ if (!strncasecmp($answer, 'q', 1)) {
+ return false;
+ } else {
+ if (!strncasecmp($answer, 'y', 1)) {
+ echo " overwrite $target\n";
+ } else {
+ if (!strncasecmp($answer, 'a', 1)) {
+ echo " overwrite $target\n";
+ $all = true;
+ } else {
+ echo " skip $target\n";
+ return true;
+ }
+ }
+ }
+ }
+ file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
+ return true;
+ }
+ echo " generate $target\n";
+ @mkdir(dirname($root . '/' . $target), 0777, true);
+ file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
+ return true;
+}
+
+function removeFile($root, $target, &$all, $params)
+{
+ if (is_file($root . '/' . $target)) {
+ if ($all) {
+ echo " delete $target\n";
+ } else {
+ echo " delete $target\n";
+ echo " ...confirm? [Yes|No|All|Quit] ";
+
+ $answer = !empty($params['delete']) ? $params['delete'] : trim(fgets(STDIN));
+ if (!strncasecmp($answer, 'q', 1)) {
+ return false;
+ } else {
+ if (!strncasecmp($answer, 'y', 1)) {
+ echo " delete $target\n";
+ } else {
+ if (!strncasecmp($answer, 'a', 1)) {
+ echo " delete $target\n";
+ $all = true;
+ } else {
+ echo " skip $target\n";
+ return true;
+ }
+ }
+ }
+ }
+ return unlink($root . '/' . $target);
+ }
+
+ return true;
+}
+
+function getParams()
+{
+ $rawParams = [];
+ if (isset($_SERVER['argv'])) {
+ $rawParams = $_SERVER['argv'];
+ array_shift($rawParams);
+ }
+
+ $params = [];
+ foreach ($rawParams as $param) {
+ if (preg_match('/^--([\w-]*\w)(=(.*))?$/', $param, $matches)) {
+ $name = $matches[1];
+ $params[$name] = isset($matches[3]) ? $matches[3] : true;
+ } else {
+ $params[] = $param;
+ }
+ }
+ return $params;
+}
+
+function setWritable($root, $paths)
+{
+ foreach ($paths as $writable) {
+ if (is_dir("$root/$writable")) {
+ if (@chmod("$root/$writable", 0777)) {
+ echo " chmod 0777 $writable\n";
+ } else {
+ printError("Operation chmod not permitted for directory $writable.");
+ }
+ } else {
+ printError("Directory $writable does not exist.");
+ }
+ }
+}
+
+function setExecutable($root, $paths)
+{
+ foreach ($paths as $executable) {
+ if (file_exists("$root/$executable")) {
+ if (@chmod("$root/$executable", 0755)) {
+ echo " chmod 0755 $executable\n";
+ } else {
+ printError("Operation chmod not permitted for $executable.");
+ }
+ } else {
+ printError("$executable does not exist.");
+ }
+ }
+}
+
+function setCookieValidationKey($root, $paths)
+{
+ foreach ($paths as $file) {
+ echo " generate cookie validation key in $file\n";
+ $file = $root . '/' . $file;
+ $length = 32;
+ $bytes = openssl_random_pseudo_bytes($length);
+ $key = strtr(substr(base64_encode($bytes), 0, $length), '+/=', '_-.');
+ $content = preg_replace('/(("|\')cookieValidationKey("|\')\s*=>\s*)(""|\'\')/', "\\1'$key'", file_get_contents($file));
+ file_put_contents($file, $content);
+ }
+}
+
+function createSymlink($root, $links)
+{
+ foreach ($links as $link => $target) {
+ //first removing folders to avoid errors if the folder already exists
+ @rmdir($root . "/" . $link);
+ //next removing existing symlink in order to update the target
+ if (is_link($root . "/" . $link)) {
+ @unlink($root . "/" . $link);
+ }
+ if (@symlink($root . "/" . $target, $root . "/" . $link)) {
+ echo " symlink $root/$target $root/$link\n";
+ } else {
+ printError("Cannot create symlink $root/$target $root/$link.");
+ }
+ }
+}
+
+/**
+ * Prints error message.
+ * @param string $message message
+ */
+function printError($message)
+{
+ echo "\n " . formatMessage("Error. $message", ['fg-red']) . " \n";
+}
+
+/**
+ * Returns true if the stream supports colorization. ANSI colors are disabled if not supported by the stream.
+ *
+ * - windows without ansicon
+ * - not tty consoles
+ *
+ * @return boolean true if the stream supports ANSI colors, otherwise false.
+ */
+function ansiColorsSupported()
+{
+ return DIRECTORY_SEPARATOR === '\\'
+ ? getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON'
+ : function_exists('posix_isatty') && @posix_isatty(STDOUT);
+}
+
+/**
+ * Get ANSI code of style.
+ * @param string $name style name
+ * @return integer ANSI code of style.
+ */
+function getStyleCode($name)
+{
+ $styles = [
+ 'bold' => 1,
+ 'fg-black' => 30,
+ 'fg-red' => 31,
+ 'fg-green' => 32,
+ 'fg-yellow' => 33,
+ 'fg-blue' => 34,
+ 'fg-magenta' => 35,
+ 'fg-cyan' => 36,
+ 'fg-white' => 37,
+ 'bg-black' => 40,
+ 'bg-red' => 41,
+ 'bg-green' => 42,
+ 'bg-yellow' => 43,
+ 'bg-blue' => 44,
+ 'bg-magenta' => 45,
+ 'bg-cyan' => 46,
+ 'bg-white' => 47,
+ ];
+ return $styles[$name];
+}
+
+/**
+ * Formats message using styles if STDOUT supports it.
+ * @param string $message message
+ * @param string[] $styles styles
+ * @return string formatted message.
+ */
+function formatMessage($message, $styles)
+{
+ if (empty($styles) || !ansiColorsSupported()) {
+ return $message;
+ }
+
+ return sprintf("\x1b[%sm", implode(';', array_map('getStyleCode', $styles))) . $message . "\x1b[0m";
+}
diff --git a/init.bat b/init.bat
new file mode 100644
index 0000000..1b92c19
--- /dev/null
+++ b/init.bat
@@ -0,0 +1,15 @@
+@echo off
+
+rem -------------------------------------------------------------
+rem Yii command line init script for Windows.
+rem -------------------------------------------------------------
+
+@setlocal
+
+set YII_PATH=%~dp0
+
+if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe
+
+"%PHP_COMMAND%" "%YII_PATH%init" %*
+
+@endlocal
diff --git a/requirements.php b/requirements.php
new file mode 100644
index 0000000..2859da7
--- /dev/null
+++ b/requirements.php
@@ -0,0 +1,155 @@
+Error\n\n"
+ . "The path to yii framework seems to be incorrect.
\n"
+ . 'You need to install Yii framework via composer or adjust the framework path in file ' . basename(__FILE__) . " .
\n"
+ . 'Please refer to the README on how to install Yii.
\n";
+ if (!empty($_SERVER['argv'])) {
+ // do not print HTML when used in console mode
+ echo strip_tags($message);
+ } else {
+ echo $message;
+ }
+ exit(1);
+}
+
+require_once $frameworkPath . '/requirements/YiiRequirementChecker.php';
+$requirementsChecker = new YiiRequirementChecker();
+
+$gdMemo = $imagickMemo = 'Either GD PHP extension with FreeType support or ImageMagick PHP extension with PNG support is required for image CAPTCHA.';
+$gdOK = $imagickOK = false;
+
+if (extension_loaded('imagick')) {
+ $imagick = new Imagick();
+ $imagickFormats = $imagick->queryFormats('PNG');
+ if (in_array('PNG', $imagickFormats)) {
+ $imagickOK = true;
+ } else {
+ $imagickMemo = 'Imagick extension should be installed with PNG support in order to be used for image CAPTCHA.';
+ }
+}
+
+if (extension_loaded('gd')) {
+ $gdInfo = gd_info();
+ if (!empty($gdInfo['FreeType Support'])) {
+ $gdOK = true;
+ } else {
+ $gdMemo = 'GD extension should be installed with FreeType support in order to be used for image CAPTCHA.';
+ }
+}
+
+/**
+ * Adjust requirements according to your application specifics.
+ */
+$requirements = array(
+ // Database :
+ array(
+ 'name' => 'PDO extension',
+ 'mandatory' => true,
+ 'condition' => extension_loaded('pdo'),
+ 'by' => 'All DB-related classes',
+ ),
+ array(
+ 'name' => 'PDO SQLite extension',
+ 'mandatory' => false,
+ 'condition' => extension_loaded('pdo_sqlite'),
+ 'by' => 'All DB-related classes',
+ 'memo' => 'Required for SQLite database.',
+ ),
+ array(
+ 'name' => 'PDO MySQL extension',
+ 'mandatory' => false,
+ 'condition' => extension_loaded('pdo_mysql'),
+ 'by' => 'All DB-related classes',
+ 'memo' => 'Required for MySQL database.',
+ ),
+ array(
+ 'name' => 'PDO PostgreSQL extension',
+ 'mandatory' => false,
+ 'condition' => extension_loaded('pdo_pgsql'),
+ 'by' => 'All DB-related classes',
+ 'memo' => 'Required for PostgreSQL database.',
+ ),
+ // Cache :
+ array(
+ 'name' => 'Memcache extension',
+ 'mandatory' => false,
+ 'condition' => extension_loaded('memcache') || extension_loaded('memcached'),
+ 'by' => 'MemCache ',
+ 'memo' => extension_loaded('memcached') ? 'To use memcached set MemCache::useMemcached to true
.' : ''
+ ),
+ array(
+ 'name' => 'APC extension',
+ 'mandatory' => false,
+ 'condition' => extension_loaded('apc'),
+ 'by' => 'ApcCache ',
+ ),
+ // CAPTCHA:
+ array(
+ 'name' => 'GD PHP extension with FreeType support',
+ 'mandatory' => false,
+ 'condition' => $gdOK,
+ 'by' => 'Captcha ',
+ 'memo' => $gdMemo,
+ ),
+ array(
+ 'name' => 'ImageMagick PHP extension with PNG support',
+ 'mandatory' => false,
+ 'condition' => $imagickOK,
+ 'by' => 'Captcha ',
+ 'memo' => $imagickMemo,
+ ),
+ // PHP ini :
+ 'phpExposePhp' => array(
+ 'name' => 'Expose PHP',
+ 'mandatory' => false,
+ 'condition' => $requirementsChecker->checkPhpIniOff("expose_php"),
+ 'by' => 'Security reasons',
+ 'memo' => '"expose_php" should be disabled at php.ini',
+ ),
+ 'phpAllowUrlInclude' => array(
+ 'name' => 'PHP allow url include',
+ 'mandatory' => false,
+ 'condition' => $requirementsChecker->checkPhpIniOff("allow_url_include"),
+ 'by' => 'Security reasons',
+ 'memo' => '"allow_url_include" should be disabled at php.ini',
+ ),
+ 'phpSmtp' => array(
+ 'name' => 'PHP mail SMTP',
+ 'mandatory' => false,
+ 'condition' => strlen(ini_get('SMTP')) > 0,
+ 'by' => 'Email sending',
+ 'memo' => 'PHP mail SMTP server required',
+ ),
+);
+
+$result = $requirementsChecker->checkYii()->check($requirements)->getResult();
+$requirementsChecker->render();
+
+exit($result['summary']['errors'] === 0 ? 0 : 1);
diff --git a/vagrant/config/.gitignore b/vagrant/config/.gitignore
new file mode 100644
index 0000000..0685a56
--- /dev/null
+++ b/vagrant/config/.gitignore
@@ -0,0 +1,2 @@
+# local configuration
+vagrant-local.yml
\ No newline at end of file
diff --git a/vagrant/config/vagrant-local.example.yml b/vagrant/config/vagrant-local.example.yml
new file mode 100644
index 0000000..7b36400
--- /dev/null
+++ b/vagrant/config/vagrant-local.example.yml
@@ -0,0 +1,22 @@
+# Your personal GitHub token
+github_token:
+# Read more: https://github.com/blog/1509-personal-api-tokens
+# You can generate it here: https://github.com/settings/tokens
+
+# Guest OS timezone
+timezone: Europe/London
+
+# Are we need check box updates for every 'vagrant up'?
+box_check_update: false
+
+# Virtual machine name
+machine_name: y2aa
+
+# Virtual machine IP
+ip: 192.168.83.137
+
+# Virtual machine CPU cores number
+cpus: 1
+
+# Virtual machine RAM
+memory: 1024
diff --git a/vagrant/nginx/app.conf b/vagrant/nginx/app.conf
new file mode 100644
index 0000000..0462830
--- /dev/null
+++ b/vagrant/nginx/app.conf
@@ -0,0 +1,77 @@
+server {
+ charset utf-8;
+ client_max_body_size 128M;
+ sendfile off;
+
+ listen 80; ## listen for ipv4
+ #listen [::]:80 default_server ipv6only=on; ## listen for ipv6
+
+ server_name y2aa-frontend.test;
+ root /app/frontend/web/;
+ index index.php;
+
+ access_log /app/vagrant/nginx/log/frontend-access.log;
+ error_log /app/vagrant/nginx/log/frontend-error.log;
+
+ location / {
+ # Redirect everything that isn't a real file to index.php
+ try_files $uri $uri/ /index.php$is_args$args;
+ }
+
+ # uncomment to avoid processing of calls to non-existing static files by Yii
+ #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
+ # try_files $uri =404;
+ #}
+ #error_page 404 /404.html;
+
+ location ~ \.php$ {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ #fastcgi_pass 127.0.0.1:9000;
+ fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
+ try_files $uri =404;
+ }
+
+ location ~ /\.(ht|svn|git) {
+ deny all;
+ }
+}
+
+server {
+ charset utf-8;
+ client_max_body_size 128M;
+ sendfile off;
+
+ listen 80; ## listen for ipv4
+ #listen [::]:80 default_server ipv6only=on; ## listen for ipv6
+
+ server_name y2aa-backend.test;
+ root /app/backend/web/;
+ index index.php;
+
+ access_log /app/vagrant/nginx/log/backend-access.log;
+ error_log /app/vagrant/nginx/log/backend-error.log;
+
+ location / {
+ # Redirect everything that isn't a real file to index.php
+ try_files $uri $uri/ /index.php$is_args$args;
+ }
+
+ # uncomment to avoid processing of calls to non-existing static files by Yii
+ #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
+ # try_files $uri =404;
+ #}
+ #error_page 404 /404.html;
+
+ location ~ \.php$ {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ #fastcgi_pass 127.0.0.1:9000;
+ fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
+ try_files $uri =404;
+ }
+
+ location ~ /\.(ht|svn|git) {
+ deny all;
+ }
+}
diff --git a/vagrant/nginx/log/.gitignore b/vagrant/nginx/log/.gitignore
new file mode 100644
index 0000000..c15cedd
--- /dev/null
+++ b/vagrant/nginx/log/.gitignore
@@ -0,0 +1,5 @@
+# nginx logs
+backend-access.log
+backend-error.log
+frontend-access.log
+frontend-error.log
\ No newline at end of file
diff --git a/vagrant/provision/always-as-root.sh b/vagrant/provision/always-as-root.sh
new file mode 100644
index 0000000..cca9cfb
--- /dev/null
+++ b/vagrant/provision/always-as-root.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+source /app/vagrant/provision/common.sh
+
+#== Provision script ==
+
+info "Provision-script user: `whoami`"
+
+info "Restart web-stack"
+service php7.4-fpm restart
+service nginx restart
+service mysql restart
\ No newline at end of file
diff --git a/vagrant/provision/common.sh b/vagrant/provision/common.sh
new file mode 100644
index 0000000..ab5e1e0
--- /dev/null
+++ b/vagrant/provision/common.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+#== Bash helpers ==
+
+function info {
+ echo " "
+ echo "--> $1"
+ echo " "
+}
diff --git a/vagrant/provision/once-as-root.sh b/vagrant/provision/once-as-root.sh
new file mode 100644
index 0000000..4542a43
--- /dev/null
+++ b/vagrant/provision/once-as-root.sh
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+
+source /app/vagrant/provision/common.sh
+
+#== Import script args ==
+
+timezone=$(echo "$1")
+readonly IP=$2
+
+#== Provision script ==
+
+info "Provision-script user: `whoami`"
+
+export DEBIAN_FRONTEND=noninteractive
+
+info "Configure timezone"
+timedatectl set-timezone ${timezone} --no-ask-password
+
+info "AWK initial replacement work"
+awk -v ip=$IP -f /app/vagrant/provision/provision.awk /app/environments/dev/*end/config/main-local.php
+
+info "Prepare root password for MySQL"
+debconf-set-selections <<< "mysql-community-server mysql-community-server/root-pass password \"''\""
+debconf-set-selections <<< "mysql-community-server mysql-community-server/re-root-pass password \"''\""
+echo "Done!"
+
+info "Update OS software"
+apt-get update
+apt-get upgrade -y
+
+info "Add ppa:ondrej/php"
+apt-get install -y python-software-properties
+apt-get update && apt-get upgrade -y
+add-apt-repository -y ppa:ondrej/php
+
+info "Install additional software"
+apt-get install -y php7.4-curl php7.4-cli php7.4-intl php7.4-mysqlnd php7.4-gd php7.4-fpm php7.4-mbstring php7.4-xml unzip nginx mysql-server-5.7 php7.4-xdebug
+
+info "Configure MySQL"
+sed -i "s/.*bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/mysql.conf.d/mysqld.cnf
+mysql -uroot <<< "CREATE USER 'root'@'%' IDENTIFIED BY ''"
+mysql -uroot <<< "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'"
+mysql -uroot <<< "DROP USER 'root'@'localhost'"
+mysql -uroot <<< "FLUSH PRIVILEGES"
+echo "Done!"
+
+info "Configure PHP-FPM"
+sed -i 's/user = www-data/user = vagrant/g' /etc/php/7.4/fpm/pool.d/www.conf
+sed -i 's/group = www-data/group = vagrant/g' /etc/php/7.4/fpm/pool.d/www.conf
+sed -i 's/owner = www-data/owner = vagrant/g' /etc/php/7.4/fpm/pool.d/www.conf
+cat << EOF > /etc/php/7.4/mods-available/xdebug.ini
+zend_extension=xdebug.so
+xdebug.remote_enable=1
+xdebug.remote_connect_back=1
+xdebug.remote_port=9000
+xdebug.remote_autostart=1
+EOF
+echo "Done!"
+
+info "Configure NGINX"
+sed -i 's/user www-data/user vagrant/g' /etc/nginx/nginx.conf
+echo "Done!"
+
+info "Enabling site configuration"
+ln -s /app/vagrant/nginx/app.conf /etc/nginx/sites-enabled/app.conf
+echo "Done!"
+
+info "Initailize databases for MySQL"
+mysql -uroot <<< "CREATE DATABASE yii2advanced"
+mysql -uroot <<< "CREATE DATABASE yii2advanced_test"
+echo "Done!"
+
+info "Install composer"
+curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
\ No newline at end of file
diff --git a/vagrant/provision/once-as-vagrant.sh b/vagrant/provision/once-as-vagrant.sh
new file mode 100644
index 0000000..ffaa898
--- /dev/null
+++ b/vagrant/provision/once-as-vagrant.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+source /app/vagrant/provision/common.sh
+
+#== Import script args ==
+
+github_token=$(echo "$1")
+
+#== Provision script ==
+
+info "Provision-script user: `whoami`"
+
+info "Configure composer"
+composer config --global github-oauth.github.com ${github_token}
+echo "Done!"
+
+info "Install project dependencies"
+cd /app
+composer --no-progress --prefer-dist install
+
+info "Init project"
+./init --env=Development --overwrite=y
+
+info "Apply migrations"
+./yii migrate --interactive=0
+./yii_test migrate --interactive=0
+
+info "Create bash-alias 'app' for vagrant user"
+echo 'alias app="cd /app"' | tee /home/vagrant/.bash_aliases
+
+info "Enabling colorized prompt for guest console"
+sed -i "s/#force_color_prompt=yes/force_color_prompt=yes/" /home/vagrant/.bashrc
diff --git a/vagrant/provision/provision.awk b/vagrant/provision/provision.awk
new file mode 100644
index 0000000..65e9bde
--- /dev/null
+++ b/vagrant/provision/provision.awk
@@ -0,0 +1,70 @@
+###
+# Modifying Yii2's files for initialize Vagrant VM
+#
+# @author HA3IK
+# @version 1.0.0
+
+BEGIN {
+ print "AWK BEGINs its work:"
+ IGNORECASE = 1
+ # Correct IP - wildcard last octet
+ match(ip, /(([0-9]+\.)+)/, arr)
+ ip = arr[1] "*"
+}
+BEGINFILE {
+ msg = "- Work with: " FILENAME
+ # Define array index for the file
+ switch (FILENAME) {
+ case /environments\/dev\/(back|front)end\/config\/main\-local\.php$/:
+ isFile["IsMainLocConf"] = 1
+ msg = msg " - allow VM IP for Gii and debug toolbar"
+ break
+ }
+ # Print the final message
+ print msg
+}
+# BODY
+{
+ # IF environments/dev/(back|front)end/config/main-local.php
+ if (isFile["IsMainLocConf"]) {
+ # IF the line[s] after yii\(debug|gii)\Module
+ if (FNR == nextLine["nubmer"]) {
+ # Prepare for next line
+ ++nextLine["nubmer"]
+ # IF line has "allowedIPs"
+ if (index($0, "allowedIPs")) {
+ # IF our IP is not there
+ if (!index($0, ip)) {
+ # Add it
+ match($0, /([^\]]+)(.+)/, arr)
+ $0 = sprintf("%s, '%s'%s", arr[1], ip, arr[2])
+ }
+ # Delete next line
+ delete nextLine
+ # IF "allowedIPs" are not set - search for the end of an array structure
+ } else if ($0 ~ /\];$/) {
+ # Rewrite line
+ $0 = nextLine["indent"] "'allowedIPs' => ['127.0.0.1', '::1', '" ip "'],\n" $0
+ delete nextLine
+ }
+ # IF line is done
+ if (!length(nextLine)) {
+ printf " Line %d: Allowed IP: %s\n", FNR, ip
+ }
+ # Search for yii\(debug|gii)\Module
+ } else if (match($0, /^(\s+).+yii\\(debug|gii)\\Module/, arr)) {
+ # Save next line and indent
+ nextLine["nubmer"] = FNR + 1
+ nextLine["indent"] = arr[1]
+ }
+ # Rewrite the file
+ print $0 > FILENAME
+ }
+}
+ENDFILE {
+ delete isFile
+ close(FILENAME)
+}
+END {
+ print "AWK ENDs its work."
+}
diff --git a/yii.bat b/yii.bat
new file mode 100644
index 0000000..3a68942
--- /dev/null
+++ b/yii.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" %*
+
+@endlocal