Создан поиск, уведомления, настройки, мониторгин, админ-панель
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "7219e565f7400643e10772d84e87d8a5",
|
"content-hash": "f259164a4251a4ef37262d42fbeb40d6",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "bower-asset/bootstrap",
|
"name": "bower-asset/bootstrap",
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
"version": "3.3.11",
|
"version": "3.3.11",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git@github.com:RobinHerbots/Inputmask.git",
|
"url": "https://github.com/RobinHerbots/Inputmask.git",
|
||||||
"reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
|
"reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
"version": "3.5.1",
|
"version": "3.5.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git@github.com:jquery/jquery-dist.git",
|
"url": "https://github.com/jquery/jquery-dist.git",
|
||||||
"reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215"
|
"reference": "4c0e4becb8263bb5b3e6dadc448d8e7305ef8215"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
|
@ -643,20 +643,20 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "markbaker/matrix",
|
"name": "markbaker/matrix",
|
||||||
"version": "2.0.0",
|
"version": "2.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/MarkBaker/PHPMatrix.git",
|
"url": "https://github.com/MarkBaker/PHPMatrix.git",
|
||||||
"reference": "9567d9c4c519fbe40de01dbd1e4469dbbb66f46a"
|
"reference": "361c0f545c3172ee26c3d596a0aa03f0cef65e6a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/9567d9c4c519fbe40de01dbd1e4469dbbb66f46a",
|
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/361c0f545c3172ee26c3d596a0aa03f0cef65e6a",
|
||||||
"reference": "9567d9c4c519fbe40de01dbd1e4469dbbb66f46a",
|
"reference": "361c0f545c3172ee26c3d596a0aa03f0cef65e6a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.2 || ^8.0"
|
"php": "^7.1 || ^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
||||||
|
@ -674,22 +674,22 @@
|
||||||
"Matrix\\": "classes/src/"
|
"Matrix\\": "classes/src/"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"classes/src/functions/adjoint.php",
|
"classes/src/Functions/adjoint.php",
|
||||||
"classes/src/functions/antidiagonal.php",
|
"classes/src/Functions/antidiagonal.php",
|
||||||
"classes/src/functions/cofactors.php",
|
"classes/src/Functions/cofactors.php",
|
||||||
"classes/src/functions/determinant.php",
|
"classes/src/Functions/determinant.php",
|
||||||
"classes/src/functions/diagonal.php",
|
"classes/src/Functions/diagonal.php",
|
||||||
"classes/src/functions/identity.php",
|
"classes/src/Functions/identity.php",
|
||||||
"classes/src/functions/inverse.php",
|
"classes/src/Functions/inverse.php",
|
||||||
"classes/src/functions/minors.php",
|
"classes/src/Functions/minors.php",
|
||||||
"classes/src/functions/trace.php",
|
"classes/src/Functions/trace.php",
|
||||||
"classes/src/functions/transpose.php",
|
"classes/src/Functions/transpose.php",
|
||||||
"classes/src/operations/add.php",
|
"classes/src/Operations/add.php",
|
||||||
"classes/src/operations/directsum.php",
|
"classes/src/Operations/directsum.php",
|
||||||
"classes/src/operations/subtract.php",
|
"classes/src/Operations/subtract.php",
|
||||||
"classes/src/operations/multiply.php",
|
"classes/src/Operations/multiply.php",
|
||||||
"classes/src/operations/divideby.php",
|
"classes/src/Operations/divideby.php",
|
||||||
"classes/src/operations/divideinto.php"
|
"classes/src/Operations/divideinto.php"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
@ -711,17 +711,17 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
|
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
|
||||||
"source": "https://github.com/MarkBaker/PHPMatrix/tree/PHP8"
|
"source": "https://github.com/MarkBaker/PHPMatrix/tree/2.1.2"
|
||||||
},
|
},
|
||||||
"time": "2020-08-28T17:11:00+00:00"
|
"time": "2021-01-23T16:37:31+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "mirzaev/yii2-arangodb",
|
"name": "mirzaev/yii2-arangodb",
|
||||||
"version": "2.1.0.x-dev",
|
"version": "2.1.x-dev",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.hood.su/mirzaev/yii2/arangodb",
|
"url": "https://git.hood.su/mirzaev/yii2/arangodb",
|
||||||
"reference": "3355611e2008933d647e96316b2a488a7be705c5"
|
"reference": "bf4483291486eb0b991907c3e55e5392f84f2ed9"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.0.0",
|
"php": "^8.0.0",
|
||||||
|
@ -763,7 +763,7 @@
|
||||||
"ArangoDb",
|
"ArangoDb",
|
||||||
"yii2"
|
"yii2"
|
||||||
],
|
],
|
||||||
"time": "2021-01-20T03:59:35+00:00"
|
"time": "2021-01-31T01:36:27+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "moonlandsoft/yii2-phpexcel",
|
"name": "moonlandsoft/yii2-phpexcel",
|
||||||
|
@ -2130,25 +2130,26 @@
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
{
|
{
|
||||||
"name": "behat/gherkin",
|
"name": "behat/gherkin",
|
||||||
"version": "v4.6.2",
|
"version": "v4.8.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Behat/Gherkin.git",
|
"url": "https://github.com/Behat/Gherkin.git",
|
||||||
"reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31"
|
"reference": "2391482cd003dfdc36b679b27e9f5326bd656acd"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Behat/Gherkin/zipball/51ac4500c4dc30cbaaabcd2f25694299df666a31",
|
"url": "https://api.github.com/repos/Behat/Gherkin/zipball/2391482cd003dfdc36b679b27e9f5326bd656acd",
|
||||||
"reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31",
|
"reference": "2391482cd003dfdc36b679b27e9f5326bd656acd",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.1"
|
"php": "~7.2|~8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~4.5|~5",
|
"cucumber/cucumber": "dev-gherkin-16.0.0",
|
||||||
"symfony/phpunit-bridge": "~2.7|~3|~4",
|
"phpunit/phpunit": "~8|~9",
|
||||||
"symfony/yaml": "~2.3|~3|~4"
|
"symfony/phpunit-bridge": "~3|~4|~5",
|
||||||
|
"symfony/yaml": "~3|~4|~5"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symfony/yaml": "If you want to parse features, represented in YAML files"
|
"symfony/yaml": "If you want to parse features, represented in YAML files"
|
||||||
|
@ -2175,7 +2176,7 @@
|
||||||
"homepage": "http://everzet.com"
|
"homepage": "http://everzet.com"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Gherkin DSL parser for PHP 5.3",
|
"description": "Gherkin DSL parser for PHP",
|
||||||
"homepage": "http://behat.org/",
|
"homepage": "http://behat.org/",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"BDD",
|
"BDD",
|
||||||
|
@ -2187,22 +2188,22 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/Behat/Gherkin/issues",
|
"issues": "https://github.com/Behat/Gherkin/issues",
|
||||||
"source": "https://github.com/Behat/Gherkin/tree/master"
|
"source": "https://github.com/Behat/Gherkin/tree/v4.8.0"
|
||||||
},
|
},
|
||||||
"time": "2020-03-17T14:03:26+00:00"
|
"time": "2021-02-04T12:44:21+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "codeception/codeception",
|
"name": "codeception/codeception",
|
||||||
"version": "4.1.15",
|
"version": "4.1.17",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Codeception/Codeception.git",
|
"url": "https://github.com/Codeception/Codeception.git",
|
||||||
"reference": "9b174d18ba58bb2e8cc4cecce619d6124df1d83a"
|
"reference": "c153b1ab289b3e3109e685379aa8847c54ac2b68"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/9b174d18ba58bb2e8cc4cecce619d6124df1d83a",
|
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/c153b1ab289b3e3109e685379aa8847c54ac2b68",
|
||||||
"reference": "9b174d18ba58bb2e8cc4cecce619d6124df1d83a",
|
"reference": "c153b1ab289b3e3109e685379aa8847c54ac2b68",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -2276,7 +2277,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/Codeception/Codeception/issues",
|
"issues": "https://github.com/Codeception/Codeception/issues",
|
||||||
"source": "https://github.com/Codeception/Codeception/tree/4.1.15"
|
"source": "https://github.com/Codeception/Codeception/tree/4.1.17"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -2284,7 +2285,7 @@
|
||||||
"type": "open_collective"
|
"type": "open_collective"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-01-17T19:19:40+00:00"
|
"time": "2021-02-01T07:30:47+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "codeception/lib-asserts",
|
"name": "codeception/lib-asserts",
|
||||||
|
@ -2342,16 +2343,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "codeception/lib-innerbrowser",
|
"name": "codeception/lib-innerbrowser",
|
||||||
"version": "1.3.6",
|
"version": "1.4.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Codeception/lib-innerbrowser.git",
|
"url": "https://github.com/Codeception/lib-innerbrowser.git",
|
||||||
"reference": "41b79ba6761001bdb1f373a347400180693ad4e7"
|
"reference": "b7406c710684c255d9b067d7795269a5585a0406"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/Codeception/lib-innerbrowser/zipball/41b79ba6761001bdb1f373a347400180693ad4e7",
|
"url": "https://api.github.com/repos/Codeception/lib-innerbrowser/zipball/b7406c710684c255d9b067d7795269a5585a0406",
|
||||||
"reference": "41b79ba6761001bdb1f373a347400180693ad4e7",
|
"reference": "b7406c710684c255d9b067d7795269a5585a0406",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -2396,9 +2397,9 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/Codeception/lib-innerbrowser/issues",
|
"issues": "https://github.com/Codeception/lib-innerbrowser/issues",
|
||||||
"source": "https://github.com/Codeception/lib-innerbrowser/tree/1.3.6"
|
"source": "https://github.com/Codeception/lib-innerbrowser/tree/1.4.0"
|
||||||
},
|
},
|
||||||
"time": "2021-01-17T11:21:09+00:00"
|
"time": "2021-01-29T18:17:25+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "codeception/module-asserts",
|
"name": "codeception/module-asserts",
|
||||||
|
@ -3938,16 +3939,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/phpunit",
|
"name": "phpunit/phpunit",
|
||||||
"version": "9.5.1",
|
"version": "9.5.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||||
"reference": "e7bdf4085de85a825f4424eae52c99a1cec2f360"
|
"reference": "f661659747f2f87f9e72095bb207bceb0f151cb4"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e7bdf4085de85a825f4424eae52c99a1cec2f360",
|
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f661659747f2f87f9e72095bb207bceb0f151cb4",
|
||||||
"reference": "e7bdf4085de85a825f4424eae52c99a1cec2f360",
|
"reference": "f661659747f2f87f9e72095bb207bceb0f151cb4",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -4025,7 +4026,7 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.1"
|
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.2"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -4037,7 +4038,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2021-01-17T07:42:25+00:00"
|
"time": "2021-02-02T14:45:58+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "psr/container",
|
"name": "psr/container",
|
||||||
|
@ -5152,16 +5153,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/browser-kit",
|
"name": "symfony/browser-kit",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/browser-kit.git",
|
"url": "https://github.com/symfony/browser-kit.git",
|
||||||
"reference": "87d6f0a7436b03a57d4cf9a6a9cd0c83a355c49a"
|
"reference": "b03b2057ed53ee4eab2e8f372084d7722b7b8ffd"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/87d6f0a7436b03a57d4cf9a6a9cd0c83a355c49a",
|
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/b03b2057ed53ee4eab2e8f372084d7722b7b8ffd",
|
||||||
"reference": "87d6f0a7436b03a57d4cf9a6a9cd0c83a355c49a",
|
"reference": "b03b2057ed53ee4eab2e8f372084d7722b7b8ffd",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -5200,10 +5201,10 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony BrowserKit Component",
|
"description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/browser-kit/tree/v5.2.1"
|
"source": "https://github.com/symfony/browser-kit/tree/v5.2.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -5219,20 +5220,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-18T08:03:05+00:00"
|
"time": "2021-01-27T12:56:27+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/console.git",
|
"url": "https://github.com/symfony/console.git",
|
||||||
"reference": "47c02526c532fb381374dab26df05e7313978976"
|
"reference": "89d4b176d12a2946a1ae4e34906a025b7b6b135a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/console/zipball/47c02526c532fb381374dab26df05e7313978976",
|
"url": "https://api.github.com/repos/symfony/console/zipball/89d4b176d12a2946a1ae4e34906a025b7b6b135a",
|
||||||
"reference": "47c02526c532fb381374dab26df05e7313978976",
|
"reference": "89d4b176d12a2946a1ae4e34906a025b7b6b135a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -5291,7 +5292,7 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony Console Component",
|
"description": "Eases the creation of beautiful and testable command line interfaces",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"cli",
|
"cli",
|
||||||
|
@ -5300,7 +5301,7 @@
|
||||||
"terminal"
|
"terminal"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/console/tree/v5.2.1"
|
"source": "https://github.com/symfony/console/tree/v5.2.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -5316,20 +5317,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-18T08:03:05+00:00"
|
"time": "2021-01-28T22:06:19+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/css-selector",
|
"name": "symfony/css-selector",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/css-selector.git",
|
"url": "https://github.com/symfony/css-selector.git",
|
||||||
"reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054"
|
"reference": "f65f217b3314504a1ec99c2d6ef69016bb13490f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/css-selector/zipball/f789e7ead4c79e04ca9a6d6162fc629c89bd8054",
|
"url": "https://api.github.com/repos/symfony/css-selector/zipball/f65f217b3314504a1ec99c2d6ef69016bb13490f",
|
||||||
"reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054",
|
"reference": "f65f217b3314504a1ec99c2d6ef69016bb13490f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -5362,10 +5363,10 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony CssSelector Component",
|
"description": "Converts CSS selectors to XPath expressions",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/css-selector/tree/v5.2.1"
|
"source": "https://github.com/symfony/css-selector/tree/v5.2.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -5381,7 +5382,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-08T17:02:38+00:00"
|
"time": "2021-01-27T10:01:46+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
|
@ -5452,16 +5453,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/dom-crawler",
|
"name": "symfony/dom-crawler",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/dom-crawler.git",
|
"url": "https://github.com/symfony/dom-crawler.git",
|
||||||
"reference": "ee7cf316fb0de786cfe5ae32ee79502b290c81ea"
|
"reference": "5d89ceb53ec65e1973a555072fac8ed5ecad3384"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/ee7cf316fb0de786cfe5ae32ee79502b290c81ea",
|
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/5d89ceb53ec65e1973a555072fac8ed5ecad3384",
|
||||||
"reference": "ee7cf316fb0de786cfe5ae32ee79502b290c81ea",
|
"reference": "5d89ceb53ec65e1973a555072fac8ed5ecad3384",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -5503,10 +5504,10 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony DomCrawler Component",
|
"description": "Eases DOM navigation for HTML and XML documents",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/dom-crawler/tree/v5.2.1"
|
"source": "https://github.com/symfony/dom-crawler/tree/v5.2.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -5522,20 +5523,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-18T08:02:46+00:00"
|
"time": "2021-01-27T10:01:46+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/event-dispatcher",
|
"name": "symfony/event-dispatcher",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||||
"reference": "1c93f7a1dff592c252574c79a8635a8a80856042"
|
"reference": "4f9760f8074978ad82e2ce854dff79a71fe45367"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1c93f7a1dff592c252574c79a8635a8a80856042",
|
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4f9760f8074978ad82e2ce854dff79a71fe45367",
|
||||||
"reference": "1c93f7a1dff592c252574c79a8635a8a80856042",
|
"reference": "4f9760f8074978ad82e2ce854dff79a71fe45367",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -5588,10 +5589,10 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony EventDispatcher Component",
|
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/event-dispatcher/tree/v5.2.1"
|
"source": "https://github.com/symfony/event-dispatcher/tree/v5.2.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -5607,7 +5608,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-18T08:03:05+00:00"
|
"time": "2021-01-27T10:36:42+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/event-dispatcher-contracts",
|
"name": "symfony/event-dispatcher-contracts",
|
||||||
|
@ -5690,16 +5691,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/finder",
|
"name": "symfony/finder",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/finder.git",
|
"url": "https://github.com/symfony/finder.git",
|
||||||
"reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba"
|
"reference": "4adc8d172d602008c204c2e16956f99257248e03"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/finder/zipball/0b9231a5922fd7287ba5b411893c0ecd2733e5ba",
|
"url": "https://api.github.com/repos/symfony/finder/zipball/4adc8d172d602008c204c2e16956f99257248e03",
|
||||||
"reference": "0b9231a5922fd7287ba5b411893c0ecd2733e5ba",
|
"reference": "4adc8d172d602008c204c2e16956f99257248e03",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -5728,10 +5729,10 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony Finder Component",
|
"description": "Finds files and directories via an intuitive fluent interface",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/finder/tree/v5.2.1"
|
"source": "https://github.com/symfony/finder/tree/v5.2.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -5747,7 +5748,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-08T17:02:38+00:00"
|
"time": "2021-01-28T22:06:19+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-ctype",
|
"name": "symfony/polyfill-ctype",
|
||||||
|
@ -6073,16 +6074,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/process.git",
|
"url": "https://github.com/symfony/process.git",
|
||||||
"reference": "bd8815b8b6705298beaa384f04fabd459c10bedd"
|
"reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/process/zipball/bd8815b8b6705298beaa384f04fabd459c10bedd",
|
"url": "https://api.github.com/repos/symfony/process/zipball/313a38f09c77fbcdc1d223e57d368cea76a2fd2f",
|
||||||
"reference": "bd8815b8b6705298beaa384f04fabd459c10bedd",
|
"reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -6112,10 +6113,10 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony Process Component",
|
"description": "Executes commands in sub-processes",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/process/tree/v5.2.1"
|
"source": "https://github.com/symfony/process/tree/v5.2.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -6131,7 +6132,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-08T17:03:37+00:00"
|
"time": "2021-01-27T10:15:41+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/service-contracts",
|
"name": "symfony/service-contracts",
|
||||||
|
@ -6214,16 +6215,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/string",
|
"name": "symfony/string",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/string.git",
|
"url": "https://github.com/symfony/string.git",
|
||||||
"reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed"
|
"reference": "c95468897f408dd0aca2ff582074423dd0455122"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/string/zipball/5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed",
|
"url": "https://api.github.com/repos/symfony/string/zipball/c95468897f408dd0aca2ff582074423dd0455122",
|
||||||
"reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed",
|
"reference": "c95468897f408dd0aca2ff582074423dd0455122",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -6266,7 +6267,7 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony String component",
|
"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",
|
"homepage": "https://symfony.com",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"grapheme",
|
"grapheme",
|
||||||
|
@ -6277,7 +6278,7 @@
|
||||||
"utf8"
|
"utf8"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/string/tree/v5.2.1"
|
"source": "https://github.com/symfony/string/tree/v5.2.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -6293,20 +6294,20 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-05T07:33:16+00:00"
|
"time": "2021-01-25T15:14:59+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/yaml",
|
"name": "symfony/yaml",
|
||||||
"version": "v5.2.1",
|
"version": "v5.2.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/yaml.git",
|
"url": "https://github.com/symfony/yaml.git",
|
||||||
"reference": "290ea5e03b8cf9b42c783163123f54441fb06939"
|
"reference": "338cddc6d74929f6adf19ca5682ac4b8e109cdb0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/290ea5e03b8cf9b42c783163123f54441fb06939",
|
"url": "https://api.github.com/repos/symfony/yaml/zipball/338cddc6d74929f6adf19ca5682ac4b8e109cdb0",
|
||||||
"reference": "290ea5e03b8cf9b42c783163123f54441fb06939",
|
"reference": "338cddc6d74929f6adf19ca5682ac4b8e109cdb0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -6349,10 +6350,10 @@
|
||||||
"homepage": "https://symfony.com/contributors"
|
"homepage": "https://symfony.com/contributors"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Symfony Yaml Component",
|
"description": "Loads and dumps YAML files",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/yaml/tree/v5.2.1"
|
"source": "https://github.com/symfony/yaml/tree/v5.2.3"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -6368,7 +6369,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-08T17:02:38+00:00"
|
"time": "2021-02-03T04:42:09+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "theseer/tokenizer",
|
"name": "theseer/tokenizer",
|
||||||
|
@ -6425,12 +6426,12 @@
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/webmozart/assert.git",
|
"url": "https://github.com/webmozarts/assert.git",
|
||||||
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
|
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
|
"url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
|
||||||
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
|
"reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
|
@ -6468,8 +6469,8 @@
|
||||||
"validate"
|
"validate"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/webmozart/assert/issues",
|
"issues": "https://github.com/webmozarts/assert/issues",
|
||||||
"source": "https://github.com/webmozart/assert/tree/master"
|
"source": "https://github.com/webmozarts/assert/tree/1.9.1"
|
||||||
},
|
},
|
||||||
"time": "2020-07-08T17:02:28+00:00"
|
"time": "2020-07-08T17:02:28+00:00"
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,6 +26,7 @@ class AppAsset extends AssetBundle
|
||||||
'css/bootstrap/bootstrap.min.css',
|
'css/bootstrap/bootstrap.min.css',
|
||||||
'css/main.css',
|
'css/main.css',
|
||||||
'css/header.css',
|
'css/header.css',
|
||||||
|
'css/notification.css',
|
||||||
'css/info_panel.css',
|
'css/info_panel.css',
|
||||||
'css/categories_blocks_panel.css',
|
'css/categories_blocks_panel.css',
|
||||||
'css/footer.css'
|
'css/footer.css'
|
||||||
|
@ -39,6 +40,7 @@ class AppAsset extends AssetBundle
|
||||||
'js/menu.js',
|
'js/menu.js',
|
||||||
'js/account.js',
|
'js/account.js',
|
||||||
'js/search.js',
|
'js/search.js',
|
||||||
|
'js/notification.js',
|
||||||
'js/reinitialization.js'
|
'js/reinitialization.js'
|
||||||
];
|
];
|
||||||
public $jsOptions = [
|
public $jsOptions = [
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$config = [
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
return [
|
||||||
'id' => 'skillparts-console',
|
'id' => 'skillparts-console',
|
||||||
'basePath' => dirname(__DIR__),
|
'basePath' => dirname(__DIR__),
|
||||||
'bootstrap' => ['log'],
|
'bootstrap' => ['log'],
|
||||||
|
@ -9,7 +11,6 @@ $config = [
|
||||||
'@vendor' => dirname(__DIR__) . '/../../../vendor',
|
'@vendor' => dirname(__DIR__) . '/../../../vendor',
|
||||||
'@bower' => '@vendor/bower-asset',
|
'@bower' => '@vendor/bower-asset',
|
||||||
'@npm' => '@vendor/npm-asset',
|
'@npm' => '@vendor/npm-asset',
|
||||||
'@explosivebit' => '@vendor/explosivebit',
|
|
||||||
'@tests' => '@app/tests',
|
'@tests' => '@app/tests',
|
||||||
],
|
],
|
||||||
'components' => [
|
'components' => [
|
||||||
|
@ -28,19 +29,9 @@ $config = [
|
||||||
],
|
],
|
||||||
'params' => require __DIR__ . '/params.php',
|
'params' => require __DIR__ . '/params.php',
|
||||||
'controllerMap' => [
|
'controllerMap' => [
|
||||||
'arangodb-migrate' => 'explosivebit\arangodb\console\controllers\MigrateController',
|
'arangodb-migrate' => 'mirzaev\yii2\arangodb\console\controllers\MigrateController',
|
||||||
'fixture' => [
|
'fixture' => [
|
||||||
'class' => 'yii\faker\FixtureController',
|
'class' => 'yii\faker\FixtureController',
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
if (YII_ENV_DEV) {
|
|
||||||
// configuration adjustments for 'dev' environment
|
|
||||||
$config['bootstrap'][] = 'gii';
|
|
||||||
$config['modules']['gii'] = [
|
|
||||||
'class' => 'yii\gii\Module',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $config;
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ class AuthenticationController extends Controller
|
||||||
|
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
$return = [
|
$return = [
|
||||||
'menu' => (new AccountForm())->deauthenticationGenHtml(),
|
'menu' => $this->renderPartial('/account/deauthentication'),
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => Yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ class AuthenticationController extends Controller
|
||||||
Yii::$app->response->statusCode = 400;
|
Yii::$app->response->statusCode = 400;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('/account', compact('model')),
|
'main' => $this->renderPartial('/account/index', compact('model')),
|
||||||
'redirect' => '/authentication',
|
'redirect' => '/authentication',
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => Yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
@ -103,7 +103,7 @@ class AuthenticationController extends Controller
|
||||||
if (!Yii::$app->user->isGuest) {
|
if (!Yii::$app->user->isGuest) {
|
||||||
Yii::$app->response->redirect('/');
|
Yii::$app->response->redirect('/');
|
||||||
} else {
|
} else {
|
||||||
return $this->render('/account');
|
return $this->render('/account/index');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
use Yii;
|
use yii;
|
||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
use yii\web\Response;
|
use yii\web\Response;
|
||||||
use yii\filters\AccessControl;
|
use yii\filters\AccessControl;
|
||||||
|
@ -34,20 +34,20 @@ class DeauthenticationController extends Controller
|
||||||
|
|
||||||
public function actionIndex()
|
public function actionIndex()
|
||||||
{
|
{
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
// Выход из аккаунта
|
// Выход из аккаунта
|
||||||
Yii::$app->user->logout();
|
yii::$app->user->logout();
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$model = new AccountForm(Yii::$app->request->post('AccountForm') ?? Yii::$app->request->get('AccountForm') ?? null);
|
$model = new AccountForm(yii::$app->request->post('AccountForm') ?? yii::$app->request->get('AccountForm') ?? null);
|
||||||
|
|
||||||
// Ответа
|
// Ответа
|
||||||
return [
|
return [
|
||||||
'menu' => $model->authenticationGenHtml($this->renderPartial('/account', compact('model'))),
|
'menu' => $this->renderPartial('/account/authentication', compact('model')),
|
||||||
'main' => $this->renderPartial('/index'),
|
'main' => $this->renderPartial('/index'),
|
||||||
'redirect' => '/',
|
'redirect' => '/',
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ namespace app\controllers;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
use yii\web\ErrorAction;
|
|
||||||
use yii\web\Response;
|
|
||||||
|
|
||||||
class ErrorController extends Controller
|
class ErrorController extends Controller
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,53 +1,56 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
use Yii;
|
use yii;
|
||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
use yii\web\Response;
|
use yii\web\Response;
|
||||||
|
|
||||||
use app\models\AccountForm;
|
use app\models\AccountForm;
|
||||||
|
|
||||||
class IdentificationController extends Controller
|
class IdentificationController extends Controller
|
||||||
{
|
{
|
||||||
public function actionIndex()
|
public function actionIndex()
|
||||||
{
|
{
|
||||||
if (Yii::$app->request->isAjax) {
|
if (yii::$app->request->isPost) {
|
||||||
// AJAX-POST-запрос
|
// POST-запрос
|
||||||
|
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
if (Yii::$app->user->isGuest) {
|
if (yii::$app->user->isGuest) {
|
||||||
// Аккаунт не аутентифицирован
|
// Аккаунт не аутентифицирован
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$model = new AccountForm(Yii::$app->request->post('AccountForm') ?? Yii::$app->request->get('AccountForm') ?? null);
|
$model = new AccountForm(yii::$app->request->post('AccountForm') ?? yii::$app->request->get('AccountForm') ?? null);
|
||||||
|
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
$return = [
|
$return = [
|
||||||
'menu' => $model->authenticationGenHtml($this->renderPartial('/account', compact('model'))),
|
'menu' => $this->renderPartial('/account/authentication', compact('model')),
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
// Аккаунт аутентифицирован
|
// Аккаунт аутентифицирован
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$model = Yii::$app->user;
|
$model = yii::$app->user;
|
||||||
|
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
$return = [
|
$return = [
|
||||||
'menu' => (new AccountForm())->deauthenticationGenHtml(),
|
'menu' => $this->renderPartial('/account/deauthentication'),
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($cookies = Yii::$app->request->cookies)->has('redirect')) {
|
if (($cookies = yii::$app->request->cookies)->has('redirect')) {
|
||||||
// Найдено cookie с переадресацией
|
// Найдено cookie с переадресацией
|
||||||
|
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
$return['redirect'] = '/' . $cookies['redirect'];
|
$return['redirect'] = '/' . $cookies['redirect'];
|
||||||
|
|
||||||
// Очистка cookie
|
// Очистка cookie
|
||||||
unset(Yii::$app->response->cookies['redirect']);
|
unset(yii::$app->response->cookies['redirect']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\controllers;
|
||||||
|
|
||||||
|
use app\models\AccountEdgeNotification;
|
||||||
|
use yii;
|
||||||
|
use yii\filters\AccessControl;
|
||||||
|
use yii\web\Controller;
|
||||||
|
use yii\web\Response;
|
||||||
|
|
||||||
|
use app\models\Notification;
|
||||||
|
|
||||||
|
class NotificationController extends Controller
|
||||||
|
{
|
||||||
|
public function behaviors()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'access' => [
|
||||||
|
'class' => AccessControl::class,
|
||||||
|
'only' => ['index'],
|
||||||
|
'rules' => [
|
||||||
|
[
|
||||||
|
'allow' => true,
|
||||||
|
'roles' => ['@']
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function actionIndex()
|
||||||
|
{
|
||||||
|
if (yii::$app->request->isPost) {
|
||||||
|
// POST-запрос
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$model = new Notification(yii::$app->request->post('Notification'));
|
||||||
|
|
||||||
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
|
$return = [
|
||||||
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
|
];
|
||||||
|
|
||||||
|
if (yii::$app->request->post('last')) {
|
||||||
|
// Запрос последнего уведомлений (всплывающее окно)
|
||||||
|
|
||||||
|
$limit = 1;
|
||||||
|
} else if (yii::$app->request->post('stream')) {
|
||||||
|
// Запрос последних уведомлений (панель)
|
||||||
|
|
||||||
|
$limit = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($limit)) {
|
||||||
|
// Обработка для всплывающего окна или панель
|
||||||
|
|
||||||
|
// Подзапрос для проверки статуса уведомления относительно пользователя
|
||||||
|
// Поиск рёбер: ПОЛЬЗОВАТЕЛЬ -> УВЕДОМЛЕНИЕ
|
||||||
|
$let = $model::find()
|
||||||
|
->for(['account', $model::collectionName() . '_edge_account'])
|
||||||
|
->traversal($model::collectionName(), 'OUTBOUND')
|
||||||
|
->in('account_edge_' . $model::collectionName())
|
||||||
|
->where(['account._id' => yii::$app->user->id])
|
||||||
|
->select($model::collectionName() . '_edge_account');
|
||||||
|
|
||||||
|
if (yii::$app->request->post('last')) {
|
||||||
|
// Запрос последнего уведомлений (всплывающее окно)
|
||||||
|
|
||||||
|
// Уведомление которое не выводилось на мониторе пользователя
|
||||||
|
$type = 'received';
|
||||||
|
} else if (yii::$app->request->post('stream')) {
|
||||||
|
// Запрос последних уведомлений (панель)
|
||||||
|
|
||||||
|
// Уведомление которое не было прочитано в окне уведомний
|
||||||
|
$type = 'checked';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Генерация подзапроса по перебору ядра
|
||||||
|
$let = $let->createCommand();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поиск рёбер: (УВЕДОМЛЕНИЕ)? -> ПОЛЬЗОВАТЕЛЬ
|
||||||
|
*
|
||||||
|
* @param bool $check Активация проверки получения
|
||||||
|
*/
|
||||||
|
$search = function (bool $check = false) use ($model, $type, $let, $limit): array {
|
||||||
|
return $model::searchByAccount(
|
||||||
|
params: $check ? $let->getBindVars() : [],
|
||||||
|
where: [
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'notification.html' => null
|
||||||
|
],
|
||||||
|
'operator' => '!='
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'account_edge_notification.type' => $type
|
||||||
|
]
|
||||||
|
],
|
||||||
|
let: [
|
||||||
|
$model::collectionName() . '_edge_account',
|
||||||
|
'(' . (string) $let . ')'
|
||||||
|
],
|
||||||
|
post_where: $check ? [
|
||||||
|
'account_edge_notification[0]._to' => null
|
||||||
|
] : [],
|
||||||
|
limit: $limit,
|
||||||
|
sort: ['DESC'],
|
||||||
|
direction: 'INBOUND'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Поиск непрочитанных уведомлений пользователя
|
||||||
|
$notifications = $search(true);
|
||||||
|
|
||||||
|
if (!yii::$app->request->post('last') && empty($notifications)) {
|
||||||
|
// Уведомления не найдены и запрошены НЕ всплывающие уведомления
|
||||||
|
|
||||||
|
// Поиск уведомлений пользователя
|
||||||
|
$notifications = $search();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($notifications)) {
|
||||||
|
// Уведомления не найдены
|
||||||
|
|
||||||
|
yii::$app->response->statusCode = 404;
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($notifications as $notification) {
|
||||||
|
// Перебор найденных уведомлений
|
||||||
|
|
||||||
|
// Запись ребра: ПОЛЬЗОВАТЕЛЬ -> УВЕДОМЛЕНИЕ (о том, что уведомление прочитано)
|
||||||
|
AccountEdgeNotification::write(yii::$app->user->id, $notification->readId(), $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yii::$app->request->post('last')) {
|
||||||
|
// Запрос последнего уведомлений (всплывающее окно)
|
||||||
|
|
||||||
|
// Реинициализация
|
||||||
|
$notification = $notifications[0];
|
||||||
|
|
||||||
|
$return['popup'] = [
|
||||||
|
'html' => $this->renderPartial('popup', compact('model', 'notification')),
|
||||||
|
'id' => 'popup/' . $notification->readId()
|
||||||
|
];
|
||||||
|
} else if (yii::$app->request->post('stream')) {
|
||||||
|
// Запрос последних уведомлений (панель)
|
||||||
|
|
||||||
|
$return['panel'] = $this->renderPartial('panel', compact('model', 'notifications'));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Иначе обрабатывается как запрос страницы уведомлений
|
||||||
|
|
||||||
|
$return['main'] = $this->renderPartial('index', compact('model'));
|
||||||
|
$return['redirect'] = '/notification';
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('index', ['model' => new Notification(yii::$app->request->get('Notification'))]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\filters\AccessControl;
|
use yii\filters\AccessControl;
|
||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
use yii\web\Response;
|
use yii\web\Response;
|
||||||
use app\models\Product;
|
|
||||||
use yii\web\HttpException;
|
use yii\web\HttpException;
|
||||||
|
|
||||||
|
use app\models\Product;
|
||||||
|
|
||||||
class ProductController extends Controller
|
class ProductController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -19,20 +22,24 @@ class ProductController extends Controller
|
||||||
return [
|
return [
|
||||||
'access' => [
|
'access' => [
|
||||||
'class' => AccessControl::class,
|
'class' => AccessControl::class,
|
||||||
'only' => ['add'],
|
|
||||||
'rules' => [
|
'rules' => [
|
||||||
|
[
|
||||||
|
'allow' => true,
|
||||||
|
'actions' => ['index'],
|
||||||
|
'roles' => ['@']
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'allow' => false,
|
'allow' => false,
|
||||||
'roles' => ['?']
|
'roles' => ['?']
|
||||||
]
|
],
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionIndex(int $id)
|
public function actionIndex(string $catn)
|
||||||
{
|
{
|
||||||
if ($model = Product::readById($id)) {
|
if ($model = Product::searchByCatn($catn)) {
|
||||||
// Товар найден
|
// Товар найден
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
|
@ -45,7 +52,7 @@ class ProductController extends Controller
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('index', compact('model')),
|
'main' => $this->renderPartial('index', compact('model')),
|
||||||
'redirect' => '/product/' . $id,
|
'redirect' => '/product/' . $catn,
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => Yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
use Yii;
|
use yii;
|
||||||
use yii\filters\AccessControl;
|
use yii\filters\AccessControl;
|
||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
use yii\web\Response;
|
use yii\web\Response;
|
||||||
|
@ -12,12 +13,13 @@ use yii\web\UploadedFile;
|
||||||
|
|
||||||
use app\models\Supply;
|
use app\models\Supply;
|
||||||
use app\models\SupplyGroup;
|
use app\models\SupplyGroup;
|
||||||
|
use app\models\Search;
|
||||||
|
use app\models\Notification;
|
||||||
|
use app\models\Settings;
|
||||||
|
use app\models\SettingsEdgeSettings;
|
||||||
|
|
||||||
class ProfileController extends Controller
|
class ProfileController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function behaviors()
|
public function behaviors()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -26,13 +28,20 @@ class ProfileController extends Controller
|
||||||
'rules' => [
|
'rules' => [
|
||||||
[
|
[
|
||||||
'allow' => true,
|
'allow' => true,
|
||||||
'roles' => ['@']
|
'roles' => ['@'],
|
||||||
|
'actions' => ['index', 'supplies', 'import', 'monitoring', 'readGroups'],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'allow' => false,
|
'allow' => false,
|
||||||
'roles' => ['?'],
|
'roles' => ['?'],
|
||||||
'verbs' => ['POST'],
|
|
||||||
'denyCallback' => [$this, 'accessDenied']
|
'denyCallback' => [$this, 'accessDenied']
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'allow' => true,
|
||||||
|
'actions' => ['trusted', 'trusted-notification-write'],
|
||||||
|
'matchCallback' => function ($rule, $action) {
|
||||||
|
return yii::$app->user->identity->trst;
|
||||||
|
}
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -41,21 +50,32 @@ class ProfileController extends Controller
|
||||||
|
|
||||||
public function accessDenied()
|
public function accessDenied()
|
||||||
{
|
{
|
||||||
$cookies = Yii::$app->response->cookies;
|
// Инициализация
|
||||||
|
$cookies = yii::$app->response->cookies;
|
||||||
|
|
||||||
|
// Запись cookie с редиректом, который выполнится после авторизации
|
||||||
$cookies->add(new Cookie([
|
$cookies->add(new Cookie([
|
||||||
'name' => 'redirect',
|
'name' => 'redirect',
|
||||||
'value' => Yii::$app->request->pathInfo
|
'value' => yii::$app->request->pathInfo
|
||||||
]));
|
]));
|
||||||
|
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
if (Yii::$app->request->isPost) {
|
||||||
|
// POST-запрос
|
||||||
|
|
||||||
// Проверить переадресацию на уровне сервера
|
// Настройка
|
||||||
Yii::$app->response->content = json_encode([
|
Yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
'main' => $this->renderPartial('/account'),
|
|
||||||
'redirect' => '/authentication',
|
// Генерация ответа
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
Yii::$app->response->content = json_encode([
|
||||||
]);
|
'main' => $this->renderPartial('/account/index'),
|
||||||
|
'redirect' => '/authentication',
|
||||||
|
'_csrf' => Yii::$app->request->getCsrfToken()
|
||||||
|
]);
|
||||||
|
} else if (Yii::$app->request->isGet) {
|
||||||
|
// GET-запрос
|
||||||
|
|
||||||
|
$this->redirect('/authentication');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,75 +84,236 @@ class ProfileController extends Controller
|
||||||
public function actionIndex(): string|array
|
public function actionIndex(): string|array
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$model = Yii::$app->user->identity;
|
$model = yii::$app->user->identity;
|
||||||
|
$attributes = Supply::searchByAccount(yii::$app->user->id);
|
||||||
|
|
||||||
|
if ($vars = yii::$app->request->post('Account') ?? yii::$app->request->get('Account')) {
|
||||||
|
// Обнаружены входные параметры
|
||||||
|
|
||||||
|
if (isset($vars['opts'])) {
|
||||||
|
// Переданы параметры
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
is_array($model->opts) || $model->opts = [];
|
||||||
|
|
||||||
|
// Запись
|
||||||
|
$model->opts = array_merge($model->opts, $vars['opts']);
|
||||||
|
|
||||||
|
$model->update();
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* @todo Написать обработчик ошибок
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Генерация
|
// Генерация
|
||||||
$sidebar = $this->renderPartial('sidebar');
|
$sidebar = $this->renderPartial('sidebar');
|
||||||
|
|
||||||
if (Yii::$app->request->isAjax) {
|
if (yii::$app->request->isPost) {
|
||||||
// AJAX-POST-запрос
|
// POST-запрос
|
||||||
|
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('index', compact('model', 'sidebar')),
|
'main' => $this->renderPartial('index', compact('model', 'sidebar', 'attributes')),
|
||||||
'redirect' => '/profile',
|
'redirect' => '/profile',
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('index', compact('model', 'sidebar'));
|
return $this->render('index', compact('model', 'sidebar', 'attributes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Страницка поставок
|
* Страница поставок
|
||||||
*/
|
*/
|
||||||
public function actionSupplies(): string|array
|
public function actionSupplies(): string|array
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$model = new Supply(Yii::$app->request->post('Supply') ?? Yii::$app->request->get('Supply'));
|
$model = new Supply(yii::$app->request->post('Supply') ?? yii::$app->request->get('Supply'));
|
||||||
|
|
||||||
// Генерация
|
// Генерация
|
||||||
$sidebar = $this->renderPartial('sidebar', compact('model'));
|
$sidebar = $this->renderPartial('sidebar');
|
||||||
|
|
||||||
if (Yii::$app->request->isAjax) {
|
if (yii::$app->request->isPost) {
|
||||||
// AJAX-POST-запрос
|
// AJAX-POST-запрос
|
||||||
|
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('supplies', compact('model', 'sidebar')),
|
'main' => $this->renderPartial('supplies', compact('model', 'sidebar')),
|
||||||
'redirect' => '/profile/supplies',
|
'redirect' => '/profile/supplies',
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('supplies', compact('model', 'sidebar'));
|
return $this->render('supplies', compact('model', 'sidebar'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Страница панели управления для доверенных пользователей
|
||||||
|
*/
|
||||||
|
public function actionTrusted(): string|array
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
$model_notifications = null;
|
||||||
|
$model_settings = Settings::readLast();
|
||||||
|
|
||||||
|
if (!is_null($vars = yii::$app->request->post('Notification') ?? yii::$app->request->get('Notification'))) {
|
||||||
|
// Обнаружены входные параметры из раздела "Уведомления"
|
||||||
|
|
||||||
|
// Реинициализация с новыми параметрами
|
||||||
|
$model_notifications = new Notification($vars);
|
||||||
|
|
||||||
|
// Запись уведомления и отправка (запись ребра до аккаунта)
|
||||||
|
$model_notifications->write();
|
||||||
|
} else if (!is_null($vars = yii::$app->request->post('Settings') ?? yii::$app->request->get('Settings'))) {
|
||||||
|
// Обнаружены входные параметры из раздела "Настройки"
|
||||||
|
|
||||||
|
if ($to = new Settings($vars)) {
|
||||||
|
// Настройки инициализированы
|
||||||
|
|
||||||
|
// Отправка
|
||||||
|
if ($to->save()) {
|
||||||
|
// Сохранено в базе данных
|
||||||
|
|
||||||
|
// Буфер
|
||||||
|
$from = $model_settings;
|
||||||
|
|
||||||
|
// Реинициализация (для представления)
|
||||||
|
$model_settings = $to;
|
||||||
|
|
||||||
|
if ($from) {
|
||||||
|
// Найдена старая версия настроек
|
||||||
|
|
||||||
|
// Запись ребра: НАСТРОЙКИ (старые) -> НАСТРОЙКИ (новые)
|
||||||
|
SettingsEdgeSettings::write($from->readId(), $to->readId(), 'update');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Не сохранено в базе данных
|
||||||
|
|
||||||
|
// Запись ошибок
|
||||||
|
$model_settings->addErrors($to->getErrors());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Деинициализация
|
||||||
|
unset($vars);
|
||||||
|
|
||||||
|
// Генерация
|
||||||
|
$sidebar = $this->renderPartial('sidebar');
|
||||||
|
|
||||||
|
if (yii::$app->request->isPost) {
|
||||||
|
// AJAX-POST-запрос
|
||||||
|
|
||||||
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'main' => $this->renderPartial('trusted', compact('model_notifications', 'model_settings', 'sidebar')),
|
||||||
|
'redirect' => '/profile/trusted',
|
||||||
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('trusted', compact('model_notifications', 'model_settings', 'sidebar'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Страницка панели управления для доверенных пользователей
|
||||||
|
*
|
||||||
|
* @todo Перенести в уведомления
|
||||||
|
*/
|
||||||
|
// public function actionTrustedNotificationWrite(): string|array
|
||||||
|
// {
|
||||||
|
// // Инициализация
|
||||||
|
// $model = new Notification(yii::$app->request->post('Notification') ?? yii::$app->request->get('Notification'));
|
||||||
|
|
||||||
|
// $model->write();
|
||||||
|
|
||||||
|
// if (yii::$app->request->isPost) {
|
||||||
|
// // POST-запрос
|
||||||
|
|
||||||
|
// yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
|
// return [
|
||||||
|
// 'main' => $this->renderPartial('trusted', compact('model', 'sidebar')),
|
||||||
|
// 'redirect' => '/profile/trusted',
|
||||||
|
// '_csrf' => yii::$app->request->getCsrfToken()
|
||||||
|
// ];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return $this->render('trusted', compact('model', 'sidebar'));
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Страницка панели управления для доверенных пользователей
|
||||||
|
*/
|
||||||
|
public function actionMonitoring(): string|array
|
||||||
|
{
|
||||||
|
|
||||||
|
// Инициализация номера страницы
|
||||||
|
$page_search_history = (yii::$app->request->post('search') ?? yii::$app->request->get('search')) - 1;
|
||||||
|
if ($page_search_history <= 0) {
|
||||||
|
$page_search_history = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Инициализация количества строк на одной странице
|
||||||
|
$rows_amount = 10;
|
||||||
|
|
||||||
|
// Генерация
|
||||||
|
$sidebar = $this->renderPartial('sidebar');
|
||||||
|
$search_history = Search::searchByAccount(yii::$app->user->id, $rows_amount, ((int) $page_search_history ?? 0) * $rows_amount);
|
||||||
|
|
||||||
|
if (yii::$app->request->isPost) {
|
||||||
|
// AJAX-POST-запрос
|
||||||
|
|
||||||
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'main' => $this->renderPartial('monitoring', compact(
|
||||||
|
'sidebar',
|
||||||
|
'search_history',
|
||||||
|
'page_search_history'
|
||||||
|
)),
|
||||||
|
'search' => $page_search_history + 1,
|
||||||
|
'redirect' => '/profile/monitoring',
|
||||||
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('monitoring', compact(
|
||||||
|
'sidebar',
|
||||||
|
'search_history',
|
||||||
|
'page_search_history'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
public function actionImport()
|
public function actionImport()
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$model = new Supply(Yii::$app->request->post('Supply') ?? Yii::$app->request->get('Supply'));
|
$model = new Supply(yii::$app->request->post('Supply') ?? yii::$app->request->get('Supply'));
|
||||||
$model->scenario = $model::SCENARIO_IMPORT;
|
$model->scenario = $model::SCENARIO_IMPORT;
|
||||||
|
|
||||||
// Генерация
|
// Генерация
|
||||||
$sidebar = $this->renderPartial('sidebar', compact('model'));
|
$sidebar = $this->renderPartial('sidebar');
|
||||||
|
|
||||||
if (Yii::$app->request->isAjax) {
|
if (yii::$app->request->isPost) {
|
||||||
// AJAX-POST-запрос
|
// AJAX-POST-запрос
|
||||||
|
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
$model->file = UploadedFile::getInstances($model, 'file');
|
$model->file = UploadedFile::getInstances($model, 'file');
|
||||||
|
|
||||||
if (!$test = $model->import()) {
|
if (!$test = $model->import()) {
|
||||||
Yii::$app->response->statusCode = 409;
|
yii::$app->response->statusCode = 409;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('supplies', compact('model', 'sidebar')),
|
'main' => $this->renderPartial('supplies', compact('model', 'sidebar')),
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
use Yii;
|
use yii;
|
||||||
use yii\filters\AccessControl;
|
use yii\filters\AccessControl;
|
||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
use yii\web\Response;
|
use yii\web\Response;
|
||||||
|
|
||||||
use app\models\AccountForm;
|
use app\models\AccountForm;
|
||||||
|
|
||||||
class RegistrationController extends Controller
|
class RegistrationController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function behaviors()
|
public function behaviors()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -31,16 +30,16 @@ class RegistrationController extends Controller
|
||||||
|
|
||||||
public function actionIndex()
|
public function actionIndex()
|
||||||
{
|
{
|
||||||
if (Yii::$app->request->isAjax) {
|
if (yii::$app->request->isPost) {
|
||||||
// AJAX-POST-запрос
|
// POST-запрос
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$model = new AccountForm(Yii::$app->request->post('AccountForm'));
|
$model = new AccountForm(yii::$app->request->post('AccountForm'));
|
||||||
$model->scenario = $model::SCENARIO_REGISTRATION;
|
$model->scenario = $model::SCENARIO_REGISTRATION;
|
||||||
|
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
if (!Yii::$app->user->isGuest || $model->registration()) {
|
if (!yii::$app->user->isGuest || $model->registration()) {
|
||||||
// Данные прошли проверку и аккаунт был создан
|
// Данные прошли проверку и аккаунт был создан
|
||||||
|
|
||||||
// Аутентификация
|
// Аутентификация
|
||||||
|
@ -49,11 +48,11 @@ class RegistrationController extends Controller
|
||||||
|
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
$return = [
|
$return = [
|
||||||
'menu' => (new AccountForm())->deauthenticationGenHtml(),
|
'menu' => $this->renderPartial('/account/deauthentication'),
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
|
||||||
if (($cookies = Yii::$app->response->cookies)->has('redirect')) {
|
if (($cookies = yii::$app->response->cookies)->has('redirect')) {
|
||||||
// Найдено cookie с переадресацией
|
// Найдено cookie с переадресацией
|
||||||
|
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
|
@ -61,11 +60,11 @@ class RegistrationController extends Controller
|
||||||
$return['main'] = $this->renderPartial($return['redirect'] . '/index');
|
$return['main'] = $this->renderPartial($return['redirect'] . '/index');
|
||||||
|
|
||||||
// Очистка cookie
|
// Очистка cookie
|
||||||
unset(Yii::$app->response->cookies['redirect']);
|
unset(yii::$app->response->cookies['redirect']);
|
||||||
} else {
|
} else {
|
||||||
// Не найдено cookie с переадресацией
|
// Не найдено cookie с переадресацией
|
||||||
|
|
||||||
if (Yii::$app->request->pathInfo === 'authentication' || Yii::$app->request->pathInfo === 'registration') {
|
if (yii::$app->request->pathInfo === 'authentication' || yii::$app->request->pathInfo === 'registration') {
|
||||||
// Если клиент на промежуточном URI
|
// Если клиент на промежуточном URI
|
||||||
|
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
|
@ -78,18 +77,18 @@ class RegistrationController extends Controller
|
||||||
} else {
|
} else {
|
||||||
// Данные не прошли проверку
|
// Данные не прошли проверку
|
||||||
|
|
||||||
Yii::$app->response->statusCode = 400;
|
yii::$app->response->statusCode = 400;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'main' => $this->renderPartial('/account', compact('model')),
|
'main' => $this->renderPartial('/account', compact('model')),
|
||||||
'redirect' => '/registration',
|
'redirect' => '/registration',
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Yii::$app->user->isGuest) {
|
if (!yii::$app->user->isGuest) {
|
||||||
Yii::$app->response->redirect('/');
|
yii::$app->response->redirect('/');
|
||||||
} else {
|
} else {
|
||||||
return $this->render('/account', compact('model'));
|
return $this->render('/account', compact('model'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,90 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
use Yii;
|
use yii;
|
||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
use yii\web\Response;
|
use yii\web\Response;
|
||||||
|
|
||||||
use app\models\Product;
|
use app\models\Product;
|
||||||
use yii\web\Cookie;
|
use app\models\Search;
|
||||||
|
|
||||||
class SearchController extends Controller
|
class SearchController extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @todo Сессию привязать к аккаунту и проверку по нему делать, иначе её можно просто сбрасывать
|
||||||
|
*/
|
||||||
public function actionIndex(): array|string
|
public function actionIndex(): array|string
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$query = Yii::$app->request->post('request') ?? Yii::$app->request->get('q');
|
$query = yii::$app->request->post('request') ?? yii::$app->request->get('q');
|
||||||
|
|
||||||
if (Yii::$app->request->post('type') === 'product' || Yii::$app->request->get('type') === 'product') {
|
if (yii::$app->request->post('type') === 'product' || yii::$app->request->get('type') === 'product') {
|
||||||
// Поиск по продуктам
|
// Поиск по продуктам
|
||||||
|
|
||||||
|
if (yii::$app->request->post('history')) {
|
||||||
|
// Запрошена история
|
||||||
|
|
||||||
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'search_line_window' => $this->renderPartial('/search/panel', ['history' => true]),
|
||||||
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
// Инициализация сессии
|
// Инициализация сессии
|
||||||
$session = Yii::$app->session;
|
$session = yii::$app->session;
|
||||||
$session->open();
|
$session->open();
|
||||||
|
|
||||||
// Инициализация ответа
|
// Инициализация ответа
|
||||||
$response = null;
|
$response = null;
|
||||||
|
|
||||||
|
// Инициализация параметров
|
||||||
|
$timer = 0;
|
||||||
|
|
||||||
// Период пропуска запросов (в секундах)
|
// Период пропуска запросов (в секундах)
|
||||||
$period = 1;
|
$period = 3;
|
||||||
|
$keep_connect = true;
|
||||||
|
$sanction = false;
|
||||||
|
$sanction_condition = ($session['last_request'] + $period - time()) < $period;
|
||||||
|
$sanction_time = 2;
|
||||||
|
$query_min = 2;
|
||||||
|
$query_max = 20;
|
||||||
|
|
||||||
|
if (isset($session['last_request'])) {
|
||||||
|
// Данные о времени последнего запроса не найдены
|
||||||
|
|
||||||
|
if ($sanction && $sanction_condition) {
|
||||||
|
// Наказание за повторный запрос при условии задержки
|
||||||
|
|
||||||
|
$session['last_request'] += $sanction_time;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Это первый запрос
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$session['last_request'] = time();
|
||||||
|
|
||||||
|
goto first_request;
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_connect_wait:
|
||||||
|
|
||||||
// Запись времени последнего запроса и вычисление об истечении таймера
|
// Запись времени последнего запроса и вычисление об истечении таймера
|
||||||
$timer = ($session['last_request'] ?? $session['last_request'] = time() + $period) - time();
|
$timer = $session['last_request'] + $period - time();
|
||||||
|
|
||||||
if ($timer > 0) {
|
if ($timer > 0) {
|
||||||
// Ожидание перед повторным запросом при условии что старых запросов нет
|
// Ожидание перед повторным запросом при условии что старых запросов нет
|
||||||
|
|
||||||
Yii::$app->response->statusCode = 202;
|
yii::$app->response->statusCode = 202;
|
||||||
|
|
||||||
$return = [
|
$return = [
|
||||||
'timer' => $timer,
|
'timer' => $timer,
|
||||||
'search_line_window' => $this->renderPartial('/loading'),
|
'search_line_window' => $this->renderPartial('/loading'),
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
// Повторный запрос по истечению ожидания
|
// Повторный запрос по истечению ожидания
|
||||||
|
@ -47,22 +92,33 @@ class SearchController extends Controller
|
||||||
// Очистка времени последнего запроса
|
// Очистка времени последнего запроса
|
||||||
unset($session['last_request']);
|
unset($session['last_request']);
|
||||||
|
|
||||||
//
|
first_request:
|
||||||
// Здесь запись истории запросов (в базе данных)
|
|
||||||
//
|
|
||||||
|
|
||||||
$limit = Yii::$app->request->isAjax ? 10 : 30;
|
if (strlen($query) < $query_min) {
|
||||||
|
// Выход за ограничения длины с недостатком
|
||||||
|
|
||||||
if ($response = Product::searchByCatn($query, $limit)) {
|
goto skip_query;
|
||||||
|
} else if (strlen($query) > $query_max) {
|
||||||
|
// Выход за ограничения длины с превышением
|
||||||
|
|
||||||
|
goto skip_query;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запись в историю
|
||||||
|
Search::write($query);
|
||||||
|
|
||||||
|
$limit = yii::$app->request->isPost ? 10 : 20;
|
||||||
|
|
||||||
|
if ($response = Product::searchByCatn($query, $limit, [])) {
|
||||||
// Данные найдены по поиску в полях Каталожного номера
|
// Данные найдены по поиску в полях Каталожного номера
|
||||||
|
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
$return = [
|
$return = [
|
||||||
'search_line_window' => $this->renderPartial('/search/panel', compact('response')),
|
'search_line_window' => $this->renderPartial('/search/panel', compact('response')),
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
|
|
||||||
if ((int) Yii::$app->request->post('advanced')) {
|
if ((int) yii::$app->request->post('advanced')) {
|
||||||
// Полноценный поиск
|
// Полноценный поиск
|
||||||
|
|
||||||
// Запись ответа
|
// Запись ответа
|
||||||
|
@ -71,30 +127,40 @@ class SearchController extends Controller
|
||||||
$return['redirect'] = '/search?type=product&q=' . $query;
|
$return['redirect'] = '/search?type=product&q=' . $query;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Данные не найдены
|
// Данные не найдены
|
||||||
|
|
||||||
Yii::$app->response->statusCode = 404;
|
yii::$app->response->statusCode = 404;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Yii::$app->request->isAjax) {
|
skip_query:
|
||||||
// AJAX-POST-запрос
|
|
||||||
|
|
||||||
Yii::$app->response->format = Response::FORMAT_JSON;
|
if (yii::$app->request->isPost) {
|
||||||
|
// POST-запрос
|
||||||
|
|
||||||
|
yii::$app->response->format = Response::FORMAT_JSON;
|
||||||
|
|
||||||
return $return ?? [
|
return $return ?? [
|
||||||
'search_line_window' => $this->renderPartial('/search/panel'),
|
'search_line_window' => $this->renderPartial('/search/panel'),
|
||||||
'_csrf' => Yii::$app->request->getCsrfToken()
|
'_csrf' => yii::$app->request->getCsrfToken()
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
// GET-запрос
|
// GET-запрос
|
||||||
|
|
||||||
|
if (empty($return['main']) && $keep_connect && $timer > 0) {
|
||||||
|
// Режим непрерывного соединения
|
||||||
|
|
||||||
|
// Ожидание
|
||||||
|
sleep($timer);
|
||||||
|
|
||||||
|
goto keep_connect_wait;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->render('/search/index', compact('response', 'timer'));
|
return $this->render('/search/index', compact('response', 'timer'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Yii::$app->user->isGuest) {
|
if (yii::$app->user->isGuest) {
|
||||||
return $this->render('/search/index', ['error_auth' => true]);
|
return $this->render('/search/index', ['error_auth' => true]);
|
||||||
} else {
|
} else {
|
||||||
return $this->render('/search/index');
|
return $this->render('/search/index');
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m201219_074926_create_account_collection extends Migration
|
class m201219_074926_create_account_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210101_092505_create_product_collection extends Migration
|
class m210101_092505_create_product_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210107_163448_create_supply_collection extends Migration
|
class m210107_163448_create_supply_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210108_014505_create_account_edge_supply_collection extends Migration
|
class m210108_014505_create_account_edge_supply_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210108_212826_create_product_group_collection extends Migration
|
class m210108_212826_create_product_group_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210108_221446_create_product_edge_product_group_collection extends Migration
|
class m210108_221446_create_product_edge_product_group_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210108_222132_create_supply_edge_product_collection extends Migration
|
class m210108_222132_create_supply_edge_product_collection extends Migration
|
||||||
{
|
{
|
||||||
public function up()
|
public function up()
|
||||||
{
|
{
|
||||||
$this->createCollection('supply_edge_product', ['Type' => 3]);
|
$this->createCollection('supply_edge_product', ['Type' => 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
$this->dropCollection('supply_edge_product');
|
$this->dropCollection('supply_edge_product');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210108_222740_create_product_edge_product_collection extends Migration
|
class m210108_222740_create_product_edge_product_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210109_214817_create_supply_group_collection extends Migration
|
class m210109_214817_create_supply_group_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210109_214833_create_supply_edge_supply_group_collection extends Migration
|
class m210109_214833_create_supply_edge_supply_group_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210111_044635_create_supply_edge_supply_collection extends Migration
|
class m210111_044635_create_supply_edge_supply_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210112_010347_create_product_group_edge_product_group_collection extends Migration
|
class m210112_010347_create_product_group_edge_product_group_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210112_010411_create_supply_group_edge_supply_group_collection extends Migration
|
class m210112_010411_create_supply_group_edge_supply_group_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210112_034135_create_requisite_collection extends Migration
|
class m210112_034135_create_requisite_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210112_034232_create_supply_edge_requisite_collection extends Migration
|
class m210112_034232_create_supply_edge_requisite_collection extends Migration
|
||||||
{
|
{
|
||||||
public function up()
|
public function up()
|
||||||
{
|
{
|
||||||
$this->createCollection('supply_edge_requisite', ['Type' => 3]);
|
$this->createCollection('supply_edge_requisite', ['Type' => 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down()
|
public function down()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210113_021800_create_purchase_collection extends Migration
|
class m210113_021800_create_purchase_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210113_021905_create_account_edge_purchase_collection extends Migration
|
class m210113_021905_create_account_edge_purchase_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use explosivebit\arangodb\Migration;
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
class m210113_021917_create_purchase_edge_supply_collection extends Migration
|
class m210113_021917_create_purchase_edge_supply_collection extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
|
class m210206_154140_create_search_collection extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->createCollection('search', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->dropCollection('search');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
|
class m210206_154210_create_account_edge_search_collection extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->createCollection('account_edge_search', ['Type' => 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->dropCollection('account_edge_search');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
|
class m210209_185314_create_notification_collection extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->createCollection('notification', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->dropCollection('notification');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
|
class m210209_185328_create_account_edge_notification_collection extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->createCollection('account_edge_notification', ['type' => 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->dropCollection('account_edge_notification');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
|
class m210223_121142_create_settings_collection extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->createCollection('settings', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->dropCollection('settings');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use mirzaev\yii2\arangodb\Migration;
|
||||||
|
|
||||||
|
class m210223_145042_create_settings_edge_settings_collection extends Migration
|
||||||
|
{
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
$this->createCollection('settings_edge_settings', ['type' => 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
$this->dropCollection('settings_edge_settings');
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,8 +16,6 @@ use carono\exchange1c\interfaces\PartnerInterface;
|
||||||
*/
|
*/
|
||||||
class Account extends Document implements IdentityInterface, PartnerInterface
|
class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
{
|
{
|
||||||
public $opts;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Имя коллекции
|
* Имя коллекции
|
||||||
*/
|
*/
|
||||||
|
@ -43,7 +41,8 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
'comp',
|
'comp',
|
||||||
'taxn',
|
'taxn',
|
||||||
'onec',
|
'onec',
|
||||||
'opts'
|
'opts',
|
||||||
|
'trst'
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +64,8 @@ class Account extends Document implements IdentityInterface, PartnerInterface
|
||||||
'comp' => 'Компания',
|
'comp' => 'Компания',
|
||||||
'taxn' => 'ИНН',
|
'taxn' => 'ИНН',
|
||||||
'onec' => 'Данные 1C',
|
'onec' => 'Данные 1C',
|
||||||
'opts' => 'Параметры'
|
'opts' => 'Параметры',
|
||||||
|
'trst' => 'Доверенный пользователь'
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
class AccountEdgeNotification extends Edge
|
||||||
|
{
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return 'account_edge_notification';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
class AccountEdgeSearch extends Edge
|
||||||
|
{
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return 'account_edge_search';
|
||||||
|
}
|
||||||
|
}
|
|
@ -135,38 +135,4 @@ class AccountForm extends Model
|
||||||
|
|
||||||
return $this->account;
|
return $this->account;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authenticationGenHtml(string $dropdown): string
|
|
||||||
{
|
|
||||||
return <<<HTML
|
|
||||||
<a class="text-dark my-auto mr-2" href="/cart"><i class="fas fa-shopping-cart mx-2"></i></a>
|
|
||||||
<a class="text-dark my-auto mr-2" href="/orders"><i class="fas fa-list mx-2"></i></a>
|
|
||||||
<div class="btn-group">
|
|
||||||
<a class="btn m-0 px-0 text-dark button_clean" title="Личный кабинет" href="/profile" role="button" onclick="return page_profile();">Личный кабинет</a>
|
|
||||||
<button id="profile_button" class="btn pr-0 dropdown-toggle dropdown-toggle-split button_clean" type="button" data-toggle="dropdown" onmouseover="$('#profile_button').dropdown('show')"></button>
|
|
||||||
<div class="dropdown-menu dropdown-menu-long dropdown-menu-right p-3" aria-labelledby="profile_button" onmouseout="$('#profile_button').dropdown('show')">
|
|
||||||
<h5 class="mb-3 text-center">Аутентификация</h5>
|
|
||||||
$dropdown
|
|
||||||
<!-- <a class="dropdown-item-text text-center px-0 py-2" href="#"><small>Восстановление пароля</small></a> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
HTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deauthenticationGenHtml(): string
|
|
||||||
{
|
|
||||||
$mail = Yii::$app->user->identity->mail;
|
|
||||||
|
|
||||||
return <<<HTML
|
|
||||||
<a class="text-dark my-auto mr-2" href="/cart"><i class="fas fa-shopping-cart mx-2"></i></a>
|
|
||||||
<a class="text-dark my-auto mr-2" href="/orders"><i class="fas fa-list mx-2"></i></a>
|
|
||||||
<div class="btn-group">
|
|
||||||
<a class="btn m-0 px-0 text-dark button_clean" title="Личный кабинет" href="/profile" role="button" onclick="return page_profile();">Личный кабинет</a>
|
|
||||||
<button id="profile_button" class="btn pr-0 dropdown-toggle dropdown-toggle-split button_clean" type="button" data-toggle="dropdown" onmouseover="$('#profile_button').dropdown('show')"></button>
|
|
||||||
<div class="dropdown-menu dropdown-menu-right py-1" aria-labelledby="profile_button" onmouseout="$('#profile_button').dropdown('show')">
|
|
||||||
<a class="dropdown-item button_white text-dark" onclick="deauthentication()">Выход ($mail)</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
HTML;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\models;
|
namespace app\models;
|
||||||
|
|
||||||
use Yii;
|
use yii;
|
||||||
|
|
||||||
use mirzaev\yii2\arangodb\ActiveRecord;
|
use mirzaev\yii2\arangodb\ActiveRecord;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ abstract class Document extends ActiveRecord
|
||||||
return [
|
return [
|
||||||
'_key',
|
'_key',
|
||||||
'date',
|
'date',
|
||||||
'writer'
|
'wrtr'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,9 @@ abstract class Document extends ActiveRecord
|
||||||
public function attributeLabels(): array
|
public function attributeLabels(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
'_key' => 'Ключ',
|
||||||
'date' => 'Дата',
|
'date' => 'Дата',
|
||||||
'writer' => 'Аккаунт записавшего'
|
'wrtr' => 'Аккаунт записавшего'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,33 +57,22 @@ abstract class Document extends ActiveRecord
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
'writer',
|
'wrtr',
|
||||||
'string'
|
'string'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'wrtr',
|
||||||
|
'default',
|
||||||
|
'value' => yii::$app->user->id
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'date',
|
||||||
|
'default',
|
||||||
|
'value' => time()
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Перед сохранением
|
|
||||||
*
|
|
||||||
* @todo Подождать обновление от ебаного Yii2 и добавить
|
|
||||||
* проверку типов передаваемых параметров
|
|
||||||
*/
|
|
||||||
public function beforeSave($data): bool
|
|
||||||
{
|
|
||||||
if (parent::beforeSave($data)) {
|
|
||||||
if ($this->isNewRecord) {
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->date = time();
|
|
||||||
$this->writer = $this->writer ?? Yii::$app->user->id;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Чтение идентификатора
|
* Чтение идентификатора
|
||||||
*/
|
*/
|
||||||
|
@ -99,6 +89,19 @@ abstract class Document extends ActiveRecord
|
||||||
return static::findOne(['_id' => $_id]);
|
return static::findOne(['_id' => $_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function readLast(): ?static
|
||||||
|
{
|
||||||
|
return static::find()->orderBy(['DESC'])->one();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Чтение всех записей
|
||||||
|
*/
|
||||||
|
public static function readAll(): array
|
||||||
|
{
|
||||||
|
return static::find()->all();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Чтение количества записей
|
* Чтение количества записей
|
||||||
*/
|
*/
|
||||||
|
@ -106,4 +109,16 @@ abstract class Document extends ActiveRecord
|
||||||
{
|
{
|
||||||
return static::find()->count();
|
return static::find()->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Проверка на то, что в свойство передан массив
|
||||||
|
*/
|
||||||
|
protected function arrayValidator(string $attribute, array $params): bool
|
||||||
|
{
|
||||||
|
if (is_array($this->$attribute)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,38 +60,6 @@ abstract class Edge extends Document
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Записать
|
|
||||||
*/
|
|
||||||
public static function write(string $_from, string $_to, string $type = '', array $data = []): ?static
|
|
||||||
{
|
|
||||||
// Инициализация
|
|
||||||
$edge = new static;
|
|
||||||
|
|
||||||
// Настройка
|
|
||||||
$edge->_from = $_from;
|
|
||||||
$edge->_to = $_to;
|
|
||||||
$edge->type = $type;
|
|
||||||
|
|
||||||
foreach ($data as $key => $value) {
|
|
||||||
if(is_int($key)) {
|
|
||||||
// Если ключ задан автоматически
|
|
||||||
|
|
||||||
$edge->{$value} = true;
|
|
||||||
} else {
|
|
||||||
// Иначе ключ записан вручную
|
|
||||||
|
|
||||||
$edge->{$key} = $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Запись
|
|
||||||
$edge->save();
|
|
||||||
|
|
||||||
return $edge;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Перед сохранением
|
* Перед сохранением
|
||||||
*
|
*
|
||||||
|
@ -111,4 +79,63 @@ abstract class Edge extends Document
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Записать (с проверкой на существование)
|
||||||
|
*
|
||||||
|
* Создаст ребро только в том случае, если его аналога не существует
|
||||||
|
*/
|
||||||
|
public static function writeSafe(string $_from, string $_to, string $type = '', array $data = []): ?static
|
||||||
|
{
|
||||||
|
if ($edge = self::searchByVertex($_from, $_to, 1)) {
|
||||||
|
// Найдено в базе данных
|
||||||
|
|
||||||
|
return $edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::write($_from, $_to, $type, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Записать
|
||||||
|
*/
|
||||||
|
public static function write(string $_from, string $_to, string $type = '', array $data = []): ?static
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
$edge = new static;
|
||||||
|
|
||||||
|
// Настройка
|
||||||
|
$edge->_from = $_from;
|
||||||
|
$edge->_to = $_to;
|
||||||
|
$edge->type = $type;
|
||||||
|
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
if (is_int($key)) {
|
||||||
|
// Обычная запись
|
||||||
|
|
||||||
|
$edge->{$value} = true;
|
||||||
|
} else {
|
||||||
|
// Ассоциативная запись
|
||||||
|
|
||||||
|
$edge->{$key} = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запись
|
||||||
|
return $edge->save() ? $edge : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поиск ребра по его вершинам
|
||||||
|
*/
|
||||||
|
public static function searchByVertex(string $_from, string $_to, int $limit = 1): static|array|null
|
||||||
|
{
|
||||||
|
$query = self::find()->where(['_from' => $_from, '_to' => $_to]);
|
||||||
|
|
||||||
|
if ($limit <= 1) {
|
||||||
|
return $query->one();
|
||||||
|
} else {
|
||||||
|
return $query->limit($limit)->all();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
use yii;
|
||||||
|
use yii\web\IdentityInterface;
|
||||||
|
|
||||||
|
use app\models\traits\SearchByAccount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поиск
|
||||||
|
*
|
||||||
|
* @see Product Поиск по товарам
|
||||||
|
*/
|
||||||
|
class Notification extends Document
|
||||||
|
{
|
||||||
|
use SearchByAccount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Сценарий для доверенного пользователя с созданием уведомления
|
||||||
|
*/
|
||||||
|
const SCENARIO_TRUSTED_CREATE = 'create';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Цель для отправки уведомления
|
||||||
|
*
|
||||||
|
* Расшифровывается как $target
|
||||||
|
*
|
||||||
|
* @see SCENARIO_TRUSTED_CREATE
|
||||||
|
*/
|
||||||
|
public IdentityInterface|string|array|null $trgt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Текст уведомления
|
||||||
|
*/
|
||||||
|
public string $text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Типы уведомлений
|
||||||
|
*/
|
||||||
|
public array $typs = [
|
||||||
|
'notice' => 'Уведомление',
|
||||||
|
'warning' => 'Предупреждение'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return 'notification';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::attributes(),
|
||||||
|
[
|
||||||
|
'html',
|
||||||
|
'type'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метки свойств
|
||||||
|
*/
|
||||||
|
public function attributeLabels(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::attributeLabels(),
|
||||||
|
[
|
||||||
|
'html' => 'HTML',
|
||||||
|
'type' => 'Тип',
|
||||||
|
'trgt' => 'Получатели',
|
||||||
|
'text' => 'Текст',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Правила
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::rules(),
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'html',
|
||||||
|
'required'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'type',
|
||||||
|
'default',
|
||||||
|
'value' => 'notice'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запись
|
||||||
|
*
|
||||||
|
* @param string $html HTML уведомления
|
||||||
|
* @param IdentityInterface $trgt Получатель уведомления
|
||||||
|
* @param string $type Тип уведомления
|
||||||
|
*
|
||||||
|
* @todo Создать параметр разделителя для администрации
|
||||||
|
*/
|
||||||
|
public function write(string $html = null, IdentityInterface|array|string $trgt = null, string $type = 'notice'): self|array|null
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
isset($this->html) ? $html = $this->html : null;
|
||||||
|
isset($this->trgt) ? $trgt = $this->trgt : null;
|
||||||
|
isset($this->type) ? $type = $this->type : null;
|
||||||
|
|
||||||
|
// Инициализация уведомления
|
||||||
|
if (isset($html) && (bool) (int) $html) {
|
||||||
|
// Получен текст в формете HTML-кода
|
||||||
|
|
||||||
|
$this->html = $this->text ?? null;
|
||||||
|
} else {
|
||||||
|
// Получен необработанный текст
|
||||||
|
|
||||||
|
$text = htmlspecialchars(strip_tags($this->text ?? null));
|
||||||
|
|
||||||
|
$this->html = <<<HTML
|
||||||
|
<p class="my-2 mx-3">$text</p>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->save()) {
|
||||||
|
// Уведомление записано
|
||||||
|
|
||||||
|
// Инициализация получателей и создание ребра
|
||||||
|
if (empty($trgt)) {
|
||||||
|
// Получатель не передан
|
||||||
|
|
||||||
|
goto test;
|
||||||
|
} else if (is_string($trgt)) {
|
||||||
|
// Передана необработанная строка
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$delimiter = ',';
|
||||||
|
|
||||||
|
// Конвертация
|
||||||
|
$trgt = array_map('trim', explode($delimiter, $trgt));
|
||||||
|
|
||||||
|
|
||||||
|
if (in_array('@all', $trgt, true)) {
|
||||||
|
// Найден флаг обозначающий отправку всем пользователям
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$return = [];
|
||||||
|
|
||||||
|
foreach (Account::readAll() as $target) {
|
||||||
|
// Перебор всех аккаунтов
|
||||||
|
|
||||||
|
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
|
||||||
|
$return[] = AccountEdgeNotification::writeSafe($this->readId(), $target->readId(), $type) ? $this : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return ? $return : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('@test', $trgt, true)) {
|
||||||
|
// Найден флаг обозначающий тестирование (отправка самому себе)
|
||||||
|
|
||||||
|
test:
|
||||||
|
return AccountEdgeNotification::writeSafe($this->readId(), yii::$app->user->id, $type) ? $this : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($trgt)) {
|
||||||
|
// Несколько получателей
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$return = [];
|
||||||
|
|
||||||
|
foreach ($trgt as $target) {
|
||||||
|
// Перебор получателей
|
||||||
|
|
||||||
|
if ($target instanceof Account) {
|
||||||
|
// Один получатель
|
||||||
|
|
||||||
|
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
|
||||||
|
return AccountEdgeNotification::writeSafe($this->readId(), $target->readId(), $type) ? $this : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "or" имеет приоритет ниже чем у "||" относительно "="
|
||||||
|
//
|
||||||
|
// if ($target = $buffer = Account::searchById($target) or
|
||||||
|
// $target = Account::searchById(Account::collectionName() . '/' . $buffer)
|
||||||
|
// ) {
|
||||||
|
//
|
||||||
|
// if (($target = Account::searchById($target)) ||
|
||||||
|
// ($target = Account::searchById(Account::collectionName() . '/' . $target))
|
||||||
|
// ) {
|
||||||
|
if ($target = Account::searchById(Account::collectionName() . '/' . $target)) {
|
||||||
|
// Аккаунт найден
|
||||||
|
|
||||||
|
echo ($target->readId()) . "\n";
|
||||||
|
|
||||||
|
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
|
||||||
|
$return[] = AccountEdgeNotification::writeSafe($this->readId(), $target->readId(), $type) ? $this : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return ? $return : null;
|
||||||
|
} else if ($trgt instanceof Account) {
|
||||||
|
// Один получатель
|
||||||
|
|
||||||
|
// Запись ребра: УВЕДОМЛЕНИЕ -> АККАУНТ
|
||||||
|
return AccountEdgeNotification::writeSafe($this->readId(), $trgt->readId(), $type) ? $this : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,6 +54,7 @@ class Product extends Document
|
||||||
'name',
|
'name',
|
||||||
'ocid',
|
'ocid',
|
||||||
'catn',
|
'catn',
|
||||||
|
'imgs',
|
||||||
'oemn'
|
'oemn'
|
||||||
// 'data',
|
// 'data',
|
||||||
// 'cost',
|
// 'cost',
|
||||||
|
@ -73,6 +74,7 @@ class Product extends Document
|
||||||
'name' => 'Название (name)',
|
'name' => 'Название (name)',
|
||||||
'ocid' => 'Идентификатор 1C (ocid)',
|
'ocid' => 'Идентификатор 1C (ocid)',
|
||||||
'catn' => 'Каталожный номер (catn)',
|
'catn' => 'Каталожный номер (catn)',
|
||||||
|
'imgs' => 'Изображения (imgs)',
|
||||||
'oemn' => 'OEM номера (oemn)',
|
'oemn' => 'OEM номера (oemn)',
|
||||||
// 'data' => 'Данные товара (data)',
|
// 'data' => 'Данные товара (data)',
|
||||||
// 'cost' => 'Цены (cost)',
|
// 'cost' => 'Цены (cost)',
|
||||||
|
@ -92,7 +94,10 @@ class Product extends Document
|
||||||
parent::rules(),
|
parent::rules(),
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
['name', 'catn'],
|
[
|
||||||
|
'name',
|
||||||
|
'catn'
|
||||||
|
],
|
||||||
'required',
|
'required',
|
||||||
'message' => 'Заполните поля: {attribute}',
|
'message' => 'Заполните поля: {attribute}',
|
||||||
'on' => self::SCENARIO_WRITE,
|
'on' => self::SCENARIO_WRITE,
|
||||||
|
@ -104,8 +109,19 @@ class Product extends Document
|
||||||
'message' => 'Заполните поля: {attribute}',
|
'message' => 'Заполните поля: {attribute}',
|
||||||
'on' => self::SCENARIO_IMPORT
|
'on' => self::SCENARIO_IMPORT
|
||||||
],
|
],
|
||||||
['catn', 'string', 'message' => '{attribute} должен быть строкой'],
|
[
|
||||||
// ['oemn', 'integer'], Нужна своя проверка на массив
|
'catn',
|
||||||
|
'string',
|
||||||
|
'message' => '{attribute} должен быть строкой'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'oemn',
|
||||||
|
'imgs'
|
||||||
|
],
|
||||||
|
'arrayValidator',
|
||||||
|
'message' => '{attribute} должен быть массивом.'
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'file',
|
'file',
|
||||||
'file',
|
'file',
|
||||||
|
@ -122,6 +138,86 @@ class Product extends Document
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запись
|
||||||
|
*
|
||||||
|
* @param string $catn Артикул, каталожный номер
|
||||||
|
*/
|
||||||
|
public static function initEmpty(string $catn): self|array
|
||||||
|
{
|
||||||
|
$oemn = self::convertOemn2Catn($catn);
|
||||||
|
|
||||||
|
if (count($oemn) === 1) {
|
||||||
|
// Передан только один артикул
|
||||||
|
|
||||||
|
if ($model = self::searchByCatn($catn)) {
|
||||||
|
// Продукт уже существует
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запись
|
||||||
|
return self::writeEmpty($catn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$models = [];
|
||||||
|
|
||||||
|
foreach ($oemn as $catn) {
|
||||||
|
// Перебор всех найденных артикулов
|
||||||
|
|
||||||
|
if ($model = self::searchByCatn($catn)) {
|
||||||
|
// Продукт уже существует
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запись
|
||||||
|
if ($model = self::writeEmpty($catn)) {
|
||||||
|
// Записано
|
||||||
|
|
||||||
|
// Запись в массив сохранённых моделей
|
||||||
|
$models[] = $model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $models;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запись
|
||||||
|
*/
|
||||||
|
public static function writeEmpty(string $catn): ?self
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
$model = new self;
|
||||||
|
|
||||||
|
// Настройки
|
||||||
|
$model->catn = $catn;
|
||||||
|
|
||||||
|
// Запись
|
||||||
|
return $model->save() ? $model : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поиск OEM номеров
|
||||||
|
*
|
||||||
|
* @param string $oemn OEM номера
|
||||||
|
* @param string $delimiters Разделители
|
||||||
|
*
|
||||||
|
* @todo НЕ ЗАБЫТЬ СДЕЛАТЬ НАСТРОЙКУ РАЗДЕЛИТЕЛЕЙ
|
||||||
|
*/
|
||||||
|
public static function convertOemn2Catn(string $oemn, string $delimiters = '\s\+\/,'): array
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
$catn = [];
|
||||||
|
|
||||||
|
// Конвертация
|
||||||
|
preg_match_all("/[^$delimiters]+/", $oemn, $catn);
|
||||||
|
|
||||||
|
return $catn[0];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Импорт товаров
|
* Импорт товаров
|
||||||
*
|
*
|
||||||
|
@ -182,13 +278,33 @@ class Product extends Document
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поиск по каталожному номеру
|
* Поиск по каталожному номеру
|
||||||
|
*
|
||||||
|
* Ищет продукт и возвращает его,
|
||||||
|
* либо выполняет поиск через представление
|
||||||
|
*
|
||||||
|
* @todo Переделать нормально
|
||||||
*/
|
*/
|
||||||
public static function searchByCatn(string $query, int $limit = 1): Product|array|null
|
public static function searchByCatn(string $catn, int $limit = 1, array $select = ['catn' => 'catn']): static|array|null
|
||||||
{
|
{
|
||||||
if ($limit <= 1) {
|
if ($limit <= 1) {
|
||||||
return static::findOne(['catn' => $query]);
|
return static::findOne(['catn' => $catn]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::find()->limit($limit)->view('product_search', ['id' => '_key', 'catn' => 'catn'], ['catn' => $query], 'START');
|
$query = self::find()
|
||||||
|
->collection('product_search')
|
||||||
|
->search(['catn' => $catn])
|
||||||
|
->limit($limit)
|
||||||
|
->select($select)
|
||||||
|
->createCommand()
|
||||||
|
->execute()
|
||||||
|
->getAll();
|
||||||
|
|
||||||
|
foreach ($query as &$attribute) {
|
||||||
|
// Приведение всех свойств в массив и очистка от лишних данных
|
||||||
|
|
||||||
|
$attribute = $attribute->getAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,11 +154,6 @@ class ProductGroup extends Document implements GroupInterface
|
||||||
return $edge->save();
|
return $edge->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function readAll()
|
|
||||||
{
|
|
||||||
return static::find()->all();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function readByName(string $name)
|
public static function readByName(string $name)
|
||||||
{
|
{
|
||||||
return static::findOne(['name' => $name]);
|
return static::findOne(['name' => $name]);
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
use yii;
|
||||||
|
use yii\web\IdentityInterface;
|
||||||
|
|
||||||
|
use app\models\traits\SearchByAccount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Поиск
|
||||||
|
*
|
||||||
|
* @see Product Поиск по товарам
|
||||||
|
*/
|
||||||
|
class Search extends Document
|
||||||
|
{
|
||||||
|
use SearchByAccount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return 'search';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::attributes(),
|
||||||
|
[
|
||||||
|
'text',
|
||||||
|
'ipv4',
|
||||||
|
'head'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метки свойств
|
||||||
|
*/
|
||||||
|
public function attributeLabels(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::attributeLabels(),
|
||||||
|
[
|
||||||
|
'text' => 'Текст',
|
||||||
|
'ipv4' => 'IPv4',
|
||||||
|
'head' => 'Заголовки'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Правила
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::rules(),
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'text',
|
||||||
|
'required'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'ipv4',
|
||||||
|
'default',
|
||||||
|
'value' => yii::$app->request->userIP
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'head',
|
||||||
|
'default',
|
||||||
|
'value' => yii::$app->request->getHeaders()
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запись
|
||||||
|
*
|
||||||
|
* @param string $text Текст запроса
|
||||||
|
* @param IdentityInterface|null $user Пользователь совершивший запрос
|
||||||
|
*/
|
||||||
|
public static function write(string $text, IdentityInterface $user = null): ?self
|
||||||
|
{
|
||||||
|
// Инициализация
|
||||||
|
$vertex = new self;
|
||||||
|
isset($user) && yii::$app->user->isGuest ?: $user = yii::$app->user->identity;
|
||||||
|
|
||||||
|
// Настройки
|
||||||
|
$vertex->text = $text;
|
||||||
|
|
||||||
|
if ($vertex->save()) {
|
||||||
|
// Поиск записан
|
||||||
|
|
||||||
|
// Запись ребра: АККАУНТ -> ПОИСК
|
||||||
|
return $user && AccountEdgeSearch::writeSafe($user->id, $vertex->readId(), 'request') ? $vertex : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Настройки
|
||||||
|
*/
|
||||||
|
class Settings extends Document
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Имя коллекции
|
||||||
|
*/
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return 'settings';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Свойства
|
||||||
|
*/
|
||||||
|
public function attributes(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::attributes(),
|
||||||
|
[
|
||||||
|
'search_period',
|
||||||
|
'search_connect_keep'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Метки свойств
|
||||||
|
*/
|
||||||
|
public function attributeLabels(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::attributeLabels(),
|
||||||
|
[
|
||||||
|
'search_period' => 'Поисковый период',
|
||||||
|
'search_connect_keep' => 'Режим удержания'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Правила
|
||||||
|
*/
|
||||||
|
public function rules(): array
|
||||||
|
{
|
||||||
|
return array_merge(
|
||||||
|
parent::rules(),
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'search_period'
|
||||||
|
],
|
||||||
|
'integer',
|
||||||
|
'message' => '{attribute} должен хранить цифровое значение'
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'search_connect_keep'
|
||||||
|
],
|
||||||
|
'string',
|
||||||
|
'message' => '{attribute} должен хранить строковый тип'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
class SettingsEdgeSettings extends Edge
|
||||||
|
{
|
||||||
|
public static function collectionName(): string
|
||||||
|
{
|
||||||
|
return 'settings_edge_settings';
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,8 @@ use app\models\traits\Xml2Array;
|
||||||
|
|
||||||
use carono\exchange1c\interfaces\ProductInterface;
|
use carono\exchange1c\interfaces\ProductInterface;
|
||||||
|
|
||||||
|
use exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Поставка (выгрузка товаров от поставщиков)
|
* Поставка (выгрузка товаров от поставщиков)
|
||||||
*
|
*
|
||||||
|
@ -66,8 +68,15 @@ class Supply extends Product implements ProductInterface
|
||||||
*/
|
*/
|
||||||
public function afterSave($data, $vars): void
|
public function afterSave($data, $vars): void
|
||||||
{
|
{
|
||||||
// Запись ребра: АККАУНТ -> ПОСТАВКА
|
if (AccountEdgeSupply::searchByVertex(Yii::$app->user->id, $this->readId())) {
|
||||||
(new AccountEdgeSupply)->write(Yii::$app->user->id, $this->readId(), 'import');
|
// Ребро уже существует
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Ребра не существует
|
||||||
|
|
||||||
|
// Запись ребра: АККАУНТ -> ПОСТАВКА
|
||||||
|
(new AccountEdgeSupply)->write(Yii::$app->user->id, $this->readId(), 'import');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,31 +106,25 @@ class Supply extends Product implements ProductInterface
|
||||||
*
|
*
|
||||||
* Ищет записанные свойства из 1C по их идентификатору и добавляет к ним
|
* Ищет записанные свойства из 1C по их идентификатору и добавляет к ним
|
||||||
* недостающие данные. Это костыль оставшийся от реляционных баз данных
|
* недостающие данные. Это костыль оставшийся от реляционных баз данных
|
||||||
|
*
|
||||||
|
* @todo Понять что может храниться внутри "$model->onec['ЗначенияСвойств']['ЗначенияСвойства']" и переписать
|
||||||
*/
|
*/
|
||||||
public static function createProperties1c($properties): void
|
public static function createProperties1c($properties): void
|
||||||
{
|
{
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$models = static::searchOnecByAccountId(Yii::$app->user->id, true);
|
$models = self::searchByAccount(Yii::$app->user->id, true);
|
||||||
$properties = self::xml2array($properties->xml);
|
$properties = self::xml2array($properties->xml);
|
||||||
|
|
||||||
$fp = fopen('1.txt', 'a');
|
|
||||||
fwrite($fp, print_r(count($models), true) . PHP_EOL);
|
|
||||||
fclose($fp);
|
|
||||||
|
|
||||||
// for ($i = 0; $i <= count($models); $i++)
|
// for ($i = 0; $i <= count($models); $i++)
|
||||||
foreach ($models as $model) {
|
foreach ($models as $model) {
|
||||||
// Перебор записей
|
// Перебор записей
|
||||||
|
|
||||||
$fp = fopen('2.txt', 'a');
|
|
||||||
fwrite($fp, $model->ocid . PHP_EOL);
|
|
||||||
fclose($fp);
|
|
||||||
|
|
||||||
// Инициализация
|
// Инициализация
|
||||||
$changes = false;
|
$changes = false;
|
||||||
$transit = $model->onec;
|
$transit = $model->onec;
|
||||||
|
|
||||||
foreach ($model->onec['ЗначенияСвойств'] as $attribute_name => $attribute_value) {
|
foreach ($model->onec['ЗначенияСвойств'] as $attribute_name => $attribute_value) {
|
||||||
// Перебор аттрибутов
|
// Перебор аттрибутовfw
|
||||||
|
|
||||||
foreach ($properties as $property) {
|
foreach ($properties as $property) {
|
||||||
// Перебор свойств
|
// Перебор свойств
|
||||||
|
@ -149,6 +152,19 @@ class Supply extends Product implements ProductInterface
|
||||||
// Настройка ($transit нужен из-за ограничений __set())
|
// Настройка ($transit нужен из-за ограничений __set())
|
||||||
$model->onec = $transit;
|
$model->onec = $transit;
|
||||||
|
|
||||||
|
foreach ($model->onec['ЗначенияСвойств'] as $property) {
|
||||||
|
// Перебор всех свойств
|
||||||
|
|
||||||
|
if (is_array($property)) {
|
||||||
|
if ($property['Ид'] === 'd99622fe-4526-11eb-b7f3-f3e52d0a06a9') {
|
||||||
|
// Если идентификатор свойства совпадает с указанным в настройках свойства хранящего OEM номера
|
||||||
|
|
||||||
|
// Настройка
|
||||||
|
$model->catn = $property['Значение'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Запись
|
// Запись
|
||||||
$model->save();
|
$model->save();
|
||||||
}
|
}
|
||||||
|
@ -165,14 +181,61 @@ class Supply extends Product implements ProductInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Запись изображений из 1С
|
* Запись изображений из 1С
|
||||||
|
*
|
||||||
|
* @todo Добавить параметры в админ-панель
|
||||||
|
* Запретить доступ к изображениям
|
||||||
*/
|
*/
|
||||||
public function addImage1c($path, $caption): mixed
|
public function addImage1c($path, $caption): bool
|
||||||
{
|
{
|
||||||
return true;
|
// Инициализация
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
if (!file_exists(YII_PATH_PUBLIC . $catalog = '/img/supplies/' . $this->_key)) {
|
||||||
|
// Директория для изображений продукта не найдена
|
||||||
|
|
||||||
|
if (!mkdir(YII_PATH_PUBLIC . $catalog, 0775, true)) {
|
||||||
|
// не удалось записать директорию
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->imgs ?? [] as $image) {
|
||||||
|
// Перебор имеющихся изображений
|
||||||
|
|
||||||
|
if ($path === $image['sorc']) {
|
||||||
|
// Изображение уже записано на сервер
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$urn = basename($path);
|
||||||
|
|
||||||
|
// Запись
|
||||||
|
copy($path, $path_local = YII_PATH_PUBLIC . $catalog . '/' . $urn);
|
||||||
|
|
||||||
|
// Запись свойства
|
||||||
|
$this->imgs = array_merge(
|
||||||
|
$this->imgs ?? [],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'desc' => $caption,
|
||||||
|
'path' => $path_local,
|
||||||
|
'sorc' => $path
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Отправка в базу данных
|
||||||
|
return $this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Запись ребра (предложения от поставок к продуктам) из 1С
|
* Запись ребра (предложения от поставок к продуктам) из 1С
|
||||||
|
*
|
||||||
|
* @todo Разобраться зачем нужно возвращать SupplyEdgeProduct
|
||||||
*/
|
*/
|
||||||
public function getOffer1c($offer): SupplyEdgeProduct
|
public function getOffer1c($offer): SupplyEdgeProduct
|
||||||
{
|
{
|
||||||
|
@ -181,32 +244,64 @@ class Supply extends Product implements ProductInterface
|
||||||
|
|
||||||
// Разработчику библеотеки надо дать по жопе
|
// Разработчику библеотеки надо дать по жопе
|
||||||
return new SupplyEdgeProduct;
|
return new SupplyEdgeProduct;
|
||||||
} else if (!$product = Product::searchByCatn($this->catn)) {
|
}
|
||||||
// Продукт не найден
|
|
||||||
|
|
||||||
if (!$this->initProduct()) {
|
// Инициализация п̸̨͇͑͋͠р̷̬̂́̀̊о̸̜̯̹̅͒͘͝д̴̨̨̨̟̈́̆у̴̨̭̮̠́͋̈́к̴̭͊̋̎т̵̛̣͈̔̐͆а̵̨͖͑
|
||||||
// Не удалось инициализировать продукт
|
$product = Product::initEmpty($this->catn);
|
||||||
|
|
||||||
// Разработчику библеотеки надо дать по жопе
|
if (!is_array($product)) {
|
||||||
return new SupplyEdgeProduct;
|
// Создался только один товар и вернулся в виде модели
|
||||||
|
|
||||||
|
$product = [$product];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($this->oemn)) {
|
||||||
|
// Значение OEM было инициализировано
|
||||||
|
|
||||||
|
foreach ($this->oemn as $oem) {
|
||||||
|
// Перебор артикулов из массива ОЕМ-номеров
|
||||||
|
|
||||||
|
// Инициализация и запись
|
||||||
|
$product[] = Product::initEmpty($oem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$product = Product::searchByCatn($this->catn);
|
|
||||||
|
|
||||||
// Запись ребра: ПОСТАВКА -> ПРОДУКТ
|
|
||||||
return (new SupplyEdgeProduct)->write(
|
// $fp = fopen('555.txt', 'a');
|
||||||
$this->readId(),
|
// fwrite($fp, print_r($property, true) . PHP_EOL);
|
||||||
$product->readId(),
|
// fclose($fp);
|
||||||
'sell',
|
|
||||||
[
|
|
||||||
'onec' => self::xml2array($offer->xml)
|
foreach ($product as $product) {
|
||||||
]
|
// Перебор всех инициализированных продуктов
|
||||||
);
|
|
||||||
|
if (SupplyEdgeProduct::searchByVertex($this->readId(), $product->readId())) {
|
||||||
|
// Ребро уже существует
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Запись ребра: ПОСТАВКА -> ПРОДУКТ
|
||||||
|
$return = (new SupplyEdgeProduct)->write(
|
||||||
|
$this->readId(),
|
||||||
|
$product->readId(),
|
||||||
|
'sell',
|
||||||
|
[
|
||||||
|
'onec' => self::xml2array($offer->xml)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Возвращает последнее сохранённое ребро
|
||||||
|
// Надо будет с этим разобраться
|
||||||
|
return $return ?? new SupplyEdgeProduct();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Запись продукта из 1С
|
* Запись продукта из 1С
|
||||||
|
*
|
||||||
|
* @todo Понять что может храниться внутри "$model->onec['ЗначенияСвойств']['ЗначенияСвойства']" и переписать
|
||||||
*/
|
*/
|
||||||
public static function createModel1c($product): ?self
|
public static function createModel1c($product): ?self
|
||||||
{
|
{
|
||||||
|
@ -216,38 +311,33 @@ class Supply extends Product implements ProductInterface
|
||||||
// Настройка
|
// Настройка
|
||||||
$model->ocid = $id ?? null;
|
$model->ocid = $id ?? null;
|
||||||
$model->catn = (string) $product->Артикул;
|
$model->catn = (string) $product->Артикул;
|
||||||
$model->oemn = null;
|
|
||||||
$model->onec = self::xml2array($product->xml);
|
$model->onec = self::xml2array($product->xml);
|
||||||
|
|
||||||
// Запись
|
if (isset($model->onec['ЗначенияСвойств'])) {
|
||||||
return $model->save() ? $model : null;
|
// Свойства инициализированы
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
foreach ($model->onec['ЗначенияСвойств'] as $property) {
|
||||||
* Инициализация продукта
|
// Перебор всех свойств
|
||||||
*/
|
|
||||||
protected function initProduct(): ?Product
|
|
||||||
{
|
|
||||||
// Надо не забыть сделать выборку полей и ручное подключение
|
|
||||||
|
|
||||||
if (empty($this->catn)) {
|
if (is_array($property)) {
|
||||||
// Не передан каталожный номер
|
if ($property['Ид'] === 'd99622fe-4526-11eb-b7f3-f3e52d0a06a9') {
|
||||||
|
// Если идентификатор свойства совпадает с указанным в настройках свойства хранящего OEM номера
|
||||||
|
|
||||||
return false;
|
// Настройка
|
||||||
} else if (Product::searchByCatn($this->catn)) {
|
$model->oemn = array_merge(self::convertOemn2Catn($property['Значение']), self::convertOemn2Catn((string) $product->Артикул));
|
||||||
// Продукт уже был инициализирован
|
}
|
||||||
|
}
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Инициализация
|
|
||||||
$product = new Product();
|
|
||||||
|
|
||||||
// Настройки
|
|
||||||
$product->catn = $this->catn;
|
|
||||||
|
|
||||||
// Запись
|
// Запись
|
||||||
return $product->save() ? $product : null;
|
if ($model->save()) {
|
||||||
|
// Поставка успешно сохранена
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -294,8 +384,18 @@ class Supply extends Product implements ProductInterface
|
||||||
return 'ocid';
|
return 'ocid';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function searchOnecByAccountId(string $id, bool $full = false): array
|
/**
|
||||||
|
* Поиск через связь с аккаунтом
|
||||||
|
*
|
||||||
|
* @param string $id Идентификатор пользователя
|
||||||
|
* @param bool $full Возврат всех значений (иначе только свойства)
|
||||||
|
*/
|
||||||
|
public static function searchByAccount(string $id = null, bool $full = false): array
|
||||||
{
|
{
|
||||||
|
if (!isset($id)) {
|
||||||
|
$id = yii::$app->user->id ?? throw new exception('Не найден идентификатор');
|
||||||
|
}
|
||||||
|
|
||||||
$subquery = static::find()
|
$subquery = static::find()
|
||||||
->for(['account', 'account_edge_supply'])
|
->for(['account', 'account_edge_supply'])
|
||||||
->traversal('supply')->in('account_edge_supply')
|
->traversal('supply')->in('account_edge_supply')
|
||||||
|
@ -304,7 +404,7 @@ class Supply extends Product implements ProductInterface
|
||||||
->createCommand();
|
->createCommand();
|
||||||
|
|
||||||
$query = static::find()
|
$query = static::find()
|
||||||
->addParams($subquery->getBindVars())
|
->params($subquery->getBindVars())
|
||||||
->let('account_edge_supply', '(' . (string) $subquery . ')')
|
->let('account_edge_supply', '(' . (string) $subquery . ')')
|
||||||
->where('supply._id == account_edge_supply[0]._to')
|
->where('supply._id == account_edge_supply[0]._to')
|
||||||
->andWhere('supply.onec["ЗначенияСвойств"] != null');
|
->andWhere('supply.onec["ЗначенияСвойств"] != null');
|
||||||
|
@ -317,6 +417,8 @@ class Supply extends Product implements ProductInterface
|
||||||
$query = $query->select('supply.onec["ЗначенияСвойств"]')->createCommand()->execute()->getAll();
|
$query = $query->select('supply.onec["ЗначенияСвойств"]')->createCommand()->execute()->getAll();
|
||||||
|
|
||||||
foreach ($query as &$attribute) {
|
foreach ($query as &$attribute) {
|
||||||
|
// Приведение всех свойств в массив и очистка от лишних данных
|
||||||
|
|
||||||
$attribute = $attribute->getAll();
|
$attribute = $attribute->getAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace app\models\traits;
|
||||||
|
|
||||||
|
use yii;
|
||||||
|
|
||||||
|
use exception;
|
||||||
|
|
||||||
|
trait SearchByAccount
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Поиск через связи рёбрами с аккаунтом
|
||||||
|
*
|
||||||
|
* @param string $id Идентификатор пользователя
|
||||||
|
* @param int $limit Количество
|
||||||
|
* @param int $offset Сдвиг
|
||||||
|
* @param string $sort Сортировка
|
||||||
|
*/
|
||||||
|
public static function searchByAccount(
|
||||||
|
string $id = null,
|
||||||
|
int $limit = 10,
|
||||||
|
int $offset = 0,
|
||||||
|
array $sort = ['ASC'],
|
||||||
|
string|array $where = [],
|
||||||
|
string|array $post_where = [],
|
||||||
|
string $direction = 'ANY',
|
||||||
|
array $let = [],
|
||||||
|
array $params = []
|
||||||
|
): ?array {
|
||||||
|
if (!isset($id)) {
|
||||||
|
$id = yii::$app->user->id ?? throw new exception('Не найден идентификатор');
|
||||||
|
}
|
||||||
|
|
||||||
|
$subquery = static::find()
|
||||||
|
->for(['account', 'account_edge_' . self::collectionName()])
|
||||||
|
->traversal(self::collectionName(), $direction)
|
||||||
|
->in('account_edge_' . self::collectionName())
|
||||||
|
->where(['account._id' => $id]);
|
||||||
|
|
||||||
|
if (!empty($where)) {
|
||||||
|
// Переданы дополнительные условия фильтрации
|
||||||
|
|
||||||
|
$subquery->where($where);
|
||||||
|
}
|
||||||
|
|
||||||
|
$subquery = $subquery->select('account_edge_' . self::collectionName())
|
||||||
|
->createCommand();
|
||||||
|
|
||||||
|
$query = static::find()
|
||||||
|
->params($params, $subquery->getBindVars())
|
||||||
|
->let('account_edge_' . self::collectionName(), '(' . (string) $subquery . ')')
|
||||||
|
->limit($limit)
|
||||||
|
->offset($offset)
|
||||||
|
->orderBy($sort);
|
||||||
|
|
||||||
|
if (!empty($let)) {
|
||||||
|
// Переданы дополнительные условия фильтрации
|
||||||
|
|
||||||
|
$query->let(...$let);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($post_where) && $post_where) {
|
||||||
|
// Если переданы дополнительные условия фильтрации
|
||||||
|
|
||||||
|
$query->where($post_where);
|
||||||
|
} else {
|
||||||
|
$query->where(self::collectionName() . '._id == account_edge_' . self::collectionName() . '[0]._to');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->select(self::collectionName())->all();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace app\models\traits;
|
namespace app\models\traits;
|
||||||
|
|
||||||
trait Xml2Array {
|
trait Xml2Array {
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use yii;
|
||||||
|
|
||||||
|
?>
|
||||||
|
<a class="text-dark my-auto mr-2" href="/cart"><i class="fas fa-shopping-cart mx-2"></i></a>
|
||||||
|
<a class="text-dark my-auto mr-2" href="/orders"><i class="fas fa-list mx-2"></i></a>
|
||||||
|
<div class="btn-group my-auto">
|
||||||
|
<a class="btn m-0 px-0 text-dark button_clean" title="Личный кабинет" href="/profile" role="button" onclick="return page_profile();">Личный кабинет</a>
|
||||||
|
<button id="profile_button" class="btn pr-0 dropdown-toggle dropdown-toggle-split button_clean" type="button" data-toggle="dropdown" onmouseover="$('#profile_button').dropdown('show')"></button>
|
||||||
|
<div class="dropdown-menu dropdown-menu-long dropdown-menu-right p-3" aria-labelledby="profile_button" onmouseout="$('#profile_button').dropdown('show')">
|
||||||
|
<h5 class="mb-3 text-center">Аутентификация</h5>
|
||||||
|
<?= yii::$app->controller->renderPartial('/account/index') ?>
|
||||||
|
<!-- <a class="dropdown-item-text text-center px-0 py-2" href="#"><small>Восстановление пароля</small></a> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use yii;
|
||||||
|
|
||||||
|
if (!yii::$app->user->isGuest) {
|
||||||
|
$popup = yii::$app->controller->renderPartial('/notification/panel');
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<a id="notification_button" class="text-dark d-flex h-100 mr-2" title="Уведомления" href="/notification" role="button" data-toggle="dropdown" data-offset="-100%p + 100%" onclick="return notification_stream();">
|
||||||
|
<i class="fas fa-bell my-auto mx-2"></i>
|
||||||
|
</a>
|
||||||
|
<div id="notification_button_panel" class="dropdown-menu py-1" aria-labelledby="notification_button">
|
||||||
|
$popup
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<a class="text-dark my-auto mr-2" href="/cart"><i class="fas fa-shopping-cart mx-2"></i></a>
|
||||||
|
<a class="text-dark my-auto mr-2" href="/orders"><i class="fas fa-list mx-2"></i></a>
|
||||||
|
<div class="btn-group my-auto">
|
||||||
|
<a class="btn m-0 px-0 text-dark button_clean" title="Личный кабинет" href="/profile" role="button" onclick="return page_profile();">Личный кабинет</a>
|
||||||
|
<button id="profile_button" class="btn pr-0 dropdown-toggle dropdown-toggle-split button_clean" type="button" data-toggle="dropdown" onmouseover="$('#profile_button').dropdown('show')"></button>
|
||||||
|
<div id="profile_button_panel" class="dropdown-menu dropdown-menu-right py-1" aria-labelledby="profile_button" onmouseout="$('#profile_button').dropdown('show')">
|
||||||
|
<a class="dropdown-item button_white text-dark" onclick="deauthentication()">Выход (<?= yii::$app->user->identity->mail ?>)</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -12,7 +12,7 @@ $this->title = 'SkillParts';
|
||||||
<div class="container h-100 d-flex flex-column justify-content-center">
|
<div class="container h-100 d-flex flex-column justify-content-center">
|
||||||
<p class="mb-4 ml-0 gilroy">Проблема с подбором запчастей?</p>
|
<p class="mb-4 ml-0 gilroy">Проблема с подбором запчастей?</p>
|
||||||
<p class="ml-0 d-flex">
|
<p class="ml-0 d-flex">
|
||||||
<span class="p-2 px-3 button_call_icon"><i class="fas fa-phone-alt text-white"></i></span>
|
<span class="p-2 px-3 button_call_icon d-flex"><i class="fas fa-phone-alt my-auto text-white"></i></span>
|
||||||
<a class="btn text-white button_clean button_blue button_call" href="/call" role="button">Связаться с менеджером</a>
|
<a class="btn text-white button_clean button_blue button_call" href="/call" role="button">Связаться с менеджером</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,21 +22,21 @@ $this->title = 'SkillParts';
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="h-100 d-flex ticker">
|
<div class="h-100 d-flex ticker">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/cummins.png" alt="Cummins">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/cummins.png" alt="Cummins">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/iveco.png" alt="Iveco">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/iveco.png" alt="Iveco">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/komatsu.png" alt="Komatsu">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/komatsu.png" alt="Komatsu">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/case.png" alt="Case">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/case.png" alt="Case">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/isuzu.png" alt="Isuzu">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/isuzu.png" alt="Isuzu">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/new_holland.svg" alt="New Holland">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/new_holland.png" alt="New Holland">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/perkins.png" alt="Perkins">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/perkins.png" alt="Perkins">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/john_deere.png" alt="John Deere">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/john_deere.png" alt="John Deere">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/caterpillar.png" alt="Caterpillar">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/caterpillar.png" alt="Caterpillar">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/shantui.png" alt="Shantui">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/shantui.png" alt="Shantui">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/xcmg.png" alt="XCMG">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/xcmg.png" alt="XCMG">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/kobelco.png" alt="Kobelco">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/kobelco.png" alt="Kobelco">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/shehwa.png" alt="SHEHWA">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/shehwa.png" alt="SHEHWA">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/bomag.png" alt="BOMAG">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/bomag.png" alt="BOMAG">
|
||||||
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h100px/compressed/hitachi.png" alt="Hitachi">
|
<img class="w-auto h-100 mr-3 my-auto" src="/img/logos/h32px/compressed/hitachi.png" alt="Hitachi">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container mb-4">
|
<div class="container mb-4">
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/* @var $this \yii\web\View */
|
declare(strict_types=1);
|
||||||
/* @var $content string */
|
|
||||||
|
|
||||||
use yii\helpers\Html;
|
use yii\helpers\Html;
|
||||||
|
|
||||||
use app\assets\AppAsset;
|
use app\assets\AppAsset;
|
||||||
|
|
||||||
AppAsset::register($this);
|
AppAsset::register($this);
|
||||||
|
@ -27,19 +27,21 @@ AppAsset::register($this);
|
||||||
<body>
|
<body>
|
||||||
<?php $this->beginBody() ?>
|
<?php $this->beginBody() ?>
|
||||||
|
|
||||||
<header class="container pt-2 mt-1 mb-4">
|
<div id="notifications_popup_wrap" class="col-3 m-4"></div>
|
||||||
|
|
||||||
|
<header class="container pt-2 mt-1 mb-2 mb-sm-4">
|
||||||
<div class="row h-100">
|
<div class="row h-100">
|
||||||
<a class="col-3 h-100 py-2" title="SkillParts" href="/" role="button" onclick="return page_main();">
|
<a id="logo" class="col-3 col-md-4 h-100 py-2" title="SkillParts" href="/" role="button" onclick="return page_main();">
|
||||||
<img class="h-100" src="/img/logos/skillparts.svg" alt="SkillParts">
|
<img class="h-100" src="/img/logos/skillparts.svg" alt="SkillParts">
|
||||||
</a>
|
</a>
|
||||||
<div class="col-6 px-0 mt-auto d-flex">
|
<div class="col px-0 mt-auto d-flex h-title">
|
||||||
<div class="ml-auto p-0 h-divider-title-left"></div>
|
<div class="ml-auto p-0 h-divider-title-left"></div>
|
||||||
<div class="px-4 d-flex flex-column justify-content-center h-divider-title">
|
<div class="px-4 d-flex flex-column justify-content-center h-divider-title">
|
||||||
<h6 class="text-center text-white my-0"><b>Запчасти для спецтехники</b></h6>
|
<h6 class="text-center text-white my-0"><b>Запчасти для спецтехники</b></h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="mr-auto p-0 h-divider-title-right"></div>
|
<div class="mr-auto p-0 h-divider-title-right"></div>
|
||||||
</div>
|
</div>
|
||||||
<menu class="col-3 mb-0 d-flex justify-content-end"></menu>
|
<menu class="col-auto col-lg-4 mb-0 d-flex justify-content-end"></menu>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-divider"></div>
|
<div class="h-divider"></div>
|
||||||
</header>
|
</header>
|
||||||
|
@ -66,11 +68,21 @@ AppAsset::register($this);
|
||||||
<input id="catalog_search_panel_button_3" class="btn btn-sm5 text-white button_clean" type="radio" name="catalog_search_panel_buttons" value="catalog_search_panel_button_3">
|
<input id="catalog_search_panel_button_3" class="btn btn-sm5 text-white button_clean" type="radio" name="catalog_search_panel_buttons" value="catalog_search_panel_button_3">
|
||||||
<label class="mb-0 px-3 px-md-4 py-1" for="catalog_search_panel_button_3">Третья кнопка</label> -->
|
<label class="mb-0 px-3 px-md-4 py-1" for="catalog_search_panel_button_3">Третья кнопка</label> -->
|
||||||
<form class="d-flex catalog_search" onsubmit="return false;">
|
<form class="d-flex catalog_search" onsubmit="return false;">
|
||||||
<div class="position-relative col-8 col-lg-10 px-0">
|
<div class="position-relative col-sm-8 col-lg-10 px-0">
|
||||||
<input id="search_line" type="text" class="form-control col-12 catalog_search_line button_clean" placeholder="Введите номер запчасти, например: 45223503481" onclick="$('#search_line').dropdown('toggle')" onmouseenter="$('#search_line').dropdown('show')" oninput="$('#search_line').dropdown('hide'); product_search(this);" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<input id="search_line" type="text" class="form-control col-12 catalog_search_line button_clean" placeholder="Введите номер запчасти, например: 45223503481" oninput="$('#search_line').dropdown('hide'); product_search(this);" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" autocomplete="off">
|
||||||
<div id="search_line_window" class="dropdown-menu w-100" aria-labelledby="search_line" onmouseout="$('#search_line').dropdown('show')">
|
<?
|
||||||
<a class="dropdown-item button_white text-dark inactive">Здесь будет история поиска</a>
|
if (!yii::$app->user->isGuest && $search_panel = $search_panel ?? yii::$app->controller->renderPartial('/search/panel', ['history' => true])) {
|
||||||
</div>
|
echo <<<HTML
|
||||||
|
<div id="search_line_window" class="dropdown-menu w-100" aria-labelledby="search_line">
|
||||||
|
$search_panel
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
} else {
|
||||||
|
echo <<<HTML
|
||||||
|
<div id="search_line_window" class="dropdown-menu w-100 d-none" aria-labelledby="search_line"></div>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
?>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="col btn button_clean catalog_search_button" onclick="product_search(this.parentElement.getElementsByTagName('input')[0], 1)">ПОИСК</button>
|
<button type="submit" class="col btn button_clean catalog_search_button" onclick="product_search(this.parentElement.getElementsByTagName('input')[0], 1)">ПОИСК</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?
|
||||||
|
if (empty($notifications)) {
|
||||||
|
echo <<<HTML
|
||||||
|
<p class="px-2 py-3 text-center">Уведомлений нет</p>
|
||||||
|
HTML;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($notifications as $notification) {
|
||||||
|
// Перебор уведомлений
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$notification = $notification->getAttributes();
|
||||||
|
|
||||||
|
if ($notification['type'] === 'notice') {
|
||||||
|
// Уведомление
|
||||||
|
|
||||||
|
echo $notification['html'];
|
||||||
|
} else if ($notification['type'] === 'warning') {
|
||||||
|
// Предупреждение
|
||||||
|
|
||||||
|
echo $notification['html'];
|
||||||
|
} else {
|
||||||
|
// Неизвестно
|
||||||
|
|
||||||
|
echo $notification['html'] ?? '<p>ОШИБКА</p>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?
|
||||||
|
$id = 'popup/' . $notification->readId();
|
||||||
|
$html = $notification->html;
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<div id="$id" class="mt-3 p-0 notification rounded" onmouseleave="return notification_popup_delete(this);">
|
||||||
|
$html
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
?>
|
|
@ -1,5 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use yii\bootstrap\ActiveForm;
|
||||||
|
use yii\helpers\Html;
|
||||||
|
|
||||||
|
use app\models\Product;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<link href="/css/pages/product.css" rel="stylesheet">
|
<link href="/css/pages/product.css" rel="stylesheet">
|
||||||
|
|
||||||
|
@ -7,11 +12,117 @@
|
||||||
<div class="container h-100">
|
<div class="container h-100">
|
||||||
<div class="row h-100 py-3">
|
<div class="row h-100 py-3">
|
||||||
<article class="col-12">
|
<article class="col-12">
|
||||||
<div class="h-100 p-3 rounded">
|
<div class="h-100 p-3 d-flex flex-column rounded">
|
||||||
<h4 class="ml-4"><?php echo $model['name'] ?></h4>
|
<div id="product_slider" class="row px-3 profile_panel">
|
||||||
<div class="dropdown-divider"></div>
|
<div class="col-1 product_slider_preview p-0 pr-3 mb-3">
|
||||||
<p class="ml-4">Дата создания: <time><?php echo date('d.m.Y H:i', $model['date']) ?></time></p>
|
<?
|
||||||
<pre class="ml-4"><?php var_dump($model) ?></pre>
|
foreach ($model['imgs'] ?? [null] as $key => $image) {
|
||||||
|
// Перебор изображений
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$name = $image['name'] ?? 'Без названия';
|
||||||
|
$h150 = $image['h150'] ?? '/img/covers/h150/product.png';
|
||||||
|
|
||||||
|
// Генерация предпросмотра изображения
|
||||||
|
echo <<<HTML
|
||||||
|
<label class="p-0 mb-2" for="product_slider_image_$key">
|
||||||
|
<img class="img-fluid rounded" src="$h150"/>
|
||||||
|
</label>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<div class="product_slider_image">
|
||||||
|
<?
|
||||||
|
// Инициализация
|
||||||
|
$imgs = $model['imgs'] ?? [null];
|
||||||
|
$checked = '';
|
||||||
|
|
||||||
|
foreach ($imgs as $key => $image) {
|
||||||
|
// Перебор изображений
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$name = $image['name'] ?? 'Без названия';
|
||||||
|
$orig = $image['orig'] ?? '/img/covers/product.png';
|
||||||
|
$covr = $image['covr'] ?? false;
|
||||||
|
|
||||||
|
if ($covr || count($imgs) < 2) {
|
||||||
|
// Если это изображение является обложкой
|
||||||
|
|
||||||
|
// Реинициализация
|
||||||
|
$checked = 'checked';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Генерация изображения
|
||||||
|
echo <<<HTML
|
||||||
|
<input type="radio" id="product_slider_image_$key" name="slider" $checked/>
|
||||||
|
<div class="col p-0">
|
||||||
|
<img class="img-fluid rounded" src="$orig"/>
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
|
||||||
|
// Деинициализация
|
||||||
|
$checked = '';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<div class="col ml-4 d-flex flex-column">
|
||||||
|
<div class="row mb-1">
|
||||||
|
<h3 class="my-auto">Название товара</h3>
|
||||||
|
<h5 class="ml-auto my-auto"><?= $model['catn'] ?></h5>
|
||||||
|
</div>
|
||||||
|
<div class="dropdown-divider px-0 mb-3"></div>
|
||||||
|
<div class="row mb-3 h-100 product_panel d-flex flex-column">
|
||||||
|
<p class="mt-0">
|
||||||
|
ОЕМ-номера можно сюда добавить с возможностью перехода
|
||||||
|
<?
|
||||||
|
// foreach ($model['catn'] ?? [] as $catn) {
|
||||||
|
// echo <<<HTML
|
||||||
|
// $catn
|
||||||
|
// HTML;
|
||||||
|
// }
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?
|
||||||
|
$form = ActiveForm::begin([
|
||||||
|
'id' => 'form_product_cart',
|
||||||
|
'action' => false,
|
||||||
|
'fieldConfig' => [
|
||||||
|
'template' => '{input}',
|
||||||
|
],
|
||||||
|
'options' => [
|
||||||
|
'onsubmit' => 'return false;',
|
||||||
|
'class' => 'row mt-auto'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Просто для теста
|
||||||
|
$model = new Product();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="col-6 px-0 mr-4 btn-group">
|
||||||
|
<?= Html::submitButton('В корзину', ['name' => 'cartWrite', 'onclick' => 'product_cart_write(this.parentElement);', 'class' => 'col-10 btn button_blue button_clean py-2 px-5']) ?>
|
||||||
|
<?= $form->field($model, 'amount', ['options' => ['class' => 'col h-100 m-0 form-group']])->textInput(['value' => '1', 'class' => 'form-control h-100 rounded-0 text-center button_clean']); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p class="mt-0">
|
||||||
|
<strong>Хабаровск: </strong>
|
||||||
|
в наличии
|
||||||
|
</p>
|
||||||
|
<p class="mb-0">
|
||||||
|
Доставим: завтра
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<? ActiveForm::end(); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-auto mx-0">
|
||||||
|
<p class="ml-0">Время для повышения релевантности в поисковиках</p>
|
||||||
|
<time class="ml-auto"><?php echo date('d.m.Y', $model['date']) ?></time>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use yii\bootstrap\ActiveForm;
|
declare(strict_types=1);
|
||||||
use app\models\Supply;
|
|
||||||
|
|
||||||
|
use yii;
|
||||||
|
use yii\bootstrap\ActiveForm;
|
||||||
|
use yii\helpers\Html;
|
||||||
|
|
||||||
|
use app\models\Notification;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<link href="/css/pages/profile.css" rel="stylesheet">
|
<link href="/css/pages/profile.css" rel="stylesheet">
|
||||||
|
@ -10,46 +14,100 @@ use app\models\Supply;
|
||||||
<div id="page_profile" class="container h-100">
|
<div id="page_profile" class="container h-100">
|
||||||
<div class="row h-100 py-3">
|
<div class="row h-100 py-3">
|
||||||
<nav class="col-3">
|
<nav class="col-3">
|
||||||
<?= $sidebar ?? Yii::$app->controller->renderPartial('/profile/sidebar') ?>
|
<?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?>
|
||||||
</nav>
|
</nav>
|
||||||
<article class="col-9">
|
<article class="col-9">
|
||||||
<div class="h-100 p-4 rounded">
|
<div class="p-4 rounded">
|
||||||
<h4 class="ml-4 mb-4">Настройки аккаунта</h4>
|
<h4 class="ml-4 mb-4"><i class="fas fa-sliders-h my-auto mr-2"></i>Настройки</h4>
|
||||||
<p>Пока не сделана нормальная панель управления я просто буду добавлять все настройки сюда</p>
|
<div id="profile_panel_settings" class="profile_panel">
|
||||||
<?php
|
<div class="profile_panel_menu mb-3">
|
||||||
$form = ActiveForm::begin([
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_settings_account">Аккаунт</label>
|
||||||
'id' => 'form_profile_options',
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_settings_company">Компания</label>
|
||||||
'action' => false,
|
<label class="btn button_white mb-0" for="profile_panel_settings_import">Импорт</label>
|
||||||
'fieldConfig' => [
|
</div>
|
||||||
'template' => '{label}{input}',
|
<div class="profile_panel_content d-flex">
|
||||||
'options' => ['class' => '']
|
<input type="radio" id="profile_panel_settings_account" name="main_panel" />
|
||||||
],
|
<div class="col">
|
||||||
'options' => [
|
1
|
||||||
'class' => 'mb-3',
|
</div>
|
||||||
'onsubmit' => 'return false;'
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
|
|
||||||
$model = $model ?? Yii::$app->user->identity;
|
<input type="radio" id="profile_panel_settings_company" name="main_panel" />
|
||||||
var_dump($attributes = Supply::searchOnecByAccountId(Yii::$app->user->id));
|
<div class="col">
|
||||||
|
2
|
||||||
|
</div>
|
||||||
|
|
||||||
// $list = [];
|
<input type="radio" id="profile_panel_settings_import" name="main_panel" checked />
|
||||||
|
<div class="col">
|
||||||
|
<h5>Параметры 1C</h5>
|
||||||
|
<div class="dropdown-divider mb-3"></div>
|
||||||
|
<?
|
||||||
|
$form = ActiveForm::begin([
|
||||||
|
'id' => 'form_profile_settings',
|
||||||
|
'action' => false,
|
||||||
|
'fieldConfig' => [
|
||||||
|
'template' => '{label}{input}',
|
||||||
|
],
|
||||||
|
'options' => [
|
||||||
|
'onsubmit' => 'return false;'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
// //
|
/**
|
||||||
// foreach ($attributes as $attribute) {
|
* @todo Перенести в модель
|
||||||
// $id = $attribute['ЗначенияСвойства']['Ид'];
|
*/
|
||||||
|
|
||||||
// if (in_array($id, $list, true)) {
|
// Инициализация
|
||||||
// continue;
|
isset($model) or $model = yii::$app->user->identity;
|
||||||
// }
|
isset($attributes) or $attributes = Supply::searchByAccount(yii::$app->user->id);
|
||||||
|
$list = [];
|
||||||
|
|
||||||
// $list[] = $id;
|
// Перебор свойств поставок
|
||||||
// }
|
foreach ($attributes as $attribute) {
|
||||||
|
// Инициализация
|
||||||
|
$id = $attribute['ЗначенияСвойства']['Ид'];
|
||||||
|
|
||||||
?>
|
if (in_array($id, $list, true)) {
|
||||||
<?= "a" //$form->field($model, 'opts[import_sections_oem]', ['options' => ['class' => "mb-3"]])->dropDownList($list ?? ['Нет данных']); ?>
|
// Если встретился дубликат (вызывается очень часто)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
<?php ActiveForm::end(); ?>
|
// Генерация
|
||||||
|
$list[$id] = $attribute['ЗначенияСвойства']['Наименование'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Инициализация текущего значения параметра в начале массива
|
||||||
|
if (isset($model->opts['import_sections_oem'])) {
|
||||||
|
// Параметр 'import_sections_oem' найден в настройках аккаунта
|
||||||
|
|
||||||
|
if (isset($list[$model->opts['import_sections_oem']])) {
|
||||||
|
// Найдено совпадение сохранённого параметра с полученным списком из поставок
|
||||||
|
|
||||||
|
// Буфер для сохранения параметра
|
||||||
|
$buffer = $list[$model->opts['import_sections_oem']];
|
||||||
|
|
||||||
|
// Удаление параметра
|
||||||
|
unset($list[$model->opts['import_sections_oem']]);
|
||||||
|
|
||||||
|
// Сохранение параметра в начале массива
|
||||||
|
$list = array_merge([$model->opts['import_sections_oem'] => $buffer], $list);
|
||||||
|
} else {
|
||||||
|
// Совпадение не найдено
|
||||||
|
|
||||||
|
// Сохранение параметра из данных аккаунта в начале массива
|
||||||
|
$list = array_merge([$model->opts['import_sections_oem'] => $model->opts['import_sections_oem']], $list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?= $form->field($model, 'opts[import_sections_oem]', ['options' => ['class' => "mb-1"]])->dropDownList($list ?? ['Нет данных'], ['onChange' => 'page_profile_settings(this.parentElement.parentElement)'])->label('OEM-номера'); ?>
|
||||||
|
<small class="d-block mb-1">Выберите поле в котором хранятся <b>ОЕМ-номера</b> и повторите импорт</small>
|
||||||
|
<small class="d-block">Значения взяты из импортированных товаров</small>
|
||||||
|
<!-- <small class="d-block mb-3">Значения взяты из импортированных товаров</small> -->
|
||||||
|
|
||||||
|
<? ActiveForm::end(); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
?>
|
||||||
|
<link href="/css/pages/profile.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<div id="page_profile" class="container h-100">
|
||||||
|
<div class="row h-100 py-3">
|
||||||
|
<nav class="col-3">
|
||||||
|
<?= $sidebar ?? Yii::$app->controller->renderPartial('/profile/sidebar') ?>
|
||||||
|
</nav>
|
||||||
|
<article class="col-9">
|
||||||
|
<div class="p-4 rounded">
|
||||||
|
<h4 class="ml-3 mb-4"><i class="fas fa-eye my-auto mr-2"></i>Мониторинг</h4>
|
||||||
|
<div id="profile_panel_monitoring" class="profile_panel">
|
||||||
|
<div class="profile_panel_menu mb-3">
|
||||||
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_monitoring_input_orders_history">Заказы</label>
|
||||||
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_monitoring_input_search_history">Поисковые запросы</label>
|
||||||
|
<label class="btn button_white mb-0" for="profile_panel_monitoring_input_log">Журнал действий</label>
|
||||||
|
</div>
|
||||||
|
<div class="profile_panel_content">
|
||||||
|
<input type="radio" id="profile_panel_monitoring_input_orders_history" name="main_panel" />
|
||||||
|
<div class="col p-3">
|
||||||
|
История заказов в разработке
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="radio" id="profile_panel_monitoring_input_search_history" name="main_panel" checked />
|
||||||
|
<div class="col">
|
||||||
|
<div class="row header_blue py-2 text-white">
|
||||||
|
<div class="col-sm-4 col-md-3">IPv4</div>
|
||||||
|
<div class="col-7 col-sm-3 col-md-4 col-lg-6 pr-0 px-sm-0 px-lg-3">Поисковый запрос</div>
|
||||||
|
<div class="col">Время</div>
|
||||||
|
</div>
|
||||||
|
<?
|
||||||
|
foreach ($search_history as $row) {
|
||||||
|
// Инициализация
|
||||||
|
$date = date('H:i d.m.Y', $row->date);
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<div class="row py-1">
|
||||||
|
<div class="col-sm-4 col-md-3">$row->ipv4</div>
|
||||||
|
<div class="col-7 col-sm-3 col-md-4 col-lg-6 pr-0 px-sm-0 px-lg-3">$row->text</div>
|
||||||
|
<div class="col">$date</div>
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="mt-3">
|
||||||
|
<?
|
||||||
|
$page = ($page_search_history ?? 0) + 1;
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<div class="row">
|
||||||
|
<button class="btn button_clean button_blue" onclick="return page_profile_monitoring(-1);">Назад</button>
|
||||||
|
<p>$page</p>
|
||||||
|
<button class="btn button_clean button_blue" onclick="return page_profile_monitoring(1);">Вперёд</button>
|
||||||
|
<div class="col-8"></div>
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="radio" id="profile_panel_monitoring_input_log" name="main_panel" />
|
||||||
|
<div class="col p-3">
|
||||||
|
Журнал в разработке
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/js/profile.js" defer></script>
|
|
@ -2,27 +2,105 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Yii;
|
use yii;
|
||||||
|
|
||||||
use app\models\Product;
|
use app\models\Product;
|
||||||
use app\models\Supply;
|
use app\models\Supply;
|
||||||
?>
|
use app\models\AccountEdgeSupply;
|
||||||
|
use app\models\SupplyEdgeProduct;
|
||||||
|
|
||||||
<div class="p-3 rounded">
|
?>
|
||||||
|
<div class="col py-3 rounded">
|
||||||
<div class="row px-3">
|
<div class="row px-3">
|
||||||
<p class="ml-0">Почта: </p>
|
<p class="ml-0">Почта: </p>
|
||||||
<p class="mr-0"><?= Yii::$app->user->identity->mail ?></p>
|
<p class="mr-0"><?= yii::$app->user->identity->mail ?></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-divider my-3"></div>
|
<div class="dropdown-divider my-3"></div>
|
||||||
<dl class="m-0">
|
<dl class="m-0">
|
||||||
|
<?
|
||||||
|
if (yii::$app->user->identity->trst) {
|
||||||
|
// Пользователь является доверенным
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
$targetUrl = '/profile/trusted';
|
||||||
|
|
||||||
|
if ('/' . yii::$app->request->pathInfo === $targetUrl) {
|
||||||
|
// Запрошена эта страница
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<dt>
|
||||||
|
<a class="row text-dark button_white button_white_hover px-3 py-3 py-lg-2 font-weight-normal" href="$targetUrl"><i class="fas fa-sliders-h my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Панель управления</span></a>
|
||||||
|
</dt>
|
||||||
|
HTML;
|
||||||
|
} else {
|
||||||
|
echo <<<HTML
|
||||||
|
<dt>
|
||||||
|
<a class="row text-dark button_white px-3 py-3 py-lg-2 font-weight-normal" href="$targetUrl"><i class="fas fa-sliders-h my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Панель управления</span></a>
|
||||||
|
</dt>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
<dt>
|
<dt>
|
||||||
<a class="row text-dark mb-3 px-3 font-weight-normal" href="/profile">Настройки аккаунта</a>
|
<?
|
||||||
|
// Инициализация
|
||||||
|
$targetUrl = '/profile/supplies';
|
||||||
|
|
||||||
|
if ('/' . yii::$app->request->pathInfo === $targetUrl) {
|
||||||
|
// Запрошена эта страница
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<a class="row text-dark button_white button_white_hover px-3 py-3 py-lg-2 font-weight-normal" href="$targetUrl"><i class="fas fa-truck my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Поставки</span></a>
|
||||||
|
HTML;
|
||||||
|
} else {
|
||||||
|
echo <<<HTML
|
||||||
|
<a class="row text-dark button_white px-3 py-3 py-lg-2 font-weight-normal" href="$targetUrl"><i class="fas fa-truck my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Поставки</span></a>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
?>
|
||||||
</dt>
|
</dt>
|
||||||
<dt>
|
<dt>
|
||||||
<a class="row text-dark px-3 font-weight-normal" href="/profile/supplies">Управление поставками</a>
|
<?
|
||||||
|
// Инициализация
|
||||||
|
$targetUrl = '/profile/monitoring';
|
||||||
|
|
||||||
|
if ('/' . yii::$app->request->pathInfo === $targetUrl) {
|
||||||
|
// Запрошена эта страница
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<a class="row text-dark button_white button_white_hover px-3 py-3 py-lg-2 font-weight-normal" href="$targetUrl"><i class="fas fa-eye my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Мониторинг</span></a>
|
||||||
|
HTML;
|
||||||
|
} else {
|
||||||
|
echo <<<HTML
|
||||||
|
<a class="row text-dark button_white px-3 py-3 py-lg-2 font-weight-normal" href="$targetUrl"><i class="fas fa-eye my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Мониторинг</span></a>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</dt>
|
||||||
|
<dt>
|
||||||
|
<?
|
||||||
|
// Инициализация
|
||||||
|
$targetUrl = '/profile';
|
||||||
|
|
||||||
|
if ('/' . yii::$app->request->pathInfo === $targetUrl) {
|
||||||
|
// Запрошена эта страница
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<a class="row text-dark button_white button_white_hover px-3 py-3 py-lg-2 font-weight-normal" href="$targetUrl"><i class="fas fa-sliders-h my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Настройки</span></a>
|
||||||
|
HTML;
|
||||||
|
} else {
|
||||||
|
echo <<<HTML
|
||||||
|
<a class="row text-dark button_white px-3 py-3 py-lg-2 font-weight-normal" href="$targetUrl"><i class="fas fa-sliders-h my-auto mx-auto mx-lg-0 col-1 pl-0 mr-lg-2"></i><span>Настройки</span></a>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
?>
|
||||||
</dt>
|
</dt>
|
||||||
</dl>
|
</dl>
|
||||||
<div class="dropdown-divider my-3"></div>
|
<div class="dropdown-divider my-3"></div>
|
||||||
|
<div class="row px-3">
|
||||||
|
<p class="ml-0">Загрузок с аккаунта:</p>
|
||||||
|
<p class="mr-0"><?= AccountEdgeSupply::readAmount() ?></p>
|
||||||
|
</div>
|
||||||
<div class="row px-3">
|
<div class="row px-3">
|
||||||
<p class="ml-0">Товары:</p>
|
<p class="ml-0">Товары:</p>
|
||||||
<p class="mr-0"><?= Product::readAmount() ?></p>
|
<p class="mr-0"><?= Product::readAmount() ?></p>
|
||||||
|
@ -31,4 +109,8 @@ use app\models\Supply;
|
||||||
<p class="ml-0">Поставки:</p>
|
<p class="ml-0">Поставки:</p>
|
||||||
<p class="mr-0"><?= Supply::readAmount() ?></p>
|
<p class="mr-0"><?= Supply::readAmount() ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row px-3">
|
||||||
|
<p class="ml-0">Связано поставок:</p>
|
||||||
|
<p class="mr-0"><?= SupplyEdgeProduct::readAmount() ?></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use yii;
|
||||||
use yii\bootstrap\ActiveForm;
|
use yii\bootstrap\ActiveForm;
|
||||||
|
|
||||||
use app\controllers\ProfileController;
|
use app\controllers\ProfileController;
|
||||||
|
@ -13,7 +14,7 @@ use app\models\Supply;
|
||||||
<div id="page_profile" class="container h-100">
|
<div id="page_profile" class="container h-100">
|
||||||
<div class="row h-100 py-3">
|
<div class="row h-100 py-3">
|
||||||
<nav class="col-3">
|
<nav class="col-3">
|
||||||
<?= $sidebar ?? Yii::$app->controller->renderPartial('/profile/sidebar') ?>
|
<?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?>
|
||||||
</nav>
|
</nav>
|
||||||
<article class="col-9">
|
<article class="col-9">
|
||||||
<div class="h-100 p-4 rounded">
|
<div class="h-100 p-4 rounded">
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use yii;
|
||||||
|
use yii\bootstrap\ActiveForm;
|
||||||
|
use yii\helpers\Html;
|
||||||
|
|
||||||
|
use app\models\Notification;
|
||||||
|
use app\models\Settings;
|
||||||
|
|
||||||
|
?>
|
||||||
|
<link href="/css/pages/profile.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<div id="page_profile" class="container h-100">
|
||||||
|
<div class="row h-100 py-3">
|
||||||
|
<nav class="col-3">
|
||||||
|
<?= $sidebar ?? yii::$app->controller->renderPartial('/profile/sidebar') ?>
|
||||||
|
</nav>
|
||||||
|
<article class="col-9">
|
||||||
|
<div class="p-4 rounded">
|
||||||
|
<h4 class="ml-4 mb-4"><i class="fas fa-user-shield my-auto mr-2"></i>Панель управления</h4>
|
||||||
|
<div id="profile_panel_trusted" class="profile_panel">
|
||||||
|
<div class="profile_panel_menu mb-3">
|
||||||
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_trusted_input_notifications">Уведомления</label>
|
||||||
|
<label class="btn button_white mb-0 mr-2" for="profile_panel_trusted_input_settings">Настройки</label>
|
||||||
|
</div>
|
||||||
|
<div class="profile_panel_content">
|
||||||
|
<input type="radio" id="profile_panel_trusted_input_notifications" name="main_panel" />
|
||||||
|
<div class="col">
|
||||||
|
<h5>Отправка уведомления</h5>
|
||||||
|
<div class="dropdown-divider mb-3"></div>
|
||||||
|
<?
|
||||||
|
$form = ActiveForm::begin([
|
||||||
|
'id' => 'form_profile_trusted_notifications',
|
||||||
|
'action' => false,
|
||||||
|
'fieldConfig' => [
|
||||||
|
'template' => '{label}{input}'
|
||||||
|
],
|
||||||
|
'options' => [
|
||||||
|
'onsubmit' => 'return false;'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Значения по умолчанию
|
||||||
|
isset($model_notifications) or $model_notifications = new Notification;
|
||||||
|
isset($model_notifications->trgt) or $model_notifications->trgt = null;
|
||||||
|
isset($model_notifications->text) or $model_notifications->text = '';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?= $form->errorSummary($model_notifications) ?>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<?= $form->field($model_notifications, 'trgt', ['options' => ['class' => "mb-1 col-9"]])->input('text', ['placeholder' => yii::$app->user->identity->_key]); ?>
|
||||||
|
<?= $form->field($model_notifications, 'type', ['options' => ['class' => "col pl-0"]])->dropDownList($model_notifications->typs); ?>
|
||||||
|
</div>
|
||||||
|
<small class="d-block mb-1"><b>Множественная отправка:</b> @all или перечислить через запятую</small>
|
||||||
|
<small class="d-block mb-3"><b>Тестирование:</b> @test или оставить поле пустым</small>
|
||||||
|
|
||||||
|
<?= $form->field($model_notifications, 'text', ['options' => ['class' => "mb-3"]])->textarea(); ?>
|
||||||
|
|
||||||
|
<?= Html::submitButton('Отправить', ['name' => 'submitNotification', 'onclick' => 'page_profile_trusted_notification_create(this.parentElement);', 'class' => 'flex-grow-1 mr-2 btn button_white button_clean']) ?>
|
||||||
|
<?= Html::submitButton('Отправить как HTML', ['name' => 'submitNotification', 'onclick' => 'page_profile_trusted_notification_create(this.parentElement, 1);', 'class' => 'flex-grow-1 mr-2 btn button_white button_clean']) ?>
|
||||||
|
|
||||||
|
<? ActiveForm::end(); ?>
|
||||||
|
</div>
|
||||||
|
<input type="radio" id="profile_panel_trusted_input_settings" name="main_panel" checked />
|
||||||
|
<div class="col">
|
||||||
|
<?
|
||||||
|
$form = ActiveForm::begin([
|
||||||
|
'id' => 'form_profile_trusted_settings_search_period',
|
||||||
|
'action' => false,
|
||||||
|
'fieldConfig' => [
|
||||||
|
'template' => '{label}{input}',
|
||||||
|
],
|
||||||
|
'options' => [
|
||||||
|
'onsubmit' => 'return false;',
|
||||||
|
'class' => 'mb-4'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?= $form->errorSummary($model_settings, ['header' => 'Получены ошибки:']) ?>
|
||||||
|
|
||||||
|
<?= $form->field($model_settings, 'search_period', ['options' => ['class' => "mb-1"]])->textInput(['value' => $model_settings['search_period'], 'onChange' => 'page_profile_trusted_settings(this.parentElement.parentElement)']); ?>
|
||||||
|
<small class="d-block mb-1">Время которое надо ждать для повторного поиска в секундах</small>
|
||||||
|
|
||||||
|
<? ActiveForm::end(); ?>
|
||||||
|
|
||||||
|
<?
|
||||||
|
$form = ActiveForm::begin([
|
||||||
|
'id' => 'form_profile_trusted_settings_search_connect_keep',
|
||||||
|
'action' => false,
|
||||||
|
'fieldConfig' => [
|
||||||
|
'template' => '{label}{input}',
|
||||||
|
],
|
||||||
|
'options' => [
|
||||||
|
'onsubmit' => 'return false;'
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$list = ['false' => 'Нет', 'true' => 'Да'];
|
||||||
|
|
||||||
|
if (isset($model_settings->search_connect_keep)) {
|
||||||
|
// Найден ранее записанный параметр
|
||||||
|
|
||||||
|
if (isset($list[$model_settings->search_connect_keep])) {
|
||||||
|
// Совпадение параметра с параметрами списка найдено
|
||||||
|
|
||||||
|
// Буфер для сохранения параметра
|
||||||
|
$buffer = $list[$model_settings->search_connect_keep];
|
||||||
|
|
||||||
|
// Удаление параметра
|
||||||
|
unset($list[$model_settings->search_connect_keep]);
|
||||||
|
|
||||||
|
// Сохранение параметра в начале массива
|
||||||
|
$list = array_merge([$model_settings->search_connect_keep => $buffer], $list);
|
||||||
|
} else {
|
||||||
|
// Совпадение параметра с параметрами списка не найдено
|
||||||
|
|
||||||
|
// Сохранение параметра из данных аккаунта в начале массива
|
||||||
|
$list = array_merge([$model_settings->search_connect_keep => $model_settings->search_connect_keep], $list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?= $form->field($model_settings, 'search_connect_keep', ['options' => ['class' => "mb-1"]])->dropDownList($list, ['onChange' => 'page_profile_trusted_settings(this.parentElement.parentElement)']); ?>
|
||||||
|
<small class="d-block mb-1">Удерживать открытое соединение до истечения срока блокировки поиска?</small>
|
||||||
|
<small class="d-block mb-1">При малой задержке позволяет снизить время загрузки страницы, но при большой будет казаться, что сайт завис</small>
|
||||||
|
|
||||||
|
<? ActiveForm::end(); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/js/profile.js" defer></script>
|
||||||
|
<script src="/js/profile_trusted.js" defer></script>
|
|
@ -8,31 +8,70 @@
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<article class="col-9">
|
<article class="col-9">
|
||||||
<div class="row p-3 rounded">
|
<div class="row mx-0 p-3 rounded">
|
||||||
<div class="d-flex flex-column mx-auto">
|
<?php
|
||||||
<?php
|
if (isset($timer) && $timer > 0) {
|
||||||
if (isset($timer) && $timer > 0) {
|
echo <<<HTML
|
||||||
echo <<<HTML
|
<div class="d-flex flex-column mx-auto">
|
||||||
<p class="d-flex justify-content-center mb-3">Слишком частые запросы, повторите попытку через: $timer секунд</p>
|
<p class="px-2 mb-1 text-center d-flex justify-content-center">Слишком частые запросы, повторите попытку через: $timer секунд</p>
|
||||||
|
<small class="mb-3 text-center d-flex justify-content-center">Подождите или нажмите на кнопку вручную</small>
|
||||||
<a class="btn text-white button_clean button_blue mx-auto" onclick="window.location.reload();">Повторить</a>
|
<a class="btn text-white button_clean button_blue mx-auto" onclick="window.location.reload();">Повторить</a>
|
||||||
HTML;
|
</div>
|
||||||
} else {
|
<script type="text/javascript">
|
||||||
|
setTimeout('window.location.reload()', $timer + '000');
|
||||||
|
</script>
|
||||||
|
HTML;
|
||||||
|
} else {
|
||||||
|
if (isset($response) && is_array($response) && $response) {
|
||||||
|
|
||||||
if (isset($response) && $response) {
|
$i = 0;
|
||||||
foreach ($response as $row) {
|
$amount = count($response);
|
||||||
$id = $row['id'];
|
|
||||||
$catn = $row['catn'];
|
|
||||||
|
|
||||||
|
foreach ($response as $row) {
|
||||||
|
$catn = $row['catn'];
|
||||||
|
$covr = $row['covr'] ?? '/img/covers/h150/product.png';
|
||||||
|
$amnt = $row['amnt'] ?? 1;
|
||||||
|
|
||||||
|
|
||||||
|
// <button class="button_clean_full d-flex p-0">
|
||||||
|
// <i class="fas fa-plus-square search_card_cart_icon my-auto"></i>
|
||||||
|
// </button>
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<div class="col-3 p-2 d-flex flex-column search_card rounded">
|
||||||
|
<div class="col">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<img class="w-100 img-fluid rounded" src="$covr"/>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-2">
|
||||||
|
<a class="mx-auto text-dark" href="/product/$catn"><h5 class="m-0">$catn</h5></a>
|
||||||
|
</div>
|
||||||
|
<div class="row px-2 mb-2">
|
||||||
|
<small class="mt-auto">{$amnt}шт</small>
|
||||||
|
<p class="mr-0">1000р</p>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<button class="btn button_grey button_clean w-100 text-white">В корзину</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
|
|
||||||
|
if (++$i % 4 === 0 && $amount - $i !== 0) {
|
||||||
echo <<<HTML
|
echo <<<HTML
|
||||||
<a class="dropdown-item button_white text-dark" href="/product/$id">$catn</a>
|
<div class="dropdown-divider my-3 mx-4 w-100 "></div>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
echo '<p class="m-0 py-2 d-flex justify-content-center">Ничего не найдено</p>';
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
echo <<<HTML
|
||||||
|
<div class="d-flex flex-column mx-auto">
|
||||||
|
<p class="m-0 py-2 d-flex justify-content-center">Ничего не найдено</p>
|
||||||
|
</div>
|
||||||
|
HTML;
|
||||||
}
|
}
|
||||||
?>
|
}
|
||||||
</div>
|
?>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,22 +1,38 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use yii\helpers\Html;
|
declare(strict_types=1);
|
||||||
use yii\bootstrap\ActiveForm;
|
|
||||||
use app\models\AccountForm;
|
|
||||||
|
|
||||||
// var_dump($response);
|
use app\models\Search;
|
||||||
|
|
||||||
|
if (isset($history) && $history) {
|
||||||
|
// Отображение истории
|
||||||
|
|
||||||
|
if (!yii::$app->user->isGuest && $rows = Search::searchByAccount(sort: ['DESC'])) {
|
||||||
|
// История поиска существует
|
||||||
|
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
// Инициализация
|
||||||
|
$date = date('H:i d.m.Y', $row->date);
|
||||||
|
|
||||||
|
echo <<<HTML
|
||||||
|
<a class="dropdown-item d-flex button_white text-dark" href="/search?type=product&q=$row->text">$row->text<span class="ml-auto">$date</span></a>
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isset($response) && $response) {
|
||||||
|
// Ответ получен
|
||||||
|
|
||||||
if (isset($response) && $response) {
|
|
||||||
foreach ($response as $row) {
|
foreach ($response as $row) {
|
||||||
$id = $row['id'];
|
// Перебор найденных данных
|
||||||
|
|
||||||
$catn = $row['catn'];
|
$catn = $row['catn'];
|
||||||
|
|
||||||
echo <<<HTML
|
echo <<<HTML
|
||||||
<a class="dropdown-item button_white text-dark" href="/product/$id">$catn</a>
|
<a class="dropdown-item button_white text-dark" href="/product/$catn">$catn</a>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
echo '<p class="m-0 py-2 d-flex justify-content-center">Ничего не найдено</p>';
|
echo <<<HTML
|
||||||
|
<p class="m-0 py-2 d-flex justify-content-center">Ничего не найдено</p>
|
||||||
|
HTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*!
|
/*!
|
||||||
* Bootstrap Grid v4.5.3 (https://getbootstrap.com/)
|
* Bootstrap Grid v4.6.0 (https://getbootstrap.com/)
|
||||||
* Copyright 2011-2020 The Bootstrap Authors
|
* Copyright 2011-2021 The Bootstrap Authors
|
||||||
* Copyright 2011-2020 Twitter, Inc.
|
* Copyright 2011-2021 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
*/
|
*/
|
||||||
html {
|
html {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*!
|
/*!
|
||||||
* Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)
|
* Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)
|
||||||
* Copyright 2011-2020 The Bootstrap Authors
|
* Copyright 2011-2021 The Bootstrap Authors
|
||||||
* Copyright 2011-2020 Twitter, Inc.
|
* Copyright 2011-2021 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||||
*/
|
*/
|
||||||
|
@ -24,7 +24,7 @@ article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
@ -198,9 +198,8 @@ button {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:focus {
|
button:focus:not(:focus-visible) {
|
||||||
outline: 1px dotted;
|
outline: 0;
|
||||||
outline: 5px auto -webkit-focus-ring-color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*!
|
/*!
|
||||||
* Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)
|
* Bootstrap Reboot v4.6.0 (https://getbootstrap.com/)
|
||||||
* Copyright 2011-2020 The Bootstrap Authors
|
* Copyright 2011-2021 The Bootstrap Authors
|
||||||
* Copyright 2011-2020 Twitter, Inc.
|
* Copyright 2011-2021 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
||||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
|
@ -1,7 +1,7 @@
|
||||||
/*!
|
/*!
|
||||||
* Bootstrap v4.5.3 (https://getbootstrap.com/)
|
* Bootstrap v4.6.0 (https://getbootstrap.com/)
|
||||||
* Copyright 2011-2020 The Bootstrap Authors
|
* Copyright 2011-2021 The Bootstrap Authors
|
||||||
* Copyright 2011-2020 Twitter, Inc.
|
* Copyright 2011-2021 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
*/
|
*/
|
||||||
:root {
|
:root {
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
--breakpoint-md: 768px;
|
--breakpoint-md: 768px;
|
||||||
--breakpoint-lg: 992px;
|
--breakpoint-lg: 992px;
|
||||||
--breakpoint-xl: 1200px;
|
--breakpoint-xl: 1200px;
|
||||||
--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
--font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
--font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
@ -228,9 +228,8 @@ button {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:focus {
|
button:focus:not(:focus-visible) {
|
||||||
outline: 1px dotted;
|
outline: 0;
|
||||||
outline: 5px auto -webkit-focus-ring-color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
|
@ -2241,6 +2240,11 @@ textarea.form-control {
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-row > .col > .valid-tooltip,
|
||||||
|
.form-row > [class*="col-"] > .valid-tooltip {
|
||||||
|
left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.was-validated :valid ~ .valid-feedback,
|
.was-validated :valid ~ .valid-feedback,
|
||||||
.was-validated :valid ~ .valid-tooltip,
|
.was-validated :valid ~ .valid-tooltip,
|
||||||
.is-valid ~ .valid-feedback,
|
.is-valid ~ .valid-feedback,
|
||||||
|
@ -2270,7 +2274,7 @@ textarea.form-control {
|
||||||
.was-validated .custom-select:valid, .custom-select.is-valid {
|
.was-validated .custom-select:valid, .custom-select.is-valid {
|
||||||
border-color: #28a745;
|
border-color: #28a745;
|
||||||
padding-right: calc(0.75em + 2.3125rem);
|
padding-right: calc(0.75em + 2.3125rem);
|
||||||
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
|
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right 0.75rem center/8px 10px no-repeat, #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {
|
.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus {
|
||||||
|
@ -2342,6 +2346,11 @@ textarea.form-control {
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-row > .col > .invalid-tooltip,
|
||||||
|
.form-row > [class*="col-"] > .invalid-tooltip {
|
||||||
|
left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.was-validated :invalid ~ .invalid-feedback,
|
.was-validated :invalid ~ .invalid-feedback,
|
||||||
.was-validated :invalid ~ .invalid-tooltip,
|
.was-validated :invalid ~ .invalid-tooltip,
|
||||||
.is-invalid ~ .invalid-feedback,
|
.is-invalid ~ .invalid-feedback,
|
||||||
|
@ -2371,7 +2380,7 @@ textarea.form-control {
|
||||||
.was-validated .custom-select:invalid, .custom-select.is-invalid {
|
.was-validated .custom-select:invalid, .custom-select.is-invalid {
|
||||||
border-color: #dc3545;
|
border-color: #dc3545;
|
||||||
padding-right: calc(0.75em + 2.3125rem);
|
padding-right: calc(0.75em + 2.3125rem);
|
||||||
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
|
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right 0.75rem center/8px 10px no-repeat, #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem) no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {
|
.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus {
|
||||||
|
@ -3388,7 +3397,7 @@ input[type="button"].btn-block {
|
||||||
.dropdown-item:hover, .dropdown-item:focus {
|
.dropdown-item:hover, .dropdown-item:focus {
|
||||||
color: #16181b;
|
color: #16181b;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #f8f9fa;
|
background-color: #e9ecef;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item.active, .dropdown-item:active {
|
.dropdown-item.active, .dropdown-item:active {
|
||||||
|
@ -3398,7 +3407,7 @@ input[type="button"].btn-block {
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item.disabled, .dropdown-item:disabled {
|
.dropdown-item.disabled, .dropdown-item:disabled {
|
||||||
color: #6c757d;
|
color: #adb5bd;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
@ -3597,12 +3606,6 @@ input[type="button"].btn-block {
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-group > .form-control:not(:last-child),
|
|
||||||
.input-group > .custom-select:not(:last-child) {
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input-group > .form-control:not(:first-child),
|
.input-group > .form-control:not(:first-child),
|
||||||
.input-group > .custom-select:not(:first-child) {
|
.input-group > .custom-select:not(:first-child) {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
|
@ -3617,14 +3620,23 @@ input[type="button"].btn-block {
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-group > .custom-file:not(:last-child) .custom-file-label,
|
.input-group > .custom-file:not(:last-child) .custom-file-label,
|
||||||
.input-group > .custom-file:not(:last-child) .custom-file-label::after {
|
.input-group > .custom-file:not(:first-child) .custom-file-label {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group:not(.has-validation) > .form-control:not(:last-child),
|
||||||
|
.input-group:not(.has-validation) > .custom-select:not(:last-child),
|
||||||
|
.input-group:not(.has-validation) > .custom-file:not(:last-child) .custom-file-label::after {
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-group > .custom-file:not(:first-child) .custom-file-label {
|
.input-group.has-validation > .form-control:nth-last-child(n + 3),
|
||||||
border-top-left-radius: 0;
|
.input-group.has-validation > .custom-select:nth-last-child(n + 3),
|
||||||
border-bottom-left-radius: 0;
|
.input-group.has-validation > .custom-file:nth-last-child(n + 3) .custom-file-label::after {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-group-prepend,
|
.input-group-prepend,
|
||||||
|
@ -3727,8 +3739,10 @@ input[type="button"].btn-block {
|
||||||
|
|
||||||
.input-group > .input-group-prepend > .btn,
|
.input-group > .input-group-prepend > .btn,
|
||||||
.input-group > .input-group-prepend > .input-group-text,
|
.input-group > .input-group-prepend > .input-group-text,
|
||||||
.input-group > .input-group-append:not(:last-child) > .btn,
|
.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .btn,
|
||||||
.input-group > .input-group-append:not(:last-child) > .input-group-text,
|
.input-group:not(.has-validation) > .input-group-append:not(:last-child) > .input-group-text,
|
||||||
|
.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .btn,
|
||||||
|
.input-group.has-validation > .input-group-append:nth-last-child(n + 3) > .input-group-text,
|
||||||
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
|
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
|
||||||
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
|
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
|
||||||
border-top-right-radius: 0;
|
border-top-right-radius: 0;
|
||||||
|
@ -3825,7 +3839,7 @@ input[type="button"].btn-block {
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
content: "";
|
content: "";
|
||||||
background: no-repeat 50% / 50% 50%;
|
background: 50% / 50% 50% no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-checkbox .custom-control-label::before {
|
.custom-checkbox .custom-control-label::before {
|
||||||
|
@ -3914,7 +3928,7 @@ input[type="button"].btn-block {
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
color: #495057;
|
color: #495057;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
background: #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px;
|
background: #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") right 0.75rem center/8px 10px no-repeat;
|
||||||
border: 1px solid #ced4da;
|
border: 1px solid #ced4da;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
@ -3983,6 +3997,7 @@ input[type="button"].btn-block {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(1.5em + 0.75rem + 2px);
|
height: calc(1.5em + 0.75rem + 2px);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4012,6 +4027,7 @@ input[type="button"].btn-block {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
height: calc(1.5em + 0.75rem + 2px);
|
height: calc(1.5em + 0.75rem + 2px);
|
||||||
padding: 0.375rem 0.75rem;
|
padding: 0.375rem 0.75rem;
|
||||||
|
overflow: hidden;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
color: #495057;
|
color: #495057;
|
||||||
|
@ -4048,7 +4064,7 @@ input[type="button"].btn-block {
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-range:focus {
|
.custom-range:focus {
|
||||||
outline: none;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-range:focus::-webkit-slider-thumb {
|
.custom-range:focus::-webkit-slider-thumb {
|
||||||
|
@ -4243,11 +4259,8 @@ input[type="button"].btn-block {
|
||||||
border-bottom: 1px solid #dee2e6;
|
border-bottom: 1px solid #dee2e6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-tabs .nav-item {
|
|
||||||
margin-bottom: -1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-tabs .nav-link {
|
.nav-tabs .nav-link {
|
||||||
|
margin-bottom: -1px;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
border-top-left-radius: 0.25rem;
|
border-top-left-radius: 0.25rem;
|
||||||
border-top-right-radius: 0.25rem;
|
border-top-right-radius: 0.25rem;
|
||||||
|
@ -4403,8 +4416,12 @@ input[type="button"].btn-block {
|
||||||
height: 1.5em;
|
height: 1.5em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
content: "";
|
content: "";
|
||||||
background: no-repeat center center;
|
background: 50% / 100% 100% no-repeat;
|
||||||
background-size: 100% 100%;
|
}
|
||||||
|
|
||||||
|
.navbar-nav-scroll {
|
||||||
|
max-height: 75vh;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 575.98px) {
|
@media (max-width: 575.98px) {
|
||||||
|
@ -4438,6 +4455,9 @@ input[type="button"].btn-block {
|
||||||
-ms-flex-wrap: nowrap;
|
-ms-flex-wrap: nowrap;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
.navbar-expand-sm .navbar-nav-scroll {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
.navbar-expand-sm .navbar-collapse {
|
.navbar-expand-sm .navbar-collapse {
|
||||||
display: -ms-flexbox !important;
|
display: -ms-flexbox !important;
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
|
@ -4480,6 +4500,9 @@ input[type="button"].btn-block {
|
||||||
-ms-flex-wrap: nowrap;
|
-ms-flex-wrap: nowrap;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
.navbar-expand-md .navbar-nav-scroll {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
.navbar-expand-md .navbar-collapse {
|
.navbar-expand-md .navbar-collapse {
|
||||||
display: -ms-flexbox !important;
|
display: -ms-flexbox !important;
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
|
@ -4522,6 +4545,9 @@ input[type="button"].btn-block {
|
||||||
-ms-flex-wrap: nowrap;
|
-ms-flex-wrap: nowrap;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
.navbar-expand-lg .navbar-nav-scroll {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
.navbar-expand-lg .navbar-collapse {
|
.navbar-expand-lg .navbar-collapse {
|
||||||
display: -ms-flexbox !important;
|
display: -ms-flexbox !important;
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
|
@ -4564,6 +4590,9 @@ input[type="button"].btn-block {
|
||||||
-ms-flex-wrap: nowrap;
|
-ms-flex-wrap: nowrap;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
.navbar-expand-xl .navbar-nav-scroll {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
.navbar-expand-xl .navbar-collapse {
|
.navbar-expand-xl .navbar-collapse {
|
||||||
display: -ms-flexbox !important;
|
display: -ms-flexbox !important;
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
|
@ -4608,6 +4637,10 @@ input[type="button"].btn-block {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.navbar-expand .navbar-nav-scroll {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
.navbar-expand .navbar-collapse {
|
.navbar-expand .navbar-collapse {
|
||||||
display: -ms-flexbox !important;
|
display: -ms-flexbox !important;
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
|
@ -4972,17 +5005,12 @@ input[type="button"].btn-block {
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb-item {
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumb-item + .breadcrumb-item {
|
.breadcrumb-item + .breadcrumb-item {
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb-item + .breadcrumb-item::before {
|
.breadcrumb-item + .breadcrumb-item::before {
|
||||||
display: inline-block;
|
float: left;
|
||||||
padding-right: 0.5rem;
|
padding-right: 0.5rem;
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
content: "/";
|
content: "/";
|
||||||
|
@ -5465,8 +5493,8 @@ a.badge-dark:focus, a.badge-dark.focus {
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-bar-animated {
|
.progress-bar-animated {
|
||||||
-webkit-animation: progress-bar-stripes 1s linear infinite;
|
-webkit-animation: 1s linear infinite progress-bar-stripes;
|
||||||
animation: progress-bar-stripes 1s linear infinite;
|
animation: 1s linear infinite progress-bar-stripes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
@ -6145,7 +6173,7 @@ a.close.disabled {
|
||||||
z-index: 1070;
|
z-index: 1070;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
@ -6258,7 +6286,7 @@ a.close.disabled {
|
||||||
z-index: 1060;
|
z-index: 1060;
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 276px;
|
max-width: 276px;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
@ -6546,7 +6574,7 @@ a.close.disabled {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
background: no-repeat 50% / 100% 100%;
|
background: 50% / 100% 100% no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-control-prev-icon {
|
.carousel-control-prev-icon {
|
||||||
|
@ -6635,8 +6663,8 @@ a.close.disabled {
|
||||||
border: 0.25em solid currentColor;
|
border: 0.25em solid currentColor;
|
||||||
border-right-color: transparent;
|
border-right-color: transparent;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
-webkit-animation: spinner-border .75s linear infinite;
|
-webkit-animation: .75s linear infinite spinner-border;
|
||||||
animation: spinner-border .75s linear infinite;
|
animation: .75s linear infinite spinner-border;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spinner-border-sm {
|
.spinner-border-sm {
|
||||||
|
@ -6677,8 +6705,8 @@ a.close.disabled {
|
||||||
background-color: currentColor;
|
background-color: currentColor;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
-webkit-animation: spinner-grow .75s linear infinite;
|
-webkit-animation: .75s linear infinite spinner-grow;
|
||||||
animation: spinner-grow .75s linear infinite;
|
animation: .75s linear infinite spinner-grow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spinner-grow-sm {
|
.spinner-grow-sm {
|
||||||
|
@ -6686,6 +6714,14 @@ a.close.disabled {
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.spinner-border,
|
||||||
|
.spinner-grow {
|
||||||
|
-webkit-animation-duration: 1.5s;
|
||||||
|
animation-duration: 1.5s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.align-baseline {
|
.align-baseline {
|
||||||
vertical-align: baseline !important;
|
vertical-align: baseline !important;
|
||||||
}
|
}
|
||||||
|
@ -7954,7 +7990,6 @@ button.bg-dark:focus {
|
||||||
.user-select-all {
|
.user-select-all {
|
||||||
-webkit-user-select: all !important;
|
-webkit-user-select: all !important;
|
||||||
-moz-user-select: all !important;
|
-moz-user-select: all !important;
|
||||||
-ms-user-select: all !important;
|
|
||||||
user-select: all !important;
|
user-select: all !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
header {
|
header {
|
||||||
height: 4rem;
|
height : 4rem;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,10 @@ nav {
|
||||||
margin-bottom: .5rem;
|
margin-bottom: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#profile_button_panel {
|
||||||
|
z-index: 1500;
|
||||||
|
}
|
||||||
|
|
||||||
.h-divider {
|
.h-divider {
|
||||||
border-bottom: 4px solid #123EAB;
|
border-bottom: 4px solid #123EAB;
|
||||||
}
|
}
|
||||||
|
@ -24,45 +28,46 @@ nav {
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-divider-title-left {
|
.h-divider-title-left {
|
||||||
max-width: 0;
|
max-width : 0;
|
||||||
max-height: 0;
|
max-height : 0;
|
||||||
border: 1rem solid transparent;
|
border : 1rem solid transparent;
|
||||||
border-right: 1rem solid #123EAB;
|
border-right : 1rem solid #123EAB;
|
||||||
border-bottom: 1rem solid #123EAB;
|
border-bottom: 1rem solid #123EAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-divider-title-right {
|
.h-divider-title-right {
|
||||||
max-width: 0;
|
max-width : 0;
|
||||||
max-height: 0;
|
max-height : 0;
|
||||||
border: 1rem solid transparent;
|
border : 1rem solid transparent;
|
||||||
border-left: 1rem solid #123EAB;
|
border-left : 1rem solid #123EAB;
|
||||||
border-bottom: 1rem solid #123EAB;
|
border-bottom: 1rem solid #123EAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog_button {
|
.catalog_button {
|
||||||
width: 100%;
|
width : 100%;
|
||||||
height: 2rem;
|
height : 2rem;
|
||||||
border-radius: 3px;
|
border-radius : 3px;
|
||||||
background-clip: unset;
|
background-clip : unset;
|
||||||
border: 1px solid #a39bb1;
|
border : 1px solid #a39bb1;
|
||||||
/* background-color: #123EAB; */
|
/* background-color: #123EAB; */
|
||||||
background-color: #e4e2ea;
|
background-color : #e4e2ea;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog_button:hover {
|
.catalog_button:hover {
|
||||||
border: 1px solid #c0b7d0;
|
border : 1px solid #c0b7d0;
|
||||||
/* background-color: #1b4bc4; */
|
/* background-color: #1b4bc4; */
|
||||||
background-color: #ebe9f2;
|
background-color : #ebe9f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog_button:active, .catalog_button:focus {
|
.catalog_button:active,
|
||||||
border: 1px solid #7b7587;
|
.catalog_button:focus {
|
||||||
|
border : 1px solid #7b7587;
|
||||||
/* background-color: #402d82; */
|
/* background-color: #402d82; */
|
||||||
background-color: #d7d4dd;
|
background-color : #d7d4dd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog_button p {
|
.catalog_button p {
|
||||||
font-size: 85%;
|
font-size : 85%;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,25 +76,25 @@ nav {
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog_search {
|
.catalog_search {
|
||||||
padding: 0.8rem;
|
padding : 0.8rem;
|
||||||
/* border-radius: 0px 5px 5px 5px; */
|
/* border-radius: 0px 5px 5px 5px; */
|
||||||
border-radius: 5px;
|
border-radius : 5px;
|
||||||
background-color: #123EAB;
|
background-color: #123EAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchPanel label {
|
#searchPanel label {
|
||||||
display: inline-block;
|
display : inline-block;
|
||||||
cursor: pointer;
|
cursor : pointer;
|
||||||
user-select: none;
|
user-select : none;
|
||||||
font-size: smaller;
|
font-size : smaller;
|
||||||
border-radius: 5px 5px 0px 0px;
|
border-radius : 5px 5px 0px 0px;
|
||||||
color: #000;
|
color : #000;
|
||||||
border-bottom: none;
|
border-bottom : none;
|
||||||
background-color: #e4e2ea;
|
background-color: #e4e2ea;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchPanel label:hover {
|
#searchPanel label:hover {
|
||||||
border-bottom: none;
|
border-bottom : none;
|
||||||
background-color: #ebe9f2;
|
background-color: #ebe9f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,101 +102,97 @@ nav {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchPanel input[type=radio]+label:active, #searchPanel input[type=radio]:checked+label:active {
|
#searchPanel input[type=radio]+label:active,
|
||||||
border-bottom: none;
|
#searchPanel input[type=radio]:checked+label:active {
|
||||||
|
border-bottom : none;
|
||||||
background-color: #d7d4dd;
|
background-color: #d7d4dd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchPanel input[type=radio]:checked+label, #searchPanel input[type=radio]:checked:hover+label, #searchPanel input[type=radio]:checked:active+label {
|
#searchPanel input[type=radio]:checked+label,
|
||||||
color: #ffffff;
|
#searchPanel input[type=radio]:checked:hover+label,
|
||||||
|
#searchPanel input[type=radio]:checked:active+label {
|
||||||
|
color : #ffffff;
|
||||||
background-color: #123EAB;
|
background-color: #123EAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchPanel input[type=radio]:disabled+label {
|
#searchPanel input[type=radio]:disabled+label {
|
||||||
background: #241c3d;
|
background: #241c3d;
|
||||||
color: #c4c4c4;
|
color : #c4c4c4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog_search_line {
|
.catalog_search_line {
|
||||||
height: 2rem;
|
height : 2rem;
|
||||||
margin: 0 .8rem 0 0;
|
margin : 0 .8rem 0 0;
|
||||||
font-size: 85%;
|
font-size : 85%;
|
||||||
line-height: 100%;
|
line-height : 100%;
|
||||||
border-radius: 3px;
|
border-radius : 3px;
|
||||||
border: 1px solid #a39bb1;
|
border : 1px solid #a39bb1;
|
||||||
background-color: #fbf9ff !important;
|
background-color: #fbf9ff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog_search_button {
|
.catalog_search_button {
|
||||||
height: 2rem;
|
height : 2rem;
|
||||||
margin: 0 0 0 .8rem;
|
margin : 0 0 0 .8rem;
|
||||||
font-size: 85%;
|
font-size : 85%;
|
||||||
line-height: 100%;
|
line-height : 100%;
|
||||||
border-radius: 3px;
|
border-radius : 3px;
|
||||||
border: 1px solid #a39bb1;
|
border : 1px solid #a39bb1;
|
||||||
background-color: #e4e2ea;
|
background-color: #e4e2ea;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog_search_button:hover {
|
.catalog_search_button:hover {
|
||||||
border: 1px solid #c0b7d0;
|
border : 1px solid #c0b7d0;
|
||||||
background-color: #ebe9f2;
|
background-color: #ebe9f2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog_search_button:active {
|
.catalog_search_button:active {
|
||||||
border: 1px solid #7b7587;
|
border : 1px solid #7b7587;
|
||||||
background-color: #d7d4dd;
|
background-color: #d7d4dd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 400px) {
|
@media (max-width: 400px) {
|
||||||
.logotype {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.catalog_search {
|
.catalog_search {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.catalog_search_line {
|
|
||||||
max-width: 100%;
|
|
||||||
border-radius: 3px 3px 0px 0px;
|
|
||||||
}
|
|
||||||
.catalog_search_button {
|
.catalog_search_button {
|
||||||
border-radius: 0px 0px 3px 3px;
|
margin: .8rem 0 0 0;
|
||||||
|
height: auto;
|
||||||
|
line-height: 200%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Малые девайсы («ландшафтные телефоны», >= 576px) */
|
/* Малые девайсы («ландшафтные телефоны», >= 576px) */
|
||||||
|
|
||||||
@media (max-width: 576px) {
|
@media (max-width: 576px) {
|
||||||
.tagline {
|
|
||||||
|
#logo,
|
||||||
|
.tagline,
|
||||||
|
.h-divider {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchPanel label {
|
#searchPanel label {
|
||||||
width: 100%;
|
width : 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
#searchPanel label:not(:nth-child(2)) {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.catalog_search {
|
|
||||||
border-radius: 0px 0px 5px 5px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Средние девайсы («таблетки», >= 768px) */
|
/* Средние девайсы («таблетки», >= 768px) */
|
||||||
|
|
||||||
@media (max-width: 768px) {}
|
@media (max-width: 768px) {
|
||||||
|
.dropdownMenuButton_column {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Большие девайсы (десктопы, >= 992px) */
|
/* Большие девайсы (десктопы, >= 992px) */
|
||||||
|
|
||||||
@media (max-width: 992px) {
|
@media (max-width: 992px) {
|
||||||
.h-divider {
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
.h-divider div {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.dropdownMenuButton_column {
|
.dropdownMenuButton_column {
|
||||||
width: max-content;
|
width: max-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dropdownMenuButton p {
|
#dropdownMenuButton p {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -199,4 +200,8 @@ nav {
|
||||||
|
|
||||||
/* Экстрабольшие девайсы (большие десктопы, >= 1200px) */
|
/* Экстрабольшие девайсы (большие десктопы, >= 1200px) */
|
||||||
|
|
||||||
@media (max-width: 1200px) {}
|
@media (max-width: 1200px) {
|
||||||
|
.h-title>* {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,17 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Gilroy';
|
font-family: 'Gilroy';
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
src: local('/fonts/Gilroy/gilroy-semibold.ttf'), url('/fonts/Gilroy/gilroy-semibold.ttf');
|
src : local('/fonts/Gilroy/gilroy-semibold.ttf'), url('/fonts/Gilroy/gilroy-semibold.ttf');
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
font-family: 'Open Sans';
|
font-family: 'Open Sans';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*:focus-visible {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -25,36 +29,95 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
min-height: 100vh;
|
min-height : 100vh;
|
||||||
display: flex;
|
display : flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow-x: hidden;
|
overflow-x : hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
flex-grow: 1;
|
flex-grow : 1;
|
||||||
background-color: #f0eefb;
|
background-color: #f0eefb;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button_clean, .button_clean:hover, .button_clean:focus, .button_clean:active {
|
.inactive,
|
||||||
outline: none !important;
|
.inactive:hover,
|
||||||
box-shadow: none !important;
|
.inactive:focus,
|
||||||
}
|
.inactive:active {
|
||||||
|
|
||||||
.inactive, .inactive:hover, .inactive:focus, .inactive:active {
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button_blue {
|
.button_clean,
|
||||||
|
.button_clean:hover,
|
||||||
|
.button_clean:focus,
|
||||||
|
.button_clean:active,
|
||||||
|
.button_clean_full,
|
||||||
|
.button_clean_full:hover,
|
||||||
|
.button_clean_full:focus,
|
||||||
|
.button_clean_full:active {
|
||||||
|
outline : none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_clean_full,
|
||||||
|
.button_clean_full:hover,
|
||||||
|
.button_clean_full:focus,
|
||||||
|
.button_clean_full:active {
|
||||||
|
border : none;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_blue_simple {
|
||||||
|
color : #eee;
|
||||||
background-color: #123EAB;
|
background-color: #123EAB;
|
||||||
|
transition : 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_blue_simple:hover {
|
||||||
|
color : #fff;
|
||||||
|
transition: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_blue_simple:active {
|
||||||
|
color : #ddd;
|
||||||
|
background-color: #391e97;
|
||||||
|
transition : 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_blue {
|
||||||
|
color : #eee;
|
||||||
|
background-color: #123EAB;
|
||||||
|
transition : 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button_blue:hover {
|
.button_blue:hover {
|
||||||
background-color: #1b4bc4;
|
color : #fff;
|
||||||
|
background-color: #244db5;
|
||||||
|
transition : 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button_blue:active {
|
.button_blue:active {
|
||||||
background-color: #402d82;
|
color : #ddd;
|
||||||
|
background-color: #391e97;
|
||||||
|
transition : 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_red {
|
||||||
|
color : #eee;
|
||||||
|
background-color: #ab1212;
|
||||||
|
transition : 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_red:hover {
|
||||||
|
color : #fff;
|
||||||
|
background-color: #b52424;
|
||||||
|
transition : 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_red:active {
|
||||||
|
color : #ddd;
|
||||||
|
background-color: #971e1e;
|
||||||
|
transition : 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button_white {
|
.button_white {
|
||||||
|
@ -63,10 +126,31 @@ main {
|
||||||
|
|
||||||
.button_white:hover {
|
.button_white:hover {
|
||||||
background-color: #eaebee;
|
background-color: #eaebee;
|
||||||
|
transition : 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button_white:active {
|
.button_white:active {
|
||||||
background-color: #cfd3dd;
|
background-color: #cfd3dd;
|
||||||
|
transition : 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_white_hover {
|
||||||
|
background-color: #eaebee !important;
|
||||||
|
transition : 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_grey {
|
||||||
|
background-color: #b4bbcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_grey:hover {
|
||||||
|
background-color: #a6aebf;
|
||||||
|
transition : 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button_grey:active {
|
||||||
|
background-color: #8c94a8;
|
||||||
|
transition : 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.d-inline-block {
|
.d-inline-block {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#notifications_popup_wrap>.notification {
|
||||||
|
min-height : 100px;
|
||||||
|
border : 1px solid #a39bb1;
|
||||||
|
background-color: #fff;
|
||||||
|
opacity: 0;
|
||||||
|
transition: .3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notifications_popup_wrap {
|
||||||
|
z-index : 100;
|
||||||
|
bottom : 0;
|
||||||
|
position: fixed;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification_button_panel {
|
||||||
|
z-index: 2500;
|
||||||
|
min-width: 250px;
|
||||||
|
}
|
|
@ -1,3 +1,33 @@
|
||||||
#page_product nav > div, #page_product article > div {
|
#page_product nav>div,
|
||||||
|
#page_product article>div {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#page_product #product_slider>.product_slider_image>div,
|
||||||
|
#page_product #product_slider>.product_slider_image>input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_product #product_slider>.product_slider_image>input:checked+div {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_product #product_slider>.product_slider_image {
|
||||||
|
max-width: 25vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_product #product_slider>.product_slider_preview>label {
|
||||||
|
border : none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_product #product_slider>.product_slider_preview>label:hover>img {
|
||||||
|
cursor: pointer;
|
||||||
|
filter: brightness(0.9) contrast(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_product #product_slider>.product_slider_preview>label:active>img,
|
||||||
|
#page_product #product_slider>.product_slider_preview>label:focus>img {
|
||||||
|
cursor: pointer;
|
||||||
|
filter: brightness(0.8) contrast(1.3);
|
||||||
|
}
|
|
@ -1,3 +1,72 @@
|
||||||
#page_profile nav > div, #page_profile article > div {
|
#page_profile nav>div,
|
||||||
|
#page_profile article>div {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#page_profile [id^=profile_panel_]>.profile_panel_content {
|
||||||
|
flex-grow : 1;
|
||||||
|
border-radius: 0 3px 3px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_profile [id^=profile_panel_]>.profile_panel_content>div,
|
||||||
|
#page_profile [id^=profile_panel_]>.profile_panel_content>input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_profile [id^=profile_panel_]>.profile_panel_content>input:checked+div {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_profile [id^=profile_panel_]>.profile_panel_content>div>.header_blue {
|
||||||
|
background-color: #123EAB;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_profile [id^=profile_panel_]>.profile_panel_content>div>.header_blue~.row:nth-child(2n) {
|
||||||
|
background-color: #f0f5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_profile [id^=profile_panel_]>.profile_panel_content>div>.header_blue~.row:nth-child(2n + 1) {
|
||||||
|
background-color: #e7edf9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Экстрабольшие девайсы (большие десктопы, >= 1200px) */
|
||||||
|
|
||||||
|
@media (max-width: 1199px) {
|
||||||
|
#page_profile nav dl>dt>a>i {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Большие девайсы (десктопы, >= 992px) */
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
#page_profile nav dl>dt>a>span {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_profile nav dl>dt>a>i {
|
||||||
|
display: inherit !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Средние девайсы («таблетки», >= 768px) */
|
||||||
|
|
||||||
|
/* @media (max-width: 768px) {} */
|
||||||
|
|
||||||
|
/* Малые девайсы («ландшафтные телефоны», >= 576px) */
|
||||||
|
|
||||||
|
@media (max-width: 576px) {
|
||||||
|
#page_profile article h4 {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_profile #profile_panel_monitoring>.profile_panel_content>div>div>div:first-child {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_profile #profile_panel_monitoring>.profile_panel_content>div>div:last-child>div:first-child {
|
||||||
|
display: flex !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @media (max-width: 400px) {} */
|
|
@ -1,3 +1,15 @@
|
||||||
#page_search nav > div, #page_search article > div {
|
#page_search nav > div, #page_search article > div {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#page_search .search_card:hover {
|
||||||
|
background-color: #eaeaf0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_search .search_card:hover img {
|
||||||
|
border: 1px solid #e1e1ea;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page_search .search_card .search_card_cart_icon {
|
||||||
|
font-size: larger;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
/supplies
|
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 980 B |
After Width: | Height: | Size: 829 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 588 B |
After Width: | Height: | Size: 780 B |
After Width: | Height: | Size: 781 B |