diff --git a/Bootstrap.php b/Bootstrap.php index 82894f7..1034a9b 100644 --- a/Bootstrap.php +++ b/Bootstrap.php @@ -1,48 +1,2 @@ -listen(HOOK_SMARTY_OUTPUTFILTER, [ApplePay::class, 'execute']); - - $this->listen(HOOK_BESTELLVORGANG_PAGE, [IncompletePaymentHandler::class, 'checkForIncompletePayment']); - - $this->listen(HOOK_BESTELLABSCHLUSS_INC_BESTELLUNGINDB, [Queue::class, 'bestellungInDB']); - - $this->listen(HOOK_INDEX_NAVI_HEAD_POSTGET, [Queue::class, 'headPostGet']); - - $this->listen(HOOK_BESTELLUNGEN_XML_BESTELLSTATUS, [Queue::class, 'xmlBestellStatus']); - - $this->listen(HOOK_BESTELLUNGEN_XML_BEARBEITESTORNO, [Queue::class, 'xmlBearbeiteStorno']); - - if (PluginHelper::getSetting('useCustomerAPI') === 'C') { - $this->listen(HOOK_CHECKBOX_CLASS_GETCHECKBOXFRONTEND, [Checkbox::class, 'execute']); - } - } -} +execute( - 'CREATE TABLE IF NOT EXISTS `xplugin_ws5_mollie_kunde` ( - `kKunde` int NOT NULL PRIMARY KEY, - `customerId` varchar(32) NOT NULL UNIQUE - ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;' - ); - } - - public function down() - { - $this->execute('DROP TABLE IF EXISTS `xplugin_ws5_mollie_kunde`'); - } - - public function getDescription(): string - { - return 'Customer Plugin-Tables (Shop<->Mollie)'; - } -} +execute( - 'CREATE TABLE IF NOT EXISTS `xplugin_ws5_mollie_orders` ( - `kId` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, - `kBestellung` int(11) DEFAULT NULL, - `cOrderId` varchar(32) COLLATE utf8_unicode_ci NOT NULL, - `cTransactionId` varchar(32) COLLATE utf8_unicode_ci NOT NULL, - `cThirdId` varchar(255) COLLATE utf8_unicode_ci NOT NULL, - `cStatus` varchar(32) COLLATE utf8_unicode_ci NOT NULL, - `cHash` varchar(32) COLLATE utf8_unicode_ci NOT NULL, - `bTest` tinyint(1) NOT NULL, - `bSynced` tinyint(1) NOT NULL DEFAULT 0, - `dModified` datetime NOT NULL, - `dCreated` datetime NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;' - ); - - $this->execute( - 'ALTER TABLE `xplugin_ws5_mollie_orders` - ADD UNIQUE KEY `cOrderId` (`cOrderId`), - ADD UNIQUE KEY `kBestellung` (`kBestellung`);' - ); - } - - public function down() - { - $this->execute('DROP TABLE IF EXISTS `xplugin_ws5_mollie_orders`'); - } - - public function getDescription(): string - { - return 'Order Plugin-Tables (Shop<->Mollie)'; - } -} +execute('ALTER TABLE `xplugin_ws5_mollie_orders` ADD `fAmount` float NULL AFTER `cHash`, ADD `fAmountRefunded` float NULL, ADD `cCurrency` VARCHAR(3), ADD `cLocale` VARCHAR(5), ADD `cBestellNr` VARCHAR(128), ADD `cMethod` VARCHAR(32) AFTER `fAmount`;'); - } - - /** - * @inheritDoc - */ - public function down() - { - $this->execute('ALTER TABLE `xplugin_ws5_mollie_orders` DROP `fAmount`, DROP `fAmountRefunded`, DROP `cCurrency`, DROP `cLocale`, DROP `cMethod`, DROP `cBestellNr`;'); - } - - public function getDescription(): string - { - return 'Extend Order Plugin-Tables (Shop<->Mollie)'; - } -} +execute('CREATE TABLE IF NOT EXISTS `xplugin_ws5_mollie_queue` ( - `kId` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, - `cType` VARCHAR(32) NOT NULL, - `cData` TEXT DEFAULT \'\', - `cResult` TEXT NULL DEFAULT NULL, - `dDone` DATETIME NULL DEFAULT NULL, - `dCreated` DATETIME NOT NULL, - `dModified` DATETIME NULL DEFAULT NULL - ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'); - } - - public function down() - { - $this->execute('DROP TABLE IF EXISTS `xplugin_ws5_mollie_queue`;'); - } - - public function getDescription(): string - { - return 'Queue Plugin-Table (WAWI<->Shop<->Mollie)'; - } -} +execute('CREATE TABLE IF NOT EXISTS `xplugin_ws5_mollie_shipments` ( - `kLieferschien` int(11) NOT NULL PRIMARY KEY, - `kBestellung` int(11) NOT NULL, - `cOrderId` VARCHAR(32) NOT NULL, - `cShipmentId` VARCHAR(32) NOT NULL, - `cCarrier` VARCHAR(255) DEFAULT \'\', - `cCode` VARCHAR(255) DEFAULT \'\', - `cUrl` VARCHAR(512) DEFAULT \'\', - `dCreated` DATETIME NOT NULL, - `dModified` DATETIME NULL DEFAULT NULL - ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;'); - } - - public function down() - { - $this->execute('DROP TABLE IF EXISTS `xplugin_ws5_mollie_shipments`;'); - } - - public function getDescription(): string - { - return 'Shipments-Table (WAWI<->Shop<->Mollie)'; - } -} +execute('ALTER TABLE `xplugin_ws5_mollie_orders` ADD `dReminder` datetime NULL;'); - } - - public function down() - { - $this->execute('ALTER TABLE `xplugin_ws5_mollie_orders` DROP `dReminder`;'); - } - - public function getDescription(): string - { - return 'adds Payment Reminder Column'; - } -} +execute('ALTER TABLE `xplugin_ws5_mollie_shipments` CHANGE `kLieferschien` `kLieferschein` int(11) NOT NULL FIRST;'); - } - - /** - * @inheritDoc - */ - public function down() - { - $this->execute('ALTER TABLE `xplugin_ws5_mollie_shipments` CHANGE `kLieferschein` `kLieferschien` int(11) NOT NULL FIRST;'); - } - - public function getDescription(): string - { - return "Fix 'shipments'-Column Typo"; - } -} +execute('ALTER TABLE `xplugin_ws5_mollie_queue` ADD `bLock` datetime NULL DEFAULT NULL;'); - } - - public function down() - { - $this->execute('ALTER TABLE `xplugin_ws5_mollie_queue` DROP `bLock`;'); - } - - public function getDescription(): string - { - return 'Lock rows in Queue.'; - } -} +execute('ALTER TABLE `xplugin_ws5_mollie_orders` CHANGE `cHash` `cHash` varchar(40) NOT NULL AFTER `cStatus`;'); - } - - public function down() - { - $this->execute('ALTER TABLE `xplugin_ws5_mollie_orders` CHANGE `cHash` `cHash` varchar(32) NOT NULL AFTER `cStatus`;'); - } - - public function getDescription(): string - { - return 'Extend Table orders[cHash] to 40 chars.'; - } -} +execute('ALTER TABLE `xplugin_ws5_mollie_queue` ADD `cError` text NULL AFTER `cResult`;'); - } - - public function down() - { - $this->execute('ALTER TABLE `xplugin_ws5_mollie_queue` DROP `cError`;'); - } - - public function getDescription(): string - { - return 'Extended Queue Table with Error-Field.'; - } -} +execute('ALTER TABLE `xplugin_ws5_mollie_orders` DROP INDEX `cOrderId`;'); - $this->execute('ALTER TABLE `xplugin_ws5_mollie_orders` DROP INDEX `kBestellung`;'); - $this->execute('ALTER TABLE `xplugin_ws5_mollie_orders` ADD UNIQUE(`kBestellung`, `cOrderId`);'); - } - - public function down() - { - // No need to change since 'xplugin_ws5_mollie_orders' is removed in Migration where it is created, and we don't support downgrading of Plugins - } - - public function getDescription(): string - { - return 'Fix UNIQUE Index on Orders-Table.'; - } -} +getLogService()->error($exception->getMessage()); -} +=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -1273,7 +1268,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -1281,7 +1276,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "netresearch/jsonmapper", @@ -1336,21 +1331,21 @@ }, { "name": "nikic/php-parser", - "version": "v4.18.0", + "version": "v4.19.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b", + "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.1" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", @@ -1386,9 +1381,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1" }, - "time": "2023-12-10T21:03:43+00:00" + "time": "2024-03-17T08:10:35+00:00" }, { "name": "openlss/lib-array2xml", @@ -1732,28 +1727,35 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", + "version": "5.4.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", + "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.1", "ext-filter": "*", - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7", "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" + "mockery/mockery": "~1.3.5", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^5.13" }, "type": "library", "extra": { @@ -1777,15 +1779,15 @@ }, { "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "email": "opensource@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1" }, - "time": "2021-10-19T17:43:47+00:00" + "time": "2024-05-21T05:55:05+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -1998,16 +2000,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.26.0", + "version": "1.29.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "231e3186624c03d7e7c890ec662b81e6b0405227" + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/231e3186624c03d7e7c890ec662b81e6b0405227", - "reference": "231e3186624c03d7e7c890ec662b81e6b0405227", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", "shasum": "" }, "require": { @@ -2039,9 +2041,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.26.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" }, - "time": "2024-02-23T16:05:55+00:00" + "time": "2024-05-31T08:52:43+00:00" }, { "name": "phpstan/phpstan", @@ -2402,16 +2404,16 @@ }, { "name": "phpunit/phpunit", - "version": "8.5.37", + "version": "8.5.38", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "fce30f306cee78be33ba00c8f9a853f41db0491b" + "reference": "1ecad678646c817a29e55a32c930f3601c3f5a8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fce30f306cee78be33ba00c8f9a853f41db0491b", - "reference": "fce30f306cee78be33ba00c8f9a853f41db0491b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1ecad678646c817a29e55a32c930f3601c3f5a8c", + "reference": "1ecad678646c817a29e55a32c930f3601c3f5a8c", "shasum": "" }, "require": { @@ -2480,7 +2482,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.37" + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.38" }, "funding": [ { @@ -2496,7 +2498,7 @@ "type": "tidelift" } ], - "time": "2024-03-06T06:27:42+00:00" + "time": "2024-04-05T04:31:23+00:00" }, { "name": "psr/cache", @@ -2706,12 +2708,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "bb15a6dc9a8493ace041a6de2929eb63ba0809ef" + "reference": "4a150f693df8f5d7b60a8557b15660a60b4d17bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/bb15a6dc9a8493ace041a6de2929eb63ba0809ef", - "reference": "bb15a6dc9a8493ace041a6de2929eb63ba0809ef", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/4a150f693df8f5d7b60a8557b15660a60b4d17bd", + "reference": "4a150f693df8f5d7b60a8557b15660a60b4d17bd", "shasum": "" }, "conflict": { @@ -2719,6 +2721,11 @@ "admidio/admidio": "<4.2.13", "adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3", "aheinze/cockpit": "<2.2", + "aimeos/ai-admin-graphql": ">=2022.04.1,<2022.10.10|>=2023.04.1,<2023.10.6|>=2024.04.1,<2024.04.6", + "aimeos/ai-admin-jsonadm": "<2020.10.13|>=2021.04.1,<2021.10.6|>=2022.04.1,<2022.10.3|>=2023.04.1,<2023.10.4|==2024.04.1", + "aimeos/ai-client-html": ">=2020.04.1,<2020.10.27|>=2021.04.1,<2021.10.22|>=2022.04.1,<2022.10.13|>=2023.04.1,<2023.10.15|>=2024.04.1,<2024.04.7", + "aimeos/ai-controller-frontend": "<2020.10.15|>=2021.04.1,<2021.10.8|>=2022.04.1,<2022.10.8|>=2023.04.1,<2023.10.9", + "aimeos/aimeos-core": ">=2022.04.1,<2022.10.17|>=2023.04.1,<2023.10.17|>=2024.04.1,<2024.04.7", "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5", "airesvsg/acf-to-rest-api": "<=3.1", "akaunting/akaunting": "<2.1.13", @@ -2727,7 +2734,7 @@ "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", "amazing/media2click": ">=1,<1.3.3", "amphp/artax": "<1.0.6|>=2,<2.0.6", - "amphp/http": "<1.0.1", + "amphp/http": "<=1.7.2|>=2,<=2.1", "amphp/http-client": ">=4,<4.4", "anchorcms/anchor-cms": "<=0.12.7", "andreapollastri/cipi": "<=3.1.15", @@ -2744,6 +2751,7 @@ "athlon1600/php-proxy-app": "<=3", "austintoddj/canvas": "<=3.4.2", "automad/automad": "<=1.10.9", + "automattic/jetpack": "<9.8", "awesome-support/awesome-support": "<=6.0.7", "aws/aws-sdk-php": "<3.288.1", "azuracast/azuracast": "<0.18.3", @@ -2758,14 +2766,19 @@ "barzahlen/barzahlen-php": "<2.0.1", "baserproject/basercms": "<5.0.9", "bassjobsen/bootstrap-3-typeahead": ">4.0.2", + "bbpress/bbpress": "<2.6.5", + "bcosca/fatfree": "<3.7.2", + "bedita/bedita": "<4", "bigfork/silverstripe-form-capture": ">=3,<3.1.1", "billz/raspap-webgui": "<2.9.5", "bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3", + "blueimp/jquery-file-upload": "==6.4.4", "bmarshall511/wordpress_zero_spam": "<5.2.13", "bolt/bolt": "<3.7.2", "bolt/core": "<=4.2", + "born05/craft-twofactorauthentication": "<3.3.4", "bottelet/flarepoint": "<2.2.1", - "bref/bref": "<2.1.13", + "bref/bref": "<2.1.17", "brightlocal/phpwhois": "<=4.2.5", "brotkrueml/codehighlight": "<2.7", "brotkrueml/schema": "<1.13.1|>=2,<2.5.1", @@ -2779,28 +2792,31 @@ "cardgate/magento2": "<2.0.33", "cardgate/woocommerce": "<=3.1.15", "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", + "cart2quote/module-quotation-encoded": ">=4.1.6,<=4.4.5|>=5,<5.4.4", "cartalyst/sentry": "<=2.1.6", "catfan/medoo": "<1.7.5", + "causal/oidc": "<2.1", "cecil/cecil": "<7.47.1", - "centreon/centreon": "<22.10.0.0-beta1", + "centreon/centreon": "<22.10.15", "cesnet/simplesamlphp-module-proxystatistics": "<3.1", "chriskacerguis/codeigniter-restserver": "<=2.7.1", "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3", "ckeditor/ckeditor": "<4.24", - "cockpit-hq/cockpit": "<=2.6.3|==2.7", + "cockpit-hq/cockpit": "<2.7|==2.7", "codeception/codeception": "<3.1.3|>=4,<4.1.22", "codeigniter/framework": "<3.1.9", - "codeigniter4/framework": "<=4.4.2", + "codeigniter4/framework": "<4.4.7", "codeigniter4/shield": "<1.0.0.0-beta8", "codiad/codiad": "<=2.8.4", - "composer/composer": "<1.10.27|>=2,<2.2.23|>=2.3,<2.7", - "concrete5/concrete5": "<9.2.7", + "composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7", + "concrete5/concrete5": "<9.2.8", "concrete5/core": "<8.5.8|>=9,<9.1", "contao-components/mediaelement": ">=2.14.2,<2.21.1", - "contao/contao": ">=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4", - "contao/core": ">=2,<3.5.39", - "contao/core-bundle": ">=3,<3.5.35|>=4,<4.9.42|>=4.10,<4.13.28|>=5,<5.1.10", - "contao/listing-bundle": ">=4,<4.4.8", + "contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4", + "contao/contao": ">=3,<3.5.37|>=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4", + "contao/core": "<3.5.39", + "contao/core-bundle": "<4.13.40|>=5,<5.3.4", + "contao/listing-bundle": ">=3,<=3.5.30|>=4,<4.4.8", "contao/managed-edition": "<=1.5", "corveda/phpsandbox": "<1.3.5", "cosenary/instagram": "<=2.3", @@ -2808,6 +2824,7 @@ "croogo/croogo": "<4", "cuyz/valinor": "<0.12", "czproject/git-php": "<4.0.3", + "dapphp/securimage": "<3.6.6", "darylldoyle/safe-svg": "<1.9.10", "datadog/dd-trace": ">=0.30,<0.30.2", "datatables/datatables": "<1.10.10", @@ -2817,26 +2834,28 @@ "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3", "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4", "desperado/xml-bundle": "<=0.1.7", + "devgroup/dotplant": "<2020.09.14-dev", "directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2", "doctrine/annotations": "<1.2.7", "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", "doctrine/common": "<2.4.3|>=2.5,<2.5.1", "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4", "doctrine/doctrine-bundle": "<1.5.2", - "doctrine/doctrine-module": "<=0.7.1", + "doctrine/doctrine-module": "<0.7.2", "doctrine/mongodb-odm": "<1.0.2", "doctrine/mongodb-odm-bundle": "<3.0.1", - "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", - "dolibarr/dolibarr": "<18.0.2", + "doctrine/orm": ">=1,<1.2.4|>=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", + "dolibarr/dolibarr": "<19.0.2", "dompdf/dompdf": "<2.0.4", "doublethreedigital/guest-entries": "<3.1.2", "drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.1.8|>=10.2,<10.2.2", "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", "duncanmcclean/guest-entries": "<3.1.2", "dweeves/magmi": "<=0.7.24", - "ec-cube/ec-cube": "<2.4.4", + "ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2", "ecodev/newsletter": "<=4", "ectouch/ectouch": "<=2.7.2", + "egroupware/egroupware": "<16.1.20170922", "elefant/cms": "<2.0.7", "elgg/elgg": "<3.3.24|>=4,<4.0.5", "elijaa/phpmemcacheadmin": "<=1.3", @@ -2857,26 +2876,30 @@ "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26", "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1", "ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12", - "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.34", + "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.35", "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8", "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev", "ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15", "ezsystems/ezplatform-user": ">=1,<1.0.1", "ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31", - "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.06,<=2019.03.5.1", + "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.03.5.1", "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3", "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15", "ezyang/htmlpurifier": "<4.1.1", "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", "facturascripts/facturascripts": "<=2022.08", + "fastly/magento2": "<1.2.26", "feehi/cms": "<=2.1.1", "feehi/feehicms": "<=2.1.1", "fenom/fenom": "<=2.12.1", "filegator/filegator": "<7.8", + "filp/whoops": "<2.1.13", + "fineuploader/php-traditional-server": "<=1.2.2", "firebase/php-jwt": "<6", "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2", "fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6", "flarum/core": "<1.8.5", + "flarum/flarum": "<0.1.0.0-beta8", "flarum/framework": "<1.8.5", "flarum/mentions": "<1.6.3", "flarum/sticky": ">=0.1.0.0-beta14,<=0.1.0.0-beta15", @@ -2889,33 +2912,37 @@ "fooman/tcpdf": "<6.2.22", "forkcms/forkcms": "<5.11.1", "fossar/tcpdf-parser": "<6.2.22", - "francoisjacquet/rosariosis": "<11", + "francoisjacquet/rosariosis": "<=11.5.1", "frappant/frp-form-answers": "<3.1.2|>=4,<4.0.2", "friendsofsymfony/oauth2-php": "<1.3", "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", - "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", + "friendsofsymfony/user-bundle": ">=1,<1.3.5", + "friendsofsymfony1/swiftmailer": ">=4,<5.4.13|>=6,<6.2.5", + "friendsofsymfony1/symfony1": ">=1.1,<1.15.19", "friendsoftypo3/mediace": ">=7.6.2,<7.6.5", "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6", - "froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.1", - "froxlor/froxlor": "<=2.1.1", + "froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.3", + "froxlor/froxlor": "<2.1.9", + "frozennode/administrator": "<=5.0.12", "fuel/core": "<1.8.1", "funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3", "gaoming13/wechat-php-sdk": "<=1.10.2", "genix/cms": "<=1.1.11", - "getgrav/grav": "<1.7.44", + "getformwork/formwork": "<1.13.1|==2.0.0.0-beta1", + "getgrav/grav": "<1.7.46", "getkirby/cms": "<4.1.1", "getkirby/kirby": "<=2.5.12", "getkirby/panel": "<2.5.14", "getkirby/starterkit": "<=3.7.0.2", "gilacms/gila": "<=1.15.4", - "gleez/cms": "<=1.2|==2", + "gleez/cms": "<=1.3|==2", "globalpayments/php-sdk": "<2", "gogentooss/samlbase": "<1.2.7", "google/protobuf": "<3.15", "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3", "gree/jose": "<2.2.1", "gregwar/rst": "<1.0.3", - "grumpydictator/firefly-iii": "<6.1.7", + "grumpydictator/firefly-iii": "<6.1.17", "gugoan/economizzer": "<=0.9.0.0-beta1", "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5", "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5", @@ -2930,18 +2957,20 @@ "httpsoft/http-message": "<1.0.12", "hyn/multi-tenant": ">=5.6,<5.7.2", "ibexa/admin-ui": ">=4.2,<4.2.3", - "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.4", + "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.6|>=4.6,<4.6.2", "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3", "ibexa/post-install": "<=1.0.4", "ibexa/solr": ">=4.5,<4.5.4", "ibexa/user": ">=4,<4.4.3", "icecoder/icecoder": "<=8.1", "idno/known": "<=1.3.1", + "ilicmiljan/secure-props": ">=1.2,<1.2.2", "illuminate/auth": "<5.5.10", - "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.99999|>=4.2,<=4.2.99999|>=5,<=5.0.99999|>=5.1,<=5.1.99999|>=5.2,<=5.2.99999|>=5.3,<=5.3.99999|>=5.4,<=5.4.99999|>=5.5,<=5.5.49|>=5.6,<=5.6.99999|>=5.7,<=5.7.99999|>=5.8,<=5.8.99999|>=6,<6.18.31|>=7,<7.22.4", + "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<6.18.31|>=7,<7.22.4", "illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40", "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", "illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75", + "imdbphp/imdbphp": "<=5.1.1", "impresscms/impresscms": "<=1.4.5", "impresspages/impresspages": "<=1.0.12", "in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3", @@ -2949,6 +2978,7 @@ "in2code/lux": "<17.6.1|>=18,<24.0.2", "innologi/typo3-appointments": "<2.0.6", "intelliants/subrion": "<4.2.2", + "inter-mediator/inter-mediator": "==5.5", "islandora/islandora": ">=2,<2.4.1", "ivankristianto/phpwhois": "<=4.3", "jackalope/jackalope-doctrine-dbal": "<1.7.4", @@ -2956,6 +2986,7 @@ "james-heinrich/phpthumb": "<1.7.12", "jasig/phpcas": "<1.3.3", "jcbrand/converse.js": "<3.3.3", + "johnbillion/wp-crontrol": "<1.16.2", "joomla/application": "<1.0.13", "joomla/archive": "<1.1.12|>=2,<2.0.1", "joomla/filesystem": "<1.6.2|>=2,<2.0.1", @@ -2968,40 +2999,45 @@ "jsdecena/laracom": "<2.0.9", "jsmitty12/phpwhois": "<5.1", "juzaweb/cms": "<=3.4", + "jweiland/events2": "<8.3.8|>=9,<9.0.6", "kazist/phpwhois": "<=4.2.6", "kelvinmo/simplexrd": "<3.1.1", "kevinpapst/kimai2": "<1.16.7", "khodakhah/nodcms": "<=3", - "kimai/kimai": "<2.1", + "kimai/kimai": "<2.16", "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", "klaviyo/magento2-extension": ">=1,<3", "knplabs/knp-snappy": "<=1.4.2", "kohana/core": "<3.3.3", "krayin/laravel-crm": "<1.2.2", "kreait/firebase-php": ">=3.2,<3.8.1", + "kumbiaphp/kumbiapp": "<=1.1.1", "la-haute-societe/tcpdf": "<6.2.22", "laminas/laminas-diactoros": "<2.18.1|==2.19|==2.20|==2.21|==2.22|==2.23|>=2.24,<2.24.2|>=2.25,<2.25.2", "laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1", "laminas/laminas-http": "<2.14.2", "laravel/fortify": "<1.11.1", "laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75", - "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", + "laravel/laravel": ">=5.4,<5.4.22", + "laravel/socialite": ">=1,<2.0.10", "latte/latte": "<2.10.8", - "lavalite/cms": "<=9", + "lavalite/cms": "<=9|==10.1", "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5", "league/commonmark": "<0.18.3", "league/flysystem": "<1.1.4|>=2,<2.1.1", "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3", "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", + "libreform/libreform": ">=2,<=2.0.8", "librenms/librenms": "<2017.08.18", "liftkit/database": "<2.13.2", + "lightsaml/lightsaml": "<1.3.5", "limesurvey/limesurvey": "<3.27.19", "livehelperchat/livehelperchat": "<=3.91", - "livewire/livewire": ">2.2.4,<2.2.6", + "livewire/livewire": ">2.2.4,<2.2.6|>=3.3.5,<3.4.9", "lms/routes": "<2.1.1", "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2", "luyadev/yii-helpers": "<1.2.1", - "magento/community-edition": "<2.4.3.0-patch3|>=2.4.4,<2.4.5", + "magento/community-edition": "<2.4.5|==2.4.5|>=2.4.5.0-patch1,<2.4.5.0-patch8|==2.4.6|>=2.4.6.0-patch1,<2.4.6.0-patch6|==2.4.7", "magento/core": "<=1.9.4.5", "magento/magento1ce": "<1.9.4.3-dev", "magento/magento1ee": ">=1,<1.14.4.3-dev", @@ -3009,10 +3045,11 @@ "magneto/core": "<1.9.4.4-dev", "maikuolan/phpmussel": ">=1,<1.6", "mainwp/mainwp": "<=4.4.3.3", - "mantisbt/mantisbt": "<2.26.1", + "mantisbt/mantisbt": "<2.26.2", "marcwillmann/turn": "<0.3.3", "matyhtf/framework": "<3.0.6", - "mautic/core": "<4.3", + "mautic/core": "<4.4.12|>=5.0.0.0-alpha,<5.0.4", + "mdanter/ecc": "<2", "mediawiki/core": "<1.36.2", "mediawiki/matomo": "<2.4.3", "mediawiki/semantic-media-wiki": "<4.0.2", @@ -3025,6 +3062,7 @@ "microsoft/microsoft-graph-beta": "<2.0.1", "microsoft/microsoft-graph-core": "<2.0.2", "microweber/microweber": "<=2.0.4", + "mikehaertl/php-shellcommand": "<1.6.1", "miniorange/miniorange-saml": "<1.4.3", "mittwald/typo3_forum": "<1.2.1", "mobiledetect/mobiledetectlib": "<2.8.32", @@ -3032,13 +3070,17 @@ "mojo42/jirafeau": "<4.4", "mongodb/mongodb": ">=1,<1.9.2", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<4.3.3", + "moodle/moodle": "<4.3.5|>=4.4.0.0-beta,<4.4.1", "mos/cimage": "<0.7.19", "movim/moxl": ">=0.8,<=0.10", + "movingbytes/social-network": "<=1.2.1", "mpdf/mpdf": "<=7.1.7", "munkireport/comment": "<4.1", "munkireport/managedinstalls": "<2.6", + "munkireport/munki_facts": "<1.5", "munkireport/munkireport": ">=2.5.3,<5.6.3", + "munkireport/reportdata": "<3.5", + "munkireport/softwareupdate": "<1.6", "mustache/mustache": ">=2,<2.14.1", "namshi/jose": "<2.2", "neoan3-apps/template": "<1.1.1", @@ -3046,8 +3088,8 @@ "neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", "neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3", "neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9", - "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2", - "neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", + "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2", + "neos/swiftmailer": "<5.4.5", "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", @@ -3055,38 +3097,46 @@ "nonfiction/nterchange": "<4.1.1", "notrinos/notrinos-erp": "<=0.7", "noumo/easyii": "<=0.9", + "novaksolutions/infusionsoft-php-sdk": "<1", "nukeviet/nukeviet": "<4.5.02", "nyholm/psr7": "<1.6.1", "nystudio107/craft-seomatic": "<3.4.12", + "nzedb/nzedb": "<0.8", "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1", "october/backend": "<1.1.2", "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1", "october/october": "<=3.4.4", "october/rain": "<1.0.472|>=1.1,<1.1.2", - "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.2", + "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.15", "omeka/omeka-s": "<4.0.3", "onelogin/php-saml": "<2.10.4", "oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5", "open-web-analytics/open-web-analytics": "<1.7.4", - "opencart/opencart": "<=3.0.3.7|>=4,<4.0.2.3-dev", + "opencart/opencart": "<=3.0.3.9|>=4", "openid/php-openid": "<2.3", "openmage/magento-lts": "<20.5", + "opensolutions/vimbadmin": "<=3.0.15", "opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2", "orchid/platform": ">=9,<9.4.4|>=14.0.0.0-alpha4,<14.5", "oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1", "oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1", "oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7", "oro/crm-call-bundle": ">=4.2,<=4.2.5|>=5,<5.0.4|>=5.1,<5.1.1", - "oro/customer-portal": ">=4.2,<=4.2.8|>=5,<5.0.11|>=5.1,<5.1.1", - "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<5.0.8", + "oro/customer-portal": ">=4.1,<=4.1.13|>=4.2,<=4.2.10|>=5,<=5.0.11|>=5.1,<=5.1.3", + "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<=5.0.12|>=5.1,<=5.1.3", "oxid-esales/oxideshop-ce": "<4.5", + "oxid-esales/paymorrow-module": ">=1,<1.0.2|>=2,<2.0.1", "packbackbooks/lti-1-3-php-library": "<5", "padraic/humbug_get_contents": "<1.1.2", "pagarme/pagarme-php": "<3", "pagekit/pagekit": "<=1.0.18", + "paragonie/ecc": "<2.0.1", "paragonie/random_compat": "<2", - "passbolt/passbolt_api": "<2.11", + "passbolt/passbolt_api": "<4.6.2", + "paypal/adaptivepayments-sdk-php": "<=3.9.2", + "paypal/invoice-sdk-php": "<=3.9", "paypal/merchant-sdk-php": "<3.12", + "paypal/permissions-sdk-php": "<=3.9.1", "pear/archive_tar": "<1.4.14", "pear/auth": "<1.2.4", "pear/crypt_gpg": "<1.6.7", @@ -3095,6 +3145,7 @@ "personnummer/personnummer": "<3.0.2", "phanan/koel": "<5.1.4", "phenx/php-svg-lib": "<0.5.2", + "php-censor/php-censor": "<2.0.13|>=2.1,<2.1.5", "php-mod/curl": "<2.3.2", "phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1", "phpems/phpems": ">=6,<=6.1.3", @@ -3102,7 +3153,8 @@ "phpmailer/phpmailer": "<6.5", "phpmussel/phpmussel": ">=1,<1.6", "phpmyadmin/phpmyadmin": "<5.2.1", - "phpmyfaq/phpmyfaq": "<3.2.5", + "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5", + "phpoffice/common": "<0.2.9", "phpoffice/phpexcel": "<1.8", "phpoffice/phpspreadsheet": "<1.16", "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36", @@ -3113,13 +3165,13 @@ "phpxmlrpc/extras": "<0.6.1", "phpxmlrpc/phpxmlrpc": "<4.9.2", "pi/pi": "<=2.5", - "pimcore/admin-ui-classic-bundle": "<1.3.4", + "pimcore/admin-ui-classic-bundle": "<=1.4.2", "pimcore/customer-management-framework-bundle": "<4.0.6", "pimcore/data-hub": "<1.2.4", "pimcore/demo": "<10.3", "pimcore/ecommerce-framework-bundle": "<1.0.10", "pimcore/perspective-editor": "<1.5.1", - "pimcore/pimcore": "<11.1.1", + "pimcore/pimcore": "<11.2.4", "pixelfed/pixelfed": "<0.11.11", "plotly/plotly.js": "<2.25.2", "pocketmine/bedrock-protocol": "<8.0.2", @@ -3131,7 +3183,7 @@ "prestashop/blockwishlist": ">=2,<2.1.1", "prestashop/contactform": ">=1.0.1,<4.3", "prestashop/gamification": "<2.3.2", - "prestashop/prestashop": "<8.1.4", + "prestashop/prestashop": "<8.1.6", "prestashop/productcomments": "<5.0.2", "prestashop/ps_emailsubscription": "<2.6.1", "prestashop/ps_facetedsearch": "<3.4.1", @@ -3140,13 +3192,15 @@ "processwire/processwire": "<=3.0.210", "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7", "propel/propel1": ">=1,<=1.7.1", - "pterodactyl/panel": "<1.7", + "pterodactyl/panel": "<1.11.6", "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2", "ptrofimov/beanstalk_console": "<1.7.14", "pubnub/pubnub": "<6.1", "pusher/pusher-php-server": "<2.2.1", "pwweb/laravel-core": "<=0.3.6.0-beta", "pyrocms/pyrocms": "<=3.9.1", + "qcubed/qcubed": "<=3.1.1", + "quickapps/cms": "<=2.0.0.0-beta2", "rainlab/blog-plugin": "<1.4.1", "rainlab/debugbar-plugin": "<3.1", "rainlab/user-plugin": "<=1.4.5", @@ -3156,7 +3210,7 @@ "really-simple-plugins/complianz-gdpr": "<6.4.2", "redaxo/source": "<=5.15.1", "remdex/livehelperchat": "<4.29", - "reportico-web/reportico": "<=7.1.21", + "reportico-web/reportico": "<=8.1", "rhukster/dom-sanitizer": "<1.0.7", "rmccue/requests": ">=1.6,<1.8", "robrichards/xmlseclibs": ">=1,<3.0.4", @@ -3171,10 +3225,10 @@ "serluck/phpwhois": "<=4.2.6", "sfroemken/url_redirect": "<=1.2.1", "sheng/yiicms": "<=1.2", - "shopware/core": "<=6.5.7.3", - "shopware/platform": "<=6.5.7.3|>=6.5.8,<6.5.8.7-dev", + "shopware/core": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1", + "shopware/platform": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1", "shopware/production": "<=6.3.5.2", - "shopware/shopware": "<=5.7.17", + "shopware/shopware": "<6.2.3", "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", "shopxo/shopxo": "<2.2.6", "showdoc/showdoc": "<2.10.4", @@ -3182,18 +3236,18 @@ "silverstripe/admin": "<1.13.19|>=2,<2.1.8", "silverstripe/assets": ">=1,<1.11.1", "silverstripe/cms": "<4.11.3", - "silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1", + "silverstripe/comments": ">=1.3,<3.1.1", "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", "silverstripe/framework": "<4.13.39|>=5,<5.1.11", "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3", "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1", "silverstripe/recipe-cms": ">=4.5,<4.5.3", "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1", - "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4", + "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4|>=2.1,<2.1.2", "silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1", "silverstripe/subsites": ">=2,<2.6.1", "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", - "silverstripe/userforms": "<3", + "silverstripe/userforms": "<3|>=5,<5.4.2", "silverstripe/versioned-admin": ">=1,<1.11.1", "simple-updates/phpwhois": "<=1", "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4|==5.0.0.0-alpha12", @@ -3208,34 +3262,37 @@ "slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1", "slim/slim": "<2.6", "slub/slub-events": "<3.0.3", - "smarty/smarty": "<3.1.48|>=4,<4.3.1", - "snipe/snipe-it": "<=6.2.2", + "smarty/smarty": "<4.5.3|>=5,<5.1.1", + "snipe/snipe-it": "<6.4.2", "socalnick/scn-social-auth": "<1.15.2", "socialiteproviders/steam": "<1.1", "spatie/browsershot": "<3.57.4", + "spatie/image-optimizer": "<1.7.3", "spipu/html2pdf": "<5.2.8", "spoon/library": "<1.4.1", "spoonity/tcpdf": "<6.2.22", "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", "ssddanbrown/bookstack": "<22.02.3", - "statamic/cms": "<4.46", + "statamic/cms": "<4.46|>=5.3,<5.6.2", "stormpath/sdk": "<9.9.99", "studio-42/elfinder": "<2.1.62", + "studiomitte/friendlycaptcha": "<0.1.4", "subhh/libconnect": "<7.0.8|>=8,<8.1", "sukohi/surpass": "<1", + "sulu/form-bundle": ">=2,<2.5.3", "sulu/sulu": "<1.6.44|>=2,<2.4.17|>=2.5,<2.5.13", "sumocoders/framework-user-bundle": "<1.4", "superbig/craft-audit": "<3.0.2", "swag/paypal": "<5.4.4", - "swiftmailer/swiftmailer": ">=4,<5.4.5", + "swiftmailer/swiftmailer": "<6.2.5", "swiftyedit/swiftyedit": "<1.2", "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", "sylius/grid-bundle": "<1.10.1", "sylius/paypal-plugin": ">=1,<1.2.4|>=1.3,<1.3.1", "sylius/resource-bundle": ">=1,<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4", - "sylius/sylius": "<1.9.10|>=1.10,<1.10.11|>=1.11,<1.11.2", - "symbiote/silverstripe-multivaluefield": ">=3,<3.0.99", + "sylius/sylius": "<1.9.10|>=1.10,<1.10.11|>=1.11,<1.11.2|>=1.12.0.0-alpha1,<1.12.16|>=1.13.0.0-alpha1,<1.13.1", + "symbiote/silverstripe-multivaluefield": ">=3,<3.1", "symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4", "symbiote/silverstripe-seed": "<6.0.3", "symbiote/silverstripe-versionedfiles": "<=2.0.3", @@ -3277,30 +3334,31 @@ "t3s/content-consent": "<1.0.3|>=2,<2.0.2", "tastyigniter/tastyigniter": "<3.3", "tcg/voyager": "<=1.4", - "tecnickcom/tcpdf": "<6.2.22", + "tecnickcom/tcpdf": "<=6.7.4", "terminal42/contao-tablelookupwizard": "<3.3.5", "thelia/backoffice-default-template": ">=2.1,<2.1.2", "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", - "thinkcmf/thinkcmf": "<=5.1.7", + "thinkcmf/thinkcmf": "<6.0.8", "thorsten/phpmyfaq": "<3.2.2", "tikiwiki/tiki-manager": "<=17.1", - "tinymce/tinymce": "<5.10.9|>=6,<6.7.3", + "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", + "tinymce/tinymce": "<7.2", "tinymighty/wiki-seo": "<1.2.2", "titon/framework": "<9.9.99", "tobiasbg/tablepress": "<=2.0.0.0-RC1", - "topthink/framework": "<6.0.14", + "topthink/framework": "<6.0.17|>=6.1,<6.1.5|>=8,<8.0.4", "topthink/think": "<=6.1.1", "topthink/thinkphp": "<=3.2.3", "torrentpier/torrentpier": "<=2.4.1", "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2", - "tribalsystems/zenario": "<=9.4.59197", + "tribalsystems/zenario": "<9.5.60602", "truckersmp/phpwhois": "<=4.3.1", "ttskch/pagination-service-provider": "<1", "twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3", "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", - "typo3/cms-core": "<=8.7.56|>=9,<=9.5.45|>=10,<=10.4.42|>=11,<=11.5.34|>=12,<=12.4.10|==13", + "typo3/cms-core": "<=8.7.56|>=9,<=9.5.47|>=10,<=10.4.44|>=11,<=11.5.36|>=12,<=12.4.14|>=13,<=13.1", "typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1", "typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1", "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", @@ -3319,15 +3377,23 @@ "userfrosting/userfrosting": ">=0.3.1,<4.6.3", "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", "uvdesk/community-skeleton": "<=1.1.1", + "uvdesk/core-framework": "<=1.1.1", "vanilla/safecurl": "<0.9.2", + "verbb/comments": "<1.5.5", + "verbb/formie": "<2.1.6", + "verbb/image-resizer": "<2.0.9", + "verbb/knock-knock": "<1.2.8", "verot/class.upload.php": "<=2.1.6", + "villagedefrance/opencart-overclocked": "<=1.11.1", "vova07/yii2-fileapi-widget": "<0.1.9", "vrana/adminer": "<4.8.1", + "vufind/vufind": ">=2,<9.1.1", "waldhacker/hcaptcha": "<2.1.2", "wallabag/tcpdf": "<6.2.22", "wallabag/wallabag": "<2.6.7", "wanglelecc/laracms": "<=1.0.3", "web-auth/webauthn-framework": ">=3.3,<3.3.4", + "web-feet/coastercms": "==5.5", "webbuilders-group/silverstripe-kapost-bridge": "<0.4", "webcoast/deferred-image-processing": "<1.0.2", "webklex/laravel-imap": "<5.3", @@ -3337,22 +3403,26 @@ "wikimedia/parsoid": "<0.12.2", "willdurand/js-translation-bundle": "<2.1.1", "winter/wn-backend-module": "<1.2.4", + "winter/wn-dusk-plugin": "<2.1", "winter/wn-system-module": "<1.2.4", - "wintercms/winter": "<1.2.3", - "woocommerce/woocommerce": "<6.6", + "wintercms/winter": "<=1.2.3", + "woocommerce/woocommerce": "<6.6|>=8.8,<8.8.5|>=8.9,<8.9.3", "wp-cli/wp-cli": ">=0.12,<2.5", "wp-graphql/wp-graphql": "<=1.14.5", + "wp-premium/gravityforms": "<2.4.21", "wpanel/wpanel4-cms": "<=4.3.1", "wpcloud/wp-stateless": "<3.2", - "wwbn/avideo": "<=12.4", + "wpglobus/wpglobus": "<=1.9.6", + "wwbn/avideo": "<14.3", "xataface/xataface": "<3", "xpressengine/xpressengine": "<3.0.15", + "yab/quarx": "<2.4.5", "yeswiki/yeswiki": "<4.1", "yetiforce/yetiforce-crm": "<=6.4", "yidashi/yii2cmf": "<=2", "yii2mod/yii2-cms": "<1.9.2", "yiisoft/yii": "<1.1.29", - "yiisoft/yii2": "<2.0.38", + "yiisoft/yii2": "<2.0.50", "yiisoft/yii2-authclient": "<2.2.15", "yiisoft/yii2-bootstrap": "<2.0.4", "yiisoft/yii2-dev": "<2.0.43", @@ -3377,9 +3447,9 @@ "zendframework/zend-http": "<2.8.1", "zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6", "zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3", - "zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2", + "zendframework/zend-mail": "<2.4.11|>=2.5,<2.7.2", "zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1", - "zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4", + "zendframework/zend-session": ">=2,<2.2.9|>=2.3,<2.3.4", "zendframework/zend-validator": ">=2.3,<2.3.6", "zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1", "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6", @@ -3438,7 +3508,7 @@ "type": "tidelift" } ], - "time": "2024-03-10T05:04:21+00:00" + "time": "2024-07-05T21:04:37+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -4170,16 +4240,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.9.0", + "version": "3.10.1", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b" + "reference": "8f90f7a53ce271935282967f53d0894f8f1ff877" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b", - "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/8f90f7a53ce271935282967f53d0894f8f1ff877", + "reference": "8f90f7a53ce271935282967f53d0894f8f1ff877", "shasum": "" }, "require": { @@ -4246,20 +4316,20 @@ "type": "open_collective" } ], - "time": "2024-02-16T15:06:51+00:00" + "time": "2024-05-22T21:24:41+00:00" }, { "name": "symfony/config", - "version": "v6.4.4", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "6ea4affc27f2086c9d16b92ab5429ce1e3c38047" + "reference": "12e7e52515ce37191b193cf3365903c4f3951e35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/6ea4affc27f2086c9d16b92ab5429ce1e3c38047", - "reference": "6ea4affc27f2086c9d16b92ab5429ce1e3c38047", + "url": "https://api.github.com/repos/symfony/config/zipball/12e7e52515ce37191b193cf3365903c4f3951e35", + "reference": "12e7e52515ce37191b193cf3365903c4f3951e35", "shasum": "" }, "require": { @@ -4305,7 +4375,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.4.4" + "source": "https://github.com/symfony/config/tree/v6.4.8" }, "funding": [ { @@ -4321,20 +4391,20 @@ "type": "tidelift" } ], - "time": "2024-02-26T07:52:26+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/console", - "version": "v6.4.4", + "version": "v6.4.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0d9e4eb5ad413075624378f474c4167ea202de78" + "reference": "6edb5363ec0c78ad4d48c5128ebf4d083d89d3a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78", - "reference": "0d9e4eb5ad413075624378f474c4167ea202de78", + "url": "https://api.github.com/repos/symfony/console/zipball/6edb5363ec0c78ad4d48c5128ebf4d083d89d3a9", + "reference": "6edb5363ec0c78ad4d48c5128ebf4d083d89d3a9", "shasum": "" }, "require": { @@ -4399,7 +4469,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.4" + "source": "https://github.com/symfony/console/tree/v6.4.9" }, "funding": [ { @@ -4415,20 +4485,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:10+00:00" + "time": "2024-06-28T09:49:33+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.4.4", + "version": "v6.4.9", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "6236e5e843cb763e9d0f74245678b994afea5363" + "reference": "a4df9dfe5da2d177af6643610c7bee2cb76a9f5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6236e5e843cb763e9d0f74245678b994afea5363", - "reference": "6236e5e843cb763e9d0f74245678b994afea5363", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a4df9dfe5da2d177af6643610c7bee2cb76a9f5e", + "reference": "a4df9dfe5da2d177af6643610c7bee2cb76a9f5e", "shasum": "" }, "require": { @@ -4480,7 +4550,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.4" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.9" }, "funding": [ { @@ -4496,20 +4566,20 @@ "type": "tidelift" } ], - "time": "2024-02-22T20:27:10+00:00" + "time": "2024-06-19T10:45:28+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { @@ -4518,7 +4588,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4547,7 +4617,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -4563,20 +4633,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.4.3", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef" + "reference": "8d7507f02b06e06815e56bb39aa0128e3806208b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ae9d3a6f3003a6caf56acd7466d8d52378d44fef", - "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8d7507f02b06e06815e56bb39aa0128e3806208b", + "reference": "8d7507f02b06e06815e56bb39aa0128e3806208b", "shasum": "" }, "require": { @@ -4627,7 +4697,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.8" }, "funding": [ { @@ -4643,20 +4713,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", "shasum": "" }, "require": { @@ -4666,7 +4736,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4703,7 +4773,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" }, "funding": [ { @@ -4719,20 +4789,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/filesystem", - "version": "v6.4.3", + "version": "v6.4.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb" + "reference": "b51ef8059159330b74a4d52f68e671033c0fe463" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", - "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b51ef8059159330b74a4d52f68e671033c0fe463", + "reference": "b51ef8059159330b74a4d52f68e671033c0fe463", "shasum": "" }, "require": { @@ -4740,6 +4810,9 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" + }, "type": "library", "autoload": { "psr-4": { @@ -4766,7 +4839,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.3" + "source": "https://github.com/symfony/filesystem/tree/v6.4.9" }, "funding": [ { @@ -4782,20 +4855,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-06-28T09:49:33+00:00" }, { "name": "symfony/finder", - "version": "v6.4.0", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" + "reference": "3ef977a43883215d560a2cecb82ec8e62131471c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", + "url": "https://api.github.com/repos/symfony/finder/zipball/3ef977a43883215d560a2cecb82ec8e62131471c", + "reference": "3ef977a43883215d560a2cecb82ec8e62131471c", "shasum": "" }, "require": { @@ -4830,7 +4903,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.0" + "source": "https://github.com/symfony/finder/tree/v6.4.8" }, "funding": [ { @@ -4846,20 +4919,20 @@ "type": "tidelift" } ], - "time": "2023-10-31T17:30:12+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.4.0", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "22301f0e7fdeaacc14318928612dee79be99860e" + "reference": "22ab9e9101ab18de37839074f8a1197f55590c1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22301f0e7fdeaacc14318928612dee79be99860e", - "reference": "22301f0e7fdeaacc14318928612dee79be99860e", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22ab9e9101ab18de37839074f8a1197f55590c1b", + "reference": "22ab9e9101ab18de37839074f8a1197f55590c1b", "shasum": "" }, "require": { @@ -4897,7 +4970,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.4.0" + "source": "https://github.com/symfony/options-resolver/tree/v6.4.8" }, "funding": [ { @@ -4913,20 +4986,20 @@ "type": "tidelift" } ], - "time": "2023-08-08T10:16:24+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "0424dff1c58f028c451efff2045f5d92410bd540" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540", + "reference": "0424dff1c58f028c451efff2045f5d92410bd540", "shasum": "" }, "require": { @@ -4976,7 +5049,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0" }, "funding": [ { @@ -4992,20 +5065,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a", + "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a", "shasum": "" }, "require": { @@ -5054,7 +5127,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0" }, "funding": [ { @@ -5070,20 +5143,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb", + "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb", "shasum": "" }, "require": { @@ -5135,7 +5208,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0" }, "funding": [ { @@ -5151,20 +5224,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c", + "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c", "shasum": "" }, "require": { @@ -5215,7 +5288,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0" }, "funding": [ { @@ -5231,20 +5304,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:30:46+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433", + "reference": "77fa7995ac1b21ab60769b7323d600a991a90433", "shasum": "" }, "require": { @@ -5295,7 +5368,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0" }, "funding": [ { @@ -5311,20 +5384,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-05-31T15:07:36+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.29.0", + "version": "v1.30.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/3fb075789fb91f9ad9af537c4012d523085bd5af", + "reference": "3fb075789fb91f9ad9af537c4012d523085bd5af", "shasum": "" }, "require": { @@ -5371,7 +5444,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.30.0" }, "funding": [ { @@ -5387,20 +5460,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-06-19T12:30:46+00:00" }, { "name": "symfony/process", - "version": "v6.4.4", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "710e27879e9be3395de2b98da3f52a946039f297" + "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/710e27879e9be3395de2b98da3f52a946039f297", - "reference": "710e27879e9be3395de2b98da3f52a946039f297", + "url": "https://api.github.com/repos/symfony/process/zipball/8d92dd79149f29e89ee0f480254db595f6a6a2c5", + "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5", "shasum": "" }, "require": { @@ -5432,7 +5505,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.4" + "source": "https://github.com/symfony/process/tree/v6.4.8" }, "funding": [ { @@ -5448,25 +5521,26 @@ "type": "tidelift" } ], - "time": "2024-02-20T12:31:00+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.1", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -5474,7 +5548,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -5514,7 +5588,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { @@ -5530,20 +5604,20 @@ "type": "tidelift" } ], - "time": "2023-12-26T14:02:43+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.4.3", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "416596166641f1f728b0a64f5b9dd07cceb410c1" + "reference": "63e069eb616049632cde9674c46957819454b8aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/416596166641f1f728b0a64f5b9dd07cceb410c1", - "reference": "416596166641f1f728b0a64f5b9dd07cceb410c1", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/63e069eb616049632cde9674c46957819454b8aa", + "reference": "63e069eb616049632cde9674c46957819454b8aa", "shasum": "" }, "require": { @@ -5576,7 +5650,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.4.3" + "source": "https://github.com/symfony/stopwatch/tree/v6.4.8" }, "funding": [ { @@ -5592,20 +5666,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:35:58+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/string", - "version": "v6.4.4", + "version": "v6.4.9", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9" + "reference": "76792dbd99690a5ebef8050d9206c60c59e681d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", - "reference": "4e465a95bdc32f49cf4c7f07f751b843bbd6dcd9", + "url": "https://api.github.com/repos/symfony/string/zipball/76792dbd99690a5ebef8050d9206c60c59e681d7", + "reference": "76792dbd99690a5ebef8050d9206c60c59e681d7", "shasum": "" }, "require": { @@ -5662,7 +5736,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.4" + "source": "https://github.com/symfony/string/tree/v6.4.9" }, "funding": [ { @@ -5678,20 +5752,20 @@ "type": "tidelift" } ], - "time": "2024-02-01T13:16:41+00:00" + "time": "2024-06-28T09:25:38+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.4.4", + "version": "v6.4.9", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "0bd342e24aef49fc82a21bd4eedd3e665d177e5b" + "reference": "f9a060622e0d93777b7f8687ec4860191e16802e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/0bd342e24aef49fc82a21bd4eedd3e665d177e5b", - "reference": "0bd342e24aef49fc82a21bd4eedd3e665d177e5b", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/f9a060622e0d93777b7f8687ec4860191e16802e", + "reference": "f9a060622e0d93777b7f8687ec4860191e16802e", "shasum": "" }, "require": { @@ -5699,6 +5773,8 @@ "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", @@ -5737,7 +5813,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.4.4" + "source": "https://github.com/symfony/var-exporter/tree/v6.4.9" }, "funding": [ { @@ -5753,7 +5829,7 @@ "type": "tidelift" } ], - "time": "2024-02-26T08:37:45+00:00" + "time": "2024-06-24T15:53:56+00:00" }, { "name": "theseer/tokenizer", diff --git a/frontend/hooks/131.php b/frontend/hooks/131.php index f395068..aa898d2 100644 --- a/frontend/hooks/131.php +++ b/frontend/hooks/131.php @@ -1,114 +1,2 @@ -select('tzahlungsession', 'cZahlungsID', $sessionHash); - if ($paymentSession && $paymentSession->kBestellung) { - $oBestellung = new \JTL\Checkout\Bestellung($paymentSession->kBestellung); - - if ( - \JTL\Shopsetting::getInstance() - ->getValue(CONF_KAUFABWICKLUNG, 'bestellabschluss_abschlussseite') === 'A' - ) { - $oBestellID = PluginHelper::getDB()->select('tbestellid', 'kBestellung', $paymentSession->kBestellung); - if ($oBestellID) { - $url = Shop::Container()->getLinkService()->getSpecialPage($linktype_ordercompleted)->getURL(); - header('Location: ' . $url . '?i=' . $oBestellID->cId); - exit(); - } - } - $oBestellstatus = PluginHelper::getDB()->select('tbestellstatus', 'kBestellung', (int) $paymentSession->kBestellung); - $url = Shop::Container()->getLinkService()->getSpecialPage($linktype_orderstatus)->getURL(); - header('Location: ' . $url . '?uid=' . $oBestellstatus->cUID); - exit(); - } - } - } else { - //eigentlich nicht notwendig, aber naja - ifndef('LINNKTYPE_BESTELLABSCHLUSS', 33); - $linktype_ordercompleted = (int) LINKTYP_BESTELLABSCHLUSS; - - - if (array_key_exists('hash', $_REQUEST) && (UrlHelper::urlHasSpecialPageLinkType($linktype_ordercompleted))) { - $sessionHash = trim(Text::htmlentities(Text::filterXSS($_REQUEST['hash'])), '_'); - $paymentSession = PluginHelper::getDB()->select('tzahlungsession', 'cZahlungsID', $sessionHash); - if ($paymentSession && $paymentSession->kBestellung) { - $oBestellung = new \JTL\Checkout\Bestellung($paymentSession->kBestellung); - - $oBestellID = PluginHelper::getDB()->select('tbestellid', 'kBestellung', $paymentSession->kBestellung); - if ($oBestellID) { - $url = Shop::Container()->getLinkService()->getSpecialPage($linktype_ordercompleted)->getURL(); - header('Location: ' . $url . '?i=' . $oBestellID->cId); - exit(); - } - - } - } - } - - - - - ifndef('MOLLIE_REMINDER_PROP', 10); - if (random_int(1, MOLLIE_REMINDER_PROP) % MOLLIE_REMINDER_PROP === 0) { - /** @noinspection PhpUndefinedConstantInspection */ - $lock = new ExclusiveLock('mollie_reminder', PFAD_ROOT . PFAD_COMPILEDIR); - if ($lock->lock()) { - AbstractCheckout::sendReminders(); - Queue::storno(PluginHelper::getSetting('autoStorno')); - } - } - - // TODO: DOKU - ifndef('MOLLIE_DISABLE_USER_CLEANUP', false); - - if (!MOLLIE_DISABLE_USER_CLEANUP) { - ifndef('MOLLIE_CLEANUP_PROP', 15); - /** @noinspection PhpUndefinedConstantInspection */ - if (MOLLIE_CLEANUP_PROP && random_int(1, MOLLIE_CLEANUP_PROP) % MOLLIE_CLEANUP_PROP === 0) { - QueueModel::cleanUp(); - } - } - if (array_key_exists('mollie_cleanup_cron', $_REQUEST)) { - exit((string) QueueModel::cleanUp()); - } -} catch (Exception $e) { - Shop::Container()->getLogService()->error($e->getMessage() . " (Trace: {$e->getTraceAsString()})"); -} +WebStollen GmbH https://www.webstollen.de 102 - 5.0.0 + 5.2.0 ws5_mollie 2023-02-13 - 1.5.0 - + 1.9.0 hooks/131.php @@ -510,6 +509,53 @@ dueDays + + Klarna + images/Payment_methods/klarnaOne@2x.png + 1 + 1 + Mollie + INVOICE + 1 + 0 + 1 + 0 + Klarna.php + Klarna + template/index.tpl + + Bezahle mit Klarna + Mollie + Bezahlen Sie bequem mit Klarna. + + + Pay with Klarna + Mollie + Pay with Klarna. + + + API + Welche API soll verwendet werden? + api + + + + + + AGB Checkbox für Klarna anzeigen + Klarna Integration konform mit Trusted Shops + trustedShopsCheckbox + + + + + + + Fälligkeit in Tagen + Wie lange hat der Kunde Zeit die Bestellung zu bezahlen? + dueDays + + SOFORT images/Payment_methods/sofort@2x.png @@ -1027,6 +1073,73 @@ dueDays + + Trustly + images/Payment_methods/trustly@2x.png + 1 + 1 + Mollie + DIRECT_E_BANKING + 1 + 0 + 1 + 0 + Trustly.php + Trustly + template/index.tpl + + trustly + Mollie + Bezahlen Sie bequem mit Trustly. + + + API + Welche API soll verwendet werden? + api + + + + + + + Fälligkeit in Tagen + Wie lange hat der Kunde Zeit die Bestellung zu bezahlen? (Order API) + dueDays + + + + Riverty + images/Payment_methods/riverty@2x.png + 1 + 1 + Mollie + INVOICE + 1 + 0 + 1 + 0 + Riverty.php + Riverty + template/index.tpl + + Riverty + Mollie + Bezahlen Sie bequem mit Riverty. + + + API + Welche API soll verwendet werden? + api + + + + + + Fälligkeit in Tagen + Wie lange hat der Kunde Zeit die Bestellung zu bezahlen? + dueDays + + diff --git a/lib/Checkout/AbstractCheckout.php b/lib/Checkout/AbstractCheckout.php index ee8a86d..f870850 100644 --- a/lib/Checkout/AbstractCheckout.php +++ b/lib/Checkout/AbstractCheckout.php @@ -1,805 +1,2 @@ -oBestellung = $oBestellung; - $this->api = $api; - } - - /** - * @param string $sessionHash - * @param string $id - * @param bool $test - * - * @throws ServiceNotFoundException - * @throws CircularReferenceException - * @return void - * - */ - public static function finalizeOrder(string $sessionHash, string $id, bool $test): void - { - $logger = Shop::Container()->getLogService(); - - try { - if ($paymentSession = PluginHelper::getDB()->select('tzahlungsession', 'cZahlungsID', $sessionHash)) { - if (session_id() !== $paymentSession->cSID) { - session_destroy(); - session_id($paymentSession->cSID); - $session = Frontend::getInstance(true, true); - } else { - $session = Frontend::getInstance(false, false); - } - - if ( - (!isset($_SESSION['Warenkorb']->PositionenArr, $paymentSession->nBezahlt, $paymentSession->kBestellung) - || !($paymentSession->nBezahlt && $paymentSession->kBestellung)) - && count($_SESSION['Warenkorb']->PositionenArr) - ) { - $paymentSession->cNotifyID = $id; - $paymentSession->dNotify = 'NOW()'; - - $api = new MollieAPI($test); - $mollie = strpos($id, 'tr_') === 0 ? - $api->getClient()->payments->get($id) : - $api->getClient()->orders->get($id, ['embed' => 'payments']); - - if (in_array($mollie->status, [OrderStatus::STATUS_PENDING, OrderStatus::STATUS_AUTHORIZED, OrderStatus::STATUS_PAID], true)) { - require_once PFAD_ROOT . PFAD_INCLUDES . 'bestellabschluss_inc.php'; - require_once PFAD_ROOT . PFAD_INCLUDES . 'mailTools.php'; - - $order = finalisiereBestellung(); - $session->cleanUp(); - $paymentSession->nBezahlt = 1; - $paymentSession->dZeitBezahlt = 'now()'; - } else { - throw new Exception('Mollie Status invalid: ' . $mollie->status . '\n' . print_r([$sessionHash, $id], 1)); - } - - if ($order->kBestellung) { - $paymentSession->kBestellung = $order->kBestellung; - PluginHelper::getDB()->update('tzahlungsession', 'cZahlungsID', $sessionHash, $paymentSession); - - try { - $checkout = self::fromID($id, false, $order); - } catch (Exception $e) { - if (strpos($id, 'tr_') === 0) { - $checkoutClass = PaymentCheckout::class; - } else { - $checkoutClass = OrderCheckout::class; - } - $checkout = new $checkoutClass($order, $api); - } - - if (strpos($mollie->id, 'ord_') === 0) { - /** @var Payment $payment */ - foreach ($mollie->payments() as $payment) { - if (in_array($payment->status, [PaymentStatus::STATUS_AUTHORIZED, PaymentStatus::STATUS_PAID, PaymentStatus::STATUS_PENDING])) { - $checkout->getModel()->cTransactionId = $payment->id; - $checkout->getModel()->save(); - } - } - } - - $checkout->updateOrderNumber() - ->handleNotification($sessionHash); - } else { - throw new Exception(sprintf('Bestellung nicht finalisiert: %s', print_r($order, 1))); - } - } else { - QueueModel::saveToQueue($_REQUEST['id'], $_REQUEST, 'webhook'); - - throw new Exception(sprintf('PaymentSession bereits bezahlt: %s - ID: %s => Queue', $sessionHash, $id)); - } - } else { - QueueModel::saveToQueue($_REQUEST['id'], $_REQUEST, 'webhook'); - - throw new Exception(sprintf('PaymentSession nicht gefunden: %s - ID: %s => Queue', $sessionHash, $id)); - } - } catch (Exception $e) { - $logger->notice(__NAMESPACE__ . ' finalize order:' . $e->getMessage()); - } - } - - /** - * @param string $id - * @param bool $bFill - * @param null|Bestellung $order - * @throws RuntimeException - * @return static - */ - public static function fromID(string $id, bool $bFill = true, Bestellung $order = null): self - { - /** @var OrderModel $model */ - $model = OrderModel::fromID($id, 'cOrderId', true); - - $oBestellung = $order; - if (!$oBestellung) { - if (!$model->kBestellung) { - throw new RuntimeException('Keine Bestell-ID hinterlegt.'); - } - $oBestellung = new Bestellung($model->kBestellung, $bFill); - } - - if (static::class !== __CLASS__) { - $self = new static($oBestellung, new MollieAPI($model->bTest)); - } elseif (strpos($model->cOrderId, 'tr_') !== false) { - $self = new PaymentCheckout($oBestellung, new MollieAPI($model->bTest)); - } else { - $self = new OrderCheckout($oBestellung, new MollieAPI($model->bTest)); - } - $self->setModel($model); - - return $self; - } - - /** - * Lädt das Model falls vorhanden, oder gibt eun neues leeres zurück - * - * @throws Exception - * @return OrderModel - */ - public function getModel(): OrderModel - { - if (!$this->model) { - $this->model = OrderModel::fromID($this->getBestellung()->kBestellung, 'kBestellung'); - $this->model->bTest = $this->getAPI()->isTest(); - } - - return $this->model; - } - - /** - * @return static - */ - protected function setModel(OrderModel $model): self - { - $this->model = $model; - - return $this; - } - - /** - * @throws Exception - * @return Bestellung - */ - public function getBestellung(): Bestellung - { - if (!$this->oBestellung && $this->getModel()->kBestellung) { - $this->oBestellung = new Bestellung($this->getModel()->kBestellung, true); - } - - return $this->oBestellung; - } - - /** - * @throws Exception - * @return MollieAPI - */ - public function getAPI(): MollieAPI - { - if (!$this->api) { - if ($this->getModel()->cOrderId) { - $this->api = new MollieAPI($this->getModel()->bTest); - } else { - $this->api = new MollieAPI(MollieAPI::getMode()); - } - } - - return $this->api; - } - - /** - * @param null|mixed $hash - * - * @throws CircularReferenceException - * @throws ServiceNotFoundException - * @throws Exception - * @return void - * - */ - public function handleNotification($hash = null): void - { - if (!$hash) { - $hash = $this->getModel()->cHash; - } - -// try{ -// $pm = $this->getPaymentMethod(); -// if(method_exists($pm, 'generatePUI') && ($pui = $pm->generatePUI($this))){ -// $this->getBestellung()->cPUIZahlungsdaten = $pui; -// $this->getBestellung()->updateInDB(); -// } -// }catch (\Exception $e){ -// -// } - - $this->updateModel()->saveModel(); - if (null === $this->getBestellung()->dBezahltDatum) { - if ($incoming = $this->getIncomingPayment()) { - $this->getPaymentMethod()->addIncomingPayment($this->getBestellung(), $incoming); - if ($this->completlyPaid()) { - $this->getPaymentMethod()->setOrderStatusToPaid($this->getBestellung()); - $this::makeFetchable($this->getBestellung(), $this->getModel()); - $this->getPaymentMethod()->deletePaymentHash($hash); - - $this->Log(sprintf("Checkout::handleNotification: Bestellung '%s' als bezahlt markiert: %.2f %s", $this->getBestellung()->cBestellNr, (float)$incoming->fBetrag, $incoming->cISO)); - - $oZahlungsart = PluginHelper::getDB()->selectSingleRow('tzahlungsart', 'cModulId', $this->getPaymentMethod()->moduleID); - if ($oZahlungsart && (int)$oZahlungsart->nMailSenden & ZAHLUNGSART_MAIL_EINGANG) { - $this->getPaymentMethod()->sendConfirmationMail($this->getBestellung()); - } - } else { - $this->Log(sprintf("Checkout::handleNotification: Bestellung '%s': nicht komplett bezahlt: %.2f %s", $this->getBestellung()->cBestellNr, (float)$incoming->fBetrag, $incoming->cISO), LOGLEVEL_ERROR); - } - } - } - - } - - /** - * Speichert das Model - * - * @throws Exception - * @return true - * - */ - public function saveModel(): bool - { - return $this->getModel()->save(); - } - - /** - * @throws Exception - * @return static - */ - public function updateModel(): self - { - if ($this->getMollie()) { - $this->getModel()->cOrderId = $this->getMollie()->id; - $this->getModel()->cLocale = $this->getMollie()->locale; - $this->getModel()->fAmount = $this->getMollie()->amount->value; - $this->getModel()->cMethod = $this->getMollie()->method; - $this->getModel()->cCurrency = $this->getMollie()->amount->currency; - $this->getModel()->cStatus = $this->getMollie()->status; - } - - // TODO: DOKU, Reminder Email, name der paymentmethod in array - if (!defined('MOLLIE_DISABLE_REMINDER')) { - define('MOLLIE_DISABLE_REMINDER', []); - } - if (is_array(MOLLIE_DISABLE_REMINDER) && $this->getModel()->cMethod && in_array($this->getModel()->cMethod, MOLLIE_DISABLE_REMINDER)) { - $this->getModel()->dReminder = date('Y-m-d H:i:s'); - } - - $this->getModel()->kBestellung = $this->getBestellung()->kBestellung ?: ModelInterface::NULL; - $this->getModel()->cBestellNr = $this->getBestellung()->cBestellNr; - $this->getModel()->bSynced = $this->getModel()->bSynced ?? !PluginHelper::getSetting('onlyPaid'); - - return $this; - } - - abstract public function getMollie(bool $force = false); - - /** - * @return stdClass - */ - abstract public function getIncomingPayment(): ?stdClass; - - /** - * @throws Exception - * @return FallbackMethod|MethodInterface|PaymentMethod|\Plugin\ws5_mollie\lib\PaymentMethod - */ - public function getPaymentMethod() - { - if (!$this->paymentMethod) { - if ($this->getBestellung()->Zahlungsart && strpos($this->getBestellung()->Zahlungsart->cModulId, "kPlugin_{$this::Plugin('ws5_mollie')->getID()}_") !== false) { - $this->paymentMethod = LegacyMethod::create($this->getBestellung()->Zahlungsart->cModulId); - } else { - $this->paymentMethod = LegacyMethod::create("kPlugin_{$this::Plugin('ws5_mollie')->getID()}_mollie"); - } - } - - return $this->paymentMethod; - } - - /** - * @throws Exception - * @return bool - */ - public function completlyPaid(): bool - { - if ( - $row = PluginHelper::getDB()->executeQueryPrepared('SELECT SUM(fBetrag) as fBetragSumme FROM tzahlungseingang WHERE kBestellung = :kBestellung', [ - ':kBestellung' => $this->oBestellung->kBestellung - ], 1) - ) { - return (float)$row->fBetragSumme >= ($this->oBestellung->fGesamtsumme * $this->getBestellung()->fWaehrungsFaktor); - } - - return false; - } - - /** - * @param Bestellung $oBestellung - * @param OrderModel $model - * @throws ServiceNotFoundException - * @throws CircularReferenceException - * @return bool - */ - public static function makeFetchable(Bestellung $oBestellung, OrderModel $model): bool - { - if ($oBestellung->cAbgeholt === 'Y' && !$model->bSynced) { - PluginHelper::getDB()->update('tbestellung', 'kBestellung', $oBestellung->kBestellung, (object)['cAbgeholt' => 'N']); - $model->bSynced = true; - - try { - return $model->save(); - } catch (Exception $e) { - Shop::Container()->getLogService()->error(sprintf('Fehler beim speichern des Models: %s / Bestellung: %s', $model->kId, $oBestellung->cBestellNr)); - } - } - - return false; - } - - /** - * @param $msg - * @param int $level - * @throws ServiceNotFoundException - * @throws CircularReferenceException - * @return $this - */ - public function Log(string $msg, $level = LOGLEVEL_NOTICE) - { - try { - $data = ''; - if ($this->getBestellung()) { - $data .= '#' . $this->getBestellung()->kBestellung; - } - if ($this->getMollie()) { - $data .= '$' . $this->getMollie()->id; - } - ZahlungsLog::add($this->getPaymentMethod()->moduleID, '[' . microtime(true) . ' - ' . $_SERVER['PHP_SELF'] . '] ' . $msg, $data, $level); - } catch (Exception $e) { - Shop::Container()->getLogService()->error(sprintf("Error while Logging: %s\nPrevious Error: %s", $e->getMessage(), $msg)); - } - - return $this; - } - - /** - * @return $this - */ - abstract protected function updateOrderNumber(); - - /** - * @param int $kBestellung - * @param bool $checkZA - * @return bool - */ - public static function isMollie(int $kBestellung, bool $checkZA = false): bool - { - if ($checkZA) { - $res = PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM tzahlungsart WHERE cModulId LIKE :cModulId AND kZahlungsart = :kZahlungsart', [ - ':kZahlungsart' => $kBestellung, - ':cModulId' => 'kPlugin_' . PluginHelper::getPlugin()->getID() . '%' - ], 1); - - return (bool)$res; - } - - return ($res = PluginHelper::getDB()->executeQueryPrepared('SELECT kId FROM xplugin_ws5_mollie_orders WHERE kBestellung = :kBestellung;', [ - ':kBestellung' => $kBestellung, - ], 1)) && $res->kId; - } - - /** - * @param Bestellung $oBestellung - * @param null|MollieAPI $api - * @return static - */ - public static function factory(Bestellung $oBestellung, MollieAPI $api = null): self - { - return new static($oBestellung, $api); - } - - /** - * @param int $kBestellung - * @param mixed $fill - * @return OrderCheckout|PaymentCheckout - */ - public static function fromBestellung(int $kBestellung, $fill = true) - { - $model = OrderModel::fromID($kBestellung, 'kBestellung', true); - - if (!$model->kBestellung) { - throw new RuntimeException(sprintf("Bestellung '%d' konnte nicht geladen werden.", $kBestellung)); - } - $oBestellung = new Bestellung($model->kBestellung, $fill); - if (!$oBestellung->kBestellung) { - throw new RuntimeException(sprintf("Bestellung '%d' konnte nicht geladen werden.", $kBestellung)); - } - if (strpos($model->cOrderId, 'tr_') !== false) { - $self = new PaymentCheckout($oBestellung, new MollieAPI($model->bTest)); - } else { - $self = new OrderCheckout($oBestellung, new MollieAPI($model->bTest)); - } - $self->setModel($model); - - return $self; - } - - /** - * @throws CircularReferenceException - * @throws ServiceNotFoundException - */ - public static function sendReminders(): void - { - $reminder = (int)PluginHelper::getSetting('reminder'); - - if (!$reminder) { - PluginHelper::getDB()->executeQueryPrepared('UPDATE xplugin_ws5_mollie_orders SET dReminder = :dReminder WHERE dReminder IS NULL', [ - ':dReminder' => date('Y-m-d H:i:s') - ], 3); - - return; - } - // TODO: DOKU - ifndef('MOLLIE_REMINDER_LIMIT_DAYS', 7); - $remindables = PluginHelper::getDB()->executeQueryPrepared("SELECT kId FROM xplugin_ws5_mollie_orders WHERE (dReminder IS NULL OR dReminder = '0000-00-00 00:00:00') AND dCreated > NOW() - INTERVAL " . MOLLIE_REMINDER_LIMIT_DAYS . " DAY AND dCreated < NOW() - INTERVAL :d MINUTE AND cStatus IN ('created','open', 'expired', 'failed', 'canceled')", [ - ':d' => $reminder - ], 2); - foreach ($remindables as $remindable) { - try { - self::sendReminder($remindable->kId); - } catch (Exception $e) { - Shop::Container()->getBackendLogService()->error('AbstractCheckout::sendReminders: ' . $e->getMessage()); - } - } - } - - /** - * @param $kID - * @param mixed $kId - * - * @throws Exception - * @return true - * - */ - public static function sendReminder($kId): bool - { - $order = OrderModel::fromID($kId, 'kId', true); - - // filter paid and storno - if (!$order->kBestellung || (int)$order->cStatus > BESTELLUNG_STATUS_IN_BEARBEITUNG || (int)$order->cStatus < 0) { - $order->dReminder = date('Y-m-d H:i:s'); - $order->save(); - - return true; - } - $oBestellung = new Bestellung($order->kBestellung); - $repayURL = Shop::getURL() . '/?m_pay=' . md5($order->kId . '-' . $order->kBestellung); - - $data = new stdClass(); - $data->tkunde = new Customer($oBestellung->kKunde); - if (!$data->tkunde->kKunde) { - $order->dReminder = date('Y-m-d H:i:s'); - $order->save(); - - throw new Exception("Kunde '$oBestellung->kKunde' nicht gefunden."); - } - $data->Bestellung = $oBestellung; - $data->PayURL = $repayURL; - $data->Amount = Preise::getLocalizedPriceString($order->fAmount, Currency::fromISO($order->cCurrency), false); - - $mailer = Shop::Container()->get(Mailer::class); - $mail = new Mail(); - $mail->createFromTemplateID('kPlugin_' . PluginHelper::getPlugin()->getID() . '_zahlungserinnerung', $data); - - $order->dReminder = date('Y-m-d H:i:s'); - $order->save(); - - if (!$mailer->send($mail)) { - throw new Exception($mail->getError() . "\n" . print_r([$data, $order->jsonSerialize()], 1)); - } - - return true; - } - - /** - * cancels oder refunds eine stornierte Bestellung - * - * @return string - */ - abstract public function cancelOrRefund(): string; - - /** - * @param array $options - * @throws Exception - * @return self - */ - public function loadRequest(array &$options = []) - { - if ($this->getBestellung()) { - $oKunde = !$this->getBestellung()->oKunde && $this->getPaymentMethod()->duringCheckout - ? $_SESSION['Kunde'] - : $this->getBestellung()->oKunde; - - $this->amount = new Amount($this->getBestellung() - ->fGesamtsumme * $this->getBestellung()->fWaehrungsFaktor, $this->getBestellung()->Waehrung, true); - $this->metadata = [ - 'kBestellung' => $this->getBestellung()->kBestellung, - 'kKunde' => $oKunde->kKunde, - 'kKundengruppe' => $oKunde->kKundengruppe, - 'cHash' => $this->getHash(), - ]; - - if ( - defined(get_class($this->getPaymentMethod()) . '::METHOD') && $this->getPaymentMethod()::METHOD !== '' - && (!PluginHelper::getSetting('resetMethod') || !$this->getMollie()) - ) { - $this->method = $this->getPaymentMethod()::METHOD; - } - - $this->redirectUrl = $this->getPaymentMethod()->duringCheckout ? - Shop::getURL() . '/bestellabschluss.php?' . http_build_query(['hash' => $this->getHash()]) : - $this->getPaymentMethod()->getReturnURL($this->getBestellung()); - - $this->webhookUrl = $this->getWebhookUrl(); - } - - $this->locale = Locale::getLocale(Frontend::get('cISOSprache', 'ger'), Frontend::getCustomer()->cLand); - - return $this; - } - - /** - * @throws Exception - * @return string - */ - public function getHash(): string - { - if ($this->getModel()->cHash) { - return $this->getModel()->cHash; - } - if (!$this->hash) { - $this->hash = $this->getPaymentMethod()->generateHash($this->getBestellung()); - } - - return $this->hash; - } - - /** - * @throws Exception - * @return string - */ - protected function getWebhookUrl(): string - { - $query = [ - 'mollie' => 1, - ]; - if ($this->getPaymentMethod()->duringCheckout) { - $query['hash'] = $this->getHash(); - $query['test'] = $this->getAPI()->isTest() ?: null; - } - - return Shop::getURL(true) . '/?' . http_build_query($query); - } - - /** - * @param array $paymentOptions - * @return Order|Payment - */ - abstract public function create(array $paymentOptions = []); - - /** - * @throws Exception - */ - public function storno(): void - { - if (in_array((int)$this->getBestellung()->cStatus, [BESTELLUNG_STATUS_OFFEN, BESTELLUNG_STATUS_IN_BEARBEITUNG], true)) { - require_once PFAD_ROOT . PFAD_INCLUDES . 'bestellabschluss_inc.php'; - - $log = []; - $conf = Shop::getSettings([CONF_GLOBAL]); - $nArtikelAnzeigefilter = (int)$conf['global']['artikel_artikelanzeigefilter']; - foreach ($this->getBestellung()->Positionen as $pos) { - if ($pos->kArtikel && $pos->Artikel && $pos->Artikel->cLagerBeachten === 'Y') { - $log[] = sprintf('Reset stock of "%s" by %d', $pos->Artikel->cArtNr, -1 * $pos->nAnzahl); - self::aktualisiereLagerbestand($pos->Artikel, -1 * $pos->nAnzahl, $pos->WarenkorbPosEigenschaftArr, $nArtikelAnzeigefilter); - } - } - $log[] = sprintf("Cancel order '%s'.", $this->getBestellung()->cBestellNr); - - if (PluginHelper::getDB()->executeQueryPrepared('UPDATE tbestellung SET cAbgeholt = "N", cStatus = :cStatus WHERE kBestellung = :kBestellung', [':cStatus' => '-1', ':kBestellung' => $this->getBestellung()->kBestellung], 3)) { - $this->Log(implode('\n', $log)); - } - } - } - - protected static function aktualisiereLagerbestand(Artikel $product, int $amount, array $attributeValues, int $productFilter = 1) - { - $inventory = $product->fLagerbestand; - $db = PluginHelper::getDB(); - if ($product->cLagerBeachten !== 'Y') { - return $inventory; - } - if ( - $product->cLagerVariation === 'Y' - && count($attributeValues) > 0 - ) { - foreach ($attributeValues as $value) { - $EigenschaftWert = new EigenschaftWert($value->kEigenschaftWert); - if ($EigenschaftWert->fPackeinheit == 0) { - $EigenschaftWert->fPackeinheit = 1; - } - $db->queryPrepared( - 'UPDATE teigenschaftwert - SET fLagerbestand = fLagerbestand - :inv - WHERE kEigenschaftWert = :aid', - [ - 'aid' => (int)$value->kEigenschaftWert, - 'inv' => $amount * $EigenschaftWert->fPackeinheit - ], - ReturnType::DEFAULT - ); - } - updateStock($product->kArtikel, $amount, $product->fPackeinheit); - } elseif ($product->fPackeinheit > 0) { - if ($product->kStueckliste > 0) { - $inventory = aktualisiereStuecklistenLagerbestand($product, $amount); - } else { - updateStock($product->kArtikel, $amount, $product->fPackeinheit); - $tmpProduct = $db->select( - 'tartikel', - 'kArtikel', - $product->kArtikel, - null, - null, - null, - null, - false, - 'fLagerbestand' - ); - if ($tmpProduct !== null) { - $inventory = (float)$tmpProduct->fLagerbestand; - } - // Stücklisten Komponente - if (Product::isStuecklisteKomponente($product->kArtikel)) { - aktualisiereKomponenteLagerbestand( - $product->kArtikel, - $inventory, - $product->cLagerKleinerNull === 'Y' - ); - } - } - // Aktualisiere Merkmale in tartikelmerkmal vom Vaterartikel - if ($product->kVaterArtikel > 0) { - Artikel::beachteVarikombiMerkmalLagerbestand($product->kVaterArtikel, $productFilter); - updateStock($product->kVaterArtikel, $amount, $product->fPackeinheit); - } - } - - return $inventory; - } - - /** - * @throws Exception - * @return string - * - */ - public function getDescription(): string - { - $descTemplate = trim(PluginHelper::getSetting('paymentDescTpl')) ?: 'Order {orderNumber}'; - $oKunde = $this->getBestellung()->oKunde ?: $_SESSION['Kunde']; - - return str_replace([ - '{orderNumber}', - '{storeName}', - '{customer.firstname}', - '{customer.lastname}', - '{customer.company}', - ], [ - $this->getBestellung()->cBestellNr, - Shopsetting::getInstance()->getValue(CONF_GLOBAL, 'global_shopname'), //Shop::getSettings([CONF_GLOBAL])['global']['global_shopname'], - $oKunde->cVorname, - $oKunde->cNachname, - $oKunde->cFirma - ], $descTemplate); - } - - /** - * @param Order|Payment $model - * @return $this; - */ - abstract protected function setMollie($model); -} +getModel()->cOrderId) { - try { - $this->order = $this->getAPI()->getClient()->orders->get($this->getModel()->cOrderId, ['embed' => 'payments']); - if (in_array($this->order->status, [OrderStatus::STATUS_COMPLETED, OrderStatus::STATUS_PAID, OrderStatus::STATUS_AUTHORIZED, OrderStatus::STATUS_PENDING], true)) { - $this->Log(PluginHelper::getPlugin()->getLocalization()->getTranslation('errAlreadyPaid')); - - return $this->order; - } - if ($this->order->status === OrderStatus::STATUS_CREATED) { - if ($this->order->payments()) { - /** @var Payment $payment */ - foreach ($this->order->payments() as $payment) { - if ($payment->status === PaymentStatus::STATUS_OPEN) { - $this->mollie = $payment; - - break; - } - } - } - if (!$this->mollie) { - $this->mollie = $this->getAPI()->getClient()->orderPayments->createForId($this->getModel()->cOrderId, $paymentOptions); - } - $this->updateModel()->saveModel(); - - return $this->getMollie(true); - } - } catch (Exception $e) { - $this->Log(sprintf("OrderCheckout::create: Letzte Order '%s' konnte nicht geladen werden: %s, versuche neue zu erstellen.", $this->getModel()->cOrderId, $e->getMessage()), LOGLEVEL_ERROR); - } - } - - try { - $this->order = $this->getAPI()->getClient()->orders->create($this->loadRequest($paymentOptions)->jsonSerialize()); - $this->updateModel()->saveModel(); - } catch (Exception $e) { - $this->Log(sprintf("OrderCheckout::create: Neue Order '%s' konnte nicht erstellt werden: %s.", $this->oBestellung->cBestellNr, $e->getMessage()), LOGLEVEL_ERROR); - - throw new RuntimeException(sprintf("OrderCheckout::create: Neue Order '%s' konnte nicht erstellt werden: %s.", $this->oBestellung->cBestellNr, $e->getMessage())); - } - - return $this->order; - } - - /** - * @throws Exception - * @return static - * - */ - public function updateModel(): AbstractCheckout - { - parent::updateModel(); - if (!$this->mollie && $this->getMollie() && $this->getMollie()->payments()) { - /** @var Payment $payment */ - foreach ($this->getMollie()->payments() as $payment) { - if (in_array($payment->status, [PaymentStatus::STATUS_OPEN, PaymentStatus::STATUS_PENDING, PaymentStatus::STATUS_AUTHORIZED, PaymentStatus::STATUS_PAID], true)) { - $this->mollie = $payment; - - break; - } - } - } - if ($this->mollie) { - $this->getModel()->cTransactionId = $this->mollie->id; - } - $this->getModel()->cStatus = $this->getMollie()->status; - $this->getModel()->cHash = $this->getHash(); - $this->getModel()->fAmountRefunded = $this->getMollie()->amountRefunded->value ?? 0; - - return $this; - } - - /** - * @param bool $force - * @throws Exception - * @return Order - */ - public function getMollie($force = false): ?Order - { - if ($force || (!$this->order && $this->getModel()->cOrderId)) { - try { - $this->order = $this->getAPI()->getClient()->orders->get($this->getModel()->cOrderId, ['embed' => 'payments,shipments,refunds']); - } catch (Exception $e) { - throw new RuntimeException(sprintf('Mollie-Order \'%s\' konnte nicht geladen werden: %s', $this->getModel()->cOrderId, $e->getMessage())); - } - } - - return $this->order; - } - - /** - * @param Order|Payment $model - * - * @return static - */ - protected function setMollie($model) - { - $this->order = $model; - - return $this; - } - - /** - * @param array $options - * @throws Exception - * @return $this - */ - public function loadRequest(array &$options = []) - { - parent::loadRequest($options); - - $this->orderNumber = $this->getBestellung()->cBestellNr; - $this->billingAddress = new Address($this->getBestellung()->oRechnungsadresse); - if ($this->getBestellung()->Lieferadresse !== null) { - if (!$this->getBestellung()->Lieferadresse->cMail) { - $this->getBestellung()->Lieferadresse->cMail = $this->getBestellung()->oRechnungsadresse->cMail; - } - $this->shippingAddress = new Address($this->getBestellung()->Lieferadresse); - } - - if ( - !empty(Frontend::getCustomer()->dGeburtstag) - && Frontend::getCustomer()->dGeburtstag !== '0000-00-00' - && preg_match('/^\d{4}-\d{2}-\d{2}$/', trim(Frontend::getCustomer()->dGeburtstag)) - ) { - $this->consumerDateOfBirth = trim(Frontend::getCustomer()->dGeburtstag); - } - - $lines = []; - - //$Positionen = $this->getPaymentMethod()->duringCheckout ? $_SESSION['Warenkorb']->PositionenArr : $this->getBestellung()->Positionen; - - $Positionen = $this->getPositionen(); - - foreach ($Positionen as $oPosition) { - $lines[] = WSOrderLine::factory($oPosition, $this->getBestellung()->Waehrung); - } - - if ($this->getBestellung()->GuthabenNutzen && $this->getBestellung()->fGuthaben > 0) { - $lines[] = WSOrderLine::getCredit($this->getBestellung()); - } - - if ($comp = WSOrderLine::getRoundingCompensation($lines, $this->amount, $this->getBestellung()->Waehrung)) { - $lines[] = $comp; - } - $this->lines = $lines; - - if (!defined('MOLLIE_DEFAULT_MAX_EXPIRY_LIMIT')) { - define('MOLLIE_DEFAULT_MAX_EXPIRY_LIMIT', 100); - } - - if (!defined('MOLLIE_KLARNA_MAX_EXPIRY_LIMIT')) { - define('MOLLIE_KLARNA_MAX_EXPIRY_LIMIT', 28); - } - - // TODO: Refactor this to use "PluginHelper::getPaymentSetting" once available - if (($dueDays = (int)self::Plugin('ws5_mollie')->getConfig()->getValue($this->getPaymentMethod()->moduleID . '_dueDays')) && $dueDays > 0) { - $max = $this->method && strpos($this->method, 'klarna') !== false ? MOLLIE_KLARNA_MAX_EXPIRY_LIMIT : MOLLIE_DEFAULT_MAX_EXPIRY_LIMIT; - $date = new DateTime(sprintf('+%d DAYS', min($dueDays, $max)), new DateTimeZone('UTC')); - $this->expiresAt = $date->format('Y-m-d'); - } - - $this->payment = $options; - - return $this; - } - - /** - * @throws Exception - * @return CartItem[] - * - * @psalm-return array - */ - public function getPositionen(): array - { - if ($this->getPaymentMethod()->duringCheckout) { - $conf = Shop::getSettings([CONF_GLOBAL]); - $oPositionenArr = []; - - if (is_array($_SESSION['Warenkorb']->PositionenArr) && count($_SESSION['Warenkorb']->PositionenArr) > 0) { - $productFilter = (int)$conf['global']['artikel_artikelanzeigefilter']; - /** @var CartItem $item */ - foreach ($_SESSION['Warenkorb']->PositionenArr as $_item) { - $item = unserialize(serialize($_item)); - - $item->cName = Text::unhtmlentities(is_array($item->cName) - ? $item->cName[$_SESSION['cISOSprache']] - : $item->cName); - - $item->fMwSt = Tax::getSalesTax($item->kSteuerklasse); - if (is_array($item->WarenkorbPosEigenschaftArr) && count($item->WarenkorbPosEigenschaftArr) > 0) { - $idx = Shop::getLanguageCode(); - // Bei einem Varkombikind dürfen nur FREIFELD oder PFLICHT-FREIFELD gespeichert werden, - // da sonst eventuelle Aufpreise in der Wawi doppelt berechnet werden - if (isset($item->Artikel->kVaterArtikel) && $item->Artikel->kVaterArtikel > 0) { - foreach ($item->WarenkorbPosEigenschaftArr as $o => $WKPosEigenschaft) { - if ($WKPosEigenschaft->cTyp === 'FREIFELD' || $WKPosEigenschaft->cTyp === 'PFLICHT-FREIFELD') { - $WKPosEigenschaft->kWarenkorbPos = $item->kWarenkorbPos; - $WKPosEigenschaft->cEigenschaftName = $WKPosEigenschaft->cEigenschaftName[$idx]; - $WKPosEigenschaft->cEigenschaftWertName = $WKPosEigenschaft->cEigenschaftWertName[$idx]; - $WKPosEigenschaft->cFreifeldWert = $WKPosEigenschaft->cEigenschaftWertName; - } - } - } else { - foreach ($item->WarenkorbPosEigenschaftArr as $o => $WKPosEigenschaft) { - $WKPosEigenschaft->kWarenkorbPos = $item->kWarenkorbPos; - $WKPosEigenschaft->cEigenschaftName = $WKPosEigenschaft->cEigenschaftName[$idx]; - $WKPosEigenschaft->cEigenschaftWertName = $WKPosEigenschaft->cEigenschaftWertName[$idx]; - if ($WKPosEigenschaft->cTyp === 'FREIFELD' || $WKPosEigenschaft->cTyp === 'PFLICHT-FREIFELD') { - $WKPosEigenschaft->cFreifeldWert = $WKPosEigenschaft->cEigenschaftWertName; - } - } - } - } - $oPositionenArr[] = $item; - } - } - - return $oPositionenArr; - } - - return $this->getBestellung()->Positionen; - } - - /** - * @throws Exception - * @return null|stdClass - */ - public function getIncomingPayment(): ?stdClass - { - /** @var Payment $payment */ - foreach ($this->getMollie()->payments() as $payment) { - if ( - in_array( - $payment->status, - [PaymentStatus::STATUS_AUTHORIZED, PaymentStatus::STATUS_PAID], - true - ) - ) { - $this->mollie = $payment; - - $cHinweis = $payment->details->paypalReference ?? $payment->id; - if (PluginHelper::getSetting('paymentID') === 'api') { - $cHinweis = $this->getMollie()->id; - } - - return (object)[ - 'fBetrag' => (float)$payment->amount->value, - 'cISO' => $payment->amount->currency, - 'cZahler' => $payment->details->paypalPayerId ?? $payment->customerId, - 'cHinweis' => $cHinweis, - ]; - } - } - - return null; - } - - /** - * @throws ApiException - * @throws Exception - * @return string - */ - public function cancelOrRefund(): string - { - if ((int)$this->getBestellung()->cStatus === BESTELLUNG_STATUS_STORNO) { - if ($this->getMollie()->isCancelable) { - $res = $this->getMollie()->cancel(); - - return 'Order cancelled, Status: ' . $res->status; - } - $res = $this->getMollie()->refundAll(); - - return 'Order Refund initiiert, Status: ' . $res->status; - } - - throw new Exception('Bestellung ist derzeit nicht storniert, Status: ' . $this->getBestellung()->cStatus); - } - - /** - * @throws CircularReferenceException - * @throws ServiceNotFoundException - * @return static - */ - protected function updateOrderNumber() - { - //update only order number - try { - if ($order = $this->getMollie()) { - $body = [ - 'orderNumber' => $this->getBestellung()->cBestellNr - ]; - $this->getAPI()->getClient()->orders->update($order->id, $body); - } - if ($this->getModel()->cTransactionId) { - $this->getAPI()->getClient()->payments->update($this->getModel()->cTransactionId, [ - 'description' => $this->getDescription() - ]); - } - } catch (Exception $e) { - $this->Log('Update only orderNumber nOrderCheckout::updateOrderNumber:' . $e->getMessage(), LOGLEVEL_ERROR); - } - - try { - if ($this->getMollie()) { - $this->getMollie()->orderNumber = $this->getBestellung()->cBestellNr; - $this->getMollie()->webhookUrl = Shop::getURL() . '/?mollie=1'; - $this->getMollie()->update(); - } - if ($this->getModel()->cTransactionId) { - $this->getAPI()->getClient()->payments->update($this->getModel()->cTransactionId, [ - 'description' => $this->getDescription() - ]); - } - } catch (Exception $e) { - $this->Log('OrderCheckout::updateOrderNumber:' . $e->getMessage(), LOGLEVEL_ERROR); - } - - return $this; - } -} +getModel()->cOrderId) { - try { - $this->payment = $this->getAPI()->getClient()->payments->get($this->getModel()->cOrderId); - if (in_array($this->payment->status, [PaymentStatus::STATUS_AUTHORIZED, PaymentStatus::STATUS_PAID], true)) { - $this->Log(PluginHelper::getPlugin()->getLocalization()->getTranslation('errAlreadyPaid')); - - return $this->payment; - } - if ($this->payment->status === PaymentStatus::STATUS_OPEN) { - $this->updateModel()->updateModel(); - - return $this->payment; - } - } catch (Exception $e) { - $this->Log(sprintf("PaymentCheckout::create: Letzte Transaktion '%s' konnte nicht geladen werden: %s, versuche neue zu erstellen.", $this->getModel()->cOrderId, $e->getMessage()), LOGLEVEL_ERROR); - } - } - - try { - $req = $this->loadRequest($paymentOptions)->jsonSerialize(); - $this->payment = $this->getAPI()->getClient()->payments->create($req); - $this->updateModel()->saveModel(); - } catch (Exception $e) { - $this->Log(sprintf("PaymentCheckout::create: Neue Transaktion '%s' konnte nicht erstellt werden: %s.\n%s", $this->oBestellung->cBestellNr, $e->getMessage(), json_encode($req)), LOGLEVEL_ERROR); - - throw new RuntimeException(sprintf('Mollie-Payment \'%s\' konnte nicht geladen werden: %s', $this->getModel()->cOrderId, $e->getMessage())); - } - - return $this->payment; - } - - /** - * @throws Exception - * - * @return static - */ - public function updateModel(): AbstractCheckout - { - parent::updateModel(); - $this->getModel()->cHash = $this->getHash(); - $this->getModel()->fAmountRefunded = $this->getMollie()->amountRefunded->value ?? 0; - - return $this; - } - - /** - * @param mixed $force - * @throws Exception - * @throws Exception - * @return Payment - */ - public function getMollie($force = false): ?Payment - { - if ($force || (!$this->payment && $this->getModel()->cOrderId)) { - try { - $this->payment = $this->getAPI()->getClient()->payments->get($this->getModel()->cOrderId, ['embed' => 'refunds']); - } catch (Exception $e) { - throw new RuntimeException('Mollie-Payment konnte nicht geladen werden: ' . $e->getMessage()); - } - } - - return $this->payment; - } - - /** - * @param array $options - * @throws Exception - * @return $this - */ - public function loadRequest(array &$options = []) - { - parent::loadRequest($options); - - $this->description = $this->getDescription(); - - foreach ($options as $key => $value) { - $this->$key = $value; - } - - return $this; - } - - /** - * @throws Exception - * @return null|stdClass - */ - public function getIncomingPayment(): ?stdClass - { - if (in_array($this->getMollie()->status, [PaymentStatus::STATUS_AUTHORIZED, PaymentStatus::STATUS_PAID], true)) { - $data = []; - $data['fBetrag'] = (float)$this->getMollie()->amount->value; - $data['cISO'] = $this->getMollie()->amount->currency; - $data['cZahler'] = $this->getMollie()->details->paypalPayerId ?? $this->getMollie()->customerId; - $data['cHinweis'] = $this->getMollie()->details->paypalReference ?? $this->getMollie()->id; - - return (object)$data; - } - - return null; - } - - /** - * @throws ApiException - * @throws IncompatiblePlatform - * @throws RuntimeException - * @return string - */ - public function cancelOrRefund(): string - { - if ((int)$this->getBestellung()->cStatus === BESTELLUNG_STATUS_STORNO) { - if ($this->getMollie()->isCancelable) { - $res = $this->getAPI()->getClient()->payments->cancel($this->getMollie()->id); - - return 'Payment cancelled, Status: ' . $res->status; - } - $res = $this->getAPI()->getClient()->payments->refund($this->getMollie(), ['amount' => $this->getMollie()->amount]); - - return 'Payment Refund initiiert, Status: ' . $res->status; - } - - throw new RuntimeException('Bestellung ist derzeit nicht storniert, Status: ' . $this->getBestellung()->cStatus); - } - - /** - * @param Order|Payment $model - * - * @return static - */ - protected function setMollie($model) - { - $this->payment = $model; - - return $this; - } - - /** - * @throws CircularReferenceException - * @throws ServiceNotFoundException - * @return static - */ - protected function updateOrderNumber() - { - //only ordernumber - try { - if ($this->getMollie()) { - $this->getMollie()->description = $this->getDescription(); - $this->getMollie()->update(true); - } - } catch (Exception $e) { - $this->Log('OrderCheckout::updateOrderNumber:' . $e->getMessage(), LOGLEVEL_ERROR); - } - - try { - if ($this->getMollie()) { - $this->getMollie()->description = $this->getDescription(); - $this->getMollie()->webhookUrl = Shop::getURL() . '/?mollie=1'; - $this->getMollie()->update(); - } - } catch (Exception $e) { - $this->Log('OrderCheckout::updateOrderNumber:' . $e->getMessage(), LOGLEVEL_ERROR); - } - - return $this; - } -} +query ?? false) { - if (isset($data->query) && is_object($data->params) && property_exists($data->params, ':limit') && property_exists($data->params, ':offset') && strpos($data->query, 'LIMIT') === false) { - $query = rtrim($data->query, ';') . ' LIMIT :offset, :limit;'; - $maxItemsParams = (array)clone $data->params; - unset($maxItemsParams[':offset'], $maxItemsParams[':limit']); - $response = [ - 'items' => PluginHelper::getDB()->executeQueryPrepared($query, (array)($data->params ?? []), 2), - 'maxItems' => PluginHelper::getDB()->executeQueryPrepared($data->query, (array)($maxItemsParams ?? []), 3), - ]; - } else { - $response = PluginHelper::getDB()->executeQueryPrepared($data->query, (array)($data->params ?? []), 2); - } - } - if (!is_array($response) && ($error = PluginHelper::getDB()->getErrorMessage())) { - throw new APIException('DB Error: ' . $error); - } - - return new AbstractResult($response); - } -} +getClient()->methods->allAvailable([/*'includeWallets' => 'applepay', 'resource' => 'orders'*/]); - $methods = []; - $oPlugin = self::Plugin('ws5_mollie'); - - foreach ($_methods as $method) { - if (in_array($method->id, ['voucher', PaymentMethod::DIRECTDEBIT, PaymentMethod::GIFTCARD], true)) { - continue; - } - $id = 'kPlugin_' . Helper::getIDByPluginID('ws5_mollie') . '_' . $method->id; - $oZahlungsart = PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM tzahlungsart WHERE cModulId = :cModulID;', [ - ':cModulID' => $id - ], 1); - - // If Mollie has new payment method that we don't support currently - if (!$oZahlungsart) { - continue; - } - - $oPaymentMethod = LegacyMethod::create($oZahlungsart->cModulId); - - $methods[$method->id] = (object)[ - 'log' => PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM tzahlungslog WHERE cModulId = :cModulId AND dDatum < DATE_SUB(NOW(), INTERVAL 30 DAY)', [':cModulId' => $oZahlungsart->cModulId], ReturnType::AFFECTED_ROWS), - 'linkToSettingsPage' => Shop::getURL() . "/admin/zahlungsarten.php?kZahlungsart=$oZahlungsart->kZahlungsart&token={$_SESSION['jtl_token']}", - 'mollie' => $method, - 'duringCheckout' => (int)$oZahlungsart->nWaehrendBestellung === 1, - 'allowDuringCheckout' => $oPaymentMethod::ALLOW_PAYMENT_BEFORE_ORDER ?? null, - 'paymentMethod' => $oZahlungsart, - 'linkedShippingMethods' => PluginHelper::getDB()->executeQueryPrepared('SELECT v.* FROM tversandart v -JOIN tversandartzahlungsart vz ON v.kVersandart = vz.kVersandart -JOIN tzahlungsart z ON vz.kZahlungsart = z.kZahlungsart -WHERE z.cModulId = :cModulID', [':cModulID' => $id], 2), - ]; - - if ($api = $oPlugin->getConfig()->getValue($id . '_api')) { - $methods[$method->id]->api = $api; - } - if ($api = $oPlugin->getConfig()->getValue($id . '_components')) { - $methods[$method->id]->components = $api; - } - if ($dueDays = $oPlugin->getConfig()->getValue($id . '_dueDays')) { - $methods[$method->id]->dueDays = (int)$dueDays; - } - } - - return new AbstractResult($methods); - } - - /** - * @param stdClass $data - * @return AbstractResult - */ - public static function cleanlog(stdClass $data): AbstractResult - { - if (isset($data->cModulId) && ($modulId = $data->cModulId)) { - return new AbstractResult(PluginHelper::getDB()->delete('tzahlungslog', 'cModulId', $modulId)); - } - - return new AbstractResult(false); - } - - /** - * @param stdClass $data - * @return AbstractResult - */ - public static function statistics(stdClass $data): AbstractResult - { - $id = 'kPlugin_' . Helper::getIDByPluginID('ws5_mollie') . '_%'; - - $result = PluginHelper::getDB()->executeQueryPrepared('( -SELECT COUNT(b.cBestellNr) as transactions, ROUND(IFNULL(SUM(b.fGesamtsumme),0),2) as amount, "day" as timespan FROM tbestellung b -WHERE kZahlungsart IN (SELECT z.kZahlungsart FROM tzahlungsart z -WHERE z.cModulId LIKE :cModulId1) -AND b.dErstellt > DATE_SUB(CURDATE(), INTERVAL 24 HOUR) -) UNION ( -SELECT COUNT(b.cBestellNr) as transactions, ROUND(IFNULL(SUM(b.fGesamtsumme),0),2) as amount, "week" as timespan FROM tbestellung b -WHERE kZahlungsart IN (SELECT z.kZahlungsart FROM tzahlungsart z -WHERE z.cModulId LIKE :cModulId2) -AND b.dErstellt > DATE_SUB(CURDATE(), INTERVAL 1 WEEK) -) UNION ( -SELECT COUNT(b.cBestellNr) as transactions, ROUND(IFNULL(SUM(b.fGesamtsumme),0),2) as amount, "month" as timespan FROM tbestellung b -WHERE kZahlungsart IN (SELECT z.kZahlungsart FROM tzahlungsart z -WHERE z.cModulId LIKE :cModulId3) -AND b.dErstellt > DATE_SUB(CURDATE(), INTERVAL 1 MONTH) -) UNION ( -SELECT COUNT(b.cBestellNr) as transactions, ROUND(IFNULL(SUM(b.fGesamtsumme),0),2) as amount, "year" as timespan FROM tbestellung b -WHERE kZahlungsart IN (SELECT z.kZahlungsart FROM tzahlungsart z -WHERE z.cModulId LIKE :cModulId4) -AND b.dErstellt > DATE_SUB(CURDATE(), INTERVAL 1 YEAR) -)', [ - ':cModulId1' => $id, - ':cModulId2' => $id, - ':cModulId3' => $id, - ':cModulId4' => $id, - ], 2); - - $response = array_combine(array_map(static function ($v) { - return $v->timespan; - }, $result), array_values($result)); - - return new AbstractResult($response); - } - - /** - * @param stdClass $data - * @throws \Exception - * @throws ApiException - * @return AbstractResult - */ - public static function cancelOrderLine(stdClass $data): AbstractResult - { - if (strpos($data->id, 'ord_') !== 0) { - throw new \RuntimeException('Invalid Order ID!'); - } - if (strpos($data->lineId, 'odl_') !== 0) { - throw new \RuntimeException('Invalid Orderline ID!'); - } - if (!$data->quantity || $data->quantity <= 0) { - throw new \RuntimeException('Invalid Quantity!'); - } - - $checkout = OrderCheckout::fromID($data->id); - $checkout->getMollie()->cancelLines([ - 'lines' => [ - [ - 'id' => $data->lineId, - 'quantity' => $data->quantity, - ], - ], - ]); - - return new AbstractResult(true); - } - - public static function cancelOrder(stdClass $data): AbstractResult - { - if (strpos($data->id, 'ord_') !== 0) { - throw new \RuntimeException('Invalid Order ID!'); - } - - $checkout = OrderCheckout::fromID($data->id); - - return new AbstractResult($checkout->getMollie()->cancel()->isCanceled()); - } - - /** - * @throws ApiException - * @throws \Exception - */ - public static function refundOrder(stdClass $data): AbstractResult - { - if (strpos($data->id, 'tr_') !== false) { - $checkout = PaymentCheckout::fromID($data->id); - $checkout->getMollie()->refund([ - 'amount' => $checkout->getMollie()->amountRemaining, - ]); - } else { - $checkout = OrderCheckout::fromID($data->id); - $checkout->getMollie()->refundAll(); - } - - return new AbstractResult(true); - } - - public static function cancelRefund(stdClass $data): AbstractResult - { - if (!$data->id || !$data->refundId) { - throw new \RuntimeException('Missing Mollie ID or Refund ID!'); - } - - if (strpos($data->id, 'tr_') !== false) { - $checkout = PaymentCheckout::fromID($data->id); - } else { - $checkout = OrderCheckout::fromID($data->id); - } - $refunds = $checkout->getMollie()->refunds(); - /** @var Refund $refund */ - foreach ($refunds as $refund) { - if ($refund->id === $data->refundId) { - $refund->cancel(); - - return new AbstractResult(true); - } - } - - throw new \RuntimeException('Refund not found!'); - } - - public static function refundOrderLine(stdClass $data): AbstractResult - { - if (strpos($data->id, 'ord_') !== 0) { - throw new \RuntimeException('Invalid Order ID!'); - } - if (strpos($data->lineId, 'odl_') !== 0) { - throw new \RuntimeException('Invalid Order ID!'); - } - if (!$data->quantity || $data->quantity <= 0) { - throw new \RuntimeException('Invalid Quantity!'); - } - - $checkout = OrderCheckout::fromID($data->id); - $checkout->getMollie()->refund([ - 'lines' => [ - [ - 'id' => $data->lineId, - 'quantity' => $data->quantity, - ], - ], - ]); - - return new AbstractResult(true); - } - - - public static function refundAmount(stdClass $data): AbstractResult - { - if (strpos($data->id, 'tr_') !== 0) { - throw new \RuntimeException('Invalid Payment ID!'); - } - - if (!$data->amount) { - throw new \RuntimeException('Invalid Amount!'); - } - - $checkout = PaymentCheckout::fromID($data->id); - $result = $checkout->getMollie()->refund([ - 'amount' => [ - 'value' => number_format((float)$data->amount, 2), - 'currency' => $checkout->getMollie()->amount->currency, - ], - 'description' => 'Refund for order ' . $checkout->getBestellung()->cBestellNr, - ]); - - return new AbstractResult($result->id); - } - - public static function getOrder(stdClass $data) - { - if (strpos($data->id, 'ord_') !== 0) { - throw new \RuntimeException('Invalid Order ID!'); - } - $checkout = OrderCheckout::fromID($data->id); - - return new AbstractResult($checkout->getMollie()); - } - - public static function getPayment(stdClass $data) - { - if (strpos($data->id, 'tr_') !== 0) { - throw new \RuntimeException('Invalid Payment ID!'); - } - $checkout = PaymentCheckout::fromID($data->id); - - return new AbstractResult($checkout->getMollie()); - } -} +id, 'cOrderId', true); - - $oBestellung = new Bestellung($orderModel->kBestellung); - - return new AbstractResult(AbstractCheckout::makeFetchable($oBestellung, $orderModel)); - } - - /** - * @param stdClass $data - * @return AbstractResult - */ - public static function shipments(stdClass $data): AbstractResult - { - $response = []; - if ($data->kBestellung) { - $lieferschein_arr = PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM tlieferschein WHERE kInetBestellung = :kBestellung', [ - ':kBestellung' => (int)$data->kBestellung - ], 2); - - foreach ($lieferschein_arr as $lieferschein) { - $shipmentsModel = ShipmentsModel::fromID((int)$lieferschein->kLieferschein, 'kLieferschein', false); - - $response[] = (object)[ - 'kLieferschein' => $lieferschein->kLieferschein, - 'cLieferscheinNr' => $lieferschein->cLieferscheinNr, - 'cHinweis' => $lieferschein->cHinweis, - 'dErstellt' => date('Y-m-d H:i:s', $lieferschein->dErstellt), - 'shipment' => $shipmentsModel->kBestellung ? $shipmentsModel : null, - ]; - } - } - - return new AbstractResult($response); - } - - /** - * @param stdClass $data - * @return AbstractResult - */ - public static function all(stdClass $data): AbstractResult - { - if (PluginHelper::getSetting('hideCompleted')) { - $query = 'SELECT o.*, b.cStatus as cJTLStatus, b.cAbgeholt, b.cVersandartName, b.cZahlungsartName, b.fGuthaben, b.fGesamtsumme ' - . 'FROM xplugin_ws5_mollie_orders o ' - . 'JOIN tbestellung b ON b.kbestellung = o.kBestellung ' - . "WHERE !(o.cStatus = 'completed' AND b.cStatus = '4')" - . 'ORDER BY b.dErstellt DESC;'; - $data->query = $query; - } - - return HelperController::selectAll($data); - } - - /** - * @param stdClass $data - * @throws Exception - * @return AbstractResult - */ - public static function one(stdClass $data): AbstractResult - { - $result = []; - if (strpos($data->id, 'tr_') !== false) { - $checkout = PaymentCheckout::fromID($data->id); - } else { - $checkout = OrderCheckout::fromID($data->id); - } - - $checkout->updateModel()->saveModel(); - - $result['mollie'] = $checkout->getMollie(); - $result['order'] = $checkout->getModel()->jsonSerialize(); - $result['bestellung'] = $checkout->getBestellung(); - $result['logs'] = PluginHelper::getDB() - ->executeQueryPrepared( - 'SELECT * FROM `xplugin_ws5_mollie_queue` WHERE cType LIKE :cTypeWebhook OR cType LIKE :cTypeHook', - [ - ':cTypeWebhook' => "%{$checkout->getModel()->cOrderId}%", - ':cTypeHook' => "%:{$checkout->getModel()->kBestellung}%" - ], - 2 - ); - - return new AbstractResult($result); - } - - /** - * @param stdClass $data - * @throws Exception - * @return AbstractResult - */ - public static function get(stdClass $data): AbstractResult - { - if (strpos($data->id, 'tr_') !== false) { - $checkout = PaymentCheckout::fromID($data->id); - } else { - $checkout = OrderCheckout::fromID($data->id); - } - $checkout->updateModel()->saveModel(); - - return new AbstractResult($checkout->getBestellung()); - } - - public static function getQueue(stdClass $data): AbstractResult - { - if (strpos($data->id, 'tr_') !== false) { - $checkout = PaymentCheckout::fromID($data->id); - } else { - $checkout = OrderCheckout::fromID($data->id); - } - - $checkout->updateModel()->saveModel(); - - return new AbstractResult(PluginHelper::getDB() - ->executeQueryPrepared( - 'SELECT * FROM `xplugin_ws5_mollie_queue` WHERE cType LIKE :cTypeWebhook OR cType LIKE :cTypeHook', - [ - ':cTypeWebhook' => "%{$checkout->getModel()->cOrderId}%", - ':cTypeHook' => "%:{$checkout->getModel()->kBestellung}%" - ], - 2 - )); - } - - - /** - * @param stdClass $data - * @throws Exception - * @return AbstractResult - */ - public static function reminder(stdClass $data): AbstractResult - { - return new AbstractResult(AbstractCheckout::sendReminder($data->id)); - } - - /** - * @param stdClass $data - * @return AbstractResult - */ - public static function zalog(stdClass $data) - { - if ($data->id && $data->kBestellung) { - $logs = PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM tzahlungslog WHERE cLogData LIKE :cLogData1 OR cLogData LIKE :cLogData2 ORDER BY dDatum DESC', [ - ':cLogData1' => sprintf('%%#%d%%', (int)$data->kBestellung), - ':cLogData2' => sprintf('%%$%s%%', trim($data->id)) - ], 2); - - return new AbstractResult($logs); - } - - return new AbstractResult(); - } -} +id) && ($id = (int)$data->id)) { - return new AbstractResult(PluginHelper::getDB()->delete('xplugin_ws5_mollie_queue', 'kId', $id)); - } - - return new AbstractResult(false); - } - - public static function unlock(stdClass $data): AbstractResult - { - if (isset($data->id) && ($id = (int)$data->id)) { - return new AbstractResult(PluginHelper::getDB()->update('xplugin_ws5_mollie_queue', 'kId', $id, (object)[ - 'bLock' => ModelInterface::NULL - ])); - } - - return new AbstractResult(false); - } - - public static function run(stdClass $data): AbstractResult - { - if (isset($data->id) && ($id = (int)$data->id)) { - $todo = QueueModel::fromID($id, 'kId'); - $todo->cError = ModelInterface::NULL; - $todo->dDone = ModelInterface::NULL; - $todo->cResult = ModelInterface::NULL; - $todo->bLock = ModelInterface::NULL; - - return new AbstractResult($todo->save()); - } - - return new AbstractResult(false); - } -} +kBestellung || !$data->kLieferschein || !$data->orderId) { - throw new APIException('Bestellung, Liefererschein oder Mollie OrderId fehlen.'); - } - - $checkout = OrderCheckout::fromID($data->orderId); - - if ($checkout->getModel()->kBestellung) { - $shipment = new Shipment((int)$data->kLieferschein, $checkout); - - $oKunde = new Customer($checkout->getBestellung()->kKunde); - - $mode = PluginHelper::getSetting('shippingMode'); - switch ($mode) { - case 'A': - // ship directly - if (!$shipment->send() && !$shipment->getShipment()) { - throw new APIException('Shipment konnte nicht gespeichert werden.'); - } - - return new AbstractResult(true); - case 'B': - // only ship if complete shipping - if ($oKunde->nRegistriert || (int)$checkout->getBestellung()->cStatus === BESTELLUNG_STATUS_VERSANDT) { - if (!$shipment->send() && !$shipment->getShipment()) { - throw new APIException('Shipment konnte nicht gespeichert werden.'); - } - - return new AbstractResult(true); - } - - throw new APIException('Gastbestellung noch nicht komplett versendet!'); - } - } else { - throw new APIException('Bestellung konnte nicht geladen werden'); - } - - return new AbstractResult($shipment); - } -} +kKunde, 'kKunde'); - - $api = new MollieAPI(MollieAPI::getMode()); - - if (!$mCustomer->customerId && isset($_SESSION['cPost_arr']) && is_array($_SESSION['cPost_arr'])) { - if (!array_key_exists('mollie_create_customer', $_SESSION['cPost_arr']) || $_SESSION['cPost_arr']['mollie_create_customer'] !== 'on') { - return null; - } - - $customer = new self(); - } else { - try { - $customer = $api->getClient()->customers->get($mCustomer->customerId); - } catch (ApiException $e) { - $customer = new self(); - } - } - - $customer->name = trim($oKunde->cVorname . ' ' . $oKunde->cNachname); - $customer->email = $oKunde->cMail; - $customer->locale = Locale::getLocale(Frontend::get('cISOSprache', 'ger'), $oKunde->cLand); - $customer->metadata = (object)[ - 'kKunde' => $oKunde->getID(), - 'kKundengruppe' => $oKunde->getGroupID(), - 'cKundenNr' => $oKunde->cKundenNr, - ]; - - if ($customer instanceof \Mollie\Api\Resources\Customer) { - $customer->update(); - } else { - try { - $customer = $api->getClient()->customers->create($customer->toArray()); - $mCustomer->kKunde = $oKunde->getID(); - $mCustomer->customerId = $customer->id; - $mCustomer->save(); - } catch (ApiException $e) { - return null; - } - } - - return $mCustomer->customerId; - } -} +key = $key; - $this->path = rtrim(realpath($path), '/') . '/'; - if (!is_dir($path) || !is_writable($path)) { - throw new RuntimeException("Lock Path '$path' doesn't exist, or is not writable!"); - } - //create a new resource or get exisitng with same key - $this->file = fopen($this->path . "$key.lockfile", 'wb+'); - } - - public function __destruct() - { - if ($this->own === true) { - $this->unlock(); - } - } - - /** - * @noinspection ForgottenDebugOutputInspection - * - * @return bool - */ - public function unlock(): bool - { - $key = $this->key; - if ($this->own === true) { - if (!flock($this->file, LOCK_UN)) { //failed - error_log("ExclusiveLock::lock FAILED to release lock [$key]"); - - return false; - } - fwrite($this->file, 'Unlocked - ' . microtime(true) . "\n"); - fflush($this->file); - $this->own = false; - } else { - error_log("ExclusiveLock::unlock called on [$key] but its not acquired by caller"); - } - - return true; // success - } - - /** - * @return bool - */ - public function lock(): bool - { - if (!flock($this->file, LOCK_EX | LOCK_NB)) { //failed - return false; - } - fwrite($this->file, 'Locked - ' . microtime(true) . "\n"); - fflush($this->file); - - $this->own = true; - - return true; // success - } -} +getLinkService()->getSpecialPage($linkType)->getSEOs(); - - if (!empty($seoLinkArray)) { - foreach ($seoLinkArray as $seoLink) { - if (strpos(strtolower($_SERVER['REQUEST_URI']), strtolower($seoLink)) !== false) { - return true; - } - } - } - - return false; - } -} +getID())) - && array_key_exists($key, $_SESSION) && !array_key_exists('Zahlungsart', $_SESSION) - ) { - unset($_SESSION[$key]); - } - - if (!array_key_exists('ws_mollie_applepay_available', $_SESSION)) { - pq('head')->append(""); - } - } catch (Exception $e) { - } - } - - /** - * @return bool - */ - public static function isAvailable(): bool - { - if (array_key_exists('ws_mollie_applepay_available', $_SESSION)) { - return $_SESSION['ws_mollie_applepay_available']; - } - - return false; - } - - /** - * @param bool $status - */ - public static function setAvailable(bool $status): void - { - $_SESSION['ws_mollie_applepay_available'] = $status; - } -} +cModulId, 'kPlugin_' . PluginHelper::getPlugin()->getID() . '_') === false) { - return; - } - - if ($args_arr['nAnzeigeOrt'] === CHECKBOX_ORT_BESTELLABSCHLUSS && ($klarnaEID = trim(PluginHelper::getSetting('klarnaEID'))) !== '') { - $modulID = Frontend::get('Zahlungsart')->cModulId; - // TODO: Refactor this to use "PluginHelper::getPaymentSetting" once available - $trustedShopsCheckbox = self::Plugin('ws5_mollie')->getConfig()->getValue($modulID . '_trustedShopsCheckbox'); - if ($trustedShopsCheckbox === 'Y') { - $checkbox = new \JTL\CheckBox(); - $checkbox->kLink = 0; - $checkbox->kCheckBox = 0; - $checkbox->kCheckBoxFunktion = 0; - $checkbox->cName = 'MOLLIE KLARNA AGB'; - $checkbox->cKundengruppe = ';1;'; - $checkbox->cAnzeigeOrt = ';2;'; - $checkbox->nAktiv = 1; - $checkbox->nPflicht = 1; - $checkbox->nLogging = 0; - $checkbox->nSort = 999; - $checkbox->dErstellt = date('Y-m-d H:i:s'); - $checkbox->oCheckBoxSprache_arr = []; - - $langs = LanguageHelper::getAllLanguages(1); - foreach ($langs as $kSprache => $lang) { - $checkbox->oCheckBoxSprache_arr[$kSprache] = (object)[ - 'cText' => PluginHelper::getPlugin()->getLocalization()->getTranslation('klarnaAGBText', $lang->getIso()), - 'cBeschreibung' => sprintf(PluginHelper::getPlugin()->getLocalization()->getTranslation('klarnaAGBDesc', $lang->getIso()), $klarnaEID), - 'kSprache' => $kSprache, - 'kCheckbox' => -1 - ]; - } - - $checkbox->kKundengruppe_arr = [Frontend::getCustomer()->getGroupID()]; - $checkbox->kAnzeigeOrt_arr = [CHECKBOX_ORT_BESTELLABSCHLUSS]; - $checkbox->cID = 'mollie_klarna_agb'; - $checkbox->cLink = ''; - - $args_arr['oCheckBox_arr'][] = $checkbox; - } - } - - - if (Frontend::getCustomer()->nRegistriert && $args_arr['nAnzeigeOrt'] === CHECKBOX_ORT_BESTELLABSCHLUSS) { - $mCustomer = CustomerModel::fromID(Frontend::getCustomer()->getID(), 'kKunde'); - - if ($mCustomer->customerId) { - return; - } - - $checkbox = new \JTL\CheckBox(); - $checkbox->kLink = 0; - $checkbox->kCheckBox = 0; - $checkbox->kCheckBoxFunktion = 0; - $checkbox->cName = 'MOLLIE SAVE CUSTOMER'; - $checkbox->cKundengruppe = ';1;'; - $checkbox->cAnzeigeOrt = ';2;'; - $checkbox->nAktiv = 1; - $checkbox->nPflicht = 0; - $checkbox->nLogging = 0; - $checkbox->nSort = 999; - $checkbox->dErstellt = date('Y-m-d H:i:s'); - $checkbox->oCheckBoxSprache_arr = []; - - $langs = LanguageHelper::getAllLanguages(1); - foreach ($langs as $kSprache => $lang) { - $checkbox->oCheckBoxSprache_arr[$kSprache] = (object)[ - 'cText' => PluginHelper::getPlugin()->getLocalization()->getTranslation('checkboxText', $lang->getIso()), - 'cBeschreibung' => PluginHelper::getPlugin()->getLocalization()->getTranslation('checkboxDescr', $lang->getIso()), - 'kSprache' => $kSprache, - 'kCheckbox' => -1 - ]; - } - - $checkbox->kKundengruppe_arr = [Frontend::getCustomer()->getGroupID()]; - $checkbox->kAnzeigeOrt_arr = [CHECKBOX_ORT_BESTELLABSCHLUSS]; - $checkbox->cID = 'mollie_create_customer'; - $checkbox->cLink = ''; - - $args_arr['oCheckBox_arr'][] = $checkbox; - } - } -} +cAnbieter) && $_SESSION["Zahlungsart"]->cAnbieter === "Mollie") || Request::isAjaxRequest()) { - return; - } - - // Check if coming back from Mollie and payment was not successful. Redirect to check out with "mollie_payment_not_completed"-parameter to be able to show correct error alert in frontend - if (Shop::getPageType() === PAGE_BESTELLVORGANG && array_key_exists('fillOut', $_REQUEST) && $_REQUEST['fillOut'] === '-1') { - - $queryArray = array_merge($_REQUEST, [static::MOLLIE_PAYMENT_NOT_COMPLETED_STRING => 1]); - unset($queryArray['fillOut']); - - $queryString = http_build_query($queryArray); - $checkoutURL = Shop::Container()->getLinkService()->getSpecialPage(LINKTYP_BESTELLVORGANG)->getURL(); - - header('Location: ' . $checkoutURL . '?' . $queryString); - } - - // Add error alert to frontend - if (array_key_exists(static::MOLLIE_PAYMENT_NOT_COMPLETED_STRING, $_REQUEST) && $_REQUEST[static::MOLLIE_PAYMENT_NOT_COMPLETED_STRING] === '1') { - - $translatedErrorMessage = PluginHelper::getPlugin()->getLocalization()->getTranslation('paymentNotCompleted'); - Shop::Container()->getAlertService()->addAlert( - Alert::TYPE_ERROR, - $translatedErrorMessage, - 'mollie_payment_incomplete' - ); - } - - } catch (Exception $e) { - Shop::Container()->getLogService()->critical($e->getMessage()); - } - } -} +kZahlungsart, true) - ) { - $args_arr['oBestellung']->cAbgeholt = 'Y'; - Shop::Container()->getLogService()->info('Switch cAbgeholt for kBestellung: ' . print_r($args_arr['oBestellung']->kBestellung, 1)); - } - } - - /** - * @param array $args_arr - * @throws CircularReferenceException - * @throws ServiceNotFoundException - */ - public static function xmlBestellStatus(array $args_arr): void - { - if (AbstractCheckout::isMollie((int)$args_arr['oBestellung']->kBestellung)) { - QueueModel::saveToQueue(HOOK_BESTELLUNGEN_XML_BESTELLSTATUS . ':' . (int)$args_arr['oBestellung']->kBestellung, [ - 'kBestellung' => $args_arr['oBestellung']->kBestellung, - 'status' => (int)$args_arr['status'] - ]); - } - } - - /** - * @param array $args_arr - * @throws CircularReferenceException - * @throws ServiceNotFoundException - */ - public static function xmlBearbeiteStorno(array $args_arr): void - { - if (AbstractCheckout::isMollie((int)$args_arr['oBestellung']->kBestellung)) { - QueueModel::saveToQueue(HOOK_BESTELLUNGEN_XML_BEARBEITESTORNO . ':' . $args_arr['oBestellung']->kBestellung, ['kBestellung' => $args_arr['oBestellung']->kBestellung]); - } - } - - /** - * @throws CircularReferenceException - * @throws ServiceNotFoundException - */ - public static function headPostGet(): void - { - if (array_key_exists('mollie', $_REQUEST) && (int)$_REQUEST['mollie'] === 1 && array_key_exists('id', $_REQUEST)) { - try { - if (array_key_exists('hash', $_REQUEST) && $hash = trim(Text::htmlentities(Text::filterXSS($_REQUEST['hash'])), '_')) { - AbstractCheckout::finalizeOrder($hash, $_REQUEST['id'], array_key_exists('test', $_REQUEST)); - } else { - QueueModel::saveToQueue($_REQUEST['id'], $_REQUEST, 'webhook'); - } - } catch (Exception $e) { - Shop::Container()->getLogService()->error(__NAMESPACE__ . ' could not finalize order or add to queue: ' . $e->getMessage() . "\n" . json_encode($_REQUEST)); - } - - // TODO: DOKU - ifndef('MOLLIE_STOP_EXEC_AFTER_WEBHOOK', true); - if (MOLLIE_STOP_EXEC_AFTER_WEBHOOK) { - exit(); - } - } - if (array_key_exists('m_pay', $_REQUEST)) { - try { - $raw = PluginHelper::getDB()->executeQueryPrepared('SELECT kId, cOrderId FROM `xplugin_ws5_mollie_orders` WHERE dReminder IS NOT NULL AND MD5(CONCAT(kId, "-", kBestellung)) = :md5', [ - ':md5' => $_REQUEST['m_pay'] - ], 1); - - if (!$raw) { - throw new RuntimeException(PluginHelper::getPlugin()->getLocalization()->getTranslation('errOrderNotFound')); - } - - if (strpos($raw->cOrderId, 'tr_') === 0) { - $checkout = PaymentCheckout::fromID($raw->cOrderId); - } else { - $checkout = OrderCheckout::fromID($raw->cOrderId); - } - $checkout->getMollie(true); - $checkout->updateModel()->saveModel(); - - if ($checkout->getBestellung()->dBezahltDatum !== null || in_array($checkout->getModel()->cStatus, ['completed', 'paid', 'authorized', 'pending'])) { - throw new RuntimeException(PluginHelper::getPlugin()->getLocalization()->getTranslation('errAlreadyPaid')); - } - - $options = []; - if (!PluginHelper::getSetting('resetMethod')) { - $options['method'] = $checkout->getModel()->cMethod; - } - $mollie = $checkout->create($options); - $url = $mollie->getCheckoutUrl(); - - header('Location: ' . $url); - exit(); - } catch (RuntimeException $e) { - $alertHelper = Shop::Container()->getAlertService(); - $alertHelper->addAlert(Alert::TYPE_ERROR, $e->getMessage(), 'mollie_repay', ['dismissable' => true]); - } catch (Exception $e) { - Shop::Container()->getLogService()->error('mollie:repay:error: ' . $e->getMessage() . "\n" . print_r($_REQUEST, 1)); - } - } - } -} + ['lang' => 'de', 'country' => ['DE', 'AT', 'CH']], - 'fre' => ['lang' => 'fr', 'country' => ['BE', 'FR']], - 'dut' => ['lang' => 'nl', 'country' => ['BE', 'NL']], - 'spa' => ['lang' => 'es', 'country' => ['ES']], - 'ita' => ['lang' => 'it', 'country' => ['IT']], - 'pol' => ['lang' => 'pl', 'country' => ['PL']], - 'hun' => ['lang' => 'hu', 'country' => ['HU']], - 'por' => ['lang' => 'pt', 'country' => ['PT']], - 'nor' => ['lang' => 'nb', 'country' => ['NO']], - 'swe' => ['lang' => 'sv', 'country' => ['SE']], - 'fin' => ['lang' => 'fi', 'country' => ['FI']], - 'dan' => ['lang' => 'da', 'country' => ['DK']], - 'ice' => ['lang' => 'is', 'country' => ['IS']], - 'eng' => ['lang' => 'en', 'country' => ['GB', 'US']], - ]; - - /** - * @param mixed $cISOSprache - * @param null|string $country - * @return string - */ - public static function getLocale($cISOSprache, ?string $country = null): string - { - if (array_key_exists($cISOSprache, self::$langs)) { - $locale = self::$langs[$cISOSprache]['lang']; - if ($country && is_array(self::$langs[$cISOSprache]['country']) && in_array($country, self::$langs[$cISOSprache]['country'], true)) { - $locale .= '_' . strtoupper($country); - } else { - $locale .= '_' . self::$langs[$cISOSprache]['country'][0]; - } - - return $locale; - } - - return PluginHelper::getSetting('fallbackLocale'); - } -} +dCreated || $this->dCreated === '0000-00-00 00:00:00') { - $this->dCreated = date('Y-m-d H:i:s'); - } - $this->dModified = date('Y-m-d H:i:s'); - - return parent::save(); - } -} +executeQueryPrepared(sprintf('DELETE FROM %s WHERE dDone IS NOT NULL AND (bLock IS NULL OR bLock = "0000-00-00 00:00:00") AND dCreated < DATE_SUB(NOW(), INTERVAL %d DAY)', self::TABLE, (int)MOLLIE_CLEANUP_DAYS), [], 3); - } - - /** - * @param null|string $result - * @param null|string $date - * @return bool - */ - public function done(string $result = null, string $date = null): bool - { - $this->cResult = $result ?? self::NULL; - $this->cError = $this->cError ?? self::NULL; - $this->dDone = $date ?? date('Y-m-d H:i:s'); - $this->bLock = self::NULL; - - return $this->save(); - } - - /** - * @return true - */ - public function save(): bool - { - $this->dModified = date('Y-m-d H:i:s'); - - return parent::save(); - } - - /** - * @param string $hook - * @param array $args_arr - * @param string $type - * @throws CircularReferenceException - * @throws ServiceNotFoundException - * @return bool - */ - public static function saveToQueue(string $hook, array $args_arr, string $type = 'hook'): bool - { - $mQueue = new self(); - $mQueue->cType = $type . ':' . $hook; - $mQueue->cData = serialize($args_arr); - $mQueue->dCreated = date('Y-m-d H:i:s'); - - try { - return $mQueue->save(); - } catch (Exception $e) { - Shop::Container()->getLogService() - ->error('mollie::saveToQueue: ' . $e->getMessage() . ' - ' . print_r($args_arr, 1)); - - return false; - } - } -} +dModified = date('Y-m-d H:i:s'); - - return parent::save(); - } -} +test = $test; - } - - /** - * - * true = TEST - * false = LIVE - * - * @return bool - */ - public static function getMode(): bool - { - try { - if (PluginHelper::getSetting('testAsAdmin') && PluginHelper::getSetting('test_apiKey') !== '') { - $_GET['fromAdmin'] = 'yes'; - - return Shop::isAdmin(true); - } - } catch (Exception $e) { - return false; - } - - return false; - } - - /** - * @throws ApiException - * @throws IncompatiblePlatform - * @return MollieApiClient - */ - public function getClient(): MollieApiClient - { - if (!$this->client) { - $this->client = new MollieApiClient(new Client([ - RequestOptions::VERIFY => CaBundle::getBundledCaBundlePath(), - RequestOptions::TIMEOUT => 60, - ])); - $this->client->setApiKey(self::getAPIKey($this->test)); - $this->client->addVersionString('JTL-Shop/' . APPLICATION_VERSION); - $this->client->addVersionString('ws5_mollie/' . PluginHelper::getPlugin()->getCurrentVersion()); - } - - return $this->client; - } - - /** - * @param boolean $test - * @return string - */ - protected static function getAPIKey(bool $test): string - { - if ($test) { - return PluginHelper::getSetting('test_apiKey'); - } - - return PluginHelper::getSetting('apiKey'); - } - - /** - * @return bool - */ - public function isTest(): bool - { - return $this->test; - } -} +title = html_entity_decode(substr(trim(($address->cAnrede === 'm' ? Shop::Lang()->get('mr') : Shop::Lang()->get('mrs')) . ' ' . $address->cTitel), 0, 20)) ?? null; - $this->givenName = html_entity_decode($address->cVorname); - $this->familyName = html_entity_decode($address->cNachname); - $this->email = html_entity_decode($address->cMail) ?? null; - - if ($organizationName = isset($address->cFirma) ? trim($address->cFirma) : null) { - $this->organizationName = html_entity_decode($organizationName); - } - } -} + true [5 Rappen Rounding]) - * @todo: prüfe mit Shop4 - */ - public function __construct($value, Currency $currency = null, bool $useRounding = false) - { - if (!$currency) { - $currency = self::fallbackCurrency(); - } - $this->value = number_format(round($useRounding ? self::round($value) : $value, 2), 2, '.', ''); - $this->currency = $currency->getCode(); - } - - /** - * @return Currency - */ - public static function fallbackCurrency(): Currency - { - $curr = $_SESSION['Waehrung'] ?? PluginHelper::getDB()->select('twaehrung', 'cStandard', 'Y'); - - return new Currency($curr->kWaehrung); - } - - /** - * @param float $gesamtsumme - * @return float - */ - public static function round(float $gesamtsumme): float - { - $conf = Shop::getSettings([CONF_KAUFABWICKLUNG]); - if ( - isset($conf['kaufabwicklung']['bestellabschluss_runden5']) - && ($conf['kaufabwicklung']['bestellabschluss_runden5'] === 1) - ) { - // simplification. see https://de.wikipedia.org/wiki/Rundung#Rappenrundung - $gesamtsumme = round($gesamtsumme * 20.0) / 20.0; - } - - return $gesamtsumme; - } -} +type = self::getType($oPosition->nPosTyp, $oPosition->fPreis >= 0); - // TODO: FktAttr? $orderLine->category - - $orderLine->name = $oPosition->cName; - if (!$orderLine->name || !is_string($orderLine->name)) { - $orderLine->name = $oPosition->cArtNr ?: '(null)'; - } - - $_vatRate = (float)$oPosition->fMwSt / 100; - if ((int)$oPosition->nPosTyp === C_WARENKORBPOS_TYP_KUPON) { - $_netto = round($oPosition->fPreis * (1 + $_vatRate), 4); - $_vatRate = 0; - } else { - $_netto = round($oPosition->fPreis, 4); - } - $_amount = (float)$oPosition->nAnzahl; - - if (fmod($oPosition->nAnzahl, 1) !== 0.0) { - $_netto *= $_amount; - $_amount = 1; - $orderLine->name .= sprintf(' (%.2f %s)', (float)$oPosition->nAnzahl, $oPosition->cEinheit); - } - - // TODO vorher 2 - $unitPriceNetto = round(($currency->getConversionFactor() * $_netto), 4); - $unitPrice = round($unitPriceNetto * (1 + $_vatRate), 2); - $totalAmount = round($_amount * $unitPrice, 2); - $vatAmount = round($totalAmount - ($totalAmount / (1 + $_vatRate)), 2); - - $orderLine->quantity = (int)$_amount; - $orderLine->unitPrice = new Amount($unitPrice, $currency, false); - $orderLine->totalAmount = new Amount($totalAmount, $currency, false); - $orderLine->vatRate = number_format($_vatRate * 100, 2); - $orderLine->vatAmount = new Amount($vatAmount, $currency, false); - - $metadata = []; - - if (isset($oPosition->Artikel)) { - $orderLine->sku = $oPosition->Artikel->cArtNr; - $metadata['kArtikel'] = $oPosition->kArtikel; - if ($oPosition->cUnique !== '') { - $metadata['cUnique'] = $oPosition->cUnique; - } - } - - if (isset($oPosition->WarenkorbPosEigenschaftArr) && is_array($oPosition->WarenkorbPosEigenschaftArr) && count($oPosition->WarenkorbPosEigenschaftArr)) { - $metadata['properties'] = []; - /** @var CartItemProperty $eigenschaft */ - foreach ($oPosition->WarenkorbPosEigenschaftArr as $eigenschaft) { - $metadata['properties'][] = [ - 'kEigenschaft' => $eigenschaft->kEigenschaft, - 'kEigenschaftWert' => $eigenschaft->kEigenschaftWert, - 'name' => $eigenschaft->cEigenschaftName, - 'value' => $eigenschaft->cEigenschaftWertName, - ]; - if (strlen(json_encode($metadata)) > 1000) { - array_pop($metadata['properties']); - - break; - } - } - } - $orderLine->metadata = $metadata; - - return $orderLine; - } - - /** - * @param $nPosTyp - * @throws Exception - * @return string - */ - protected static function getType($nPosTyp, $positive = true): string - { - switch ($nPosTyp) { - case C_WARENKORBPOS_TYP_ARTIKEL: - case C_WARENKORBPOS_TYP_GRATISGESCHENK: - // TODO: digital / Download Artikel? - return OrderLineType::TYPE_PHYSICAL; - case C_WARENKORBPOS_TYP_VERSANDPOS: - return OrderLineType::TYPE_SHIPPING_FEE; - case C_WARENKORBPOS_TYP_VERPACKUNG: - case C_WARENKORBPOS_TYP_VERSANDZUSCHLAG: - case C_WARENKORBPOS_TYP_ZAHLUNGSART: - case C_WARENKORBPOS_TYP_VERSAND_ARTIKELABHAENGIG: - case C_WARENKORBPOS_TYP_NACHNAHMEGEBUEHR: - return OrderLineType::TYPE_SURCHARGE; - case C_WARENKORBPOS_TYP_GUTSCHEIN: - case C_WARENKORBPOS_TYP_KUPON: - case C_WARENKORBPOS_TYP_NEUKUNDENKUPON: - return OrderLineType::TYPE_DISCOUNT; - default: - return $positive ? OrderLineType::TYPE_SURCHARGE : OrderLineType::TYPE_DISCOUNT; - - } - - throw new Exception('Unknown PosTyp.', (int)$nPosTyp); - } - - /** - * @param OrderLine[] $orderLines - * @param Amount $amount - * @param Currency $currency - * @return null|OrderLine - */ - public static function getRoundingCompensation(array $orderLines, Amount $amount, Currency $currency): ?self - { - $sum = .0; - foreach ($orderLines as $line) { - $sum += (float)$line->totalAmount->value; - } - if (abs($sum - (float)$amount->value) > 0) { - $diff = (round((float)$amount->value - $sum, 2)); - if ($diff !== 0.0) { - $line = new self(); - $line->type = $diff > 0 ? OrderLineType::TYPE_SURCHARGE : OrderLineType::TYPE_DISCOUNT; - $line->name = 'Rundungsausgleich'; - $line->quantity = 1; - $line->unitPrice = new Amount($diff, $currency, false); - $line->totalAmount = new Amount($diff, $currency, false); - $line->vatRate = '0.00'; - $line->vatAmount = new Amount(0, $currency, false); - - return $line; - } - } - - return null; - } - - /** - * @param Bestellung $oBestellung - * @return OrderLine - */ - public static function getCredit(Bestellung $oBestellung): self - { - $line = new self(); - $line->type = OrderLineType::TYPE_STORE_CREDIT; - $line->name = 'Guthaben'; - $line->quantity = 1; - $line->unitPrice = (object)[ - 'value' => number_format($oBestellung->Waehrung->getConversionFactor() * $oBestellung->fGuthaben, 2, '.', ''), - 'currency' => $oBestellung->Waehrung->getCode(), - ]; - $line->totalAmount = (object)[ - 'value' => number_format($oBestellung->Waehrung->getConversionFactor() * $oBestellung->fGuthaben, 2, '.', ''), - 'currency' => $oBestellung->Waehrung->getCode(), - ]; - $line->vatRate = '0.00'; - $line->vatAmount = (object)[ - 'value' => number_format(0, 2, '.', ''), - 'currency' => $oBestellung->Waehrung->getCode(), - ]; - - return $line; - } -} +streetAndNumber = html_entity_decode($address->cStrasse . ' ' . $address->cHausnummer); - $this->postalCode = html_entity_decode($address->cPLZ); - $this->city = html_entity_decode($address->cOrt); - $this->country = html_entity_decode($address->cLand); - - if ( - isset($adresse->cAdressZusatz) - && trim($adresse->cAdressZusatz) !== '' - ) { - $this->streetAdditional = html_entity_decode(trim($adresse->cAdressZusatz)); - } - } -} +kPlugin = JtlPluginHelper::getIDByModuleID($this->moduleID); - - return $this; - } - - /** - * @return true - */ - public function canPayAgain(): bool - { - return true; - } - - /** - * @param array $args_arr - * @return bool - */ - public function isValidIntern(array $args_arr = []): bool - { - return $this->duringCheckout - ? static::ALLOW_PAYMENT_BEFORE_ORDER && parent::isValidIntern($args_arr) - : parent::isValidIntern($args_arr); - } - - /** - * @return bool - */ - public function isSelectable(): bool - { - if (MollieAPI::getMode()) { - $selectable = trim(PluginHelper::getSetting('test_apiKey')) !== ''; - } else { - $selectable = trim(PluginHelper::getSetting('apiKey')) !== ''; - if (!$selectable) { - $this->doLog('Live API Key missing!', LOGLEVEL_ERROR); - } - } - if ($selectable) { - try { - $locale = self::getLocale(Frontend::getInstance()->getLanguage()->gibISO(), Frontend::getCustomer()->cLand); - $amount = Frontend::getCart()->gibGesamtsummeWaren(true) * Frontend::getCurrency()->getConversionFactor(); - if ($amount <= 0) { - $amount = 0.01; - } - $selectable = self::isMethodPossible( - static::METHOD, - $locale, - Frontend::getCustomer()->cLand, - Frontend::getCurrency()->getCode(), - $amount - ); - } catch (Exception $e) { - $selectable = false; - } - } - - return $selectable && parent::isSelectable(); - } - - /** - * @param string $cISOSprache - * @param null|string $country - * @return string - */ - public static function getLocale(string $cISOSprache, string $country = null): string - { - switch ($cISOSprache) { - case 'ger': - if ($country === 'AT') { - return 'de_AT'; - } - if ($country === 'CH') { - return 'de_CH'; - } - return 'de_DE'; - case 'fre': - if ($country === 'BE') { - return 'fr_BE'; - } - return 'fr_FR'; - case 'dut': - if ($country === 'BE') { - return 'nl_BE'; - } - return 'nl_NL'; - case 'spa': - return 'es_ES'; - case 'ita': - return 'it_IT'; - case 'pol': - return 'pl_PL'; - case 'hun': - return 'hu_HU'; - case 'por': - return 'pt_PT'; - case 'nor': - return 'nb_NO'; - case 'swe': - return 'sv_SE'; - case 'fin': - return 'fi_FI'; - case 'dan': - return 'da_DK'; - case 'ice': - return 'is_IS'; - default: - return 'en_US'; - } - } - - /** - * @param $method - * @param string $locale - * @param $billingCountry - * @param $currency - * @param $amount - * @throws IncompatiblePlatform - * @throws ApiException - * @return bool - */ - protected static function isMethodPossible($method, string $locale, $billingCountry, $currency, $amount): bool - { - $api = new MollieAPI(MollieAPI::getMode()); - - if (!array_key_exists('mollie_possibleMethods', $_SESSION)) { - //Frontend::set('mollie_possibleMethods', []); - $_SESSION['mollie_possibleMethods'] = []; - } - - $key = md5(serialize([$locale, $billingCountry, $currency, $amount])); - if (!array_key_exists($key, $_SESSION['mollie_possibleMethods'])) { - $active = $api->getClient()->methods->allActive([ - 'locale' => $locale, - 'amount' => [ - 'currency' => $currency, - 'value' => number_format($amount, 2, '.', '') - ], - 'billingCountry' => $billingCountry, - 'resource' => 'orders', - 'includeWallets' => 'applepay', - ]); - foreach ($active as $a) { - $_SESSION['mollie_possibleMethods'][$key][] = (object)['id' => $a->id]; - } - } - - if ($method !== '') { - foreach ($_SESSION['mollie_possibleMethods'][$key] as $m) { - if ($m->id === $method) { - return true; - } - } - } else { - return true; - } - - return false; - } - - /** - * @param Bestellung $order - */ - public function preparePaymentProcess(Bestellung $order): void - { - parent::preparePaymentProcess($order); - - try { - if ($this->duringCheckout && !static::ALLOW_PAYMENT_BEFORE_ORDER) { - $this->doLog('Zahlung vor Bestellabschluss nicht unterstützt!', LOGLEVEL_ERROR); - - return; - } - - $payable = (float)$order->fGesamtsumme > 0; - if (!$payable) { - $this->doLog(sprintf("Bestellung '%s': Gesamtsumme %.2f, keine Zahlung notwendig!", $order->cBestellNr, $order->fGesamtsumme), LOGLEVEL_NOTICE); - - return; - } - - $paymentOptions = []; - - if (Frontend::getCustomer()->nRegistriert && ($customerID = Customer::createOrUpdate(Frontend::getCustomer()))) { - $paymentOptions['customerId'] = $customerID; - } - - // TODO: Refactor this to use "PluginHelper::getPaymentSetting" once available - $api = self::Plugin('ws5_mollie')->getConfig()->getValue($this->moduleID . '_api'); - - $paymentOptions = array_merge($paymentOptions, $this->getPaymentOptions($order, $api)); - - if ($api === 'payment') { - $checkout = PaymentCheckout::factory($order); - $payment = $checkout->create($paymentOptions); - $url = $payment->getCheckoutUrl(); - } else { - $checkout = OrderCheckout::factory($order); - $mOrder = $checkout->create($paymentOptions); - $url = $mOrder->getCheckoutUrl(); - } - - try { - if ($order->kBestellung > 0 && method_exists($this, 'generatePUI') && ($pui = $this->generatePUI($checkout))) { - $order->cPUIZahlungsdaten = $pui; - $order->updateInDB(); - } - } catch (\Exception $e) { - $this->doLog('mollie::preparePaymentProcess: PUI - ' . $e->getMessage() . ' - ' . print_r(['cBestellNr' => $order->cBestellNr], 1), LOGLEVEL_NOTICE); - } - - if ($url) { - ifndef('MOLLIE_REDIRECT_DELAY', 3); - $checkoutMode = PluginHelper::getSetting('checkoutMode'); - Shop::Smarty()->assign('redirect', $url) - ->assign('checkoutMode', $checkoutMode); - if ($checkoutMode === 'Y' && !headers_sent()) { - header('Location: ' . $url); - ifndef('MOLLIE_STOP_EXEC_AFTER_WEBHOOK', true); - if (MOLLIE_STOP_EXEC_AFTER_WEBHOOK) { - exit(); - } - } - } - } catch (Exception $e) { - $this->doLog('mollie::preparePaymentProcess: ' . $e->getMessage() . ' - ' . print_r(['cBestellNr' => $order->cBestellNr], 1), LOGLEVEL_ERROR); - - Shop::Container()->getAlertService()->addAlert( - Alert::TYPE_ERROR, - PluginHelper::getPlugin()->getLocalization()->getTranslation('error_create'), - 'paymentFailed' - ); - } - } - - abstract public function getPaymentOptions(Bestellung $order, $apiType): array; - - /** - * @param Bestellung $order - * @param string $hash - * @param array $args - * @throws CircularReferenceException - * @throws ServiceNotFoundException - */ - public function handleNotification(Bestellung $order, string $hash, array $args): void - { - parent::handleNotification($order, $hash, $args); - - try { - $orderId = $args['id']; - if (strpos($orderId, 'tr_') === 0) { - $checkout = PaymentCheckout::factory($order); - } else { - $checkout = OrderCheckout::factory($order); - } - $checkout->handleNotification($hash); - } catch (Exception $e) { - $this->doLog("ERROR: mollie::handleNotification: Bestellung '$order->cBestellNr': {$e->getMessage()}", LOGLEVEL_ERROR); - Shop::Container()->getBackendLogService()->critical($e->getMessage(), $_REQUEST); - } - } -} +cType))) { - try { - switch ($type) { - case 'webhook': - self::handleWebhook($id, $todo); - - break; - case 'hook': - self::handleHook((int)$id, $todo); - - break; - } - } catch (Exception $e) { - Shop::Container()->getLogService()->notice('Mollie Queue Fehler: ' . $e->getMessage() . " ($type, $id)"); - $todo->cError = "{$e->getMessage()}\n{$e->getFile()}:{$e->getLine()}\n{$e->getTraceAsString()}"; - $todo->done(); - } - } - - self::unlock($todo); - } - } - - /** - * @param int $limit - * @return Generator - */ - private static function getOpen(int $limit): Generator - { - if (!defined('MOLLIE_HOOK_DELAY')) { - define('MOLLIE_HOOK_DELAY', 3); - } - $open = PluginHelper::getDB()->executeQueryPrepared("SELECT * FROM xplugin_ws5_mollie_queue WHERE (dDone IS NULL OR dDone = '0000-00-00 00:00:00') AND `bLock` IS NULL AND (cType LIKE 'webhook:%%' OR (cType LIKE 'hook:%%' AND dCreated < DATE_SUB(NOW(), INTERVAL :hd MINUTE))) ORDER BY dCreated DESC LIMIT 0, :LIMIT;", [ - ':LIMIT' => $limit, - ':hd' => MOLLIE_HOOK_DELAY - ], 2); - - foreach ($open as $_raw) { - yield new QueueModel($_raw); - } - } - - /** - * @param QueueModel $todo - * @return bool - */ - protected static function lock(QueueModel $todo): bool - { - // Validation should not be necessary here since QueueModel::TABLE is a constant, but we do it anyway to lead by example - if (!AbstractPluginHelper::isAlphaNumericPlus(QueueModel::TABLE)) { - return false; - } - - return $todo->kId && PluginHelper::getDB()->executeQueryPrepared(sprintf('UPDATE %s SET `bLock` = NOW() WHERE `bLock` IS NULL AND kId = :kId', QueueModel::TABLE), [ - 'kId' => $todo->kId - ], 3) >= 1; - } - - /** - * @param string $id - * @param QueueModel $todo - * @throws Exception - * @return bool - */ - protected static function handleWebhook(string $id, QueueModel $todo): bool - { - $checkout = AbstractCheckout::fromID($id); - if ($checkout->getBestellung()->kBestellung && $checkout->getPaymentMethod()) { - $checkout->handleNotification(); - - return $todo->done('Status: ' . $checkout->getMollie()->status); - } - - throw new RuntimeException("Bestellung oder Zahlungsart konnte nicht geladen werden: $id"); - } - - /** - * @param int $hook - * @param QueueModel $queueModel - * @return bool - * @throws CircularReferenceException - * @throws ServiceNotFoundException - * @throws Exception - */ - protected static function handleHook(int $hook, QueueModel $queueModel): bool - { - $data = unserialize($queueModel->cData); //, [stdClass::class, Bestellung::class, \JTL\Customer\Customer::class]); - if (array_key_exists('kBestellung', $data)) { - switch ($hook) { - case HOOK_BESTELLUNGEN_XML_BESTELLSTATUS: - if ((int)$data['kBestellung']) { - $checkout = AbstractCheckout::fromBestellung($data['kBestellung']); - - $result = ''; - if ((int)$checkout->getBestellung()->cStatus < BESTELLUNG_STATUS_VERSANDT) { - return $queueModel->done("Bestellung noch nicht versendet: {$checkout->getBestellung()->cStatus}"); - } - - if (!count($checkout->getBestellung()->oLieferschein_arr)) { - if (!defined('MOLLIE_HOOK_DELAY')) { - define('MOLLIE_HOOK_DELAY', 3); - } - $queueModel->dCreated = date('Y-m-d H:i:s', strtotime(sprintf('+%d MINUTES', MOLLIE_HOOK_DELAY))); - $queueModel->cResult = 'Noch keine Lieferscheine, delay...'; - - return $queueModel->save(); - } - - if ( - (int)$data['status'] - && array_key_exists('status', $data) - && $checkout->getPaymentMethod() - && (strpos($checkout->getModel()->cOrderId, 'tr_') === false) - && $checkout->getMollie() - ) { - /** @var OrderCheckout $checkout */ - $checkout->handleNotification(); - if ($checkout->getMollie()->status === OrderStatus::STATUS_COMPLETED) { - $result = 'Mollie Status already ' . $checkout->getMollie()->status; - } elseif ( - $checkout->getMollie()->isCreated() - || $checkout->getMollie()->isPaid() - || $checkout->getMollie()->isAuthorized() - || $checkout->getMollie()->isShipping() - || $checkout->getMollie()->isPending() - ) { - try { - if ($shipments = Shipment::syncBestellung($checkout)) { - foreach ($shipments as $shipment) { - if (is_string($shipment)) { - $checkout->Log("Shipping-Error: $shipment"); - $result .= "Shipping-Error: $shipment\n"; - } else { - $checkout->Log("Order shipped: $shipment->id"); - $result .= "Order shipped: $shipment->id\n"; - } - } - } else { - $result = 'No Shipments ready!'; - } - } catch (Exception $e) { - $result = $e->getMessage() . "\n" . $e->getFile() . ':' . $e->getLine() . "\n" . $e->getTraceAsString(); - } - } else { - $result = 'Unexpected Mollie Status: ' . $checkout->getMollie()->status; - } - } else { - $result = 'Nothing to do.'; - } - - return $queueModel->done($result); - } - - return $queueModel->done('kBestellung missing'); - case HOOK_BESTELLUNGEN_XML_BEARBEITESTORNO: - if (!PluginHelper::getSetting('autoRefund')) { - throw new RuntimeException('Auto-Refund disabled'); - } - $checkout = AbstractCheckout::fromBestellung((int)$data['kBestellung']); - - if (!isset($checkout)){ - return $queueModel->done("No Checkout found for kBestellung:" . (int)$data['kBestellung']); - } - return $queueModel->done($checkout->cancelOrRefund()); - } - } - - return false; - } - - /** - * @param QueueModel $qm - * @return bool - */ - protected static function unlock(QueueModel $qm): bool - { - // Validation should not be necessary here since QueueModel::TABLE is a constant, but we do it anyway to lead by example - if (!AbstractPluginHelper::isAlphaNumericPlus(QueueModel::TABLE)) { - return false; - } - - return $qm->kId && PluginHelper::getDB()->executeQueryPrepared(sprintf('UPDATE %s SET `bLock` = NULL WHERE kId = :kId OR bLock < DATE_SUB(NOW(), INTERVAL 15 MINUTE)', QueueModel::TABLE), [ - 'kId' => $qm->kId - ], 3) >= 1; - } - - /** - * @param mixed $delay - * @throws ServiceNotFoundException - * @throws CircularReferenceException - * @return true - */ - public static function storno($delay): bool - { - if (!$delay) { - return true; - } - - $open = PluginHelper::getDB()->executeQueryPrepared( - "SELECT p.kId, b.cBestellNr, p.kBestellung, b.cStatus FROM xplugin_ws5_mollie_orders p JOIN tbestellung b ON b.kBestellung = p.kBestellung WHERE b.cStatus IN ('1', '2') AND p.dCreated < NOW() - INTERVAL :d HOUR", - [':d' => $delay], - 2 - ); - - foreach ($open as $o) { - try { - $checkout = AbstractCheckout::fromBestellung($o->kBestellung); - $pm = $checkout->getPaymentMethod(); - if ($pm::ALLOW_AUTO_STORNO && $pm::METHOD === $checkout->getMollie()->method) { - if ($checkout->getBestellung()->cAbgeholt === 'N' && (bool)$checkout->getModel()->bSynced === false) { - if (!in_array($checkout->getMollie()->status, [OrderStatus::STATUS_PAID, OrderStatus::STATUS_COMPLETED, OrderStatus::STATUS_AUTHORIZED], true)) { - $checkout->storno(); - } else { - $checkout->Log(sprintf('AutoStorno: Bestellung bezahlt? %s - Method: %s', $checkout->getMollie()->status, $checkout->getMollie()->method), LOGLEVEL_ERROR); - } - } else { - $checkout->Log('AutoStorno: bereits zur WAWI synchronisiert.', LOGLEVEL_ERROR); - } - }/* else { - $checkout->Log(sprintf('AutoStorno aktiv: %d (%s) - Method: %s', (int)$pm::ALLOW_AUTO_STORNO, $pm::METHOD, $checkout->getMollie()->method), LOGLEVEL_ERROR); - }*/ - } catch (Exception $e) { - Shop::Container()->getLogService()->error(sprintf('Fehler beim stornieren der Order: %s / Bestellung: %s: %s', $o->cBestellNr, $o->kId, $e->getMessage())); - } - } - - return true; - } -} +kLieferschein = $kLieferschein; - if ($checkout) { - $this->checkout = $checkout; - } - - if (!$this->getLieferschein() || !$this->getLieferschein()->getLieferschein()) { - throw new APIException('Lieferschein konnte nicht geladen werden'); - } - - if (!count($this->getLieferschein()->oVersand_arr)) { - throw new APIException('Kein Versand gefunden!'); - } - } - - /** - * @return Lieferschein - */ - public function getLieferschein(): Lieferschein - { - if (!$this->oLieferschein && $this->kLieferschein) { - $this->oLieferschein = new Lieferschein($this->kLieferschein); - } - - return $this->oLieferschein; - } - - /** - * @param OrderCheckout $checkout - * @throws Exception - * @return array (\Mollie\Api\Resources\Shipment|null|string)[] - */ - public static function syncBestellung(OrderCheckout $checkout): array - { - $shipments = []; - if ($checkout->getBestellung()->kBestellung) { - $oKunde = $checkout->getBestellung()->oKunde ?? new \JTL\Customer\Customer($checkout->getBestellung()->kKunde); - - $shippingActive = PluginHelper::getSetting('shippingActive'); - if ($shippingActive === 'N') { - throw new RuntimeException('Shipping deaktiviert'); - } - - if ($shippingActive === 'K' && !$oKunde->nRegistriert && (int)$checkout->getBestellung()->cStatus !== BESTELLUNG_STATUS_VERSANDT) { - throw new RuntimeException('Shipping für Gast-Bestellungen und Teilversand deaktiviert'); - } - - /** @var Lieferschein $oLieferschein */ - foreach ($checkout->getBestellung()->oLieferschein_arr as $oLieferschein) { - try { - $shipment = new self($oLieferschein->getLieferschein(), $checkout); - - $mode = PluginHelper::getSetting('shippingMode'); - switch ($mode) { - case 'A': - // ship directly - if (!$shipment->send() && !$shipment->getShipment()) { - throw new APIException('Shipment konnte nicht gespeichert werden.'); - } - $shipments[] = $shipment->getShipment(); - - break; - case 'B': - // only ship if complete shipping - if ($oKunde->nRegistriert || (int)$checkout->getBestellung()->cStatus === BESTELLUNG_STATUS_VERSANDT) { - if (!$shipment->send() && !$shipment->getShipment()) { - throw new APIException('Shipment konnte nicht gespeichert werden.'); - } - $shipments[] = $shipment->getShipment(); - - break; - } - - throw new APIException('Gastbestellung noch nicht komplett versendet!'); - } - } catch (APIException $e) { - //TODO: handle url entity error - $shipments[] = $e->getMessage(); - } catch (Exception $e) { - $shipments[] = $e->getMessage(); - Shop::Container()->getLogService()->error("mollie: Shipment::syncBestellung (BestellNr. {$checkout->getBestellung()->cBestellNr}, Lieferschein: {$shipment->getLieferschein()->getLieferscheinNr()}) - " . $e->getMessage()); - } - } - } - - return $shipments; - } - - /** - * @throws IncompatiblePlatform - * @throws Exception - * @throws ApiException - * @return bool - */ - public function send(): bool - { - if ($this->getShipment()) { - throw new APIException('Lieferschien bereits an Mollie übertragen: ' . $this->getShipment()->id); - } - - if ($this->getCheckout()->getMollie(true)->status === OrderStatus::STATUS_COMPLETED) { - throw new APIException('Bestellung bei Mollie bereits abgeschlossen!'); - } - - $api = $this->getCheckout()->getAPI()->getClient(); - - $this->shipment = $api->shipments->createForId($this->checkout->getModel()->cOrderId, $this->loadRequest()->jsonSerialize()); - - return $this->updateModel()->saveModel(); - } - - /** - * @param false $force - * @throws IncompatiblePlatform - * @throws \Mollie\Api\Exceptions\ApiException - * @return null|\Mollie\Api\Resources\Shipment - */ - public function getShipment(bool $force = false): ?\Mollie\Api\Resources\Shipment - { - if (($force || !$this->shipment) && $this->getModel() && $this->getModel()->cShipmentId) { - $this->shipment = $this->getCheckout()->getAPI()->getClient()->shipments->getForId($this->getModel()->cOrderId, $this->getModel()->cShipmentId); - } - - return $this->shipment; - } - - /** - * @throws Exception - * @return ShipmentsModel - */ - public function getModel(): ShipmentsModel - { - if (!$this->model && $this->kLieferschein) { - $this->model = ShipmentsModel::fromID($this->kLieferschein, 'kLieferschein'); - if (!$this->model->dCreated) { - $this->getModel()->dCreated = date('Y-m-d H:i:s'); - } - $this->updateModel(); - } - - return $this->model; - } - - /** - * @throws Exception - * - * @return static - */ - public function updateModel(): self - { - $this->getModel()->kLieferschein = $this->kLieferschein; - if ($this->getCheckout()) { - $this->getModel()->cOrderId = $this->getCheckout()->getModel()->cOrderId; - $this->getModel()->kBestellung = $this->getCheckout()->getModel()->kBestellung; - } - if ($this->getShipment()) { - $this->getModel()->cShipmentId = $this->getShipment()->id; - $this->getModel()->cUrl = $this->getShipment()->getTrackingUrl() ?? ''; - } - if ($this->tracking) { - $this->getModel()->cCarrier = $this->tracking['carrier'] ?? ''; - $this->getModel()->cCode = $this->tracking['code'] ?? ''; - } - - return $this; - } - - /** - * @throws Exception - * @return OrderCheckout - */ - public function getCheckout(): OrderCheckout - { - if (!$this->checkout) { - //TODO evtl. load by lieferschien - throw new RuntimeException('Should not happen, but it did!'); - } - - return $this->checkout; - } - - /** - * @throws Exception - * @return $this - */ - public function loadRequest(array &$options = []) - { - /** @var Versand $oVersand */ - $oVersand = $this->getLieferschein()->oVersand_arr[0]; - //TODO: add setting for url - if ($oVersand->getIdentCode() && $oVersand->getLogistik()) { - $tracking = [ - 'carrier' => $oVersand->getLogistik(), - 'code' => $oVersand->getIdentCode(), - ]; - if ($oVersand->getLogistikVarUrl() && PluginHelper::getSetting('trackingActive')) { - $tracking['url'] = $oVersand->getLogistikURL(); - } - $this->tracking = $tracking; - } - - $this->tracking = $tracking; - - - // TODO: Wenn alle Lieferschiene in der WAWI erstellt wurden, aber nicht im Shop, kommt status 4. - if ((int)$this->getCheckout()->getBestellung()->cStatus === BESTELLUNG_STATUS_VERSANDT) { - $this->lines = []; - } else { - $this->lines = $this->getOrderLines(); - } - - return $this; - } - - /** - * @throws Exception - * @return array (float|int|string)[][] - * - */ - protected function getOrderLines(): array - { - $lines = []; - - if (!count($this->getLieferschein()->oLieferscheinPos_arr)) { - return $lines; - } - - // Bei Stücklisten, sonst gibt es mehrere OrderLines für die selbe ID - $shippedOrderLines = []; - - /** @var Lieferscheinpos $oLieferschienPos */ - foreach ($this->getLieferschein()->oLieferscheinPos_arr as $oLieferschienPos) { - $wkpos = PluginHelper::getDB()->executeQueryPrepared('SELECT * FROM twarenkorbpos WHERE kBestellpos = :kBestellpos', [ - ':kBestellpos' => $oLieferschienPos->getBestellPos() - ], 1); - - /** @var OrderLine $orderLine */ - foreach ($this->getCheckout()->getMollie()->lines as $orderLine) { - if ($orderLine->sku === $wkpos->cArtNr && !in_array($orderLine->id, $shippedOrderLines, true)) { - if ($quantity = min($oLieferschienPos->getAnzahl(), $orderLine->shippableQuantity)) { - $lines[] = [ - 'id' => $orderLine->id, - 'quantity' => $quantity - ]; - } - $shippedOrderLines[] = $orderLine->id; - - break; - } - } - } - - return $lines; - } - - /** - * @throws Exception - * @return true - * - */ - public function saveModel(): bool - { - return $this->getModel()->save(); - } -} +requestData) { - $this->loadRequest(); - } - - return $this->requestData; - } - - /** - * @param array $options - * @return $this - */ - abstract public function loadRequest(array &$options = []); - - /** - * @param string $name - * @throws Exception - * @return false|mixed|string - */ - public function __get(string $name) - { - if (!$this->requestData) { - $this->loadRequest(); - } - - if (!array_key_exists($name, $this->requestData)) { - return null; - } - - return is_string($this->requestData[$name]) ? utf8_decode($this->requestData[$name]) : $this->requestData[$name]; - } - - /** - * @param string $name - * @param mixed $value - * @return $this - */ - public function __set(string $name, $value) - { - if (!$this->requestData) { - $this->requestData = []; - } - - $this->requestData[$name] = is_string($value) ? utf8_encode($value) : $value; - - return $this; - } - - /** - * @return array - */ - public function __serialize(): array - { - return $this->requestData ?: []; - } - - /** - * @param string $name - * @return bool - */ - public function __isset(string $name) - { - return $this->requestData[$name] !== null; - } -} +getConfig()->getValue($this->moduleID . '_usePUI') === 'N') { - return false; - } - - $template = PluginHelper::getPlugin()->getLocalization()->getTranslation('banktransferPUI'); - - return str_replace( - [ - '%amount%', - '%expiresAt%', - '%bankName%', - '%bankAccount%', - '%bankBic%', - '%transferReference%' - ], - [ - "{$checkout->getMollie()->amount->value} {$checkout->getMollie()->amount->currency}", - date('d.m.Y', strtotime($checkout->getMollie()->expiresAt)), - $checkout->getMollie()->details->bankName, - $checkout->getMollie()->details->bankAccount, - $checkout->getMollie()->details->bankBic, - $checkout->getMollie()->details->transferReference - ], - $template - ); - } - - public function getPaymentOptions(Bestellung $order, $apiType): array - { - $paymentOptions = []; - if ($apiType === 'payment') { - $paymentOptions['billingEmail'] = $order->oRechnungsadresse->cMail; - $paymentOptions['locale'] = Locale::getLocale(Frontend::get('cISOSprache', 'ger'), $order->oRechnungsadresse->cLand); - // TODO: Refactor this to use "PluginHelper::getPaymentSetting" once available - $dueDays = (int)self::Plugin('ws5_mollie')->getConfig()->getValue($this->moduleID . '_dueDays'); - if ($dueDays > 3) { - $paymentOptions['dueDate'] = date('Y-m-d', strtotime("+{$dueDays} DAYS")); - } - } - - return $paymentOptions; - } -} +cFirma) && strlen($_SESSION['Kunde']->cFirma)); - return $company && parent::isSelectable(); - } - -} \ No newline at end of file +clearToken(); - } - - protected function clearToken(): bool - { - $this->unsetCache(self::CACHE_TOKEN) - ->unsetCache(self::CACHE_TOKEN_TIMESTAMP); - - return true; - } - - public function handleAdditional(array $post): bool - { - // TODO: Refactor this to use "PluginHelper::getPaymentSetting" once available - $components = self::Plugin('ws5_mollie')->getConfig()->getValue($this->moduleID . '_components'); - $profileId = PluginHelper::getSetting('profileId'); - - if ($components === 'N' || !$profileId || trim($profileId) === '' || (array_key_exists('pruefekupon', $post) && $post['pruefekupon'] === '1')) { - return parent::handleAdditional($post); - } - - $cleared = false; - if (array_key_exists('clear', $post) && (int)$post['clear']) { - $cleared = $this->clearToken(); - } - - if ($components === 'S' && array_key_exists('skip', $post) && (int)$post['skip']) { - return parent::handleAdditional($post); - } - - // Skip handleAdditional if "Guthaben nutzen"-Request is being processed - if (array_key_exists('guthabenVerrechnen', $post) && (int)$post['guthabenVerrechnen'] === 1) { - return true; - } - - try { - // TODO: Refactor this to use "PluginHelper::getPaymentSetting" once available - $trustBadge = self::Plugin('ws5_mollie')->getConfig()->getValue($this->moduleID . '_trustBadge') === 'Y' - ? PluginHelper::getPlugin()->getPaths()->getFrontendURL() . 'img/trust_' . Frontend::getInstance()->getLanguage()->getIso() . '.png' - : false; - $locale = self::getLocale(Frontend::getInstance()->getLanguage()->getIso(), Frontend::getCustomer()->cLand ?? null); - $mode = MollieAPI::getMode(); - $errorMessage = json_encode(PluginHelper::getPlugin()->getLocalization()->getTranslation('mcErrorMessage'), JSON_THROW_ON_ERROR); - } catch (Exception $e) { - Shop::Container()->getLogService()->error($e->getMessage(), ['e' => $e]); - - return parent::handleAdditional($post); - } - - if (!$cleared && array_key_exists('cardToken', $post) && ($token = trim($post['cardToken']))) { - return $this->setToken($token) && parent::handleAdditional($post); - } - - if (($ctTS = (int)$this->getCache(self::CACHE_TOKEN_TIMESTAMP)) && $ctTS > time()) { - $token = $this->getCache(self::CACHE_TOKEN); - } - - Shop::Smarty()->assign('profileId', $profileId) - ->assign('trustBadge', $trustBadge ?? false) - ->assign('components', $components) - ->assign('locale', $locale ?? 'de_DE') - ->assign('token', $token ?? false) - ->assign('testMode', $mode ?? false) - ->assign('errorMessage', $errorMessage ?? 'Unexpected Error.') - ->assign('mollieLang', PluginHelper::getPlugin()->getLocalization()->getTranslations()); - - return false; - } - - protected function setToken(string $token): bool - { - $this->addCache(self::CACHE_TOKEN, $token) - ->addCache(self::CACHE_TOKEN_TIMESTAMP, time() + 3600); - - return true; - } - - public function getPaymentOptions(Bestellung $order, $apiType): array - { - $paymentOptions = []; - - if ($apiType === 'payment') { - if ($order->Lieferadresse !== null) { - if (!$order->Lieferadresse->cMail) { - $order->Lieferadresse->cMail = $order->oRechnungsadresse->cMail; - } - $paymentOptions['shippingAddress'] = new Address($order->Lieferadresse); - } - - $paymentOptions['billingAddress'] = new Address($order->oRechnungsadresse); - } - if ((int)$this->getCache(self::CACHE_TOKEN_TIMESTAMP) > time() && ($token = trim($this->getCache(self::CACHE_TOKEN)))) { - $paymentOptions['cardToken'] = $token; - } - - return $paymentOptions; - } -} + substr($order->cBestellNr, 0, 13)] : []; - } -} +Lieferadresse !== null) { - if (!$order->Lieferadresse->cMail) { - $order->Lieferadresse->cMail = $order->oRechnungsadresse->cMail; - } - $paymentOptions['shippingAddress'] = new Address($order->Lieferadresse); - } - $paymentOptions['description'] = 'Order ' . $order->cBestellNr; - } - - return $paymentOptions; - } -} + $order->oKunde->getID()] : []; - } -} + $order->oRechnungsadresse->cMail] : []; - } -} + \ No newline at end of file + + + + + + + diff --git a/paymentmethod/images/Payment_methods/banktransfer@2x.png b/paymentmethod/images/Payment_methods/banktransfer@2x.png index c70206b..0fb9f5b 100644 Binary files a/paymentmethod/images/Payment_methods/banktransfer@2x.png and b/paymentmethod/images/Payment_methods/banktransfer@2x.png differ diff --git a/paymentmethod/images/Payment_methods/klarnaOne@2x.png b/paymentmethod/images/Payment_methods/klarnaOne@2x.png new file mode 100644 index 0000000..5294a4b Binary files /dev/null and b/paymentmethod/images/Payment_methods/klarnaOne@2x.png differ diff --git a/paymentmethod/images/Payment_methods/riverty@2x.png b/paymentmethod/images/Payment_methods/riverty@2x.png new file mode 100644 index 0000000..1591aa4 Binary files /dev/null and b/paymentmethod/images/Payment_methods/riverty@2x.png differ diff --git a/paymentmethod/images/Payment_methods/trustly.png b/paymentmethod/images/Payment_methods/trustly.png new file mode 100644 index 0000000..0dc8420 Binary files /dev/null and b/paymentmethod/images/Payment_methods/trustly.png differ diff --git a/paymentmethod/images/Payment_methods/trustly@2x.png b/paymentmethod/images/Payment_methods/trustly@2x.png new file mode 100644 index 0000000..b2874d2 Binary files /dev/null and b/paymentmethod/images/Payment_methods/trustly@2x.png differ diff --git a/pluginSettings.json b/pluginSettings.json index d60201a..1f02bd6 100644 --- a/pluginSettings.json +++ b/pluginSettings.json @@ -55,7 +55,7 @@ { "id": "autoStorno", "label": "Unbezahlte Bestellungen stornieren", - "description": "Soll bei fehlgeschlagener Zahlung die Bestellung storniert werden? Angabe in Stunden nach Bestellung. (0 = deaktiviert)", + "description": "Soll bei fehlgeschlagener Zahlung die Bestellung storniert werden? Angabe in Stunden nach Bestellung. (0 = deaktiviert) Achtung: Gilt nur für Bestellungen, die noch nicht an die WaWi übertragen wurden.", "settingType": "input", "type": "int", "defaultValue": 0 @@ -99,6 +99,13 @@ "settingType": "checkbox", "defaultValue": false }, + { + "id": "syncExpirationDate", + "label": "Ablaufdatum als Bestellattribut an die WaWi übertragen", + "description": "Soll das Ablaufdatum von Bestellungen bei Mollie als Bestellattribut an die WaWi übertragen werden (mollieOrderExpirationDate)?", + "settingType": "checkbox", + "defaultValue": false + }, { "settingType": "heading", "label": "Allgemein"