Merge branch 'release/2022.05-02'

This commit is contained in:
Björn Fromme
2022-05-27 15:30:20 +02:00
16 changed files with 575 additions and 809 deletions
Generated
+164 -125
View File
@@ -8,16 +8,16 @@
"packages": [ "packages": [
{ {
"name": "b13/container", "name": "b13/container",
"version": "1.6.0", "version": "1.6.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/b13/container.git", "url": "https://github.com/b13/container.git",
"reference": "7b4ea2cc0d287ffae8acef99610b79517571b054" "reference": "625ad7c08074ba8846954cc64061ce5bca1fb52e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/b13/container/zipball/7b4ea2cc0d287ffae8acef99610b79517571b054", "url": "https://api.github.com/repos/b13/container/zipball/625ad7c08074ba8846954cc64061ce5bca1fb52e",
"reference": "7b4ea2cc0d287ffae8acef99610b79517571b054", "reference": "625ad7c08074ba8846954cc64061ce5bca1fb52e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -32,6 +32,7 @@
"codeception/module-asserts": "^1.0", "codeception/module-asserts": "^1.0",
"codeception/module-db": "^1.0", "codeception/module-db": "^1.0",
"codeception/module-webdriver": "^1.0", "codeception/module-webdriver": "^1.0",
"friendsofphp/php-cs-fixer": "^3.4",
"ichhabrecht/content-defender": "^3.2", "ichhabrecht/content-defender": "^3.2",
"phpstan/phpstan": "^0.12.11", "phpstan/phpstan": "^0.12.11",
"phpunit/phpunit": "^8.4", "phpunit/phpunit": "^8.4",
@@ -39,7 +40,7 @@
"typo3/cms-info": "^10.4", "typo3/cms-info": "^10.4",
"typo3/cms-install": "^10.4", "typo3/cms-install": "^10.4",
"typo3/cms-workspaces": "^10.4", "typo3/cms-workspaces": "^10.4",
"typo3/coding-standards": "^0.2.0", "typo3/coding-standards": "^0.5",
"typo3/testing-framework": "^6" "typo3/testing-framework": "^6"
}, },
"type": "typo3-cms-extension", "type": "typo3-cms-extension",
@@ -63,9 +64,9 @@
"homepage": "https://b13.com", "homepage": "https://b13.com",
"support": { "support": {
"issues": "https://github.com/b13/container/issues", "issues": "https://github.com/b13/container/issues",
"source": "https://github.com/b13/container/tree/1.6.0" "source": "https://github.com/b13/container/tree/1.6.1"
}, },
"time": "2022-04-19T08:27:22+00:00" "time": "2022-05-18T08:20:38+00:00"
}, },
{ {
"name": "christophlehmann/imageoptimizer", "name": "christophlehmann/imageoptimizer",
@@ -198,16 +199,16 @@
}, },
{ {
"name": "doctrine/cache", "name": "doctrine/cache",
"version": "2.1.1", "version": "2.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/cache.git", "url": "https://github.com/doctrine/cache.git",
"reference": "331b4d5dbaeab3827976273e9356b3b453c300ce" "reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce", "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
"reference": "331b4d5dbaeab3827976273e9356b3b453c300ce", "reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -217,18 +218,12 @@
"doctrine/common": ">2.2,<2.4" "doctrine/common": ">2.2,<2.4"
}, },
"require-dev": { "require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
"cache/integration-tests": "dev-master", "cache/integration-tests": "dev-master",
"doctrine/coding-standard": "^8.0", "doctrine/coding-standard": "^9",
"mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
"predis/predis": "~1.0",
"psr/cache": "^1.0 || ^2.0 || ^3.0", "psr/cache": "^1.0 || ^2.0 || ^3.0",
"symfony/cache": "^4.4 || ^5.2 || ^6.0@dev", "symfony/cache": "^4.4 || ^5.4 || ^6",
"symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev" "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -277,7 +272,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/cache/issues", "issues": "https://github.com/doctrine/cache/issues",
"source": "https://github.com/doctrine/cache/tree/2.1.1" "source": "https://github.com/doctrine/cache/tree/2.2.0"
}, },
"funding": [ "funding": [
{ {
@@ -293,7 +288,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-07-17T14:49:29+00:00" "time": "2022-05-20T20:07:39+00:00"
}, },
{ {
"name": "doctrine/dbal", "name": "doctrine/dbal",
@@ -1000,16 +995,16 @@
}, },
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
"version": "6.5.5", "version": "6.5.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/guzzle.git", "url": "https://github.com/guzzle/guzzle.git",
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" "reference": "f092dd734083473658de3ee4bef093ed77d2689c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f092dd734083473658de3ee4bef093ed77d2689c",
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", "reference": "f092dd734083473658de3ee4bef093ed77d2689c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1046,10 +1041,40 @@
"MIT" "MIT"
], ],
"authors": [ "authors": [
{
"name": "Graham Campbell",
"email": "[email protected]",
"homepage": "https://github.com/GrahamCampbell"
},
{ {
"name": "Michael Dowling", "name": "Michael Dowling",
"email": "[email protected]", "email": "[email protected]",
"homepage": "https://github.com/mtdowling" "homepage": "https://github.com/mtdowling"
},
{
"name": "Jeremy Lindblom",
"email": "[email protected]",
"homepage": "https://github.com/jeremeamia"
},
{
"name": "George Mponos",
"email": "[email protected]",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "[email protected]",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "[email protected]",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "[email protected]",
"homepage": "https://github.com/Tobion"
} }
], ],
"description": "Guzzle is a PHP HTTP client library", "description": "Guzzle is a PHP HTTP client library",
@@ -1065,9 +1090,23 @@
], ],
"support": { "support": {
"issues": "https://github.com/guzzle/guzzle/issues", "issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/6.5" "source": "https://github.com/guzzle/guzzle/tree/6.5.6"
}, },
"time": "2020-06-16T21:01:06+00:00" "funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
"type": "tidelift"
}
],
"time": "2022-05-25T13:19:12+00:00"
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
@@ -1323,16 +1362,16 @@
}, },
{ {
"name": "helhum/typo3-console", "name": "helhum/typo3-console",
"version": "v6.7.2", "version": "v6.7.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/TYPO3-Console/TYPO3-Console.git", "url": "https://github.com/TYPO3-Console/TYPO3-Console.git",
"reference": "faa96c02ed58c135fcd98b530f5aadeb5ff1ecf3" "reference": "b3a4823a93266928f9e3304e46d33aa52a184dcf"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/TYPO3-Console/TYPO3-Console/zipball/faa96c02ed58c135fcd98b530f5aadeb5ff1ecf3", "url": "https://api.github.com/repos/TYPO3-Console/TYPO3-Console/zipball/b3a4823a93266928f9e3304e46d33aa52a184dcf",
"reference": "faa96c02ed58c135fcd98b530f5aadeb5ff1ecf3", "reference": "b3a4823a93266928f9e3304e46d33aa52a184dcf",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1422,7 +1461,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2022-04-11T09:55:08+00:00" "time": "2022-05-22T12:40:43+00:00"
}, },
{ {
"name": "kigkonsult/icalcreator", "name": "kigkonsult/icalcreator",
@@ -1677,16 +1716,16 @@
}, },
{ {
"name": "lolli42/finediff", "name": "lolli42/finediff",
"version": "1.0.1", "version": "1.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/lolli42/FineDiff.git", "url": "https://github.com/lolli42/FineDiff.git",
"reference": "72b57e1355c6bbe2f51921e6a3a5bb7441471a7a" "reference": "f72cd968b663fc09bc73ef0ab5a3288583d0d59d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/lolli42/FineDiff/zipball/72b57e1355c6bbe2f51921e6a3a5bb7441471a7a", "url": "https://api.github.com/repos/lolli42/FineDiff/zipball/f72cd968b663fc09bc73ef0ab5a3288583d0d59d",
"reference": "72b57e1355c6bbe2f51921e6a3a5bb7441471a7a", "reference": "f72cd968b663fc09bc73ef0ab5a3288583d0d59d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1697,8 +1736,8 @@
"cogpowered/finediff": "*" "cogpowered/finediff": "*"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "^3.2", "friendsofphp/php-cs-fixer": "^3.4",
"phpstan/phpstan": "^0.12.99", "phpstan/phpstan": "^1.6",
"phpunit/phpunit": "^8 || ^9" "phpunit/phpunit": "^8 || ^9"
}, },
"type": "library", "type": "library",
@@ -1736,9 +1775,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/lolli42/FineDiff/issues", "issues": "https://github.com/lolli42/FineDiff/issues",
"source": "https://github.com/lolli42/FineDiff/tree/1.0.1" "source": "https://github.com/lolli42/FineDiff/tree/1.0.2"
}, },
"time": "2022-05-11T13:15:52+00:00" "time": "2022-05-23T07:44:28+00:00"
}, },
{ {
"name": "masterminds/html5", "name": "masterminds/html5",
@@ -2741,16 +2780,16 @@
}, },
{ {
"name": "symfony/cache", "name": "symfony/cache",
"version": "v5.4.8", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/cache.git", "url": "https://github.com/symfony/cache.git",
"reference": "4c6747cf7e56c6b8e3094dd24852bd3e364375b1" "reference": "a50b7249bea81ddd6d3b799ce40c5521c2f72f0b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/cache/zipball/4c6747cf7e56c6b8e3094dd24852bd3e364375b1", "url": "https://api.github.com/repos/symfony/cache/zipball/a50b7249bea81ddd6d3b799ce40c5521c2f72f0b",
"reference": "4c6747cf7e56c6b8e3094dd24852bd3e364375b1", "reference": "a50b7249bea81ddd6d3b799ce40c5521c2f72f0b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2818,7 +2857,7 @@
"psr6" "psr6"
], ],
"support": { "support": {
"source": "https://github.com/symfony/cache/tree/v5.4.8" "source": "https://github.com/symfony/cache/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -2834,7 +2873,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-26T13:19:20+00:00" "time": "2022-05-21T10:24:18+00:00"
}, },
{ {
"name": "symfony/cache-contracts", "name": "symfony/cache-contracts",
@@ -2917,16 +2956,16 @@
}, },
{ {
"name": "symfony/config", "name": "symfony/config",
"version": "v5.4.8", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/config.git", "url": "https://github.com/symfony/config.git",
"reference": "9f8964f56f7234f8ace16f66cb3fbae950c04e68" "reference": "8f551fe22672ac7ab2c95fe46d899f960ed4d979"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/config/zipball/9f8964f56f7234f8ace16f66cb3fbae950c04e68", "url": "https://api.github.com/repos/symfony/config/zipball/8f551fe22672ac7ab2c95fe46d899f960ed4d979",
"reference": "9f8964f56f7234f8ace16f66cb3fbae950c04e68", "reference": "8f551fe22672ac7ab2c95fe46d899f960ed4d979",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2976,7 +3015,7 @@
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/config/tree/v5.4.8" "source": "https://github.com/symfony/config/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -2992,20 +3031,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-12T16:02:29+00:00" "time": "2022-05-17T10:39:36+00:00"
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v5.4.8", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b" "reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b", "url": "https://api.github.com/repos/symfony/console/zipball/829d5d1bf60b2efeb0887b7436873becc71a45eb",
"reference": "ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b", "reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3075,7 +3114,7 @@
"terminal" "terminal"
], ],
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v5.4.8" "source": "https://github.com/symfony/console/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -3091,20 +3130,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-12T16:02:29+00:00" "time": "2022-05-18T06:17:34+00:00"
}, },
{ {
"name": "symfony/dependency-injection", "name": "symfony/dependency-injection",
"version": "v5.4.8", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/dependency-injection.git", "url": "https://github.com/symfony/dependency-injection.git",
"reference": "855e29cd715ad62bb840c9841fe09a7cde50811f" "reference": "beecae161577305926ec078c4ed973f2b98880b3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/855e29cd715ad62bb840c9841fe09a7cde50811f", "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/beecae161577305926ec078c4ed973f2b98880b3",
"reference": "855e29cd715ad62bb840c9841fe09a7cde50811f", "reference": "beecae161577305926ec078c4ed973f2b98880b3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3164,7 +3203,7 @@
"description": "Allows you to standardize and centralize the way objects are constructed in your application", "description": "Allows you to standardize and centralize the way objects are constructed in your application",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.8" "source": "https://github.com/symfony/dependency-injection/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -3180,7 +3219,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-26T13:08:29+00:00" "time": "2022-05-27T06:40:03+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
@@ -3251,16 +3290,16 @@
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v5.4.3", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d" "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/dec8a9f58d20df252b9cd89f1c6c1530f747685d", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc",
"reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d", "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3316,7 +3355,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "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.4.3" "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -3332,7 +3371,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-01-02T09:53:40+00:00" "time": "2022-05-05T16:45:39+00:00"
}, },
{ {
"name": "symfony/event-dispatcher-contracts", "name": "symfony/event-dispatcher-contracts",
@@ -3478,16 +3517,16 @@
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
"version": "v5.4.7", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/filesystem.git", "url": "https://github.com/symfony/filesystem.git",
"reference": "3a4442138d80c9f7b600fb297534ac718b61d37f" "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/3a4442138d80c9f7b600fb297534ac718b61d37f", "url": "https://api.github.com/repos/symfony/filesystem/zipball/36a017fa4cce1eff1b8e8129ff53513abcef05ba",
"reference": "3a4442138d80c9f7b600fb297534ac718b61d37f", "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3522,7 +3561,7 @@
"description": "Provides basic utilities for the filesystem", "description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/filesystem/tree/v5.4.7" "source": "https://github.com/symfony/filesystem/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -3538,7 +3577,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-01T12:33:59+00:00" "time": "2022-05-20T13:55:35+00:00"
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
@@ -3605,16 +3644,16 @@
}, },
{ {
"name": "symfony/http-client", "name": "symfony/http-client",
"version": "v4.4.41", "version": "v4.4.42",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-client.git", "url": "https://github.com/symfony/http-client.git",
"reference": "bad7c3296590c5a69a9ed89e8a51f13c07c34b54" "reference": "0366fe9d67709477e86b45e2e51a34ccf5018d04"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/bad7c3296590c5a69a9ed89e8a51f13c07c34b54", "url": "https://api.github.com/repos/symfony/http-client/zipball/0366fe9d67709477e86b45e2e51a34ccf5018d04",
"reference": "bad7c3296590c5a69a9ed89e8a51f13c07c34b54", "reference": "0366fe9d67709477e86b45e2e51a34ccf5018d04",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3666,7 +3705,7 @@
"description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-client/tree/v4.4.41" "source": "https://github.com/symfony/http-client/tree/v4.4.42"
}, },
"funding": [ "funding": [
{ {
@@ -3682,7 +3721,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-12T15:19:55+00:00" "time": "2022-05-17T14:14:05+00:00"
}, },
{ {
"name": "symfony/http-client-contracts", "name": "symfony/http-client-contracts",
@@ -3764,16 +3803,16 @@
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v5.4.8", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "ff2818d1c3d49860bcae1f2cbb5eb00fcd3bf9e2" "reference": "6b0d0e4aca38d57605dcd11e2416994b38774522"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/ff2818d1c3d49860bcae1f2cbb5eb00fcd3bf9e2", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6b0d0e4aca38d57605dcd11e2416994b38774522",
"reference": "ff2818d1c3d49860bcae1f2cbb5eb00fcd3bf9e2", "reference": "6b0d0e4aca38d57605dcd11e2416994b38774522",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3817,7 +3856,7 @@
"description": "Defines an object-oriented layer for the HTTP specification", "description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-foundation/tree/v5.4.8" "source": "https://github.com/symfony/http-foundation/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -3833,7 +3872,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-22T08:14:12+00:00" "time": "2022-05-17T15:07:29+00:00"
}, },
{ {
"name": "symfony/inflector", "name": "symfony/inflector",
@@ -3986,16 +4025,16 @@
}, },
{ {
"name": "symfony/mime", "name": "symfony/mime",
"version": "v5.4.8", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mime.git", "url": "https://github.com/symfony/mime.git",
"reference": "af49bc163ec3272f677bde3bc44c0d766c1fd662" "reference": "2b3802a24e48d0cfccf885173d2aac91e73df92e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/af49bc163ec3272f677bde3bc44c0d766c1fd662", "url": "https://api.github.com/repos/symfony/mime/zipball/2b3802a24e48d0cfccf885173d2aac91e73df92e",
"reference": "af49bc163ec3272f677bde3bc44c0d766c1fd662", "reference": "2b3802a24e48d0cfccf885173d2aac91e73df92e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4049,7 +4088,7 @@
"mime-type" "mime-type"
], ],
"support": { "support": {
"source": "https://github.com/symfony/mime/tree/v5.4.8" "source": "https://github.com/symfony/mime/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -4065,7 +4104,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-12T15:48:08+00:00" "time": "2022-05-21T10:24:18+00:00"
}, },
{ {
"name": "symfony/options-resolver", "name": "symfony/options-resolver",
@@ -5099,16 +5138,16 @@
}, },
{ {
"name": "symfony/property-info", "name": "symfony/property-info",
"version": "v5.4.7", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/property-info.git", "url": "https://github.com/symfony/property-info.git",
"reference": "0fc07795712972b9792f203d0fe0e77c26c3281d" "reference": "6f0a452aaba45e763f89e328df437f73a720e18e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/property-info/zipball/0fc07795712972b9792f203d0fe0e77c26c3281d", "url": "https://api.github.com/repos/symfony/property-info/zipball/6f0a452aaba45e763f89e328df437f73a720e18e",
"reference": "0fc07795712972b9792f203d0fe0e77c26c3281d", "reference": "6f0a452aaba45e763f89e328df437f73a720e18e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5170,7 +5209,7 @@
"validator" "validator"
], ],
"support": { "support": {
"source": "https://github.com/symfony/property-info/tree/v5.4.7" "source": "https://github.com/symfony/property-info/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -5186,7 +5225,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-03-30T13:40:48+00:00" "time": "2022-05-17T09:47:20+00:00"
}, },
{ {
"name": "symfony/routing", "name": "symfony/routing",
@@ -5280,16 +5319,16 @@
}, },
{ {
"name": "symfony/serializer", "name": "symfony/serializer",
"version": "v4.4.41", "version": "v4.4.42",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/serializer.git", "url": "https://github.com/symfony/serializer.git",
"reference": "15e4f450697b66cb6b2f3098b4038ba22cb9b71a" "reference": "234c6d024b5664d8fe6c117140196e00ba3fa626"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/serializer/zipball/15e4f450697b66cb6b2f3098b4038ba22cb9b71a", "url": "https://api.github.com/repos/symfony/serializer/zipball/234c6d024b5664d8fe6c117140196e00ba3fa626",
"reference": "15e4f450697b66cb6b2f3098b4038ba22cb9b71a", "reference": "234c6d024b5664d8fe6c117140196e00ba3fa626",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5354,7 +5393,7 @@
"description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/serializer/tree/v4.4.41" "source": "https://github.com/symfony/serializer/tree/v4.4.42"
}, },
"funding": [ "funding": [
{ {
@@ -5370,7 +5409,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-12T15:19:55+00:00" "time": "2022-05-10T09:16:50+00:00"
}, },
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
@@ -5457,16 +5496,16 @@
}, },
{ {
"name": "symfony/string", "name": "symfony/string",
"version": "v5.4.8", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/string.git", "url": "https://github.com/symfony/string.git",
"reference": "3c061a76bff6d6ea427d85e12ad1bb8ed8cd43e8" "reference": "985e6a9703ef5ce32ba617c9c7d97873bb7b2a99"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/3c061a76bff6d6ea427d85e12ad1bb8ed8cd43e8", "url": "https://api.github.com/repos/symfony/string/zipball/985e6a9703ef5ce32ba617c9c7d97873bb7b2a99",
"reference": "3c061a76bff6d6ea427d85e12ad1bb8ed8cd43e8", "reference": "985e6a9703ef5ce32ba617c9c7d97873bb7b2a99",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5523,7 +5562,7 @@
"utf8" "utf8"
], ],
"support": { "support": {
"source": "https://github.com/symfony/string/tree/v5.4.8" "source": "https://github.com/symfony/string/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -5543,16 +5582,16 @@
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v5.4.8", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "cdcadd343d31ad16fc5e006b0de81ea307435053" "reference": "af52239a330fafd192c773795520dc2dd62b5657"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/cdcadd343d31ad16fc5e006b0de81ea307435053", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/af52239a330fafd192c773795520dc2dd62b5657",
"reference": "cdcadd343d31ad16fc5e006b0de81ea307435053", "reference": "af52239a330fafd192c773795520dc2dd62b5657",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5612,7 +5651,7 @@
"dump" "dump"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-dumper/tree/v5.4.8" "source": "https://github.com/symfony/var-dumper/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -5628,20 +5667,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-26T13:19:20+00:00" "time": "2022-05-21T10:24:18+00:00"
}, },
{ {
"name": "symfony/var-exporter", "name": "symfony/var-exporter",
"version": "v5.4.8", "version": "v5.4.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-exporter.git", "url": "https://github.com/symfony/var-exporter.git",
"reference": "7e132a3fcd4b57add721b4207236877b6017ec93" "reference": "63249ebfca4e75a357679fa7ba2089cfb898aa67"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-exporter/zipball/7e132a3fcd4b57add721b4207236877b6017ec93", "url": "https://api.github.com/repos/symfony/var-exporter/zipball/63249ebfca4e75a357679fa7ba2089cfb898aa67",
"reference": "7e132a3fcd4b57add721b4207236877b6017ec93", "reference": "63249ebfca4e75a357679fa7ba2089cfb898aa67",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5685,7 +5724,7 @@
"serialize" "serialize"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-exporter/tree/v5.4.8" "source": "https://github.com/symfony/var-exporter/tree/v5.4.9"
}, },
"funding": [ "funding": [
{ {
@@ -5701,7 +5740,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-04-26T13:19:20+00:00" "time": "2022-05-21T10:24:18+00:00"
}, },
{ {
"name": "symfony/web-link", "name": "symfony/web-link",
+1
View File
@@ -17,6 +17,7 @@ set('allow_anonymous_stats', false);
add('shared_files', [ add('shared_files', [
'{{typo3_webroot}}/typo3conf/LocalConfiguration.php', '{{typo3_webroot}}/typo3conf/LocalConfiguration.php',
'{{typo3_webroot}}/sinkhole.html', '{{typo3_webroot}}/sinkhole.html',
'{{typo3_webroot}}/.htpasswd',
]); ]);
add('shared_dirs', [ add('shared_dirs', [
+1
View File
@@ -0,0 +1 @@
semester:$apr1$SbGrn7Nb$RMpKt6GZARkX8oKHR0wv/1
@@ -77,7 +77,7 @@ class DateCommandController extends Command
* @param OutputInterface $output * @param OutputInterface $output
* @throws \Doctrine\DBAL\DBALException * @throws \Doctrine\DBAL\DBALException
*/ */
public function execute(InputInterface $input, OutputInterface $output) public function execute(InputInterface $input, OutputInterface $output): int
{ {
$path = GeneralUtility::getFileAbsFileName('fileadmin/xmlexport'); $path = GeneralUtility::getFileAbsFileName('fileadmin/xmlexport');
$count = $this->dateImportService->import($path); $count = $this->dateImportService->import($path);
@@ -92,7 +92,7 @@ class DateCommandController extends Command
/** /**
* @return array * @return array
*/ */
protected function getSettings() protected function getSettings(): array
{ {
$settings = $this $settings = $this
->configurationManager ->configurationManager
@@ -61,19 +61,19 @@ class AjaxSearchController extends ActionController
public function initializeSearchresultAction() public function initializeSearchresultAction()
{ {
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); $forcedConceptUids = GeneralUtility::intExplode(',', $this->settings['forcedConceptUids'], true);
$this->processFilterSettingsArgument($forcedConceptUids); $this->processFilterSettingsArgument($forcedConceptUids);
} }
/** /**
* @param array $filterSettings * @param array $filterSettings
*/ */
public function searchresultAction(array $filterSettings) public function searchresultAction(array $filterSettings): void
{ {
$dateSelected = false; $dateSelected = false;
$organic = true; $organic = true;
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); $forcedConceptUids = GeneralUtility::intExplode(',', $this->settings['forcedConceptUids'], true);
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']); $excludedConceptUids = GeneralUtility::intExplode(',', $this->settings['excludedConceptUids'], true);
if (isset($filterSettings['dateFrom']) || isset($filterSettings['dateTo'])) { if (isset($filterSettings['dateFrom']) || isset($filterSettings['dateTo'])) {
$dateSelected = true; $dateSelected = true;
@@ -116,7 +116,7 @@ class ProductController extends ActionController
Hotel $hotel = null, Hotel $hotel = null,
$dateFrom = null, $dateFrom = null,
$dateTo = null $dateTo = null
) { ): void {
// Get product to display from flexform settings if not provided via url // Get product to display from flexform settings if not provided via url
if ($product === null) { if ($product === null) {
$productUid = $this->settings['productUid']; $productUid = $this->settings['productUid'];
@@ -186,7 +186,7 @@ class ProductController extends ActionController
]); ]);
} }
public function pricetableAction() public function pricetableAction(): void
{ {
$productUid = $this->settings['productUid']; $productUid = $this->settings['productUid'];
/** @var \EP\EpProducts\Domain\Model\Product $product */ /** @var \EP\EpProducts\Domain\Model\Product $product */
@@ -205,7 +205,7 @@ class ProductController extends ActionController
/** /**
* @param Product $product * @param Product $product
*/ */
public function hotelListAction(Product $product) public function hotelListAction(Product $product): void
{ {
$hotels = $this->hotelDataService->getList($product); $hotels = $this->hotelDataService->getList($product);
$this->view->assignMultiple([ $this->view->assignMultiple([
@@ -215,7 +215,7 @@ class ProductController extends ActionController
]); ]);
} }
public function teasergroupAction() public function teasergroupAction(): void
{ {
$filterSettings = $this->filterService->getFiltersettingsFromSettings($this->settings); $filterSettings = $this->filterService->getFiltersettingsFromSettings($this->settings);
$dateAuto = !$this->settings['dateFrom'] && !$this->settings['dateTo']; $dateAuto = !$this->settings['dateFrom'] && !$this->settings['dateTo'];
@@ -94,7 +94,7 @@ class SearchController extends ActionController
$filterSettings = $filterSettingsEncoder->decode($encodedFilterSettings); $filterSettings = $filterSettingsEncoder->decode($encodedFilterSettings);
$this->request->setArgument('filterSettings', $filterSettings); $this->request->setArgument('filterSettings', $filterSettings);
} }
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); $forcedConceptUids = GeneralUtility::intExplode(',', $this->settings['forcedConceptUids'], true);
$this->processFilterSettingsArgument($forcedConceptUids); $this->processFilterSettingsArgument($forcedConceptUids);
} }
@@ -105,8 +105,8 @@ class SearchController extends ActionController
{ {
$dateSelected = false; $dateSelected = false;
$organic = true; $organic = true;
$forcedConceptUids = GeneralUtility::trimExplode(',', $this->settings['forcedConceptUids'], true); $forcedConceptUids = GeneralUtility::intExplode(',', $this->settings['forcedConceptUids'], true);
$excludedConceptUids = GeneralUtility::trimExplode(',', $this->settings['excludedConceptUids']); $excludedConceptUids = GeneralUtility::intExplode(',', $this->settings['excludedConceptUids']);
if (!empty($filterSettings['dateFrom']) || !empty($filterSettings['dateTo'])) { if (!empty($filterSettings['dateFrom']) || !empty($filterSettings['dateTo'])) {
$dateSelected = true; $dateSelected = true;
@@ -2,43 +2,19 @@
namespace EP\EpProducts\Domain\Repository; namespace EP\EpProducts\Domain\Repository;
/***************************************************************
*
* Copyright notice
*
* (c) 2016 Björn Fromme <[email protected]>, dreipunktnull
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use EP\EpProducts\Domain\Model\Dto\FilterOptions; use EP\EpProducts\Domain\Model\Dto\FilterOptions;
use EP\EpProducts\Service\FilterService; use EP\EpProducts\Service\FilterService;
use EP\EpProducts\Traits\DbConnectionTrait; use EP\EpProducts\Traits\DbConnectionTrait;
use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings; use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
use TYPO3\CMS\Extbase\Persistence\Repository;
abstract class AbstractRepository extends \TYPO3\CMS\Extbase\Persistence\Repository abstract class AbstractRepository extends Repository
{ {
use DbConnectionTrait; use DbConnectionTrait;
public function initializeObject() public function initializeObject(): void
{ {
/** @var $querySettings \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings */ /** @var $querySettings \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings */
$querySettings = $this->objectManager->get(Typo3QuerySettings::class); $querySettings = $this->objectManager->get(Typo3QuerySettings::class);
@@ -60,202 +36,195 @@ abstract class AbstractRepository extends \TYPO3\CMS\Extbase\Persistence\Reposit
return $query->execute(); return $query->execute();
} }
protected function addDateFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addFiltersettingsConditions
(
QueryBuilder $qb,
array $filterSettings,
bool $constraintDates = true
): void {
if ($constraintDates) {
$this->addDateFilterConditions($qb, $filterSettings);
}
$this->addPriceRangeFilterConditions($qb, $filterSettings);
$this->addCountryRegionAndCityFilterConditions($qb, $filterSettings);
$this->addConceptFilterConditions($qb, $filterSettings);
$this->addPaxFilterConditions($qb, $filterSettings);
$this->addDurationFilterConditions($qb, $filterSettings);
$this->addHotelTypesFilterConditions($qb, $filterSettings);
$this->addBoardTypesFilterConditions($qb, $filterSettings);
$this->addRoomTypesFilterConditions($qb, $filterSettings);
$this->addTransportationFilterConditions($qb, $filterSettings);
// Product
if (!empty($filterSettings['productUid'])) {
$qb->andWhere($qb->expr()->eq(
'date.product',
$qb->createNamedParameter((int)$filterSettings['productUid'], Connection::PARAM_INT)
));
}
// Hotel
if (!empty($filterSettings['hotelUid'])) {
$qb->andWhere($qb->expr()->eq(
'date.hotel',
$qb->createNamedParameter((int)$filterSettings['hotelUid'], Connection::PARAM_INT)
));
}
}
protected function addDateFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
// Date Start // Date Start
if (!empty($filterSettings['dateFrom'])) { if (!empty($filterSettings['dateFrom'])) {
$query $qb->andWhere($qb->expr()->gte(
->andWhere('date.date_start >= :dateStart') 'date.date_start',
->setParameter('dateStart', $filterSettings['dateFrom']) $qb->createNamedParameter($filterSettings['dateFrom'])
; ));
} }
// Date End // Date End
if (!empty($filterSettings['dateTo'])) { if (!empty($filterSettings['dateTo'])) {
$query $qb->andWhere($qb->expr()->lte(
->andWhere('date.date_end <= :dateEnd') 'date.date_end',
->setParameter('dateEnd', $filterSettings['dateTo']) $qb->createNamedParameter($filterSettings['dateTo'])
; ));
} }
} }
protected function addHotelFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addHotelFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
// Hotel // Hotel
if (!empty($filterSettings['hotelUid'])) { if ($filterSettings['hotelUid'] > 0) {
$query $qb->andWhere($qb->expr()->eq(
->andWhere('date.hotel = :hotelUid') 'date.hotel',
->setParameter('hotelUid', (int)$filterSettings['hotelUid']) $qb->createNamedParameter((int)$filterSettings['hotelUid'], Connection::PARAM_INT)
; ));
} }
// Hotel types // Hotel types
if (!empty($filterSettings['hotelTypes'])) { if (count($filterSettings['hotelTypes']) > 0) {
$query $qb->andWhere($qb->expr()->in(
->andWhere('date.hotel_type IN (:hotelTypes)') 'date.hotel_type',
->setParameter('hotelTypes', (array)$filterSettings['hotelTypes'], Connection::PARAM_INT_ARRAY) $qb->createNamedParameter($filterSettings['hotelTypes'], Connection::PARAM_INT_ARRAY)
; ));
} }
} }
protected function addCountryRegionAndCityFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addCountryRegionAndCityFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
if (!empty($filterSettings['cityUids'])) { foreach (['city', 'region', 'country'] as $column) {
$query $key = $column . 'Uids';
->andWhere('date.city IN (:cityUids)') if (count($filterSettings[$key]) > 0) {
->setParameter('cityUids', (array)$filterSettings['cityUids'], Connection::PARAM_INT_ARRAY) $qb->andWhere($qb->expr()->in(
; 'date.' . $column,
} elseif (!empty($filterSettings['regionUids'])) { $qb->createNamedParameter($filterSettings[$key], Connection::PARAM_INT_ARRAY)
$query ));
->andWhere('date.region IN (:regionUids)') break;
->setParameter('regionUids', (array)$filterSettings['regionUids'], Connection::PARAM_INT_ARRAY) }
;
} elseif (!empty($filterSettings['countryUids'])) {
$query
->andWhere('date.country IN (:countryUids)')
->setParameter('countryUids', (array)$filterSettings['countryUids'], Connection::PARAM_INT_ARRAY)
;
} }
} }
protected function addConceptFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addConceptFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
if (!empty($filterSettings['conceptUids'])) { if (count($filterSettings['conceptUids']) > 0) {
$query $qb->andWhere($qb->expr()->in(
->andWhere('date.concept IN (:conceptUids)') 'date.concept',
->setParameter('conceptUids', (array)$filterSettings['conceptUids'], Connection::PARAM_INT_ARRAY) $qb->createNamedParameter($filterSettings['conceptUids'], Connection::PARAM_INT_ARRAY)
; ));
} }
} }
protected function addPaxFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addPaxFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
// Pax // Pax
if (!empty($filterSettings['pax'])) { if ($filterSettings['pax'] > 0) {
$query $qb->andWhere($qb->expr()->gte(
->andWhere('date.available >= :pax') 'date.available',
->setParameter('pax', (int)$filterSettings['pax']) $qb->createNamedParameter($filterSettings['pax'], Connection::PARAM_INT)
; ));
} }
} }
protected function addPriceRangeFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addPriceRangeFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
// Price ranges // Price ranges
if (!empty($filterSettings['priceRanges'])) { if (count($filterSettings['priceRanges']) > 0) {
$orX = $query->expr()->orX(); $orX = $qb->expr()->orX();
foreach ((array)$filterSettings['priceRanges'] as $priceRange) { foreach ($filterSettings['priceRanges'] as $priceRange) {
[ $priceMin, $priceMax ] = FilterOptions::$priceRangeOptions[$priceRange]; [ $priceMin, $priceMax ] = FilterOptions::$priceRangeOptions[$priceRange];
$orX->add($query->expr()->andX( $orX->add($qb->expr()->andX(
$query->expr()->gte('date.min_price', ':priceMin'), $qb->expr()->gte(
$query->expr()->lt('date.min_price', ':priceMax') 'date.min_price',
$qb->createNamedParameter($priceMin, Connection::PARAM_INT)
),
$qb->expr()->lt(
'date.min_price',
$qb->createNamedParameter($priceMax, Connection::PARAM_INT)
)
)); ));
$query
->setParameter('priceMin', $priceMin)
->setParameter('priceMax', $priceMax)
;
} }
$query->andWhere($orX); $qb->andWhere($orX);
} }
} }
protected function addDurationFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addDurationFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
// Duration // Duration
if (empty($filterSettings['nights'])) { if (0 === $filterSettings['nights']) {
return; return;
} }
$nights = (int)$filterSettings['nights']; $nights = $filterSettings['nights'];
if ($nights === FilterService::DURATION_SHORT) { if ($nights === FilterService::DURATION_SHORT) {
$query $qb->andWhere($qb->expr()->lte(
->andWhere('date.nights <= :nights') 'date.nights',
->setParameter('nights', $nights) $qb->createNamedParameter($nights, Connection::PARAM_INT))
; );
} elseif ($nights === FilterService::DURATION_LONG) { } elseif ($nights === FilterService::DURATION_LONG) {
$query $qb->andWhere($qb->expr()->gte(
->andWhere('date.nights >= :nights') 'date.nights',
->setParameter('nights', $nights) $qb->createNamedParameter($nights, Connection::PARAM_INT))
; );
} }
} }
protected function addHotelTypesFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addHotelTypesFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
// Hotel types // Hotel types
if (!empty($filterSettings['hotelTypes'])) { if (count($filterSettings['hotelTypes']) > 0) {
$query $qb->andWhere($qb->expr()->in(
->andWhere('date.hotel_type IN (:hotelTypes)') 'date.hotel_type',
->setParameter('hotelTypes', (array)$filterSettings['hotelTypes'], Connection::PARAM_INT_ARRAY) $qb->createNamedParameter($filterSettings['hotelTypes'], Connection::PARAM_INT_ARRAY)
; ));
} }
} }
protected function addBoardTypesFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addBoardTypesFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
// Board types // Board types
if (!empty($filterSettings['boardTypes'])) { if (count($filterSettings['boardTypes']) > 0) {
$query $qb->andWhere($qb->expr()->in(
->andWhere('date.board_bus_pro_id IN (:boardTypes)') 'date.board_bus_pro_id',
->setParameter('boardTypes', (array)$filterSettings['boardTypes'], Connection::PARAM_STR_ARRAY) $qb->createNamedParameter($filterSettings['boardTypes'], Connection::PARAM_INT_ARRAY)
; ));
} }
} }
protected function addRoomTypesFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addRoomTypesFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
// Room types // Room types
if (!empty($filterSettings['roomTypes'])) { if (count($filterSettings['roomTypes']) > 0) {
$query $qb->andWhere($qb->expr()->in(
->andWhere('room.type IN (:roomTypes)') 'room.type',
->setParameter('roomTypes', (array)$filterSettings['roomTypes'], Connection::PARAM_INT_ARRAY) $qb->createNamedParameter($filterSettings['roomTypes'], Connection::PARAM_INT_ARRAY)
; ));
} }
} }
protected function addTransportationFilterConditions(QueryBuilder $query, array $filterSettings): void protected function addTransportationFilterConditions(QueryBuilder $qb, array $filterSettings): void
{ {
// Transportation // Transportation
if (!empty($filterSettings['bus'])) { if (null !== $filterSettings['bus']) {
$query->andWhere('date.bus_available = 1'); $qb->andWhere($qb->expr()->eq('date.bus_available', 1));
} }
} }
/**
* Adds general conditions for provided filtersettings
*
* @param QueryBuilder $query
* @param array $filterSettings
* @param bool $constraintDates
*/
protected function addFiltersettingsConditions(QueryBuilder $query, array $filterSettings, bool $constraintDates = true)
{
if ($constraintDates) {
$this->addDateFilterConditions($query, $filterSettings);
}
$this->addPriceRangeFilterConditions($query, $filterSettings);
$this->addCountryRegionAndCityFilterConditions($query, $filterSettings);
$this->addConceptFilterConditions($query, $filterSettings);
$this->addPaxFilterConditions($query, $filterSettings);
$this->addDurationFilterConditions($query, $filterSettings);
$this->addHotelTypesFilterConditions($query, $filterSettings);
$this->addBoardTypesFilterConditions($query, $filterSettings);
$this->addRoomTypesFilterConditions($query, $filterSettings);
$this->addTransportationFilterConditions($query, $filterSettings);
// Product
if (!empty($filterSettings['productUid'])) {
$query
->andWhere('date.product = :productUid')
->setParameter('productUid', (int)$filterSettings['productUid'])
;
}
// Hotel
if (!empty($filterSettings['hotelUid'])) {
$query
->andWhere('date.hotel = :hotel')
->setParameter(':hotel', (int)$filterSettings['hotelUid'])
;
}
}
} }
@@ -2,200 +2,5 @@
namespace EP\EpProducts\Domain\Repository; namespace EP\EpProducts\Domain\Repository;
/***************************************************************
*
* Copyright notice
*
* (c) 2016 Björn Fromme <[email protected]>, dreipunktnull
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use EP\EpProducts\Domain\Model\Product;
use TYPO3\CMS\Core\Database\Connection;
class DateRepository extends AbstractRepository class DateRepository extends AbstractRepository
{ {}
/**
* @param Product $product
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getDateRange(Product $product = null)
{
$qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb
->addSelectLiteral('MIN(date_start) dateRangeFrom')
->addSelectLiteral('MAX(date_end) dateRangeTo')
->from('tx_epproducts_domain_model_date', 'date')
->where('date_start >= NOW()')
->andWhere('product_searchable = 1')
;
if ($product !== null) {
$query
->andWhere('product = :productUid')
->setParameter('productUid', $product->getUid())
;
}
$dates = $query->execute()->fetchAssociative();
if ($dates['dateRangeFrom'] !== null && $dates['dateRangeTo'] !== null) {
$dateRangeFrom = \DateTime::createFromFormat('Y-m-d', $dates['dateRangeFrom']);
$dateRangeTo = \DateTime::createFromFormat('Y-m-d', $dates['dateRangeTo']);
} else {
$dateRangeFrom = new \DateTime('now');
$dateRangeTo = clone $dateRangeFrom;
$dateRangeTo->add(new \DateInterval('P1Y'));
}
return [$dateRangeFrom, $dateRangeTo];
}
/**
* @param string $search
* @param array $filterSettings
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function searchHotels($search, array $filterSettings)
{
$qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb
->select('hotel as uid')
->addSelectLiteral('REPLACE(hotel_name, "\r\n", " ") name')
->from('tx_epproducts_domain_model_date', 'date')
->where('product_searchable = 1')
->andWhere($qb->expr()->orX(
$qb->expr()->like('hotel_name',':searchName'),
$qb->expr()->like('hotel_keywords', ':searchKeywords')
))
->orderBy('hotel_name')
->groupBy('hotel_name')
->setParameters([
'searchName' => '%' . $search . '%',
'searchKeywords' => '%' . $search . '%'
])
;
$this->addDateFilterConditions($query, $filterSettings);
$this->addDurationFilterConditions($query, $filterSettings);
$this->addPaxFilterConditions($query, $filterSettings);
$this->addConceptFilterConditions($query, $filterSettings);
return $query->execute()->fetchAllAssociative();
}
/**
* @param string $search
* @param array $filterSettings
* @param array $excludedConceptUids
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function searchProducts($search, array $filterSettings, $excludedConceptUids = [])
{
$qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb
->select('product as uid')
->addSelectLiteral('CONCAT(REPLACE(product_name, "\r\n", " "), " (", concept_name, ")") as name')
->from('tx_epproducts_domain_model_date', 'date')
->where('product_searchable = 1')
->andWhere($qb->expr()->orX(
$qb->expr()->like('product_name',':searchName'),
$qb->expr()->like('product_keywords', ':searchKeywords'),
$qb->expr()->like('country_name',':searchKeywords'),
$qb->expr()->like('country_keywords', ':searchKeywords'),
$qb->expr()->like('region_name', ':searchKeywords'),
$qb->expr()->like('region_keywords', ':searchKeywords'),
$qb->expr()->like('city_name', ':searchKeywords'),
$qb->expr()->like('city_keywords', ':searchKeywords')
))
->orderBy('product_name')
->groupBy('product_name')
->setParameters([
'searchName' => '%' . $search . '%',
'searchKeywords' => '%' . $search . '%'
])
;
if (count($excludedConceptUids) > 0) {
$qb
->andWhere('concept NOT IN (:excludedConceptUids)')
->setParameter('excludedConceptUids', $excludedConceptUids, Connection::PARAM_INT_ARRAY)
;
}
$this->addDateFilterConditions($query, $filterSettings);
$this->addDurationFilterConditions($query, $filterSettings);
$this->addPaxFilterConditions($query, $filterSettings);
$this->addConceptFilterConditions($query, $filterSettings);
return $query->execute()->fetchAllAssociative();
}
/**
* @param string $type
* @param string $search
* @param array $filterSettings
* @param array $excludedRegionUids
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function searchDestinations($type, $search, array $filterSettings, $excludedRegionUids = [])
{
$qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb
->select($type . ' as uid')
->addSelectLiteral('REPLACE(' . $type . '_name, "\r\n", " ") as name')
->from('tx_epproducts_domain_model_date', 'date')
->where('product_searchable = 1')
->andWhere($qb->expr()->orX(
$qb->expr()->like($type . '_name',':searchName'),
$qb->expr()->like($type . '_keywords', ':searchKeywords')
))
->orderBy($type . '_name')
->groupBy($type . '_name')
->setParameters([
'searchName' => '%' . $search . '%',
'searchKeywords' => '%' . $search . '%'
])
;
$this->addDateFilterConditions($query, $filterSettings);
$this->addDurationFilterConditions($query, $filterSettings);
$this->addPaxFilterConditions($query, $filterSettings);
$this->addConceptFilterConditions($query, $filterSettings);
if (count($excludedRegionUids) > 0) {
$query
->andWhere('date.region NOT IN (:excludedRegionUids)')
->setParameter('excludedRegionUids', $excludedRegionUids, Connection::PARAM_INT_ARRAY)
;
}
return $query->execute()->fetchAllAssociative();
}
}
@@ -2,31 +2,6 @@
namespace EP\EpProducts\Domain\Repository; namespace EP\EpProducts\Domain\Repository;
/***************************************************************
*
* Copyright notice
*
* (c) 2016 Björn Fromme <[email protected]>, dreipunktnull
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use EP\EpProducts\Domain\Model\Date; use EP\EpProducts\Domain\Model\Date;
use EP\EpProducts\Domain\Model\Hotel; use EP\EpProducts\Domain\Model\Hotel;
use EP\EpProducts\Domain\Model\Product; use EP\EpProducts\Domain\Model\Product;
@@ -34,21 +9,14 @@ use TYPO3\CMS\Core\Database\Connection;
class ProductRepository extends AbstractRepository class ProductRepository extends AbstractRepository
{ {
public function getWatchlist(array $productUids, array $hotelUids): array
/**
* @param array $productUids
* @param array $hotelUids
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getWatchlist(array $productUids, array $hotelUids)
{ {
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb $qb
->select( ->select(
'date.concept as conceptUid', 'date.concept_name as conceptName', 'date.concept_code as conceptCode', 'date.concept as conceptUid', 'date.concept_name as conceptName',
'date.product as productUid', 'date.product_name as productName', 'date.concept_code as conceptCode', 'date.product as productUid', 'date.product_name as productName',
'date.product_detail_page as productDetailPage', 'date.product_feature as productFeature', 'date.product_detail_page as productDetailPage', 'date.product_feature as productFeature',
'date.country as countryUid','date.country_name as countryName', 'date.country_code as countryCode', 'date.country as countryUid','date.country_name as countryName', 'date.country_code as countryCode',
'date.region as regionUid', 'date.region_name as regionName', 'date.region_feature as regionFeature', 'date.region as regionUid', 'date.region_name as regionName', 'date.region_feature as regionFeature',
@@ -61,35 +29,36 @@ class ProductRepository extends AbstractRepository
'date.pseudo_price as pseudoPrice' 'date.pseudo_price as pseudoPrice'
) )
->from('tx_epproducts_domain_model_date', 'date') ->from('tx_epproducts_domain_model_date', 'date')
->where('date.product IN (:productUids)') ->where($qb->expr()->in(
->andWhere('date.hotel IN (:hotelUids)') 'date.product',
->andWhere('date.product_searchable = 1') $qb->createNamedParameter($productUids, Connection::PARAM_INT_ARRAY))
)
->andWhere($qb->expr()->in(
'date.hotel',
$qb->createNamedParameter($hotelUids, Connection::PARAM_INT_ARRAY))
)
->andWhere($qb->expr()->eq('date.product_searchable', 1))
->orderBy('date.concept_sorting') ->orderBy('date.concept_sorting')
->addOrderBy('date.product_name') ->addOrderBy('date.product_name')
->addOrderBy('date.min_price') ->addOrderBy('date.min_price')
->addOrderBy('date.date_start') ->addOrderBy('date.date_start')
->addOrderBy('date.hotel_name') ->addOrderBy('date.hotel_name')
->setParameter('productUids', $productUids, Connection::PARAM_INT_ARRAY)
->setParameter('hotelUids', $hotelUids, Connection::PARAM_INT_ARRAY)
; ;
return $query->execute()->fetchAllAssociative(); return $qb
->execute()
->fetchAllAssociative()
;
} }
/** public function getSearchResult(array $filterSettings, array $excludedConceptUids = []): array
* @param array $filterSettings
* @param array $excludedConceptUids
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getSearchResult(array $filterSettings, $excludedConceptUids = [])
{ {
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb $qb
->select( ->select(
'date.concept as conceptUid', 'date.concept_name as conceptName', 'date.concept_code as conceptCode', 'date.concept as conceptUid', 'date.concept_name as conceptName',
'date.concept_sorting as conceptSorting', 'date.concept_code as conceptCode', 'date.concept_sorting as conceptSorting',
'date.product as productUid', 'date.product_name as productName', 'date.product as productUid', 'date.product_name as productName',
'date.product_detail_page as productDetailPage', 'date.product_feature as productFeature', 'date.product_detail_page as productDetailPage', 'date.product_feature as productFeature',
'date.daytrip as daytrip', 'date.country as countryUid','date.country_name as countryName', 'date.daytrip as daytrip', 'date.country as countryUid','date.country_name as countryName',
@@ -108,7 +77,7 @@ class ProductRepository extends AbstractRepository
) )
->from('tx_epproducts_domain_model_date', 'date') ->from('tx_epproducts_domain_model_date', 'date')
->leftJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid') ->leftJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid')
->where('date.product_searchable = 1') ->where($qb->expr()->eq('date.product_searchable', 1))
->andWhere('date.date_start >= NOW()') ->andWhere('date.date_start >= NOW()')
->groupBy('date.product') ->groupBy('date.product')
->addGroupBy('date.hotel') ->addGroupBy('date.hotel')
@@ -123,29 +92,25 @@ class ProductRepository extends AbstractRepository
; ;
if (count($excludedConceptUids) > 0) { if (count($excludedConceptUids) > 0) {
$qb $qb->andWhere($qb->expr()->notIn(
->andWhere('concept NOT IN (:excludedConceptUids)') 'concept',
->setParameter('excludedConceptUids', $excludedConceptUids, Connection::PARAM_INT_ARRAY) $qb->createNamedParameter($excludedConceptUids, Connection::PARAM_INT_ARRAY))
; );
} }
$this->addFiltersettingsConditions($query, $filterSettings); $this->addFiltersettingsConditions($qb, $filterSettings);
return $query->execute()->fetchAllAssociative(); return $qb
->execute()
->fetchAllAssociative()
;
} }
/** public function getTeasers(array $filterSettings, array $excludedConceptUids = [], int $limit = 0): array
* @param array $filterSettings
* @param array $excludedConceptUids
* @param int $limit
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getTeasers(array $filterSettings, $excludedConceptUids = [], $limit = 0)
{ {
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb $qb
->select( ->select(
'product as productUid', 'product_name as productName', 'product_detail_page as productDetailPage', 'product as productUid', 'product_name as productName', 'product_detail_page as productDetailPage',
'product_feature as productFeature', 'product_teaser as productTeaser', 'product_fact as productFact', 'product_feature as productFeature', 'product_teaser as productTeaser', 'product_fact as productFact',
@@ -173,52 +138,55 @@ class ProductRepository extends AbstractRepository
->addOrderBy('date_start') ->addOrderBy('date_start')
; ;
if (null !== $filterSettings['productsPid']) {
$qb->andWhere($qb->expr()->eq(
'date.product_pid',
$qb->createNamedParameter($filterSettings['productsPid'], Connection::PARAM_INT))
);
}
if ($limit > 0) { if ($limit > 0) {
$query->setMaxResults($limit); $qb->setMaxResults($limit);
} }
if (empty($filterSettings['productUid'])) { if (empty($filterSettings['productUid'])) {
$query->andWhere('product_searchable = 1'); $qb->andWhere($qb->expr()->eq('product_searchable', 1));
} else { } else {
$query $qb->andWhere($qb->expr()->eq(
->andWhere('product = :productUid') 'product',
->setParameter('productUid', (int)$filterSettings['productUid']) $qb->createNamedParameter($filterSettings['productUid'], Connection::PARAM_INT))
; );
} }
$this->addDateFilterConditions($query, $filterSettings); $this->addDateFilterConditions($qb, $filterSettings);
$this->addHotelFilterConditions($query, $filterSettings); $this->addHotelFilterConditions($qb, $filterSettings);
$this->addCountryRegionAndCityFilterConditions($query, $filterSettings); $this->addCountryRegionAndCityFilterConditions($qb, $filterSettings);
$this->addConceptFilterConditions($query, $filterSettings); $this->addConceptFilterConditions($qb, $filterSettings);
$this->addTransportationFilterConditions($query, $filterSettings); $this->addTransportationFilterConditions($qb, $filterSettings);
if (count($excludedConceptUids) > 0) { if (count($excludedConceptUids) > 0) {
$qb $qb->andWhere($qb->expr()->notIn(
->andWhere('concept NOT IN (:excludedConceptUids)') 'concept',
->setParameter('excludedConceptUids', $excludedConceptUids, Connection::PARAM_INT_ARRAY) $qb->createNamedParameter($excludedConceptUids, Connection::PARAM_INT_ARRAY))
; );
} }
return $query->execute()->fetchAllAssociative(); return $qb
->execute()
->fetchAllAssociative()
;
} }
/** public function getPricetable(Product $product, Hotel $hotel, array $filterSettings, Date $date = null): array
* @param Product $product
* @param Hotel $hotel
* @param array $filterSettings
* @param Date $date
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getPricetable(Product $product, Hotel $hotel, array $filterSettings, Date $date = null)
{ {
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb $qb
->select( ->select(
'date.uid as dateUid', 'date.date_start as dateStart', 'date.date_end as dateEnd', 'date.bus_pro_id as dateBusProId', 'date.uid as dateUid', 'date.date_start as dateStart', 'date.date_end as dateEnd',
'date.hotel as hotelUid', 'date.hotel_bus_pro_id as hotelBusProId', 'date.bus_included as dateBusIncluded', 'date.bus_pro_id as dateBusProId', 'date.hotel as hotelUid', 'date.hotel_bus_pro_id as hotelBusProId',
'date.skipass_included as dateSkipassIncluded', 'date.season as season', 'date.bus_included as dateBusIncluded', 'date.skipass_included as dateSkipassIncluded',
'date.season as season',
'room.uid as roomUid', 'room.bus_pro_id as roomBusProId', 'room.name as roomName', 'room.uid as roomUid', 'room.bus_pro_id as roomBusProId', 'room.name as roomName',
'room.price as roomPrice', 'date.discount as roomDiscount', 'date.bus_price as busPrice', 'room.price as roomPrice', 'date.discount as roomDiscount', 'date.bus_price as busPrice',
'room.services as roomOptionalServices', 'room.nights as roomNights', 'room.available as roomAvailable' 'room.services as roomOptionalServices', 'room.nights as roomNights', 'room.available as roomAvailable'
@@ -229,38 +197,43 @@ class ProductRepository extends AbstractRepository
->addOrderBy('room.pax', 'ASC') ->addOrderBy('room.pax', 'ASC')
->addOrderBy('room.price', 'ASC') ->addOrderBy('room.price', 'ASC')
->where('date.date_start >= NOW()') ->where('date.date_start >= NOW()')
->andWhere('date.product = :product') ->andWhere($qb->expr()->eq(
->andWhere('date.hotel = :hotel') 'date.product',
->setParameters([ $qb->createNamedParameter($product->getUid(), Connection::PARAM_INT))
'product' => $product->getUid(), )
'hotel' => $hotel->getUid(), ->andWhere($qb->expr()->eq(
]) 'date.hotel',
$qb->createNamedParameter($hotel->getUid(), Connection::PARAM_INT))
)
; ;
if ($date !== null) { if (null !== $filterSettings['productsPid']) {
$query $qb->andWhere($qb->expr()->eq(
->andWhere('date.uid = :date') 'date.product_pid',
->setParameter('date', $date->getUid()) $qb->createNamedParameter($filterSettings['productsPid'], Connection::PARAM_INT))
; );
} }
$this->addFiltersettingsConditions($query, $filterSettings); if ($date !== null) {
$qb->andWhere($qb->expr()->eq(
'date.uid',
$qb->createNamedParameter($date->getUid(), Connection::PARAM_INT))
);
}
return $query->execute()->fetchAllAssociative(); $this->addFiltersettingsConditions($qb, $filterSettings);
return $qb
->execute()
->fetchAllAssociative()
;
} }
/** public function getAvailableDates(Product $product, Hotel $hotel, array $filterSettings): array
* @param Product $product
* @param Hotel $hotel
* @param array $filterSettings
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getAvailableDates(Product $product, Hotel $hotel, array $filterSettings)
{ {
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb $qb
->select( ->select(
'date.uid as dateUid', 'date.date_start as dateStart', 'date.date_end as dateEnd', 'date.uid as dateUid', 'date.date_start as dateStart', 'date.date_end as dateEnd',
'date.season as season', 'date.min_price as dateMinPrice', 'date.pseudo_price as datePseudoPrice', 'date.season as season', 'date.min_price as dateMinPrice', 'date.pseudo_price as datePseudoPrice',
@@ -275,61 +248,65 @@ class ProductRepository extends AbstractRepository
->orderBy('date.date_start', 'ASC') ->orderBy('date.date_start', 'ASC')
->addOrderBy('date.min_price', 'ASC') ->addOrderBy('date.min_price', 'ASC')
->where('date.date_start >= NOW()') ->where('date.date_start >= NOW()')
->andWhere('date.product = :product') ->andWhere($qb->expr()->eq(
->andWhere('date.hotel = :hotel') 'date.product',
$qb->createNamedParameter($product->getUid(), Connection::PARAM_INT))
)
->andWhere($qb->expr()->eq(
'date.hotel',
$qb->createNamedParameter($hotel->getUid(), Connection::PARAM_INT))
)
->groupBy('date.date_start') ->groupBy('date.date_start')
->setParameters([
'product' => $product->getUid(),
'hotel' => $hotel->getUid(),
])
; ;
$this->addFiltersettingsConditions($query, $filterSettings, true); if (null !== $filterSettings['productsPid']) {
$qb->andWhere($qb->expr()->eq(
'date.product_pid',
$qb->createNamedParameter($filterSettings['productsPid'], Connection::PARAM_INT))
);
}
return $query->execute()->fetchAllAssociative(); $this->addFiltersettingsConditions($qb, $filterSettings, true);
return $qb
->execute()
->fetchAllAssociative()
;
} }
/** public function hasDates(Product $product): bool
* @param Product $product
* @return bool
* @throws \Doctrine\DBAL\DBALException
*/
public function hasDates(Product $product)
{ {
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb $result = $qb
->select('date.uid') ->select('date.uid')
->from('tx_epproducts_domain_model_date', 'date') ->from('tx_epproducts_domain_model_date', 'date')
->where('date.product = :product') ->where($qb->expr()->eq(
->setParameter('product', $product->getUid()) 'date.product',
$qb->createNamedParameter($product->getUid(), Connection::PARAM_INT))
)
->setMaxResults(1) ->setMaxResults(1)
->execute() ->execute()
->fetchColumn() ->fetchOne()
; ;
return $query !== false; return $result !== false;
} }
/** public function getDatesForExport(Product $product, Hotel $hotel): array
* @param Product $product
* @param Hotel $hotel
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getDatesForExport(Product $product, Hotel $hotel)
{ {
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb $qb
->select( ->select(
'date.bus_pro_id as dateBusProId', 'date.date_start as dateStart', 'date.date_end as dateEnd', 'date.bus_pro_id as dateBusProId', 'date.date_start as dateStart', 'date.date_end as dateEnd',
'date.min_price as dateMinPrice', 'date.discount as dateDiscount', 'date.bus_price as busPrice', 'date.min_price as dateMinPrice', 'date.discount as dateDiscount', 'date.bus_price as busPrice',
'date.nights as dateNights', 'date.bus_included as dateBusIncluded', 'date.services_included as dateServicesIncluded', 'date.nights as dateNights', 'date.bus_included as dateBusIncluded', 'date.bus_price as busPrice',
'date.services_general as dateServicesGeneral', 'date.skipass_included as dateSkipassIncluded', 'date.services_included as dateServicesIncluded', 'date.services_general as dateServicesGeneral',
'date.bus_pro_id as dateBusProId', 'date.hotel_bus_pro_id as hotelBusProId', 'date.pickups as pickups', 'date.skipass_included as dateSkipassIncluded', 'date.bus_pro_id as dateBusProId',
'room.uid as roomUid', 'room.bus_pro_id as roomBusProId', 'room.code as roomCode', 'room.name as roomName', 'date.discount as roomDiscount', 'date.hotel_bus_pro_id as hotelBusProId', 'date.pickups as pickups',
'room.price as roomPrice', 'room.pax as roomPax', 'date.discount as roomDiscount', 'date.bus_price as busPrice', 'room.uid as roomUid', 'room.bus_pro_id as roomBusProId', 'room.code as roomCode',
'room.name as roomName', 'room.price as roomPrice', 'room.pax as roomPax',
'room.services as roomOptionalServices', 'room.nights as roomNights', 'room.available as roomAvailable' 'room.services as roomOptionalServices', 'room.nights as roomNights', 'room.available as roomAvailable'
) )
->from('tx_epproducts_domain_model_date', 'date') ->from('tx_epproducts_domain_model_date', 'date')
@@ -337,43 +314,49 @@ class ProductRepository extends AbstractRepository
->orderBy('date.date_start', 'ASC') ->orderBy('date.date_start', 'ASC')
->addOrderBy('date.min_price', 'ASC') ->addOrderBy('date.min_price', 'ASC')
->where('date.date_start >= NOW()') ->where('date.date_start >= NOW()')
->andWhere('date.product = :product') ->andWhere($qb->expr()->eq(
->andWhere('date.hotel = :hotel') 'date.product',
->setParameters([ $qb->createNamedParameter($product->getUid(), Connection::PARAM_INT))
'product' => $product->getUid(), )
'hotel' => $hotel->getUid(), ->andWhere($qb->expr()->eq(
]) 'date.hotel',
$qb->createNamedParameter($hotel->getUid(), Connection::PARAM_INT))
)
; ;
return $query->execute()->fetchAllAssociative(); return $qb
->execute()
->fetchAllAssociative()
;
} }
/** public function getEventPriceTable(Product $product): array
* @param Product $product
* @return array
* @throws \Doctrine\DBAL\DBALException
*/
public function getEventPriceTable(Product $product)
{ {
$qb = $this->getDbConnection()->createQueryBuilder(); $qb = $this->getDbConnection()->createQueryBuilder();
$query = $qb $qb
->select( ->select(
'date.bus_pro_id as dateBusProId', 'date.hotel_bus_pro_id as hotelBusProId', 'date.date_end as dateEnd', 'date.bus_pro_id as dateBusProId', 'date.hotel_bus_pro_id as hotelBusProId',
'date.hotel as hotelUid', 'date.hotel_name as hotelName', 'date.hotel_header_title as hotelTitle', 'date.date_end as dateEnd', 'date.hotel as hotelUid', 'date.hotel_name as hotelName',
'date.hotel_category as hotelCategory', 'date.hotel_header_title as hotelTitle', 'date.hotel_category as hotelCategory',
'room.pax as roomPax', 'room.price as roomPrice', 'room.available as available', 'room.pax as roomPax', 'room.price as roomPrice', 'room.available as available',
'room.pax as roomPax', 'room.price as roomPrice', 'room.available as available', 'room.pax as roomPax', 'room.price as roomPrice', 'room.available as available',
'hotel.detail_page as hotelDetailPageUid', 'hotel.short_name as hotelShortName', 'hotel.show_as_teaser as hotelShowAsTeaser' 'hotel.detail_page as hotelDetailPageUid', 'hotel.short_name as hotelShortName',
'hotel.show_as_teaser as hotelShowAsTeaser'
) )
->from('tx_epproducts_domain_model_date', 'date') ->from('tx_epproducts_domain_model_date', 'date')
->innerJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid') ->innerJoin('date', 'tx_epproducts_domain_model_room', 'room', 'room.date = date.uid')
->innerJoin('date', 'tx_epproducts_domain_model_hotel', 'hotel', 'hotel.uid = date.hotel') ->innerJoin('date', 'tx_epproducts_domain_model_hotel', 'hotel', 'hotel.uid = date.hotel')
->where('date.product = :productUid') ->where($qb->expr()->eq(
->setParameter('productUid', $product->getUid()) 'date.product',
$qb->createNamedParameter($product->getUid(), Connection::PARAM_INT))
)
; ;
return $query->execute()->fetchAllAssociative(); return $qb
->execute()
->fetchAllAssociative()
;
} }
} }
@@ -116,7 +116,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @return int * @return int
* @throws \Doctrine\DBAL\DBALException * @throws \Doctrine\DBAL\DBALException
*/ */
public function import($path) public function import($path): int
{ {
$this->db = $this->getDbConnection(); $this->db = $this->getDbConnection();
$this->getRoomMappings(); $this->getRoomMappings();
@@ -129,6 +129,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
$this->copyTables(); $this->copyTables();
$this->clearTempTables(); $this->clearTempTables();
$this->cacheService->clearPageCache(); $this->cacheService->clearPageCache();
return $dateCount; return $dateCount;
} }
@@ -147,13 +148,14 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* *
* @return bool * @return bool
*/ */
public function checkActiveUpload($path) public function checkActiveUpload($path): bool
{ {
$tempFile = $path . '/.pureftpd-upload.*'; $tempFile = $path . '/.pureftpd-upload.*';
return count(glob($tempFile)) > 0; return count(glob($tempFile)) > 0;
} }
public function parseXmlFilesForProducts($path) public function parseXmlFilesForProducts($path): int
{ {
$dateCount = 0; $dateCount = 0;
@@ -172,7 +174,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param string $file * @param string $file
* @return int * @return int
*/ */
public function parseProductXmlFile($file) public function parseProductXmlFile($file): int
{ {
if (!file_exists($file)) { if (!file_exists($file)) {
$this->logger->error('product xml not found', ['file' => $file]); $this->logger->error('product xml not found', ['file' => $file]);
@@ -193,60 +195,50 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
return $this->parseProduct($xmlData->reise[0]); return $this->parseProduct($xmlData->reise[0]);
} }
/** public function createTempTables(): void
* @throws \Doctrine\DBAL\DBALException
*/
public function createTempTables()
{ {
$this->db->exec('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_date_temp LIKE tx_epproducts_domain_model_date'); $this->db->executeStatement('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_date_temp LIKE tx_epproducts_domain_model_date');
$this->db->exec('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_room_temp LIKE tx_epproducts_domain_model_room'); $this->db->executeStatement('CREATE TABLE IF NOT EXISTS tx_epproducts_domain_model_room_temp LIKE tx_epproducts_domain_model_room');
} }
/** public function clearTables(): void
* @throws \Doctrine\DBAL\DBALException
*/
public function clearTables()
{ {
$this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_date'); $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_date');
$this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_room'); $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_room');
} }
/** public function copyTables(): void
* @throws \Doctrine\DBAL\DBALException
*/
public function copyTables()
{ {
$this->db->exec('INSERT INTO tx_epproducts_domain_model_date SELECT * FROM tx_epproducts_domain_model_date_temp'); $this->db->executeStatement('INSERT INTO tx_epproducts_domain_model_date SELECT * FROM tx_epproducts_domain_model_date_temp');
$this->db->exec('INSERT INTO tx_epproducts_domain_model_room SELECT * FROM tx_epproducts_domain_model_room_temp'); $this->db->executeStatement('INSERT INTO tx_epproducts_domain_model_room SELECT * FROM tx_epproducts_domain_model_room_temp');
} }
/** public function clearTempTables(): void
* @throws \Doctrine\DBAL\DBALException
*/
public function clearTempTables()
{ {
$this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_date_temp'); $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_date_temp');
$this->db->exec('TRUNCATE TABLE tx_epproducts_domain_model_room_temp'); $this->db->executeStatement('TRUNCATE TABLE tx_epproducts_domain_model_room_temp');
} }
/** /**
* @param \SimpleXMLElement $xmlProduct * @param \SimpleXMLElement $xmlProduct
* @return int * @return int
*/ */
protected function parseProduct(\SimpleXMLElement $xmlProduct) protected function parseProduct(\SimpleXMLElement $xmlProduct): int
{ {
$code = (string) $xmlProduct->attributes()['code']; $code = (string) $xmlProduct->attributes()['code'];
$busProId = (int) $xmlProduct->attributes()['idbuspro']; $busProId = (int) $xmlProduct->attributes()['idbuspro'];
$dateCount = 0; $dateCount = 0;
$sql = ' $sql = '
SELECT p.uid uid, p.daytrip daytrip, p.hide_booking_button, p.important important, p.name product_name, SELECT p.uid uid, p.pid pid, p.daytrip daytrip, p.hide_booking_button, p.important important,
p.searchable product_searchable, p.detail_page product_detail_page, p.keywords product_keywords, p.name product_name, p.searchable product_searchable, p.detail_page product_detail_page,
p.teaser product_teaser, p.feature product_feature, p.subline product_subline, p.country country, p.keywords product_keywords, p.teaser product_teaser, p.feature product_feature,
p.region region, p.city city, p.path_segment slug, p.season season, p.subline product_subline, p.country country, p.region region, p.city city, p.path_segment slug,
cnt.name country_name, cnt.code country_code, cnt.keywords country_keywords, r.name region_name, p.season season, p.concept concept,
r.keywords region_keywords, r.feature region_feature, c.name city_name, c.keywords city_keywords, cnt.name country_name, cnt.code country_code, cnt.keywords country_keywords, r.name region_name,
p.concept concept, con.name concept_name, con.code concept_code, con.sorting concept_sorting r.keywords region_keywords, r.feature region_feature,
c.name city_name, c.keywords city_keywords,
con.name concept_name, con.code concept_code, con.sorting concept_sorting
FROM tx_epproducts_domain_model_product p FROM tx_epproducts_domain_model_product p
INNER JOIN tx_epproducts_domain_model_country cnt ON p.country = cnt.uid INNER JOIN tx_epproducts_domain_model_country cnt ON p.country = cnt.uid
INNER JOIN tx_epproducts_domain_model_region r ON p.region = r.uid INNER JOIN tx_epproducts_domain_model_region r ON p.region = r.uid
@@ -285,7 +277,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param array $product * @param array $product
* @return int * @return int
*/ */
protected function parseDates(\SimpleXMLElement $xmlDate, array $product) protected function parseDates(\SimpleXMLElement $xmlDate, array $product): int
{ {
$dateCount = 0; $dateCount = 0;
foreach ($xmlDate->hotel as $xmlHotel) { foreach ($xmlDate->hotel as $xmlHotel) {
@@ -328,7 +320,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param \SimpleXMLElement $xmlDate * @param \SimpleXMLElement $xmlDate
* @return array * @return array
*/ */
protected function createDateRecord(array $product, \SimpleXMLElement $xmlDate) protected function createDateRecord(array $product, \SimpleXMLElement $xmlDate): array
{ {
$dateStart = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate->attributes()['termin']); $dateStart = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate->attributes()['termin']);
$dateEnd = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate->attributes()['bis']); $dateEnd = \DateTime::createFromFormat('d.m.Y', (string) $xmlDate->attributes()['bis']);
@@ -340,6 +332,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
$date = [ $date = [
'pid' => $this->pid, 'pid' => $this->pid,
'product' => $product['uid'], 'product' => $product['uid'],
'product_pid' => $product['pid'],
'product_name' => $product['product_name'], 'product_name' => $product['product_name'],
'product_fact' => $product['product_fact'], 'product_fact' => $product['product_fact'],
'product_searchable' => $product['product_searchable'], 'product_searchable' => $product['product_searchable'],
@@ -480,13 +473,14 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param array $date * @param array $date
* @return bool * @return bool
*/ */
protected function parseHotel(\SimpleXMLElement $xmlHotel, array &$date) protected function parseHotel(\SimpleXMLElement $xmlHotel, array &$date): bool
{ {
$code = (string) $xmlHotel->attributes()['code']; $code = (string) $xmlHotel->attributes()['code'];
$busProId = (string) $xmlHotel->attributes()['idbuspro']; $busProId = (string) $xmlHotel->attributes()['idbuspro'];
if (!array_key_exists($code, $this->hotelMappings)) { if (!array_key_exists($code, $this->hotelMappings)) {
$this->logger->warning('hotel not found', ['code' => $code]); $this->logger->warning('hotel not found', ['code' => $code]);
return false; return false;
} }
@@ -520,6 +514,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
$date['hotel_detail_page'] = $hotel['detail_page']; $date['hotel_detail_page'] = $hotel['detail_page'];
$date['earlybird'] = $hotel['earlybird']; $date['earlybird'] = $hotel['earlybird'];
$date['new'] = $hotel['new']; $date['new'] = $hotel['new'];
return true; return true;
} }
@@ -529,7 +524,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param array $date * @param array $date
* @param array $services * @param array $services
*/ */
protected function parseRooms(\SimpleXMLElement $xmlHotel, $hotelUid, array &$date, array $services) protected function parseRooms(\SimpleXMLElement $xmlHotel, $hotelUid, array &$date, array $services): void
{ {
$minPriceOverall = 0; $minPriceOverall = 0;
$minPriceAvailable = 0; $minPriceAvailable = 0;
@@ -557,10 +552,6 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
$available = (int) $roomXml->attributes()['verfuegbar']; $available = (int) $roomXml->attributes()['verfuegbar'];
$price = (int) $roomXml->attributes()['preis']; $price = (int) $roomXml->attributes()['preis'];
// Skip all unavailable rooms
// if (!$available) {
// continue;
// }
// Skip rooms with zero price _and_ zero availability. // Skip rooms with zero price _and_ zero availability.
if (!$available && !$price) { if (!$available && !$price) {
continue; continue;
@@ -623,7 +614,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param array $services * @param array $services
* @return int * @return int
*/ */
protected function determineDiscount(array $services) protected function determineDiscount(array $services): int
{ {
foreach ($services as $key => $section) { foreach ($services as $key => $section) {
foreach ($section as $service) { foreach ($section as $service) {
@@ -642,7 +633,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param bool $skipWithoutPrice * @param bool $skipWithoutPrice
* @return array * @return array
*/ */
protected function parseService(\SimpleXMLElement $xmlData, $serviceLabel, $skipWithoutPrice = false) protected function parseService(\SimpleXMLElement $xmlData, string $serviceLabel, bool $skipWithoutPrice = false): array
{ {
$data = []; $data = [];
$services = $xmlData->xpath($serviceLabel . '/leistung'); $services = $xmlData->xpath($serviceLabel . '/leistung');
@@ -703,7 +694,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param string $label * @param string $label
* @return array * @return array
*/ */
protected function parseSelectionGroup(\SimpleXMLElement $xmlDate, $label) protected function parseSelectionGroup(\SimpleXMLElement $xmlDate, string $label): array
{ {
$data = []; $data = [];
$selectionGroup = $xmlDate->xpath('selektiongruppe[@bezeichnung="' . $label . '"]/selektion'); $selectionGroup = $xmlDate->xpath('selektiongruppe[@bezeichnung="' . $label . '"]/selektion');
@@ -725,7 +716,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param array $services * @param array $services
* @param array $date * @param array $date
*/ */
protected function processBusConditions(array $services, array &$date) protected function processBusConditions(array $services, array &$date): void
{ {
if (!array_key_exists('BUS', $services)) { if (!array_key_exists('BUS', $services)) {
return; return;
@@ -738,7 +729,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
} }
} }
protected function getRoomMappings() protected function getRoomMappings(): void
{ {
$sql = 'SELECT code, type FROM tx_epproducts_domain_model_roommapping'; $sql = 'SELECT code, type FROM tx_epproducts_domain_model_roommapping';
$roomMappings = $this->db->fetchAllAssociative($sql); $roomMappings = $this->db->fetchAllAssociative($sql);
@@ -747,7 +738,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
} }
} }
protected function getHotelMappings() protected function getHotelMappings(): void
{ {
$sql = ' $sql = '
SELECT u.code code, u.uid uid, h.name name, h.type type, SELECT u.code code, u.uid uid, h.name name, h.type type,
@@ -787,9 +778,9 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
/** /**
* @param string $table * @param string $table
* @param int $uid * @param int $uid
* @return array * @return string
*/ */
protected function getTopFactForRecord($table, $uid) protected function getTopFactForRecord($table, $uid): string
{ {
$sql = ' $sql = '
SELECT f.name SELECT f.name
@@ -807,7 +798,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
* @param array $services * @param array $services
* @param array $list * @param array $list
*/ */
protected function addServices(array $services, array &$list) protected function addServices(array $services, array &$list): void
{ {
foreach ($services as $key => $section) { foreach ($services as $key => $section) {
if (!array_key_exists($key, $list)) { if (!array_key_exists($key, $list)) {
@@ -817,7 +808,7 @@ class DateImportService implements SingletonInterface, LoggerAwareInterface
} }
} }
protected function importPickups() protected function importPickups(): void
{ {
libxml_use_internal_errors (true); libxml_use_internal_errors (true);
$path = GeneralUtility::getFileAbsFileName('fileadmin/xmlexport/zustiege.xml'); $path = GeneralUtility::getFileAbsFileName('fileadmin/xmlexport/zustiege.xml');
@@ -2,37 +2,13 @@
namespace EP\EpProducts\Service; namespace EP\EpProducts\Service;
/***************************************************************
*
* Copyright notice
*
* (c) 2016 Björn Fromme <[email protected]>, dreipunktnull
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use EP\EpProducts\Domain\Model\Dto\FilterOptions; use EP\EpProducts\Domain\Model\Dto\FilterOptions;
use EP\EpProducts\Domain\Model\SearchResult; use EP\EpProducts\Domain\Model\SearchResult;
use EP\EpProducts\Domain\Repository\DateRepository; use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
class FilterService implements SingletonInterface class FilterService implements SingletonInterface
{ {
@@ -40,22 +16,23 @@ class FilterService implements SingletonInterface
public const DURATION_LONG = 5; public const DURATION_LONG = 5;
/** /**
* @var \EP\EpProducts\Domain\Repository\DateRepository * @var ConfigurationManagerInterface
*/ */
protected $dateRepository; protected $configurationManager;
/** /**
* @param DateRepository $dateRepository * @param ConfigurationManagerInterface $configurationManager
*/ */
public function __construct(DateRepository $dateRepository) public function __construct(ConfigurationManagerInterface $configurationManager)
{ {
$this->dateRepository = $dateRepository; $this->configurationManager = $configurationManager;
} }
public function getNormalizedFilterSettings(array $filterSettings = [], array $forcedConceptUids = []): array public function getNormalizedFilterSettings(array $filterSettings = [], array $forcedConceptUids = []): array
{ {
$optionsResolver = new OptionsResolver(); $optionsResolver = new OptionsResolver();
$optionsResolver->setDefaults([ $optionsResolver->setDefaults([
'productsPid' => null,
'priceRanges' => [], 'priceRanges' => [],
'countryUids' => [], 'countryUids' => [],
'regionUids' => [], 'regionUids' => [],
@@ -72,6 +49,22 @@ class FilterService implements SingletonInterface
'pax' => 0, 'pax' => 0,
'bus' => null, 'bus' => null,
]); ]);
foreach (['productsPid', 'hotelUid', 'productUid', 'nights', 'pax'] as $key) {
$optionsResolver->setNormalizer($key, function (Options $options, $value) {
return null !== $value ? (int)$value : null;
});
}
foreach (['priceRanges', 'countryUids', 'regionUids', 'cityUids', 'conceptUids', 'boardTypes', 'hotelTypes', 'roomTypes'] as $key) {
$optionsResolver->setNormalizer($key, function (Options $options, $value) {
if (empty($value)) {
return [];
}
return array_map('intval', $value);
});
}
$optionsResolver->setNormalizer('bus', function (Options $options, $value) {
return null !== $value ? (bool)$value : null;
});
$filterSettings = $optionsResolver->resolve($filterSettings); $filterSettings = $optionsResolver->resolve($filterSettings);
@@ -79,12 +72,15 @@ class FilterService implements SingletonInterface
array_push($filterSettings['conceptUids'], ...$forcedConceptUids); array_push($filterSettings['conceptUids'], ...$forcedConceptUids);
} }
$typoScriptSettings = $this->getTypoScriptSettings();
$filterSettings['productsPid'] = $typoScriptSettings['productsPid'] ? (int)$typoScriptSettings['productsPid'] : null;
return $filterSettings; return $filterSettings;
} }
public function getFilterSettingsFromSearchParams(array $searchParams, array $forcedConceptUids = []): array public function getFilterSettingsFromSearchParams(array $searchParams, array $forcedConceptUids = []): array
{ {
$filterSettings = $this->getNormalizedFilterSettings([], $forcedConceptUids); $filterSettings = [];
if ($searchParams['destinationType'] && $searchParams['destinationUid']) { if ($searchParams['destinationType'] && $searchParams['destinationUid']) {
switch ($searchParams['destinationType']) { switch ($searchParams['destinationType']) {
@@ -112,18 +108,18 @@ class FilterService implements SingletonInterface
$filterSettings['priceRanges'] = [ $searchParams['priceRange'] ]; $filterSettings['priceRanges'] = [ $searchParams['priceRange'] ];
} }
if ($searchParams['pax']) { if ($searchParams['pax']) {
$filterSettings['pax'] = (int)$searchParams['pax']; $filterSettings['pax'] = $searchParams['pax'];
} }
if ($searchParams['nights']) { if ($searchParams['nights']) {
$filterSettings['nights'] = (int)$searchParams['nights']; $filterSettings['nights'] = $searchParams['nights'];
} }
return $filterSettings; return $this->getNormalizedFilterSettings($filterSettings, $forcedConceptUids);
} }
public function getFilterSettingsFromStaticSearchParams(array $staticSearchParams): array public function getFilterSettingsFromStaticSearchParams(array $staticSearchParams): array
{ {
$filterSettings = $this->getNormalizedFilterSettings(); $filterSettings = [];
if (!empty($staticSearchParams['country'])) { if (!empty($staticSearchParams['country'])) {
$filterSettings['countryUids'] = [ $staticSearchParams['country'] ]; $filterSettings['countryUids'] = [ $staticSearchParams['country'] ];
@@ -132,7 +128,7 @@ class FilterService implements SingletonInterface
$filterSettings['regionUids'] = [ $staticSearchParams['region'] ]; $filterSettings['regionUids'] = [ $staticSearchParams['region'] ];
} }
if (!empty($staticSearchParams['concept'])) { if (!empty($staticSearchParams['concept'])) {
$filterSettings['conceptUids'] = GeneralUtility::trimExplode(',', $staticSearchParams['concept'], true); $filterSettings['conceptUids'] = GeneralUtility::intExplode(',', $staticSearchParams['concept'], true);
} }
if (!empty($staticSearchParams['hotel'])) { if (!empty($staticSearchParams['hotel'])) {
$filterSettings['hotelUid'] = $staticSearchParams['hotel']; $filterSettings['hotelUid'] = $staticSearchParams['hotel'];
@@ -141,10 +137,10 @@ class FilterService implements SingletonInterface
$filterSettings['productUid'] = $staticSearchParams['product']; $filterSettings['productUid'] = $staticSearchParams['product'];
} }
if (!empty($staticSearchParams['hotel_types'])) { if (!empty($staticSearchParams['hotel_types'])) {
$filterSettings['hotelTypes'] = GeneralUtility::trimExplode(',', $staticSearchParams['hotel_types'], true); $filterSettings['hotelTypes'] = GeneralUtility::intExplode(',', $staticSearchParams['hotel_types'], true);
} }
if (!empty($staticSearchParams['bus'])) { if (!empty($staticSearchParams['bus'])) {
$filterSettings['bus'] = (bool)$staticSearchParams['bus']; $filterSettings['bus'] = $staticSearchParams['bus'];
} }
if (!empty($staticSearchParams['date_from']) && $staticSearchParams['date_from'] !== '0000-00-00') { if (!empty($staticSearchParams['date_from']) && $staticSearchParams['date_from'] !== '0000-00-00') {
$filterSettings['dateFrom'] = $staticSearchParams['date_from']; $filterSettings['dateFrom'] = $staticSearchParams['date_from'];
@@ -152,11 +148,11 @@ class FilterService implements SingletonInterface
if (!empty($staticSearchParams['date_to']) && $staticSearchParams['date_to'] !== '0000-00-00') { if (!empty($staticSearchParams['date_to']) && $staticSearchParams['date_to'] !== '0000-00-00') {
$filterSettings['dateTo'] = $staticSearchParams['date_to']; $filterSettings['dateTo'] = $staticSearchParams['date_to'];
} }
if (!empty($staticSearchParams['pax']) && (int)$staticSearchParams['pax'] > 0) { if (!empty($staticSearchParams['pax']) && $staticSearchParams['pax'] > 0) {
$filterSettings['pax'] = (int)$staticSearchParams['pax']; $filterSettings['pax'] = $staticSearchParams['pax'];
} }
return $filterSettings; return $this->getNormalizedFilterSettings($filterSettings);
} }
public function collectFilterOptionsFromSearchResult(SearchResult $searchResult): FilterOptions public function collectFilterOptionsFromSearchResult(SearchResult $searchResult): FilterOptions
@@ -291,15 +287,16 @@ class FilterService implements SingletonInterface
public function getFiltersettingsFromSettings(array $settings): array public function getFiltersettingsFromSettings(array $settings): array
{ {
$filterSettings = $this->getNormalizedFilterSettings(); $filterSettings = [];
if (isset($settings['regionUid']) && (int) $settings['regionUid'] > 0) {
if (isset($settings['regionUid']) && (int)$settings['regionUid'] > 0) {
$filterSettings['regionUids'] = [ $settings['regionUid'] ]; $filterSettings['regionUids'] = [ $settings['regionUid'] ];
} elseif (isset($settings['countryUid']) && (int) $settings['countryUid'] > 0) { } elseif (isset($settings['countryUid']) && (int) $settings['countryUid'] > 0) {
$filterSettings['countryUids'] = [ $settings['countryUid'] ]; $filterSettings['countryUids'] = [ $settings['countryUid'] ];
} elseif (isset($settings['hotelUid']) && (int) $settings['hotelUid'] > 0) { } elseif (isset($settings['hotelUid']) && (int) $settings['hotelUid'] > 0) {
$filterSettings['hotelUid'] = $settings['hotelUid']; $filterSettings['hotelUid'] = $settings['hotelUid'];
} }
$conceptUids = GeneralUtility::trimExplode(',', $settings['conceptUid'], true); $conceptUids = GeneralUtility::intExplode(',', $settings['conceptUid'], true);
if ($conceptUids) { if ($conceptUids) {
$filterSettings['conceptUids'] = $conceptUids; $filterSettings['conceptUids'] = $conceptUids;
} }
@@ -317,10 +314,20 @@ class FilterService implements SingletonInterface
$filterSettings['bus'] = true; $filterSettings['bus'] = true;
} }
if (array_key_exists('hotelTypes', $settings)) { if (array_key_exists('hotelTypes', $settings)) {
$hotelTypes = GeneralUtility::trimExplode(',', $settings['hotelTypes'], true); $hotelTypes = GeneralUtility::intExplode(',', $settings['hotelTypes'], true);
$filterSettings['hotelTypes'] = $hotelTypes; $filterSettings['hotelTypes'] = $hotelTypes;
} }
return $filterSettings; return $this->getNormalizedFilterSettings($filterSettings);
} }
protected function getTypoScriptSettings(): array
{
$settings = $this
->configurationManager
->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
return $settings['plugin.']['tx_epproducts.']['settings.'];
}
} }
@@ -65,8 +65,7 @@ class ProductDataService implements SingletonInterface
HotelRepository $hotelRepository, HotelRepository $hotelRepository,
HotelImageService $hotelImageService, HotelImageService $hotelImageService,
ProductImageService $productImageService ProductImageService $productImageService
) ) {
{
$this->productRepository = $productRepository; $this->productRepository = $productRepository;
$this->hotelRepository = $hotelRepository; $this->hotelRepository = $hotelRepository;
$this->productImageService = $productImageService; $this->productImageService = $productImageService;
@@ -78,10 +77,11 @@ class ProductDataService implements SingletonInterface
* *
* @return array * @return array
*/ */
public function getTeaser(array $filterSettings) public function getTeaser(array $filterSettings): array
{ {
$teaserData = $this->productRepository->getTeasers($filterSettings); $teaserData = $this->productRepository->getTeasers($filterSettings);
$teasers = $this->preprocessTeasergroup($teaserData); $teasers = $this->preprocessTeasergroup($teaserData);
return reset($teasers); return reset($teasers);
} }
@@ -92,9 +92,10 @@ class ProductDataService implements SingletonInterface
* *
* @return array * @return array
*/ */
public function getTeasergroup(array $filterSettings, $excludedConceptUids = [], $limit = 0) public function getTeasergroup(array $filterSettings, array $excludedConceptUids = [], int $limit = 0): array
{ {
$teaserData = $this->productRepository->getTeasers($filterSettings, $excludedConceptUids); $teaserData = $this->productRepository->getTeasers($filterSettings, $excludedConceptUids);
return $this->preprocessTeasergroup($teaserData, $limit); return $this->preprocessTeasergroup($teaserData, $limit);
} }
@@ -104,12 +105,11 @@ class ProductDataService implements SingletonInterface
* *
* @return array * @return array
*/ */
public function preprocessTeasergroup(array $teaserData, $limit = 0) public function preprocessTeasergroup(array $teaserData, int $limit = 0): array
{ {
$data = []; $data = [];
foreach ($teaserData as $row) foreach ($teaserData as $row) {
{
if (!array_key_exists($row['productUid'], $data)) { if (!array_key_exists($row['productUid'], $data)) {
$data[$row['productUid']] = $this->createTeaserData($row); $data[$row['productUid']] = $this->createTeaserData($row);
} }
@@ -166,7 +166,7 @@ class ProductDataService implements SingletonInterface
* *
* @return array * @return array
*/ */
public function createTeaserData(array $teaserData) public function createTeaserData(array $teaserData): array
{ {
$hotelCategory = Hotel::$categoryLabels[$teaserData['hotelCategory']] ?? null; $hotelCategory = Hotel::$categoryLabels[$teaserData['hotelCategory']] ?? null;
@@ -2,31 +2,6 @@
namespace EP\EpProducts\Traits; namespace EP\EpProducts\Traits;
/***************************************************************
*
* Copyright notice
*
* (c) 2016 Björn Fromme <[email protected]>, dreipunktnull
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use EP\EpProducts\Service\FilterService; use EP\EpProducts\Service\FilterService;
use EP\EpProducts\Service\SearchResultService; use EP\EpProducts\Service\SearchResultService;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -35,10 +10,7 @@ use TYPO3\CMS\Extbase\Object\ObjectManager;
trait RequestArgumentTypeConversionTrait trait RequestArgumentTypeConversionTrait
{ {
/** public function processSearchParamsArgument(): void
* Converts array to searchparams object
*/
public function processSearchParamsArgument()
{ {
/** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */ /** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
$objectManager = GeneralUtility::makeInstance(ObjectManager::class); $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
@@ -58,11 +30,7 @@ trait RequestArgumentTypeConversionTrait
$this->request->setArgument('searchParams', $searchParams); $this->request->setArgument('searchParams', $searchParams);
} }
/** public function processFilterSettingsArgument(array $forcedConceptUids = []): void
* Converts urlencoded json or array to filtersettings object
* @param array $forcedConceptUids
*/
public function processFilterSettingsArgument(array $forcedConceptUids = [])
{ {
/** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */ /** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
$objectManager = GeneralUtility::makeInstance(ObjectManager::class); $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
@@ -24,6 +24,7 @@ plugin.tx_epproducts {
} }
} }
settings { settings {
productsPid = {$plugin.tx_epproducts.settings.productsStoragePid}
destinationsStoragePid = {$plugin.tx_epproducts.settings.destinationsStoragePid} destinationsStoragePid = {$plugin.tx_epproducts.settings.destinationsStoragePid}
snowReportStoragePid = {$plugin.tx_epproducts.settings.snowReportStoragePid} snowReportStoragePid = {$plugin.tx_epproducts.settings.snowReportStoragePid}
defaultSearchPageUid = {$plugin.tx_epproducts.settings.defaultSearchPageUid} defaultSearchPageUid = {$plugin.tx_epproducts.settings.defaultSearchPageUid}
@@ -123,6 +123,7 @@ CREATE TABLE tx_epproducts_domain_model_date
pseudo_price int(11) DEFAULT '0' NOT NULL, pseudo_price int(11) DEFAULT '0' NOT NULL,
available int(11) DEFAULT '0' NOT NULL, available int(11) DEFAULT '0' NOT NULL,
product int(11) unsigned DEFAULT '0', product int(11) unsigned DEFAULT '0',
product_pid int(11) unsigned DEFAULT '0',
daytrip tinyint(1) unsigned DEFAULT '0' NOT NULL, daytrip tinyint(1) unsigned DEFAULT '0' NOT NULL,
hide_booking_button tinyint(1) unsigned DEFAULT '0' NOT NULL, hide_booking_button tinyint(1) unsigned DEFAULT '0' NOT NULL,
important tinyint(1) unsigned DEFAULT '0' NOT NULL, important tinyint(1) unsigned DEFAULT '0' NOT NULL,
@@ -189,7 +190,7 @@ CREATE TABLE tx_epproducts_domain_model_date
l10n_diffsource mediumblob, l10n_diffsource mediumblob,
PRIMARY KEY (uid), PRIMARY KEY (uid),
KEY parent (pid), KEY parent (pid, product_pid),
KEY t3ver_oid (t3ver_oid, t3ver_wsid), KEY t3ver_oid (t3ver_oid, t3ver_wsid),
KEY language (l10n_parent, sys_language_uid), KEY language (l10n_parent, sys_language_uid),
KEY aggregates (date_start, date_end, min_price), KEY aggregates (date_start, date_end, min_price),